Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
908c104c
Commit
908c104c
authored
Dec 04, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC64]: Copy over readv/writev 32-bit compat fixes from ppc64.
parent
a091cf75
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
71 additions
and
35 deletions
+71
-35
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sparc32.c
+71
-35
No files found.
arch/sparc64/kernel/sys_sparc32.c
View file @
908c104c
...
@@ -952,25 +952,40 @@ static long do_readv_writev32(int type, struct file *file,
...
@@ -952,25 +952,40 @@ static long do_readv_writev32(int type, struct file *file,
io_fn_t
fn
;
io_fn_t
fn
;
iov_fn_t
fnv
;
iov_fn_t
fnv
;
/*
* SuS says "The readv() function *may* fail if the iovcnt argument
* was less than or equal to 0, or greater than {IOV_MAX}. Linux has
* traditionally returned zero for zero segments, so...
*/
retval
=
0
;
if
(
count
==
0
)
goto
out
;
/* First get the "struct iovec" from user memory and
/* First get the "struct iovec" from user memory and
* verify all the pointers
* verify all the pointers
*/
*/
retval
=
0
;
if
(
!
count
)
goto
out_nofree
;
retval
=
-
EFAULT
;
if
(
verify_area
(
VERIFY_READ
,
vector
,
sizeof
(
struct
iovec32
)
*
count
))
goto
out_nofree
;
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
if
(
count
>
UIO_MAXIOV
)
if
(
count
>
UIO_MAXIOV
)
goto
out_nofree
;
goto
out
;
if
(
!
file
->
f_op
)
goto
out
;
if
(
count
>
UIO_FASTIOV
)
{
if
(
count
>
UIO_FASTIOV
)
{
retval
=
-
ENOMEM
;
retval
=
-
ENOMEM
;
iov
=
kmalloc
(
count
*
sizeof
(
struct
iovec
),
GFP_KERNEL
);
iov
=
kmalloc
(
count
*
sizeof
(
struct
iovec
),
GFP_KERNEL
);
if
(
!
iov
)
if
(
!
iov
)
goto
out
_nofree
;
goto
out
;
}
}
retval
=
-
EFAULT
;
if
(
verify_area
(
VERIFY_READ
,
vector
,
sizeof
(
struct
iovec32
)
*
count
))
goto
out
;
/*
* Single unix specification:
* We should -EINVAL if an element length is not >= 0 and fitting an
* ssize_t. The total length is fitting an ssize_t
*
* Be careful here because iov_len is a size_t not an ssize_t
*/
tot_len
=
0
;
tot_len
=
0
;
i
=
count
;
i
=
count
;
ivp
=
iov
;
ivp
=
iov
;
...
@@ -980,9 +995,12 @@ static long do_readv_writev32(int type, struct file *file,
...
@@ -980,9 +995,12 @@ static long do_readv_writev32(int type, struct file *file,
compat_ssize_t
len
;
compat_ssize_t
len
;
u32
buf
;
u32
buf
;
__get_user
(
len
,
&
vector
->
iov_len
);
if
(
__get_user
(
len
,
&
vector
->
iov_len
)
||
__get_user
(
buf
,
&
vector
->
iov_base
);
__get_user
(
buf
,
&
vector
->
iov_base
))
{
if
(
len
<
0
)
/* size_t not fittina an compat_ssize_t .. */
retval
=
-
EFAULT
;
goto
out
;
}
if
(
len
<
0
)
/* size_t not fitting an ssize_t32 .. */
goto
out
;
goto
out
;
tot_len
+=
len
;
tot_len
+=
len
;
if
(
tot_len
<
tmp
)
/* maths overflow on the compat_ssize_t */
if
(
tot_len
<
tmp
)
/* maths overflow on the compat_ssize_t */
...
@@ -993,25 +1011,32 @@ static long do_readv_writev32(int type, struct file *file,
...
@@ -993,25 +1011,32 @@ static long do_readv_writev32(int type, struct file *file,
ivp
++
;
ivp
++
;
i
--
;
i
--
;
}
}
if
(
tot_len
==
0
)
{
retval
=
0
;
goto
out
;
}
inode
=
file
->
f_dentry
->
d_inode
;
inode
=
file
->
f_dentry
->
d_inode
;
/* VERIFY_WRITE actually means a read, as we write to user space */
/* VERIFY_WRITE actually means a read, as we write to user space */
retval
=
locks_verify_area
((
type
==
VERIFY_WRITE
retval
=
locks_verify_area
((
type
==
READ
?
FLOCK_VERIFY_READ
:
FLOCK_VERIFY_WRITE
),
?
FLOCK_VERIFY_READ
:
FLOCK_VERIFY_WRITE
),
inode
,
file
,
file
->
f_pos
,
tot_len
);
inode
,
file
,
file
->
f_pos
,
tot_len
);
if
(
retval
)
if
(
retval
)
goto
out
;
goto
out
;
/* VERIFY_WRITE actually means a read, as we write to user space */
if
(
type
==
READ
)
{
fnv
=
(
type
==
VERIFY_WRITE
?
file
->
f_op
->
readv
:
file
->
f_op
->
writev
);
fn
=
file
->
f_op
->
read
;
fnv
=
file
->
f_op
->
readv
;
}
else
{
fn
=
(
io_fn_t
)
file
->
f_op
->
write
;
fnv
=
file
->
f_op
->
writev
;
}
if
(
fnv
)
{
if
(
fnv
)
{
retval
=
fnv
(
file
,
iov
,
count
,
&
file
->
f_pos
);
retval
=
fnv
(
file
,
iov
,
count
,
&
file
->
f_pos
);
goto
out
;
goto
out
;
}
}
fn
=
(
type
==
VERIFY_WRITE
?
file
->
f_op
->
read
:
/* Do it by hand, with file-ops */
(
io_fn_t
)
file
->
f_op
->
write
);
ivp
=
iov
;
ivp
=
iov
;
while
(
count
>
0
)
{
while
(
count
>
0
)
{
void
*
base
;
void
*
base
;
...
@@ -1021,7 +1046,9 @@ static long do_readv_writev32(int type, struct file *file,
...
@@ -1021,7 +1046,9 @@ static long do_readv_writev32(int type, struct file *file,
len
=
ivp
->
iov_len
;
len
=
ivp
->
iov_len
;
ivp
++
;
ivp
++
;
count
--
;
count
--
;
nr
=
fn
(
file
,
base
,
len
,
&
file
->
f_pos
);
nr
=
fn
(
file
,
base
,
len
,
&
file
->
f_pos
);
if
(
nr
<
0
)
{
if
(
nr
<
0
)
{
if
(
!
retval
)
if
(
!
retval
)
retval
=
nr
;
retval
=
nr
;
...
@@ -1034,11 +1061,9 @@ static long do_readv_writev32(int type, struct file *file,
...
@@ -1034,11 +1061,9 @@ static long do_readv_writev32(int type, struct file *file,
out:
out:
if
(
iov
!=
iovstack
)
if
(
iov
!=
iovstack
)
kfree
(
iov
);
kfree
(
iov
);
out_nofree:
if
((
retval
+
(
type
==
READ
))
>
0
)
/* VERIFY_WRITE actually means a read, as we write to user space */
if
((
retval
+
(
type
==
VERIFY_WRITE
))
>
0
)
dnotify_parent
(
file
->
f_dentry
,
dnotify_parent
(
file
->
f_dentry
,
(
type
==
VERIFY_WRITE
)
?
DN_ACCESS
:
DN_MODIFY
);
(
type
==
READ
)
?
DN_ACCESS
:
DN_MODIFY
);
return
retval
;
return
retval
;
}
}
...
@@ -1046,35 +1071,46 @@ static long do_readv_writev32(int type, struct file *file,
...
@@ -1046,35 +1071,46 @@ static long do_readv_writev32(int type, struct file *file,
asmlinkage
long
sys32_readv
(
int
fd
,
struct
iovec32
*
vector
,
u32
count
)
asmlinkage
long
sys32_readv
(
int
fd
,
struct
iovec32
*
vector
,
u32
count
)
{
{
struct
file
*
file
;
struct
file
*
file
;
long
ret
=
-
EBADF
;
int
ret
;
file
=
fget
(
fd
);
file
=
fget
(
fd
);
if
(
!
file
)
if
(
!
file
)
goto
bad_file
;
return
-
EBADF
;
if
(
file
->
f_op
&&
(
file
->
f_mode
&
FMODE_READ
)
&&
ret
=
-
EBADF
;
(
file
->
f_op
->
readv
||
file
->
f_op
->
read
))
if
(
!
(
file
->
f_mode
&
FMODE_READ
))
ret
=
do_readv_writev32
(
VERIFY_WRITE
,
file
,
vector
,
count
);
goto
out
;
fput
(
file
);
ret
=
-
EINVAL
;
if
(
!
file
->
f_op
||
(
!
file
->
f_op
->
readv
&&
!
file
->
f_op
->
read
))
goto
out
;
ret
=
do_readv_writev32
(
READ
,
file
,
vector
,
count
);
bad_file:
out:
fput
(
file
);
return
ret
;
return
ret
;
}
}
asmlinkage
long
sys32_writev
(
int
fd
,
struct
iovec32
*
vector
,
u32
count
)
asmlinkage
long
sys32_writev
(
int
fd
,
struct
iovec32
*
vector
,
u32
count
)
{
{
struct
file
*
file
;
struct
file
*
file
;
int
ret
=
-
EBADF
;
int
ret
;
file
=
fget
(
fd
);
file
=
fget
(
fd
);
if
(
!
file
)
if
(
!
file
)
goto
bad_file
;
return
-
EBADF
;
if
(
file
->
f_op
&&
(
file
->
f_mode
&
FMODE_WRITE
)
&&
(
file
->
f_op
->
writev
||
file
->
f_op
->
write
))
ret
=
do_readv_writev32
(
VERIFY_READ
,
file
,
vector
,
count
);
fput
(
file
);
bad_file:
ret
=
-
EBADF
;
if
(
!
(
file
->
f_mode
&
FMODE_WRITE
))
goto
out
;
ret
=
-
EINVAL
;
if
(
!
file
->
f_op
||
(
!
file
->
f_op
->
writev
&&
!
file
->
f_op
->
write
))
goto
out
;
ret
=
do_readv_writev32
(
WRITE
,
file
,
vector
,
count
);
out:
fput
(
file
);
return
ret
;
return
ret
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment