mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-13 15:53:56 +08:00
vfs: vfs: Define new syscalls preadv2,pwritev2
New syscalls that take an flag argument. No flags are added yet in this patch. Signed-off-by: Milosz Tanski <milosz@adfin.com> [hch: rebased on top of my kiocb changes] Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Stephen Bates <stephen.bates@pmcs.com> Tested-by: Stephen Bates <stephen.bates@pmcs.com> Acked-by: Jeff Moyer <jmoyer@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
793b80ef14
commit
f17d8b3545
161
fs/read_write.c
161
fs/read_write.c
@ -895,15 +895,15 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
|
||||
|
||||
EXPORT_SYMBOL(vfs_writev);
|
||||
|
||||
SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen)
|
||||
static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, int flags)
|
||||
{
|
||||
struct fd f = fdget_pos(fd);
|
||||
ssize_t ret = -EBADF;
|
||||
|
||||
if (f.file) {
|
||||
loff_t pos = file_pos_read(f.file);
|
||||
ret = vfs_readv(f.file, vec, vlen, &pos, 0);
|
||||
ret = vfs_readv(f.file, vec, vlen, &pos, flags);
|
||||
if (ret >= 0)
|
||||
file_pos_write(f.file, pos);
|
||||
fdput_pos(f);
|
||||
@ -915,15 +915,15 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen)
|
||||
static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, int flags)
|
||||
{
|
||||
struct fd f = fdget_pos(fd);
|
||||
ssize_t ret = -EBADF;
|
||||
|
||||
if (f.file) {
|
||||
loff_t pos = file_pos_read(f.file);
|
||||
ret = vfs_writev(f.file, vec, vlen, &pos, 0);
|
||||
ret = vfs_writev(f.file, vec, vlen, &pos, flags);
|
||||
if (ret >= 0)
|
||||
file_pos_write(f.file, pos);
|
||||
fdput_pos(f);
|
||||
@ -941,10 +941,9 @@ static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
|
||||
return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
|
||||
static ssize_t do_preadv(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos, int flags)
|
||||
{
|
||||
loff_t pos = pos_from_hilo(pos_h, pos_l);
|
||||
struct fd f;
|
||||
ssize_t ret = -EBADF;
|
||||
|
||||
@ -955,7 +954,7 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
|
||||
if (f.file) {
|
||||
ret = -ESPIPE;
|
||||
if (f.file->f_mode & FMODE_PREAD)
|
||||
ret = vfs_readv(f.file, vec, vlen, &pos, 0);
|
||||
ret = vfs_readv(f.file, vec, vlen, &pos, flags);
|
||||
fdput(f);
|
||||
}
|
||||
|
||||
@ -965,10 +964,9 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
|
||||
static ssize_t do_pwritev(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos, int flags)
|
||||
{
|
||||
loff_t pos = pos_from_hilo(pos_h, pos_l);
|
||||
struct fd f;
|
||||
ssize_t ret = -EBADF;
|
||||
|
||||
@ -979,7 +977,7 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
|
||||
if (f.file) {
|
||||
ret = -ESPIPE;
|
||||
if (f.file->f_mode & FMODE_PWRITE)
|
||||
ret = vfs_writev(f.file, vec, vlen, &pos, 0);
|
||||
ret = vfs_writev(f.file, vec, vlen, &pos, flags);
|
||||
fdput(f);
|
||||
}
|
||||
|
||||
@ -989,6 +987,58 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen)
|
||||
{
|
||||
return do_readv(fd, vec, vlen, 0);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen)
|
||||
{
|
||||
return do_writev(fd, vec, vlen, 0);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
|
||||
{
|
||||
loff_t pos = pos_from_hilo(pos_h, pos_l);
|
||||
|
||||
return do_preadv(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE6(preadv2, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
|
||||
int, flags)
|
||||
{
|
||||
loff_t pos = pos_from_hilo(pos_h, pos_l);
|
||||
|
||||
if (pos == -1)
|
||||
return do_readv(fd, vec, vlen, flags);
|
||||
|
||||
return do_preadv(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
|
||||
{
|
||||
loff_t pos = pos_from_hilo(pos_h, pos_l);
|
||||
|
||||
return do_pwritev(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec,
|
||||
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
|
||||
int, flags)
|
||||
{
|
||||
loff_t pos = pos_from_hilo(pos_h, pos_l);
|
||||
|
||||
if (pos == -1)
|
||||
return do_writev(fd, vec, vlen, flags);
|
||||
|
||||
return do_pwritev(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
static ssize_t compat_do_readv_writev(int type, struct file *file,
|
||||
@ -1046,7 +1096,7 @@ out:
|
||||
|
||||
static size_t compat_readv(struct file *file,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t *pos)
|
||||
unsigned long vlen, loff_t *pos, int flags)
|
||||
{
|
||||
ssize_t ret = -EBADF;
|
||||
|
||||
@ -1057,7 +1107,7 @@ static size_t compat_readv(struct file *file,
|
||||
if (!(file->f_mode & FMODE_CAN_READ))
|
||||
goto out;
|
||||
|
||||
ret = compat_do_readv_writev(READ, file, vec, vlen, pos, 0);
|
||||
ret = compat_do_readv_writev(READ, file, vec, vlen, pos, flags);
|
||||
|
||||
out:
|
||||
if (ret > 0)
|
||||
@ -1066,9 +1116,9 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
compat_ulong_t, vlen)
|
||||
static size_t do_compat_readv(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
compat_ulong_t vlen, int flags)
|
||||
{
|
||||
struct fd f = fdget_pos(fd);
|
||||
ssize_t ret;
|
||||
@ -1077,16 +1127,24 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
pos = f.file->f_pos;
|
||||
ret = compat_readv(f.file, vec, vlen, &pos);
|
||||
ret = compat_readv(f.file, vec, vlen, &pos, flags);
|
||||
if (ret >= 0)
|
||||
f.file->f_pos = pos;
|
||||
fdput_pos(f);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static long __compat_sys_preadv64(unsigned long fd,
|
||||
COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
compat_ulong_t, vlen)
|
||||
{
|
||||
return do_compat_readv(fd, vec, vlen, 0);
|
||||
}
|
||||
|
||||
static long do_compat_preadv64(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos)
|
||||
unsigned long vlen, loff_t pos, int flags)
|
||||
{
|
||||
struct fd f;
|
||||
ssize_t ret;
|
||||
@ -1098,7 +1156,7 @@ static long __compat_sys_preadv64(unsigned long fd,
|
||||
return -EBADF;
|
||||
ret = -ESPIPE;
|
||||
if (f.file->f_mode & FMODE_PREAD)
|
||||
ret = compat_readv(f.file, vec, vlen, &pos);
|
||||
ret = compat_readv(f.file, vec, vlen, &pos, flags);
|
||||
fdput(f);
|
||||
return ret;
|
||||
}
|
||||
@ -1108,7 +1166,7 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
unsigned long, vlen, loff_t, pos)
|
||||
{
|
||||
return __compat_sys_preadv64(fd, vec, vlen, pos);
|
||||
return do_compat_preadv64(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1118,12 +1176,25 @@ COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
return __compat_sys_preadv64(fd, vec, vlen, pos);
|
||||
return do_compat_preadv64(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
compat_ulong_t, vlen, u32, pos_low, u32, pos_high,
|
||||
int, flags)
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
if (pos == -1)
|
||||
return do_compat_readv(fd, vec, vlen, flags);
|
||||
|
||||
return do_compat_preadv64(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
static size_t compat_writev(struct file *file,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t *pos)
|
||||
unsigned long vlen, loff_t *pos, int flags)
|
||||
{
|
||||
ssize_t ret = -EBADF;
|
||||
|
||||
@ -1143,9 +1214,9 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *, vec,
|
||||
compat_ulong_t, vlen)
|
||||
static size_t do_compat_writev(compat_ulong_t fd,
|
||||
const struct compat_iovec __user* vec,
|
||||
compat_ulong_t vlen, int flags)
|
||||
{
|
||||
struct fd f = fdget_pos(fd);
|
||||
ssize_t ret;
|
||||
@ -1154,16 +1225,23 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
pos = f.file->f_pos;
|
||||
ret = compat_writev(f.file, vec, vlen, &pos);
|
||||
ret = compat_writev(f.file, vec, vlen, &pos, flags);
|
||||
if (ret >= 0)
|
||||
f.file->f_pos = pos;
|
||||
fdput_pos(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long __compat_sys_pwritev64(unsigned long fd,
|
||||
COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *, vec,
|
||||
compat_ulong_t, vlen)
|
||||
{
|
||||
return do_compat_writev(fd, vec, vlen, 0);
|
||||
}
|
||||
|
||||
static long do_compat_pwritev64(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos)
|
||||
unsigned long vlen, loff_t pos, int flags)
|
||||
{
|
||||
struct fd f;
|
||||
ssize_t ret;
|
||||
@ -1175,7 +1253,7 @@ static long __compat_sys_pwritev64(unsigned long fd,
|
||||
return -EBADF;
|
||||
ret = -ESPIPE;
|
||||
if (f.file->f_mode & FMODE_PWRITE)
|
||||
ret = compat_writev(f.file, vec, vlen, &pos);
|
||||
ret = compat_writev(f.file, vec, vlen, &pos, flags);
|
||||
fdput(f);
|
||||
return ret;
|
||||
}
|
||||
@ -1185,7 +1263,7 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
unsigned long, vlen, loff_t, pos)
|
||||
{
|
||||
return __compat_sys_pwritev64(fd, vec, vlen, pos);
|
||||
return do_compat_pwritev64(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1195,8 +1273,21 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
return __compat_sys_pwritev64(fd, vec, vlen, pos);
|
||||
return do_compat_pwritev64(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
compat_ulong_t, vlen, u32, pos_low, u32, pos_high, int, flags)
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
if (pos == -1)
|
||||
return do_compat_writev(fd, vec, vlen, flags);
|
||||
|
||||
return do_compat_pwritev64(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
||||
|
@ -340,6 +340,12 @@ asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
|
||||
asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
compat_ulong_t vlen, u32 pos_low, u32 pos_high);
|
||||
asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
compat_ulong_t vlen, u32 pos_low, u32 pos_high, int flags);
|
||||
asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
compat_ulong_t vlen, u32 pos_low, u32 pos_high, int flags);
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
|
||||
asmlinkage long compat_sys_preadv64(unsigned long fd,
|
||||
|
@ -575,8 +575,14 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
|
||||
size_t count, loff_t pos);
|
||||
asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
|
||||
asmlinkage long sys_preadv2(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, unsigned long pos_l, unsigned long pos_h,
|
||||
int flags);
|
||||
asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
|
||||
asmlinkage long sys_pwritev2(unsigned long fd, const struct iovec __user *vec,
|
||||
unsigned long vlen, unsigned long pos_l, unsigned long pos_h,
|
||||
int flags);
|
||||
asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
|
||||
asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode);
|
||||
asmlinkage long sys_chdir(const char __user *filename);
|
||||
|
Loading…
Reference in New Issue
Block a user