btrfs: plumb fs_info into btrfs_work
authorJeff Mahoney <jeffm@suse.com>
Thu, 9 Jun 2016 20:22:11 +0000 (16:22 -0400)
committerDavid Sterba <dsterba@suse.com>
Tue, 26 Jul 2016 11:53:15 +0000 (13:53 +0200)
In order to provide an fsid for trace events, we'll need a btrfs_fs_info
pointer.  The most lightweight way to do that for btrfs_work structures
is to associate it with the __btrfs_workqueue structure.  Each queued
btrfs_work structure has a workqueue associated with it, so that's
a natural fit.  It's a privately defined structures, so we add accessors
to retrieve the fs_info pointer.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/async-thread.c
fs/btrfs/async-thread.h
fs/btrfs/disk-io.c
fs/btrfs/scrub.c

index 5fb60ea7eee2b2c28e067d11b54c2fad7127c7d8..e0f071f6b5a761faa6a00b741017a759c91e100a 100644 (file)
 
 struct __btrfs_workqueue {
        struct workqueue_struct *normal_wq;
+
+       /* File system this workqueue services */
+       struct btrfs_fs_info *fs_info;
+
        /* List head pointing to ordered work list */
        struct list_head ordered_list;
 
@@ -70,6 +74,18 @@ void btrfs_##name(struct work_struct *arg)                           \
        normal_work_helper(work);                                       \
 }
 
+struct btrfs_fs_info *
+btrfs_workqueue_owner(struct __btrfs_workqueue *wq)
+{
+       return wq->fs_info;
+}
+
+struct btrfs_fs_info *
+btrfs_work_owner(struct btrfs_work *work)
+{
+       return work->wq->fs_info;
+}
+
 BTRFS_WORK_HELPER(worker_helper);
 BTRFS_WORK_HELPER(delalloc_helper);
 BTRFS_WORK_HELPER(flush_delalloc_helper);
@@ -94,14 +110,15 @@ BTRFS_WORK_HELPER(scrubnc_helper);
 BTRFS_WORK_HELPER(scrubparity_helper);
 
 static struct __btrfs_workqueue *
-__btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active,
-                        int thresh)
+__btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info, const char *name,
+                       unsigned int flags, int limit_active, int thresh)
 {
        struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_KERNEL);
 
        if (!ret)
                return NULL;
 
+       ret->fs_info = fs_info;
        ret->limit_active = limit_active;
        atomic_set(&ret->pending, 0);
        if (thresh == 0)
@@ -143,7 +160,8 @@ __btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active,
 static inline void
 __btrfs_destroy_workqueue(struct __btrfs_workqueue *wq);
 
-struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
+struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info,
+                                             const char *name,
                                              unsigned int flags,
                                              int limit_active,
                                              int thresh)
@@ -153,7 +171,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
        if (!ret)
                return NULL;
 
-       ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI,
+       ret->normal = __btrfs_alloc_workqueue(fs_info, name,
+                                             flags & ~WQ_HIGHPRI,
                                              limit_active, thresh);
        if (!ret->normal) {
                kfree(ret);
@@ -161,8 +180,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
        }
 
        if (flags & WQ_HIGHPRI) {
-               ret->high = __btrfs_alloc_workqueue(name, flags, limit_active,
-                                                   thresh);
+               ret->high = __btrfs_alloc_workqueue(fs_info, name, flags,
+                                                   limit_active, thresh);
                if (!ret->high) {
                        __btrfs_destroy_workqueue(ret->normal);
                        kfree(ret);
index ad4d0647d1a6c03b6b3ba9d1b4aae9a1ceff6df5..8e52484cd4615544a9d25687ba33f36a56c29d52 100644 (file)
@@ -21,6 +21,7 @@
 #define __BTRFS_ASYNC_THREAD_
 #include <linux/workqueue.h>
 
+struct btrfs_fs_info;
 struct btrfs_workqueue;
 /* Internal use only */
 struct __btrfs_workqueue;
@@ -67,7 +68,8 @@ BTRFS_WORK_HELPER_PROTO(scrubnc_helper);
 BTRFS_WORK_HELPER_PROTO(scrubparity_helper);
 
 
-struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
+struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info,
+                                             const char *name,
                                              unsigned int flags,
                                              int limit_active,
                                              int thresh);
@@ -80,4 +82,6 @@ void btrfs_queue_work(struct btrfs_workqueue *wq,
 void btrfs_destroy_workqueue(struct btrfs_workqueue *wq);
 void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max);
 void btrfs_set_work_high_priority(struct btrfs_work *work);
+struct btrfs_fs_info *btrfs_work_owner(struct btrfs_work *work);
+struct btrfs_fs_info *btrfs_workqueue_owner(struct __btrfs_workqueue *wq);
 #endif
index 49565626321e5266a70f7604c885b2bbc3855f6c..cb6d13c39bee59f18d2dacbda2a90a5890385aea 100644 (file)
@@ -2310,17 +2310,19 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
        unsigned int flags = WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND;
 
        fs_info->workers =
-               btrfs_alloc_workqueue("worker", flags | WQ_HIGHPRI,
-                                     max_active, 16);
+               btrfs_alloc_workqueue(fs_info, "worker",
+                                     flags | WQ_HIGHPRI, max_active, 16);
 
        fs_info->delalloc_workers =
-               btrfs_alloc_workqueue("delalloc", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "delalloc",
+                                     flags, max_active, 2);
 
        fs_info->flush_workers =
-               btrfs_alloc_workqueue("flush_delalloc", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "flush_delalloc",
+                                     flags, max_active, 0);
 
        fs_info->caching_workers =
-               btrfs_alloc_workqueue("cache", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "cache", flags, max_active, 0);
 
        /*
         * a higher idle thresh on the submit workers makes it much more
@@ -2328,41 +2330,48 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
         * devices
         */
        fs_info->submit_workers =
-               btrfs_alloc_workqueue("submit", flags,
+               btrfs_alloc_workqueue(fs_info, "submit", flags,
                                      min_t(u64, fs_devices->num_devices,
                                            max_active), 64);
 
        fs_info->fixup_workers =
-               btrfs_alloc_workqueue("fixup", flags, 1, 0);
+               btrfs_alloc_workqueue(fs_info, "fixup", flags, 1, 0);
 
        /*
         * endios are largely parallel and should have a very
         * low idle thresh
         */
        fs_info->endio_workers =
-               btrfs_alloc_workqueue("endio", flags, max_active, 4);
+               btrfs_alloc_workqueue(fs_info, "endio", flags, max_active, 4);
        fs_info->endio_meta_workers =
-               btrfs_alloc_workqueue("endio-meta", flags, max_active, 4);
+               btrfs_alloc_workqueue(fs_info, "endio-meta", flags,
+                                     max_active, 4);
        fs_info->endio_meta_write_workers =
-               btrfs_alloc_workqueue("endio-meta-write", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "endio-meta-write", flags,
+                                     max_active, 2);
        fs_info->endio_raid56_workers =
-               btrfs_alloc_workqueue("endio-raid56", flags, max_active, 4);
+               btrfs_alloc_workqueue(fs_info, "endio-raid56", flags,
+                                     max_active, 4);
        fs_info->endio_repair_workers =
-               btrfs_alloc_workqueue("endio-repair", flags, 1, 0);
+               btrfs_alloc_workqueue(fs_info, "endio-repair", flags, 1, 0);
        fs_info->rmw_workers =
-               btrfs_alloc_workqueue("rmw", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "rmw", flags, max_active, 2);
        fs_info->endio_write_workers =
-               btrfs_alloc_workqueue("endio-write", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "endio-write", flags,
+                                     max_active, 2);
        fs_info->endio_freespace_worker =
-               btrfs_alloc_workqueue("freespace-write", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "freespace-write", flags,
+                                     max_active, 0);
        fs_info->delayed_workers =
-               btrfs_alloc_workqueue("delayed-meta", flags, max_active, 0);
+               btrfs_alloc_workqueue(fs_info, "delayed-meta", flags,
+                                     max_active, 0);
        fs_info->readahead_workers =
-               btrfs_alloc_workqueue("readahead", flags, max_active, 2);
+               btrfs_alloc_workqueue(fs_info, "readahead", flags,
+                                     max_active, 2);
        fs_info->qgroup_rescan_workers =
-               btrfs_alloc_workqueue("qgroup-rescan", flags, 1, 0);
+               btrfs_alloc_workqueue(fs_info, "qgroup-rescan", flags, 1, 0);
        fs_info->extent_workers =
-               btrfs_alloc_workqueue("extent-refs", flags,
+               btrfs_alloc_workqueue(fs_info, "extent-refs", flags,
                                      min_t(u64, fs_devices->num_devices,
                                            max_active), 8);
 
index acfe72004646762db89985fec00cb867d2325764..68c8a09ae7e556b92451e5f0bed6582a049585bf 100644 (file)
@@ -3781,27 +3781,27 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
        if (fs_info->scrub_workers_refcnt == 0) {
                if (is_dev_replace)
                        fs_info->scrub_workers =
-                               btrfs_alloc_workqueue("scrub", flags,
+                               btrfs_alloc_workqueue(fs_info, "scrub", flags,
                                                      1, 4);
                else
                        fs_info->scrub_workers =
-                               btrfs_alloc_workqueue("scrub", flags,
+                               btrfs_alloc_workqueue(fs_info, "scrub", flags,
                                                      max_active, 4);
                if (!fs_info->scrub_workers)
                        goto fail_scrub_workers;
 
                fs_info->scrub_wr_completion_workers =
-                       btrfs_alloc_workqueue("scrubwrc", flags,
+                       btrfs_alloc_workqueue(fs_info, "scrubwrc", flags,
                                              max_active, 2);
                if (!fs_info->scrub_wr_completion_workers)
                        goto fail_scrub_wr_completion_workers;
 
                fs_info->scrub_nocow_workers =
-                       btrfs_alloc_workqueue("scrubnc", flags, 1, 0);
+                       btrfs_alloc_workqueue(fs_info, "scrubnc", flags, 1, 0);
                if (!fs_info->scrub_nocow_workers)
                        goto fail_scrub_nocow_workers;
                fs_info->scrub_parity_workers =
-                       btrfs_alloc_workqueue("scrubparity", flags,
+                       btrfs_alloc_workqueue(fs_info, "scrubparity", flags,
                                              max_active, 2);
                if (!fs_info->scrub_parity_workers)
                        goto fail_scrub_parity_workers;