diff options
author | Christoph Hellwig <hch@lst.de> | 2018-04-06 03:28:17 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2018-05-02 13:56:30 -0400 |
commit | 92ce4728563ad1fc42466f9bbecc1ac31d675894 (patch) | |
tree | ea7ad875762949ff60965974a18473af3d9c8f52 /fs/aio.c | |
parent | 75321b50a37a5ba612125a04bfc9e43e3da5b305 (diff) |
aio: remove the extra get_file/fput pair in io_submit_one
If we release the lockdep write protection token before calling into
->write_iter and thus never access the file pointer after an -EIOCBQUEUED
return from ->write_iter or ->read_iter we don't need this extra
reference.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 25 |
1 files changed, 16 insertions, 9 deletions
@@ -1515,16 +1515,19 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored, | |||
1515 | return ret; | 1515 | return ret; |
1516 | ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter)); | 1516 | ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter)); |
1517 | if (!ret) { | 1517 | if (!ret) { |
1518 | req->ki_flags |= IOCB_WRITE; | ||
1519 | file_start_write(file); | ||
1520 | ret = aio_ret(req, call_write_iter(file, req, &iter)); | ||
1521 | /* | 1518 | /* |
1522 | * We release freeze protection in aio_complete(). Fool lockdep | 1519 | * Open-code file_start_write here to grab freeze protection, |
1523 | * by telling it the lock got released so that it doesn't | 1520 | * which will be released by another thread in aio_complete(). |
1524 | * complain about held lock when we return to userspace. | 1521 | * Fool lockdep by telling it the lock got released so that it |
1522 | * doesn't complain about the held lock when we return to | ||
1523 | * userspace. | ||
1525 | */ | 1524 | */ |
1526 | if (S_ISREG(file_inode(file)->i_mode)) | 1525 | if (S_ISREG(file_inode(file)->i_mode)) { |
1526 | __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); | ||
1527 | __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE); | 1527 | __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE); |
1528 | } | ||
1529 | req->ki_flags |= IOCB_WRITE; | ||
1530 | ret = aio_ret(req, call_write_iter(file, req, &iter)); | ||
1528 | } | 1531 | } |
1529 | kfree(iovec); | 1532 | kfree(iovec); |
1530 | return ret; | 1533 | return ret; |
@@ -1599,7 +1602,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1599 | req->ki_user_iocb = user_iocb; | 1602 | req->ki_user_iocb = user_iocb; |
1600 | req->ki_user_data = iocb->aio_data; | 1603 | req->ki_user_data = iocb->aio_data; |
1601 | 1604 | ||
1602 | get_file(file); | ||
1603 | switch (iocb->aio_lio_opcode) { | 1605 | switch (iocb->aio_lio_opcode) { |
1604 | case IOCB_CMD_PREAD: | 1606 | case IOCB_CMD_PREAD: |
1605 | ret = aio_read(&req->common, iocb, false, compat); | 1607 | ret = aio_read(&req->common, iocb, false, compat); |
@@ -1618,8 +1620,13 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1618 | ret = -EINVAL; | 1620 | ret = -EINVAL; |
1619 | break; | 1621 | break; |
1620 | } | 1622 | } |
1621 | fput(file); | ||
1622 | 1623 | ||
1624 | /* | ||
1625 | * If ret is -EIOCBQUEUED, ownership of the file reference acquired | ||
1626 | * above passed to the file system, which at this point might have | ||
1627 | * dropped the reference, so we must be careful to not reference it | ||
1628 | * once we have called into the file system. | ||
1629 | */ | ||
1623 | if (ret && ret != -EIOCBQUEUED) | 1630 | if (ret && ret != -EIOCBQUEUED) |
1624 | goto out_put_req; | 1631 | goto out_put_req; |
1625 | return 0; | 1632 | return 0; |