aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-03-20 20:17:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-04-11 22:26:45 -0400
commit4c185ce06dca14f5cea192f5a2c981ef50663f2b (patch)
tree1a6d775a568d477089b85690160f11b07a812180
parentac15ac0669d5f5ce7fddec0d9cf3721c42d77a2c (diff)
aio: lift iov_iter_init() into aio_setup_..._rw()
the only non-trivial detail is that we do it before rw_verify_area(), so we'd better cap the length ourselves in aio_setup_single_rw() case (for vectored case rw_copy_check_uvector() will do that for us). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/aio.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 435ca29eca31..7816e8ec3c0e 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1357,7 +1357,8 @@ static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb,
1357 unsigned long *nr_segs, 1357 unsigned long *nr_segs,
1358 size_t *len, 1358 size_t *len,
1359 struct iovec **iovec, 1359 struct iovec **iovec,
1360 bool compat) 1360 bool compat,
1361 struct iov_iter *iter)
1361{ 1362{
1362 ssize_t ret; 1363 ssize_t ret;
1363 1364
@@ -1378,6 +1379,7 @@ static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb,
1378 1379
1379 /* len now reflect bytes instead of segs */ 1380 /* len now reflect bytes instead of segs */
1380 *len = ret; 1381 *len = ret;
1382 iov_iter_init(iter, rw, *iovec, *nr_segs, *len);
1381 return 0; 1383 return 0;
1382} 1384}
1383 1385
@@ -1385,14 +1387,18 @@ static ssize_t aio_setup_single_vector(struct kiocb *kiocb,
1385 int rw, char __user *buf, 1387 int rw, char __user *buf,
1386 unsigned long *nr_segs, 1388 unsigned long *nr_segs,
1387 size_t len, 1389 size_t len,
1388 struct iovec *iovec) 1390 struct iovec *iovec,
1391 struct iov_iter *iter)
1389{ 1392{
1393 if (len > MAX_RW_COUNT)
1394 len = MAX_RW_COUNT;
1390 if (unlikely(!access_ok(!rw, buf, len))) 1395 if (unlikely(!access_ok(!rw, buf, len)))
1391 return -EFAULT; 1396 return -EFAULT;
1392 1397
1393 iovec->iov_base = buf; 1398 iovec->iov_base = buf;
1394 iovec->iov_len = len; 1399 iovec->iov_len = len;
1395 *nr_segs = 1; 1400 *nr_segs = 1;
1401 iov_iter_init(iter, rw, iovec, *nr_segs, len);
1396 return 0; 1402 return 0;
1397} 1403}
1398 1404
@@ -1438,10 +1444,10 @@ rw_common:
1438 1444
1439 if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV) 1445 if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV)
1440 ret = aio_setup_vectored_rw(req, rw, buf, &nr_segs, 1446 ret = aio_setup_vectored_rw(req, rw, buf, &nr_segs,
1441 &len, &iovec, compat); 1447 &len, &iovec, compat, &iter);
1442 else 1448 else
1443 ret = aio_setup_single_vector(req, rw, buf, &nr_segs, 1449 ret = aio_setup_single_vector(req, rw, buf, &nr_segs,
1444 len, iovec); 1450 len, iovec, &iter);
1445 if (!ret) 1451 if (!ret)
1446 ret = rw_verify_area(rw, file, &req->ki_pos, len); 1452 ret = rw_verify_area(rw, file, &req->ki_pos, len);
1447 if (ret < 0) { 1453 if (ret < 0) {
@@ -1463,10 +1469,9 @@ rw_common:
1463 file_start_write(file); 1469 file_start_write(file);
1464 1470
1465 if (iter_op) { 1471 if (iter_op) {
1466 iov_iter_init(&iter, rw, iovec, nr_segs, len);
1467 ret = iter_op(req, &iter); 1472 ret = iter_op(req, &iter);
1468 } else { 1473 } else {
1469 ret = rw_op(req, iovec, nr_segs, req->ki_pos); 1474 ret = rw_op(req, iter.iov, iter.nr_segs, req->ki_pos);
1470 } 1475 }
1471 1476
1472 if (rw == WRITE) 1477 if (rw == WRITE)