vfs: extract common parts of {compat_,}do_readv_writev()
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
bfe219d373
commit
7687a7a443
|
@ -834,25 +834,15 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t do_readv_writev(int type, struct file *file,
|
static ssize_t __do_readv_writev(int type, struct file *file,
|
||||||
const struct iovec __user * uvector,
|
struct iov_iter *iter, loff_t *pos, int flags)
|
||||||
unsigned long nr_segs, loff_t *pos,
|
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
size_t tot_len;
|
size_t tot_len;
|
||||||
struct iovec iovstack[UIO_FASTIOV];
|
ssize_t ret = 0;
|
||||||
struct iovec *iov = iovstack;
|
|
||||||
struct iov_iter iter;
|
|
||||||
ssize_t ret;
|
|
||||||
io_fn_t fn;
|
io_fn_t fn;
|
||||||
iter_fn_t iter_fn;
|
iter_fn_t iter_fn;
|
||||||
|
|
||||||
ret = import_iovec(type, uvector, nr_segs,
|
tot_len = iov_iter_count(iter);
|
||||||
ARRAY_SIZE(iovstack), &iov, &iter);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
tot_len = iov_iter_count(&iter);
|
|
||||||
if (!tot_len)
|
if (!tot_len)
|
||||||
goto out;
|
goto out;
|
||||||
ret = rw_verify_area(type, file, pos, tot_len);
|
ret = rw_verify_area(type, file, pos, tot_len);
|
||||||
|
@ -869,15 +859,14 @@ static ssize_t do_readv_writev(int type, struct file *file,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter_fn)
|
if (iter_fn)
|
||||||
ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags);
|
ret = do_iter_readv_writev(file, iter, pos, iter_fn, flags);
|
||||||
else
|
else
|
||||||
ret = do_loop_readv_writev(file, &iter, pos, fn, flags);
|
ret = do_loop_readv_writev(file, iter, pos, fn, flags);
|
||||||
|
|
||||||
if (type != READ)
|
if (type != READ)
|
||||||
file_end_write(file);
|
file_end_write(file);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(iov);
|
|
||||||
if ((ret + (type == READ)) > 0) {
|
if ((ret + (type == READ)) > 0) {
|
||||||
if (type == READ)
|
if (type == READ)
|
||||||
fsnotify_access(file);
|
fsnotify_access(file);
|
||||||
|
@ -887,6 +876,27 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t do_readv_writev(int type, struct file *file,
|
||||||
|
const struct iovec __user *uvector,
|
||||||
|
unsigned long nr_segs, loff_t *pos,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
struct iovec iovstack[UIO_FASTIOV];
|
||||||
|
struct iovec *iov = iovstack;
|
||||||
|
struct iov_iter iter;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
ret = import_iovec(type, uvector, nr_segs,
|
||||||
|
ARRAY_SIZE(iovstack), &iov, &iter);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = __do_readv_writev(type, file, &iter, pos, flags);
|
||||||
|
kfree(iov);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
|
ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
|
||||||
unsigned long vlen, loff_t *pos, int flags)
|
unsigned long vlen, loff_t *pos, int flags)
|
||||||
{
|
{
|
||||||
|
@ -1064,51 +1074,19 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
|
||||||
unsigned long nr_segs, loff_t *pos,
|
unsigned long nr_segs, loff_t *pos,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
compat_ssize_t tot_len;
|
|
||||||
struct iovec iovstack[UIO_FASTIOV];
|
struct iovec iovstack[UIO_FASTIOV];
|
||||||
struct iovec *iov = iovstack;
|
struct iovec *iov = iovstack;
|
||||||
struct iov_iter iter;
|
struct iov_iter iter;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
io_fn_t fn;
|
|
||||||
iter_fn_t iter_fn;
|
|
||||||
|
|
||||||
ret = compat_import_iovec(type, uvector, nr_segs,
|
ret = compat_import_iovec(type, uvector, nr_segs,
|
||||||
UIO_FASTIOV, &iov, &iter);
|
UIO_FASTIOV, &iov, &iter);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
tot_len = iov_iter_count(&iter);
|
ret = __do_readv_writev(type, file, &iter, pos, flags);
|
||||||
if (!tot_len)
|
|
||||||
goto out;
|
|
||||||
ret = rw_verify_area(type, file, pos, tot_len);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (type == READ) {
|
|
||||||
fn = file->f_op->read;
|
|
||||||
iter_fn = file->f_op->read_iter;
|
|
||||||
} else {
|
|
||||||
fn = (io_fn_t)file->f_op->write;
|
|
||||||
iter_fn = file->f_op->write_iter;
|
|
||||||
file_start_write(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter_fn)
|
|
||||||
ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags);
|
|
||||||
else
|
|
||||||
ret = do_loop_readv_writev(file, &iter, pos, fn, flags);
|
|
||||||
|
|
||||||
if (type != READ)
|
|
||||||
file_end_write(file);
|
|
||||||
|
|
||||||
out:
|
|
||||||
kfree(iov);
|
kfree(iov);
|
||||||
if ((ret + (type == READ)) > 0) {
|
|
||||||
if (type == READ)
|
|
||||||
fsnotify_access(file);
|
|
||||||
else
|
|
||||||
fsnotify_modify(file);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue