gfs2: Move delete workqueue into super block
authorAndreas Gruenbacher <agruenba@redhat.com>
Tue, 6 Dec 2022 15:04:22 +0000 (16:04 +0100)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 31 Jan 2023 21:40:24 +0000 (22:40 +0100)
Move the global delete workqueue into struct gfs2_sbd so that we can
flush / drain it without interfering with other filesystems.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/incore.h
fs/gfs2/ops_fstype.c
fs/gfs2/super.c

index 8d55616..1565fdf 100644 (file)
@@ -67,7 +67,6 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state,
 
 static struct dentry *gfs2_root;
 static struct workqueue_struct *glock_workqueue;
-struct workqueue_struct *gfs2_delete_workqueue;
 static LIST_HEAD(lru_list);
 static atomic_t lru_count = ATOMIC_INIT(0);
 static DEFINE_SPINLOCK(lru_lock);
@@ -2060,7 +2059,9 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
 
 bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay)
 {
-       return queue_delayed_work(gfs2_delete_workqueue,
+       struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+
+       return queue_delayed_work(sdp->sd_delete_wq,
                                  &gl->gl_delete, delay);
 }
 
@@ -2073,8 +2074,10 @@ void gfs2_cancel_delete_work(struct gfs2_glock *gl)
 static void flush_delete_work(struct gfs2_glock *gl)
 {
        if (gl->gl_name.ln_type == LM_TYPE_IOPEN) {
+               struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+
                if (cancel_delayed_work(&gl->gl_delete)) {
-                       queue_delayed_work(gfs2_delete_workqueue,
+                       queue_delayed_work(sdp->sd_delete_wq,
                                           &gl->gl_delete, 0);
                }
        }
@@ -2083,7 +2086,7 @@ static void flush_delete_work(struct gfs2_glock *gl)
 void gfs2_flush_delete_work(struct gfs2_sbd *sdp)
 {
        glock_hash_walk(flush_delete_work, sdp);
-       flush_workqueue(gfs2_delete_workqueue);
+       flush_workqueue(sdp->sd_delete_wq);
 }
 
 /**
@@ -2444,18 +2447,9 @@ int __init gfs2_glock_init(void)
                rhashtable_destroy(&gl_hash_table);
                return -ENOMEM;
        }
-       gfs2_delete_workqueue = alloc_workqueue("delete_workqueue",
-                                               WQ_MEM_RECLAIM | WQ_FREEZABLE,
-                                               0);
-       if (!gfs2_delete_workqueue) {
-               destroy_workqueue(glock_workqueue);
-               rhashtable_destroy(&gl_hash_table);
-               return -ENOMEM;
-       }
 
        ret = register_shrinker(&glock_shrinker, "gfs2-glock");
        if (ret) {
-               destroy_workqueue(gfs2_delete_workqueue);
                destroy_workqueue(glock_workqueue);
                rhashtable_destroy(&gl_hash_table);
                return ret;
@@ -2472,7 +2466,6 @@ void gfs2_glock_exit(void)
        unregister_shrinker(&glock_shrinker);
        rhashtable_destroy(&gl_hash_table);
        destroy_workqueue(glock_workqueue);
-       destroy_workqueue(gfs2_delete_workqueue);
 }
 
 static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)
index 17b05d5..b9da61d 100644 (file)
@@ -144,7 +144,6 @@ struct gfs2_glock_aspace {
        struct address_space mapping;
 };
 
-extern struct workqueue_struct *gfs2_delete_workqueue;
 static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
 {
        struct gfs2_holder *gh;
index cd88636..6e8a5f2 100644 (file)
@@ -770,6 +770,10 @@ struct gfs2_sbd {
 
        struct completion sd_journal_ready;
 
+       /* Workqueue stuff */
+
+       struct workqueue_struct *sd_delete_wq;
+
        /* Daemon stuff */
 
        struct task_struct *sd_logd_process;
index c0cf1d2..f13a940 100644 (file)
@@ -1197,9 +1197,15 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
 
        snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s", sdp->sd_table_name);
 
+       sdp->sd_delete_wq = alloc_workqueue("gfs2-delete/%s",
+                       WQ_MEM_RECLAIM | WQ_FREEZABLE, 0, sdp->sd_fsname);
+       error = -ENOMEM;
+       if (!sdp->sd_delete_wq)
+               goto fail_free;
+
        error = gfs2_sys_fs_add(sdp);
        if (error)
-               goto fail_free;
+               goto fail_delete_wq;
 
        gfs2_create_debugfs_file(sdp);
 
@@ -1309,6 +1315,8 @@ fail_lm:
 fail_debug:
        gfs2_delete_debugfs_file(sdp);
        gfs2_sys_fs_del(sdp);
+fail_delete_wq:
+       destroy_workqueue(sdp->sd_delete_wq);
 fail_free:
        free_sbd(sdp);
        sb->s_fs_info = NULL;
index a857b99..0b5cda4 100644 (file)
@@ -630,6 +630,8 @@ restart:
        /*  Unmount the locking protocol  */
        gfs2_lm_unmount(sdp);
 
+       destroy_workqueue(sdp->sd_delete_wq);
+
        /*  At this point, we're through participating in the lockspace  */
        gfs2_sys_fs_del(sdp);
        free_sbd(sdp);