Commit 9392a27d authored by Jens Axboe's avatar Jens Axboe
Browse files

io-wq: add support for inheriting ->fs



Some work items need this for relative path lookup, make it available
like the other inherited credentials/mm/etc.

Cc: stable@vger.kernel.org # 5.3+
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent faac996c
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/rculist_nulls.h>
#include <linux/fs_struct.h>

#include "io-wq.h"

@@ -59,6 +60,7 @@ struct io_worker {
	const struct cred *cur_creds;
	const struct cred *saved_creds;
	struct files_struct *restore_files;
	struct fs_struct *restore_fs;
};

#if BITS_PER_LONG == 64
@@ -151,6 +153,9 @@ static bool __io_worker_unuse(struct io_wqe *wqe, struct io_worker *worker)
		task_unlock(current);
	}

	if (current->fs != worker->restore_fs)
		current->fs = worker->restore_fs;

	/*
	 * If we have an active mm, we need to drop the wq lock before unusing
	 * it. If we do, return true and let the caller retry the idle loop.
@@ -311,6 +316,7 @@ static void io_worker_start(struct io_wqe *wqe, struct io_worker *worker)

	worker->flags |= (IO_WORKER_F_UP | IO_WORKER_F_RUNNING);
	worker->restore_files = current->files;
	worker->restore_fs = current->fs;
	io_wqe_inc_running(wqe, worker);
}

@@ -481,6 +487,8 @@ next:
			current->files = work->files;
			task_unlock(current);
		}
		if (work->fs && current->fs != work->fs)
			current->fs = work->fs;
		if (work->mm != worker->mm)
			io_wq_switch_mm(worker, work);
		if (worker->cur_creds != work->creds)
+3 −1
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ struct io_wq_work {
	struct files_struct *files;
	struct mm_struct *mm;
	const struct cred *creds;
	struct fs_struct *fs;
	unsigned flags;
};

@@ -81,10 +82,11 @@ struct io_wq_work {
	do {						\
		(work)->list.next = NULL;		\
		(work)->func = _func;			\
		(work)->flags = 0;			\
		(work)->files = NULL;			\
		(work)->mm = NULL;			\
		(work)->creds = NULL;			\
		(work)->fs = NULL;			\
		(work)->flags = 0;			\
	} while (0)					\

typedef void (get_work_fn)(struct io_wq_work *);