Skip to content

Commit f0d3699

Browse files
committed
Merge tag 'io_uring-6.12-20241101' of git://git.kernel.dk/linux
Pull io_uring fix from Jens Axboe: - Fix not honoring IOCB_NOWAIT for starting buffered writes in terms of calling sb_start_write(), leading to a deadlock if someone is attempting to freeze the file system with writes in progress, as each side will end up waiting for the other to make progress. * tag 'io_uring-6.12-20241101' of git://git.kernel.dk/linux: io_uring/rw: fix missing NOWAIT check for O_DIRECT start write
2 parents c426456 + 1d60d74 commit f0d3699

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

io_uring/rw.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,25 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
10141014
return IOU_OK;
10151015
}
10161016

1017+
static bool io_kiocb_start_write(struct io_kiocb *req, struct kiocb *kiocb)
1018+
{
1019+
struct inode *inode;
1020+
bool ret;
1021+
1022+
if (!(req->flags & REQ_F_ISREG))
1023+
return true;
1024+
if (!(kiocb->ki_flags & IOCB_NOWAIT)) {
1025+
kiocb_start_write(kiocb);
1026+
return true;
1027+
}
1028+
1029+
inode = file_inode(kiocb->ki_filp);
1030+
ret = sb_start_write_trylock(inode->i_sb);
1031+
if (ret)
1032+
__sb_writers_release(inode->i_sb, SB_FREEZE_WRITE);
1033+
return ret;
1034+
}
1035+
10171036
int io_write(struct io_kiocb *req, unsigned int issue_flags)
10181037
{
10191038
bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
@@ -1051,8 +1070,8 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
10511070
if (unlikely(ret))
10521071
return ret;
10531072

1054-
if (req->flags & REQ_F_ISREG)
1055-
kiocb_start_write(kiocb);
1073+
if (unlikely(!io_kiocb_start_write(req, kiocb)))
1074+
return -EAGAIN;
10561075
kiocb->ki_flags |= IOCB_WRITE;
10571076

10581077
if (likely(req->file->f_op->write_iter))

0 commit comments

Comments
 (0)