Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f78d06a authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

vfs: pass type instead of fn to do_{loop,iter}_readv_writev()

parent 7687a7a4
Loading
Loading
Loading
Loading
+18 −19
Original line number Diff line number Diff line
@@ -23,9 +23,6 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>

typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
typedef ssize_t (*iter_fn_t)(struct kiocb *, struct iov_iter *);

const struct file_operations generic_ro_fops = {
	.llseek		= generic_file_llseek,
	.read_iter	= generic_file_read_iter,
@@ -675,7 +672,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
EXPORT_SYMBOL(iov_shorten);

static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
		loff_t *ppos, iter_fn_t fn, int flags)
		loff_t *ppos, int type, int flags)
{
	struct kiocb kiocb;
	ssize_t ret;
@@ -692,7 +689,10 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
		kiocb.ki_flags |= (IOCB_DSYNC | IOCB_SYNC);
	kiocb.ki_pos = *ppos;

	ret = fn(&kiocb, iter);
	if (type == READ)
		ret = filp->f_op->read_iter(&kiocb, iter);
	else
		ret = filp->f_op->write_iter(&kiocb, iter);
	BUG_ON(ret == -EIOCBQUEUED);
	*ppos = kiocb.ki_pos;
	return ret;
@@ -700,7 +700,7 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,

/* Do it by hand, with file-ops */
static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
		loff_t *ppos, io_fn_t fn, int flags)
		loff_t *ppos, int type, int flags)
{
	ssize_t ret = 0;

@@ -711,7 +711,13 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
		struct iovec iovec = iov_iter_iovec(iter);
		ssize_t nr;

		nr = fn(filp, iovec.iov_base, iovec.iov_len, ppos);
		if (type == READ) {
			nr = filp->f_op->read(filp, iovec.iov_base,
					      iovec.iov_len, ppos);
		} else {
			nr = filp->f_op->write(filp, iovec.iov_base,
					       iovec.iov_len, ppos);
		}

		if (nr < 0) {
			if (!ret)
@@ -839,8 +845,6 @@ static ssize_t __do_readv_writev(int type, struct file *file,
{
	size_t tot_len;
	ssize_t ret = 0;
	io_fn_t fn;
	iter_fn_t iter_fn;

	tot_len = iov_iter_count(iter);
	if (!tot_len)
@@ -849,19 +853,14 @@ static ssize_t __do_readv_writev(int type, struct file *file,
	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;
	if (type != READ)
		file_start_write(file);
	}

	if (iter_fn)
		ret = do_iter_readv_writev(file, iter, pos, iter_fn, flags);
	if ((type == READ && file->f_op->read_iter) ||
	    (type == WRITE && file->f_op->write_iter))
		ret = do_iter_readv_writev(file, iter, pos, type, flags);
	else
		ret = do_loop_readv_writev(file, iter, pos, fn, flags);
		ret = do_loop_readv_writev(file, iter, pos, type, flags);

	if (type != READ)
		file_end_write(file);