@@ -1626,12 +1626,16 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
if (ret < 0)
return ret;
ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter));
- if (!ret) {
- if (S_ISREG(file_inode(file)->i_mode))
- kiocb_start_write(req);
- req->ki_flags |= IOCB_WRITE;
- aio_rw_done(req, file->f_op->write_iter(req, &iter));
+ if (unlikely(ret))
+ goto out;
+ if (S_ISREG(file_inode(file)->i_mode)) {
+ ret = kiocb_start_write(req);
+ if (unlikely(ret))
+ goto out;
}
+ req->ki_flags |= IOCB_WRITE;
+ aio_rw_done(req, file->f_op->write_iter(req, &iter));
+out:
kfree(iovec);
return ret;
}
@@ -859,7 +859,9 @@ ssize_t vfs_iocb_iter_write(struct file *file, struct kiocb *iocb,
if (ret < 0)
return ret;
- kiocb_start_write(iocb);
+ ret = kiocb_start_write(iocb);
+ if (ret < 0)
+ return ret;
ret = file->f_op->write_iter(iocb, iter);
if (ret != -EIOCBQUEUED)
kiocb_end_write(iocb);
@@ -2920,7 +2920,7 @@ static inline void file_end_write(struct file *file)
* This is a variant of sb_start_write() for async io submission.
* Should be matched with a call to kiocb_end_write().
*/
-static inline void kiocb_start_write(struct kiocb *iocb)
+static inline int __must_check kiocb_start_write(struct kiocb *iocb)
{
struct inode *inode = file_inode(iocb->ki_filp);
@@ -2930,6 +2930,7 @@ static inline void kiocb_start_write(struct kiocb *iocb)
* doesn't complain about the held lock when we return to userspace.
*/
__sb_writers_release(inode->i_sb, SB_FREEZE_WRITE);
+ return 0;
}
/**
@@ -1040,8 +1040,11 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
if (unlikely(ret))
return ret;
- if (req->flags & REQ_F_ISREG)
- kiocb_start_write(kiocb);
+ if (req->flags & REQ_F_ISREG) {
+ ret = kiocb_start_write(kiocb);
+ if (unlikely(ret))
+ return ret;
+ }
kiocb->ki_flags |= IOCB_WRITE;
if (likely(req->file->f_op->write_iter))
sb_start_write() will be returning error on shutdown filesystem. Teach callers of kiocb_start_write() to handle the error. Signed-off-by: Jan Kara <jack@suse.cz> --- fs/aio.c | 14 +++++++++----- fs/read_write.c | 4 +++- include/linux/fs.h | 3 ++- io_uring/rw.c | 7 +++++-- 4 files changed, 19 insertions(+), 9 deletions(-)