summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTasayco Loarte, VictorX <victorx.tasayco.loarte@intel.com>2016-09-27 09:08:58 +0100
committerVictor Tasayco Loarte <victorx.tasayco.loarte@intel.com>2016-09-27 10:43:07 +0200
commit84a4d0e435e4f0d7cb24ad5aec0162fbd8d13831 (patch)
tree0b2e2f57a6c8d6604486a27de023c2a467330d9b
parent6f46fc00b7f3e7a2a717f83768da4734891b16c9 (diff)
downloadx86-android-x86-glacier-3.10-marshmallow-mr1-wear-release.tar.gz
Revert "vfs: make AIO use the proper rw_verify_area() area helpers"android-wear-6.0.1_r0.74android-x86-glacier-3.10-marshmallow-mr1-wear-release
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>
-rw-r--r--fs/aio.c82
1 files changed, 31 insertions, 51 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 379639e41237..9798d4edfd8f 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -970,34 +970,30 @@ static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat)
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 @@ static ssize_t aio_run_iocb(struct kiocb *req, bool compat)
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;