diff options
author | Christoph Hellwig <hch@lst.de> | 2018-05-02 13:57:21 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2018-05-02 13:57:21 -0400 |
commit | 54843f875f7a9f802bbb0d9895c3266b4a0b2f37 (patch) | |
tree | 913604f34f93f8af030a457f102216fef133f0b8 /fs/aio.c | |
parent | 92ce4728563ad1fc42466f9bbecc1ac31d675894 (diff) |
aio: refactor read/write iocb setup
Don't reference the kiocb structure from the common aio code, and move
any use of it into helper specific to the read/write path. This is in
preparation for aio_poll support that wants to use the space for different
fields.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Jeff Moyer <jmoyer@redhat.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 161 |
1 files changed, 92 insertions, 69 deletions
@@ -170,7 +170,9 @@ struct kioctx { | |||
170 | #define KIOCB_CANCELLED ((void *) (~0ULL)) | 170 | #define KIOCB_CANCELLED ((void *) (~0ULL)) |
171 | 171 | ||
172 | struct aio_kiocb { | 172 | struct aio_kiocb { |
173 | struct kiocb common; | 173 | union { |
174 | struct kiocb rw; | ||
175 | }; | ||
174 | 176 | ||
175 | struct kioctx *ki_ctx; | 177 | struct kioctx *ki_ctx; |
176 | kiocb_cancel_fn *ki_cancel; | 178 | kiocb_cancel_fn *ki_cancel; |
@@ -549,7 +551,7 @@ static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events) | |||
549 | 551 | ||
550 | void kiocb_set_cancel_fn(struct kiocb *iocb, kiocb_cancel_fn *cancel) | 552 | void kiocb_set_cancel_fn(struct kiocb *iocb, kiocb_cancel_fn *cancel) |
551 | { | 553 | { |
552 | struct aio_kiocb *req = container_of(iocb, struct aio_kiocb, common); | 554 | struct aio_kiocb *req = container_of(iocb, struct aio_kiocb, rw); |
553 | struct kioctx *ctx = req->ki_ctx; | 555 | struct kioctx *ctx = req->ki_ctx; |
554 | unsigned long flags; | 556 | unsigned long flags; |
555 | 557 | ||
@@ -581,7 +583,7 @@ static int kiocb_cancel(struct aio_kiocb *kiocb) | |||
581 | cancel = cmpxchg(&kiocb->ki_cancel, old, KIOCB_CANCELLED); | 583 | cancel = cmpxchg(&kiocb->ki_cancel, old, KIOCB_CANCELLED); |
582 | } while (cancel != old); | 584 | } while (cancel != old); |
583 | 585 | ||
584 | return cancel(&kiocb->common); | 586 | return cancel(&kiocb->rw); |
585 | } | 587 | } |
586 | 588 | ||
587 | /* | 589 | /* |
@@ -1046,15 +1048,6 @@ out_put: | |||
1046 | return NULL; | 1048 | return NULL; |
1047 | } | 1049 | } |
1048 | 1050 | ||
1049 | static void kiocb_free(struct aio_kiocb *req) | ||
1050 | { | ||
1051 | if (req->common.ki_filp) | ||
1052 | fput(req->common.ki_filp); | ||
1053 | if (req->ki_eventfd != NULL) | ||
1054 | eventfd_ctx_put(req->ki_eventfd); | ||
1055 | kmem_cache_free(kiocb_cachep, req); | ||
1056 | } | ||
1057 | |||
1058 | static struct kioctx *lookup_ioctx(unsigned long ctx_id) | 1051 | static struct kioctx *lookup_ioctx(unsigned long ctx_id) |
1059 | { | 1052 | { |
1060 | struct aio_ring __user *ring = (void __user *)ctx_id; | 1053 | struct aio_ring __user *ring = (void __user *)ctx_id; |
@@ -1085,27 +1078,14 @@ out: | |||
1085 | /* aio_complete | 1078 | /* aio_complete |
1086 | * Called when the io request on the given iocb is complete. | 1079 | * Called when the io request on the given iocb is complete. |
1087 | */ | 1080 | */ |
1088 | static void aio_complete(struct kiocb *kiocb, long res, long res2) | 1081 | static void aio_complete(struct aio_kiocb *iocb, long res, long res2) |
1089 | { | 1082 | { |
1090 | struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, common); | ||
1091 | struct kioctx *ctx = iocb->ki_ctx; | 1083 | struct kioctx *ctx = iocb->ki_ctx; |
1092 | struct aio_ring *ring; | 1084 | struct aio_ring *ring; |
1093 | struct io_event *ev_page, *event; | 1085 | struct io_event *ev_page, *event; |
1094 | unsigned tail, pos, head; | 1086 | unsigned tail, pos, head; |
1095 | unsigned long flags; | 1087 | unsigned long flags; |
1096 | 1088 | ||
1097 | if (kiocb->ki_flags & IOCB_WRITE) { | ||
1098 | struct file *file = kiocb->ki_filp; | ||
1099 | |||
1100 | /* | ||
1101 | * Tell lockdep we inherited freeze protection from submission | ||
1102 | * thread. | ||
1103 | */ | ||
1104 | if (S_ISREG(file_inode(file)->i_mode)) | ||
1105 | __sb_writers_acquired(file_inode(file)->i_sb, SB_FREEZE_WRITE); | ||
1106 | file_end_write(file); | ||
1107 | } | ||
1108 | |||
1109 | if (!list_empty_careful(&iocb->ki_list)) { | 1089 | if (!list_empty_careful(&iocb->ki_list)) { |
1110 | unsigned long flags; | 1090 | unsigned long flags; |
1111 | 1091 | ||
@@ -1167,11 +1147,12 @@ static void aio_complete(struct kiocb *kiocb, long res, long res2) | |||
1167 | * eventfd. The eventfd_signal() function is safe to be called | 1147 | * eventfd. The eventfd_signal() function is safe to be called |
1168 | * from IRQ context. | 1148 | * from IRQ context. |
1169 | */ | 1149 | */ |
1170 | if (iocb->ki_eventfd != NULL) | 1150 | if (iocb->ki_eventfd) { |
1171 | eventfd_signal(iocb->ki_eventfd, 1); | 1151 | eventfd_signal(iocb->ki_eventfd, 1); |
1152 | eventfd_ctx_put(iocb->ki_eventfd); | ||
1153 | } | ||
1172 | 1154 | ||
1173 | /* everything turned out well, dispose of the aiocb. */ | 1155 | kmem_cache_free(kiocb_cachep, iocb); |
1174 | kiocb_free(iocb); | ||
1175 | 1156 | ||
1176 | /* | 1157 | /* |
1177 | * We have to order our ring_info tail store above and test | 1158 | * We have to order our ring_info tail store above and test |
@@ -1434,6 +1415,45 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) | |||
1434 | return -EINVAL; | 1415 | return -EINVAL; |
1435 | } | 1416 | } |
1436 | 1417 | ||
1418 | static void aio_complete_rw(struct kiocb *kiocb, long res, long res2) | ||
1419 | { | ||
1420 | struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, rw); | ||
1421 | |||
1422 | if (kiocb->ki_flags & IOCB_WRITE) { | ||
1423 | struct inode *inode = file_inode(kiocb->ki_filp); | ||
1424 | |||
1425 | /* | ||
1426 | * Tell lockdep we inherited freeze protection from submission | ||
1427 | * thread. | ||
1428 | */ | ||
1429 | if (S_ISREG(inode->i_mode)) | ||
1430 | __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); | ||
1431 | file_end_write(kiocb->ki_filp); | ||
1432 | } | ||
1433 | |||
1434 | fput(kiocb->ki_filp); | ||
1435 | aio_complete(iocb, res, res2); | ||
1436 | } | ||
1437 | |||
1438 | static int aio_prep_rw(struct kiocb *req, struct iocb *iocb) | ||
1439 | { | ||
1440 | int ret; | ||
1441 | |||
1442 | req->ki_filp = fget(iocb->aio_fildes); | ||
1443 | if (unlikely(!req->ki_filp)) | ||
1444 | return -EBADF; | ||
1445 | req->ki_complete = aio_complete_rw; | ||
1446 | req->ki_pos = iocb->aio_offset; | ||
1447 | req->ki_flags = iocb_flags(req->ki_filp); | ||
1448 | if (iocb->aio_flags & IOCB_FLAG_RESFD) | ||
1449 | req->ki_flags |= IOCB_EVENTFD; | ||
1450 | req->ki_hint = file_write_hint(req->ki_filp); | ||
1451 | ret = kiocb_set_rw_flags(req, iocb->aio_rw_flags); | ||
1452 | if (unlikely(ret)) | ||
1453 | fput(req->ki_filp); | ||
1454 | return ret; | ||
1455 | } | ||
1456 | |||
1437 | static int aio_setup_rw(int rw, struct iocb *iocb, struct iovec **iovec, | 1457 | static int aio_setup_rw(int rw, struct iocb *iocb, struct iovec **iovec, |
1438 | bool vectored, bool compat, struct iov_iter *iter) | 1458 | bool vectored, bool compat, struct iov_iter *iter) |
1439 | { | 1459 | { |
@@ -1453,7 +1473,7 @@ static int aio_setup_rw(int rw, struct iocb *iocb, struct iovec **iovec, | |||
1453 | return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter); | 1473 | return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter); |
1454 | } | 1474 | } |
1455 | 1475 | ||
1456 | static inline ssize_t aio_ret(struct kiocb *req, ssize_t ret) | 1476 | static inline ssize_t aio_rw_ret(struct kiocb *req, ssize_t ret) |
1457 | { | 1477 | { |
1458 | switch (ret) { | 1478 | switch (ret) { |
1459 | case -EIOCBQUEUED: | 1479 | case -EIOCBQUEUED: |
@@ -1469,7 +1489,7 @@ static inline ssize_t aio_ret(struct kiocb *req, ssize_t ret) | |||
1469 | ret = -EINTR; | 1489 | ret = -EINTR; |
1470 | /*FALLTHRU*/ | 1490 | /*FALLTHRU*/ |
1471 | default: | 1491 | default: |
1472 | aio_complete(req, ret, 0); | 1492 | aio_complete_rw(req, ret, 0); |
1473 | return 0; | 1493 | return 0; |
1474 | } | 1494 | } |
1475 | } | 1495 | } |
@@ -1477,59 +1497,79 @@ static inline ssize_t aio_ret(struct kiocb *req, ssize_t ret) | |||
1477 | static ssize_t aio_read(struct kiocb *req, struct iocb *iocb, bool vectored, | 1497 | static ssize_t aio_read(struct kiocb *req, struct iocb *iocb, bool vectored, |
1478 | bool compat) | 1498 | bool compat) |
1479 | { | 1499 | { |
1480 | struct file *file = req->ki_filp; | ||
1481 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; | 1500 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
1482 | struct iov_iter iter; | 1501 | struct iov_iter iter; |
1502 | struct file *file; | ||
1483 | ssize_t ret; | 1503 | ssize_t ret; |
1484 | 1504 | ||
1505 | ret = aio_prep_rw(req, iocb); | ||
1506 | if (ret) | ||
1507 | return ret; | ||
1508 | file = req->ki_filp; | ||
1509 | |||
1510 | ret = -EBADF; | ||
1485 | if (unlikely(!(file->f_mode & FMODE_READ))) | 1511 | if (unlikely(!(file->f_mode & FMODE_READ))) |
1486 | return -EBADF; | 1512 | goto out_fput; |
1513 | ret = -EINVAL; | ||
1487 | if (unlikely(!file->f_op->read_iter)) | 1514 | if (unlikely(!file->f_op->read_iter)) |
1488 | return -EINVAL; | 1515 | goto out_fput; |
1489 | 1516 | ||
1490 | ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter); | 1517 | ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter); |
1491 | if (ret) | 1518 | if (ret) |
1492 | return ret; | 1519 | goto out_fput; |
1493 | ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); | 1520 | ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); |
1494 | if (!ret) | 1521 | if (!ret) |
1495 | ret = aio_ret(req, call_read_iter(file, req, &iter)); | 1522 | ret = aio_rw_ret(req, call_read_iter(file, req, &iter)); |
1496 | kfree(iovec); | 1523 | kfree(iovec); |
1524 | out_fput: | ||
1525 | if (unlikely(ret && ret != -EIOCBQUEUED)) | ||
1526 | fput(file); | ||
1497 | return ret; | 1527 | return ret; |
1498 | } | 1528 | } |
1499 | 1529 | ||
1500 | static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored, | 1530 | static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored, |
1501 | bool compat) | 1531 | bool compat) |
1502 | { | 1532 | { |
1503 | struct file *file = req->ki_filp; | ||
1504 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; | 1533 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
1505 | struct iov_iter iter; | 1534 | struct iov_iter iter; |
1535 | struct file *file; | ||
1506 | ssize_t ret; | 1536 | ssize_t ret; |
1507 | 1537 | ||
1538 | ret = aio_prep_rw(req, iocb); | ||
1539 | if (ret) | ||
1540 | return ret; | ||
1541 | file = req->ki_filp; | ||
1542 | |||
1543 | ret = -EBADF; | ||
1508 | if (unlikely(!(file->f_mode & FMODE_WRITE))) | 1544 | if (unlikely(!(file->f_mode & FMODE_WRITE))) |
1509 | return -EBADF; | 1545 | goto out_fput; |
1546 | ret = -EINVAL; | ||
1510 | if (unlikely(!file->f_op->write_iter)) | 1547 | if (unlikely(!file->f_op->write_iter)) |
1511 | return -EINVAL; | 1548 | goto out_fput; |
1512 | 1549 | ||
1513 | ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter); | 1550 | ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter); |
1514 | if (ret) | 1551 | if (ret) |
1515 | return ret; | 1552 | goto out_fput; |
1516 | ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter)); | 1553 | ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter)); |
1517 | if (!ret) { | 1554 | if (!ret) { |
1518 | /* | 1555 | /* |
1519 | * Open-code file_start_write here to grab freeze protection, | 1556 | * Open-code file_start_write here to grab freeze protection, |
1520 | * which will be released by another thread in aio_complete(). | 1557 | * which will be released by another thread in |
1521 | * Fool lockdep by telling it the lock got released so that it | 1558 | * aio_complete_rw(). Fool lockdep by telling it the lock got |
1522 | * doesn't complain about the held lock when we return to | 1559 | * released so that it doesn't complain about the held lock when |
1523 | * userspace. | 1560 | * we return to userspace. |
1524 | */ | 1561 | */ |
1525 | if (S_ISREG(file_inode(file)->i_mode)) { | 1562 | if (S_ISREG(file_inode(file)->i_mode)) { |
1526 | __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); | 1563 | __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); |
1527 | __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE); | 1564 | __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE); |
1528 | } | 1565 | } |
1529 | req->ki_flags |= IOCB_WRITE; | 1566 | req->ki_flags |= IOCB_WRITE; |
1530 | ret = aio_ret(req, call_write_iter(file, req, &iter)); | 1567 | ret = aio_rw_ret(req, call_write_iter(file, req, &iter)); |
1531 | } | 1568 | } |
1532 | kfree(iovec); | 1569 | kfree(iovec); |
1570 | out_fput: | ||
1571 | if (unlikely(ret && ret != -EIOCBQUEUED)) | ||
1572 | fput(file); | ||
1533 | return ret; | 1573 | return ret; |
1534 | } | 1574 | } |
1535 | 1575 | ||
@@ -1537,7 +1577,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1537 | struct iocb *iocb, bool compat) | 1577 | struct iocb *iocb, bool compat) |
1538 | { | 1578 | { |
1539 | struct aio_kiocb *req; | 1579 | struct aio_kiocb *req; |
1540 | struct file *file; | ||
1541 | ssize_t ret; | 1580 | ssize_t ret; |
1542 | 1581 | ||
1543 | /* enforce forwards compatibility on users */ | 1582 | /* enforce forwards compatibility on users */ |
@@ -1560,16 +1599,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1560 | if (unlikely(!req)) | 1599 | if (unlikely(!req)) |
1561 | return -EAGAIN; | 1600 | return -EAGAIN; |
1562 | 1601 | ||
1563 | req->common.ki_filp = file = fget(iocb->aio_fildes); | ||
1564 | if (unlikely(!req->common.ki_filp)) { | ||
1565 | ret = -EBADF; | ||
1566 | goto out_put_req; | ||
1567 | } | ||
1568 | req->common.ki_pos = iocb->aio_offset; | ||
1569 | req->common.ki_complete = aio_complete; | ||
1570 | req->common.ki_flags = iocb_flags(req->common.ki_filp); | ||
1571 | req->common.ki_hint = file_write_hint(file); | ||
1572 | |||
1573 | if (iocb->aio_flags & IOCB_FLAG_RESFD) { | 1602 | if (iocb->aio_flags & IOCB_FLAG_RESFD) { |
1574 | /* | 1603 | /* |
1575 | * If the IOCB_FLAG_RESFD flag of aio_flags is set, get an | 1604 | * If the IOCB_FLAG_RESFD flag of aio_flags is set, get an |
@@ -1583,14 +1612,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1583 | req->ki_eventfd = NULL; | 1612 | req->ki_eventfd = NULL; |
1584 | goto out_put_req; | 1613 | goto out_put_req; |
1585 | } | 1614 | } |
1586 | |||
1587 | req->common.ki_flags |= IOCB_EVENTFD; | ||
1588 | } | ||
1589 | |||
1590 | ret = kiocb_set_rw_flags(&req->common, iocb->aio_rw_flags); | ||
1591 | if (unlikely(ret)) { | ||
1592 | pr_debug("EINVAL: aio_rw_flags\n"); | ||
1593 | goto out_put_req; | ||
1594 | } | 1615 | } |
1595 | 1616 | ||
1596 | ret = put_user(KIOCB_KEY, &user_iocb->aio_key); | 1617 | ret = put_user(KIOCB_KEY, &user_iocb->aio_key); |
@@ -1604,16 +1625,16 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1604 | 1625 | ||
1605 | switch (iocb->aio_lio_opcode) { | 1626 | switch (iocb->aio_lio_opcode) { |
1606 | case IOCB_CMD_PREAD: | 1627 | case IOCB_CMD_PREAD: |
1607 | ret = aio_read(&req->common, iocb, false, compat); | 1628 | ret = aio_read(&req->rw, iocb, false, compat); |
1608 | break; | 1629 | break; |
1609 | case IOCB_CMD_PWRITE: | 1630 | case IOCB_CMD_PWRITE: |
1610 | ret = aio_write(&req->common, iocb, false, compat); | 1631 | ret = aio_write(&req->rw, iocb, false, compat); |
1611 | break; | 1632 | break; |
1612 | case IOCB_CMD_PREADV: | 1633 | case IOCB_CMD_PREADV: |
1613 | ret = aio_read(&req->common, iocb, true, compat); | 1634 | ret = aio_read(&req->rw, iocb, true, compat); |
1614 | break; | 1635 | break; |
1615 | case IOCB_CMD_PWRITEV: | 1636 | case IOCB_CMD_PWRITEV: |
1616 | ret = aio_write(&req->common, iocb, true, compat); | 1637 | ret = aio_write(&req->rw, iocb, true, compat); |
1617 | break; | 1638 | break; |
1618 | default: | 1639 | default: |
1619 | pr_debug("invalid aio operation %d\n", iocb->aio_lio_opcode); | 1640 | pr_debug("invalid aio operation %d\n", iocb->aio_lio_opcode); |
@@ -1633,7 +1654,9 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1633 | out_put_req: | 1654 | out_put_req: |
1634 | put_reqs_available(ctx, 1); | 1655 | put_reqs_available(ctx, 1); |
1635 | percpu_ref_put(&ctx->reqs); | 1656 | percpu_ref_put(&ctx->reqs); |
1636 | kiocb_free(req); | 1657 | if (req->ki_eventfd) |
1658 | eventfd_ctx_put(req->ki_eventfd); | ||
1659 | kmem_cache_free(kiocb_cachep, req); | ||
1637 | return ret; | 1660 | return ret; |
1638 | } | 1661 | } |
1639 | 1662 | ||