Skip to content

Commit 92ce472

Browse files
author
Christoph Hellwig
committed
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 <[email protected]>
1 parent 75321b5 commit 92ce472

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

fs/aio.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,16 +1515,19 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored,
15151515
return ret;
15161516
ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter));
15171517
if (!ret) {
1518-
req->ki_flags |= IOCB_WRITE;
1519-
file_start_write(file);
1520-
ret = aio_ret(req, call_write_iter(file, req, &iter));
15211518
/*
1522-
* We release freeze protection in aio_complete(). Fool lockdep
1523-
* by telling it the lock got released so that it doesn't
1524-
* complain about held lock when we return to userspace.
1519+
* Open-code file_start_write here to grab freeze protection,
1520+
* which will be released by another thread in aio_complete().
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.
15251524
*/
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);
15271527
__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));
15281531
}
15291532
kfree(iovec);
15301533
return ret;
@@ -1599,7 +1602,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
15991602
req->ki_user_iocb = user_iocb;
16001603
req->ki_user_data = iocb->aio_data;
16011604

1602-
get_file(file);
16031605
switch (iocb->aio_lio_opcode) {
16041606
case IOCB_CMD_PREAD:
16051607
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,
16181620
ret = -EINVAL;
16191621
break;
16201622
}
1621-
fput(file);
16221623

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+
*/
16231630
if (ret && ret != -EIOCBQUEUED)
16241631
goto out_put_req;
16251632
return 0;

0 commit comments

Comments
 (0)