]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
io-wq: add support for inheriting ->fs
authorJens Axboe <axboe@kernel.dk>
Fri, 7 Feb 2020 04:42:51 +0000 (21:42 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Feb 2020 18:54:13 +0000 (19:54 +0100)
[ Upstream commit 9392a27d88b9707145d713654eb26f0c29789e50 ]

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: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/io-wq.c
fs/io-wq.h

index 5147d2213b019f9b80841a0e14a1709ba719bf69..0dc4bb6de6566f8f8d5f99533e4c0fe3f2e575e0 100644 (file)
@@ -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"
 
@@ -58,6 +59,7 @@ struct io_worker {
        struct mm_struct *mm;
        const struct cred *creds;
        struct files_struct *restore_files;
+       struct fs_struct *restore_fs;
 };
 
 #if BITS_PER_LONG == 64
@@ -150,6 +152,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.
@@ -310,6 +315,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);
 }
 
@@ -456,6 +462,8 @@ next:
                }
                if (!worker->creds)
                        worker->creds = override_creds(wq->creds);
+               if (work->fs && current->fs != work->fs)
+                       current->fs = work->fs;
                if (test_bit(IO_WQ_BIT_CANCEL, &wq->state))
                        work->flags |= IO_WQ_WORK_CANCEL;
                if (worker->mm)
index 3f5e356de98050f67503336cfac1db64f455230d..bbab98d1d328b929fada6086aba33124f46ba8b1 100644 (file)
@@ -72,6 +72,7 @@ struct io_wq_work {
        };
        void (*func)(struct io_wq_work **);
        struct files_struct *files;
+       struct fs_struct *fs;
        unsigned flags;
 };
 
@@ -79,8 +80,9 @@ struct io_wq_work {
        do {                                            \
                (work)->list.next = NULL;               \
                (work)->func = _func;                   \
-               (work)->flags = 0;                      \
                (work)->files = NULL;                   \
+               (work)->fs = NULL;                      \
+               (work)->flags = 0;                      \
        } while (0)                                     \
 
 typedef void (get_work_fn)(struct io_wq_work *);