Revert "vfs: make AIO use the proper rw_verify_area() area helpers"
This change is already present in current kernel 3.10 via commit
a70b52ec1aaeaf60f4739edb1b422827cb6f3893.
This reverts commit 99315b974f1f85e44bdfe8f9caf5e1cdbf8125e6.
Change-Id: I514162e7cd0a6dfd05c16c246b7954537f0af109
Tracked-On: https://jira01.devtools.intel.com/browse/AW-2060
Signed-off-by: Victor Tasayco Loarte <victorx.tasayco.loarte@intel.com>
diff --git a/fs/aio.c b/fs/aio.c
index 379639e..9798d4e 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -970,34 +970,30 @@
if (ret < 0)
return ret;
- ret = rw_verify_area(rw, kiocb->ki_filp, &kiocb->ki_pos, ret);
- if (ret < 0)
- return ret;
-
- kiocb->ki_nr_segs = kiocb->ki_nbytes;
- kiocb->ki_cur_seg = 0;
- /* ki_nbytes/left now reflect bytes instead of segs */
+ /* ki_nbytes now reflect bytes instead of segs */
kiocb->ki_nbytes = ret;
return 0;
}
-static ssize_t aio_setup_single_vector(int type, struct file * file, struct kiocb *kiocb)
+static ssize_t aio_setup_single_vector(int rw, struct kiocb *kiocb)
{
- int bytes;
+ size_t len = kiocb->ki_nbytes;
- bytes = rw_verify_area(type, file, &kiocb->ki_pos, kiocb->ki_left);
- if (bytes < 0)
- return bytes;
+ if (len > MAX_RW_COUNT)
+ len = MAX_RW_COUNT;
+
+ if (unlikely(!access_ok(!rw, kiocb->ki_buf, len)))
+ return -EFAULT;
kiocb->ki_iovec = &kiocb->ki_inline_vec;
kiocb->ki_iovec->iov_base = kiocb->ki_buf;
- kiocb->ki_iovec->iov_len = bytes;
+ kiocb->ki_iovec->iov_len = len;
kiocb->ki_nr_segs = 1;
return 0;
}
/*
- * aio_run_iocb:
+ * aio_setup_iocb:
* Performs the initial checks and aio retry method
* setup for the kiocb at the time of io submission.
*/
@@ -1011,45 +1007,29 @@
switch (req->ki_opcode) {
case IOCB_CMD_PREAD:
- ret = -EBADF;
- if (unlikely(!(file->f_mode & FMODE_READ)))
- break;
- ret = -EFAULT;
- if (unlikely(!access_ok(VERIFY_WRITE, req->ki_buf,
- req->ki_left)))
- break;
- ret = aio_setup_single_vector(READ, file, req);
- if (ret)
- break;
- ret = -EINVAL;
- break;
- case IOCB_CMD_PWRITE:
- ret = -EBADF;
- if (unlikely(!(file->f_mode & FMODE_WRITE)))
- break;
- ret = -EFAULT;
- if (unlikely(!access_ok(VERIFY_READ, req->ki_buf,
- req->ki_left)))
- break;
- ret = aio_setup_single_vector(WRITE, file, req);
- if (ret)
- break;
- ret = -EINVAL;
- break;
case IOCB_CMD_PREADV:
- ret = -EBADF;
- if (unlikely(!(file->f_mode & FMODE_READ)))
- break;
- ret = aio_setup_vectored_rw(READ, req, compat);
- if (ret)
- break;
- ret = -EINVAL;
- break;
+ mode = FMODE_READ;
+ rw = READ;
+ rw_op = file->f_op->aio_read;
+ goto rw_common;
+
+ case IOCB_CMD_PWRITE:
case IOCB_CMD_PWRITEV:
- ret = -EBADF;
- if (unlikely(!(file->f_mode & FMODE_WRITE)))
- break;
- ret = aio_setup_vectored_rw(WRITE, req, compat);
+ mode = FMODE_WRITE;
+ rw = WRITE;
+ rw_op = file->f_op->aio_write;
+ goto rw_common;
+rw_common:
+ if (unlikely(!(file->f_mode & mode)))
+ return -EBADF;
+
+ if (!rw_op)
+ return -EINVAL;
+
+ ret = (req->ki_opcode == IOCB_CMD_PREADV ||
+ req->ki_opcode == IOCB_CMD_PWRITEV)
+ ? aio_setup_vectored_rw(rw, req, compat)
+ : aio_setup_single_vector(rw, req);
if (ret)
return ret;