Skip to content

Commit af60470

Browse files
isilenceaxboe
authored andcommitted
io_uring: fix files grab/cancel race
When one task is in io_uring_cancel_files() and another is doing io_prep_async_work() a race may happen. That's because after accounting a request inflight in first call to io_grab_identity() it still may fail and go to io_identity_cow(), which migh briefly keep dangling work.identity and not only. Grab files last, so io_prep_async_work() won't fail if it did get into ->inflight_list. note: the bug shouldn't exist after making io_uring_cancel_files() not poking into other tasks' requests. Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 9c3a205 commit af60470

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

fs/io_uring.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,22 +1313,6 @@ static bool io_grab_identity(struct io_kiocb *req)
13131313
return false;
13141314
req->work.flags |= IO_WQ_WORK_FSIZE;
13151315
}
1316-
1317-
if (!(req->work.flags & IO_WQ_WORK_FILES) &&
1318-
(def->work_flags & IO_WQ_WORK_FILES) &&
1319-
!(req->flags & REQ_F_NO_FILE_TABLE)) {
1320-
if (id->files != current->files ||
1321-
id->nsproxy != current->nsproxy)
1322-
return false;
1323-
atomic_inc(&id->files->count);
1324-
get_nsproxy(id->nsproxy);
1325-
req->flags |= REQ_F_INFLIGHT;
1326-
1327-
spin_lock_irq(&ctx->inflight_lock);
1328-
list_add(&req->inflight_entry, &ctx->inflight_list);
1329-
spin_unlock_irq(&ctx->inflight_lock);
1330-
req->work.flags |= IO_WQ_WORK_FILES;
1331-
}
13321316
#ifdef CONFIG_BLK_CGROUP
13331317
if (!(req->work.flags & IO_WQ_WORK_BLKCG) &&
13341318
(def->work_flags & IO_WQ_WORK_BLKCG)) {
@@ -1370,6 +1354,21 @@ static bool io_grab_identity(struct io_kiocb *req)
13701354
}
13711355
spin_unlock(&current->fs->lock);
13721356
}
1357+
if (!(req->work.flags & IO_WQ_WORK_FILES) &&
1358+
(def->work_flags & IO_WQ_WORK_FILES) &&
1359+
!(req->flags & REQ_F_NO_FILE_TABLE)) {
1360+
if (id->files != current->files ||
1361+
id->nsproxy != current->nsproxy)
1362+
return false;
1363+
atomic_inc(&id->files->count);
1364+
get_nsproxy(id->nsproxy);
1365+
req->flags |= REQ_F_INFLIGHT;
1366+
1367+
spin_lock_irq(&ctx->inflight_lock);
1368+
list_add(&req->inflight_entry, &ctx->inflight_list);
1369+
spin_unlock_irq(&ctx->inflight_lock);
1370+
req->work.flags |= IO_WQ_WORK_FILES;
1371+
}
13731372

13741373
return true;
13751374
}

0 commit comments

Comments
 (0)