diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-05-26 19:11:40 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-05-29 23:17:40 -0400 |
commit | 9061d14a8a97009085242b284b5b5f668af2bf97 (patch) | |
tree | 10a98679764221cdf87a9b067e60d13d1e72c110 | |
parent | 3c96c7f4caeb044da53a85092903f9192f4e2342 (diff) |
aio: all callers of aio_{read,write,fsync,poll} treat 0 and -EIOCBQUEUED the same way
... so just make them return 0 when caller does not need to destroy iocb
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/aio.c | 26 |
1 files changed, 12 insertions, 14 deletions
@@ -1461,11 +1461,11 @@ static int aio_setup_rw(int rw, struct iocb *iocb, struct iovec **iovec, | |||
1461 | return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter); | 1461 | return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter); |
1462 | } | 1462 | } |
1463 | 1463 | ||
1464 | static inline ssize_t aio_rw_ret(struct kiocb *req, ssize_t ret) | 1464 | static inline void aio_rw_done(struct kiocb *req, ssize_t ret) |
1465 | { | 1465 | { |
1466 | switch (ret) { | 1466 | switch (ret) { |
1467 | case -EIOCBQUEUED: | 1467 | case -EIOCBQUEUED: |
1468 | return ret; | 1468 | break; |
1469 | case -ERESTARTSYS: | 1469 | case -ERESTARTSYS: |
1470 | case -ERESTARTNOINTR: | 1470 | case -ERESTARTNOINTR: |
1471 | case -ERESTARTNOHAND: | 1471 | case -ERESTARTNOHAND: |
@@ -1478,7 +1478,6 @@ static inline ssize_t aio_rw_ret(struct kiocb *req, ssize_t ret) | |||
1478 | /*FALLTHRU*/ | 1478 | /*FALLTHRU*/ |
1479 | default: | 1479 | default: |
1480 | aio_complete_rw(req, ret, 0); | 1480 | aio_complete_rw(req, ret, 0); |
1481 | return 0; | ||
1482 | } | 1481 | } |
1483 | } | 1482 | } |
1484 | 1483 | ||
@@ -1507,10 +1506,10 @@ static ssize_t aio_read(struct kiocb *req, struct iocb *iocb, bool vectored, | |||
1507 | goto out_fput; | 1506 | goto out_fput; |
1508 | ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); | 1507 | ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); |
1509 | if (!ret) | 1508 | if (!ret) |
1510 | ret = aio_rw_ret(req, call_read_iter(file, req, &iter)); | 1509 | aio_rw_done(req, call_read_iter(file, req, &iter)); |
1511 | kfree(iovec); | 1510 | kfree(iovec); |
1512 | out_fput: | 1511 | out_fput: |
1513 | if (unlikely(ret && ret != -EIOCBQUEUED)) | 1512 | if (unlikely(ret)) |
1514 | fput(file); | 1513 | fput(file); |
1515 | return ret; | 1514 | return ret; |
1516 | } | 1515 | } |
@@ -1552,11 +1551,11 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored, | |||
1552 | __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE); | 1551 | __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE); |
1553 | } | 1552 | } |
1554 | req->ki_flags |= IOCB_WRITE; | 1553 | req->ki_flags |= IOCB_WRITE; |
1555 | ret = aio_rw_ret(req, call_write_iter(file, req, &iter)); | 1554 | aio_rw_done(req, call_write_iter(file, req, &iter)); |
1556 | } | 1555 | } |
1557 | kfree(iovec); | 1556 | kfree(iovec); |
1558 | out_fput: | 1557 | out_fput: |
1559 | if (unlikely(ret && ret != -EIOCBQUEUED)) | 1558 | if (unlikely(ret)) |
1560 | fput(file); | 1559 | fput(file); |
1561 | return ret; | 1560 | return ret; |
1562 | } | 1561 | } |
@@ -1587,7 +1586,7 @@ static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync) | |||
1587 | req->datasync = datasync; | 1586 | req->datasync = datasync; |
1588 | INIT_WORK(&req->work, aio_fsync_work); | 1587 | INIT_WORK(&req->work, aio_fsync_work); |
1589 | schedule_work(&req->work); | 1588 | schedule_work(&req->work); |
1590 | return -EIOCBQUEUED; | 1589 | return 0; |
1591 | } | 1590 | } |
1592 | 1591 | ||
1593 | /* need to use list_del_init so we can check if item was present */ | 1592 | /* need to use list_del_init so we can check if item was present */ |
@@ -1715,7 +1714,7 @@ static ssize_t aio_poll(struct aio_kiocb *aiocb, struct iocb *iocb) | |||
1715 | done: | 1714 | done: |
1716 | if (mask) | 1715 | if (mask) |
1717 | __aio_poll_complete(aiocb, mask); | 1716 | __aio_poll_complete(aiocb, mask); |
1718 | return -EIOCBQUEUED; | 1717 | return 0; |
1719 | out_fail: | 1718 | out_fail: |
1720 | fput(req->file); | 1719 | fput(req->file); |
1721 | return -EINVAL; /* same as no support for IOCB_CMD_POLL */ | 1720 | return -EINVAL; /* same as no support for IOCB_CMD_POLL */ |
@@ -1800,12 +1799,11 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1800 | } | 1799 | } |
1801 | 1800 | ||
1802 | /* | 1801 | /* |
1803 | * If ret is -EIOCBQUEUED, ownership of the file reference acquired | 1802 | * If ret is 0, we'd either done aio_complete() ourselves or have |
1804 | * above passed to the file system, which at this point might have | 1803 | * arranged for that to be done asynchronously. Anything non-zero |
1805 | * dropped the reference, so we must be careful to not reference it | 1804 | * means that we need to destroy req ourselves. |
1806 | * once we have called into the file system. | ||
1807 | */ | 1805 | */ |
1808 | if (ret && ret != -EIOCBQUEUED) | 1806 | if (ret) |
1809 | goto out_put_req; | 1807 | goto out_put_req; |
1810 | return 0; | 1808 | return 0; |
1811 | out_put_req: | 1809 | out_put_req: |