mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
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 <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
9c3a205c5f
commit
af60470347
@ -1313,22 +1313,6 @@ static bool io_grab_identity(struct io_kiocb *req)
|
||||
return false;
|
||||
req->work.flags |= IO_WQ_WORK_FSIZE;
|
||||
}
|
||||
|
||||
if (!(req->work.flags & IO_WQ_WORK_FILES) &&
|
||||
(def->work_flags & IO_WQ_WORK_FILES) &&
|
||||
!(req->flags & REQ_F_NO_FILE_TABLE)) {
|
||||
if (id->files != current->files ||
|
||||
id->nsproxy != current->nsproxy)
|
||||
return false;
|
||||
atomic_inc(&id->files->count);
|
||||
get_nsproxy(id->nsproxy);
|
||||
req->flags |= REQ_F_INFLIGHT;
|
||||
|
||||
spin_lock_irq(&ctx->inflight_lock);
|
||||
list_add(&req->inflight_entry, &ctx->inflight_list);
|
||||
spin_unlock_irq(&ctx->inflight_lock);
|
||||
req->work.flags |= IO_WQ_WORK_FILES;
|
||||
}
|
||||
#ifdef CONFIG_BLK_CGROUP
|
||||
if (!(req->work.flags & IO_WQ_WORK_BLKCG) &&
|
||||
(def->work_flags & IO_WQ_WORK_BLKCG)) {
|
||||
@ -1370,6 +1354,21 @@ static bool io_grab_identity(struct io_kiocb *req)
|
||||
}
|
||||
spin_unlock(¤t->fs->lock);
|
||||
}
|
||||
if (!(req->work.flags & IO_WQ_WORK_FILES) &&
|
||||
(def->work_flags & IO_WQ_WORK_FILES) &&
|
||||
!(req->flags & REQ_F_NO_FILE_TABLE)) {
|
||||
if (id->files != current->files ||
|
||||
id->nsproxy != current->nsproxy)
|
||||
return false;
|
||||
atomic_inc(&id->files->count);
|
||||
get_nsproxy(id->nsproxy);
|
||||
req->flags |= REQ_F_INFLIGHT;
|
||||
|
||||
spin_lock_irq(&ctx->inflight_lock);
|
||||
list_add(&req->inflight_entry, &ctx->inflight_list);
|
||||
spin_unlock_irq(&ctx->inflight_lock);
|
||||
req->work.flags |= IO_WQ_WORK_FILES;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user