gfs2: Sanitize kthread stopping
authorAndreas Gruenbacher <agruenba@redhat.com>
Fri, 25 Aug 2023 09:18:38 +0000 (11:18 +0200)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 5 Sep 2023 13:58:17 +0000 (15:58 +0200)
Immediately stop the logd and quotad kernel threads when a filesystem
withdraw is detected: those threads aren't doing anything useful after a
withdraw.  (Depends on the extra logd and quotad task struct references
held since commit 7a109f383fa3 ("gfs2: Fix asynchronous thread
destruction").)

In addition, check for kthread_should_stop() in the wait condition in
gfs2_quotad() to stop immediately when kthread_stop() is called.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/log.c
fs/gfs2/quota.c

index addf4ce..e5271ae 100644 (file)
@@ -1298,11 +1298,9 @@ int gfs2_logd(void *data)
        unsigned long t = 1;
 
        while (!kthread_should_stop()) {
+               if (gfs2_withdrawn(sdp))
+                       break;
 
-               if (gfs2_withdrawn(sdp)) {
-                       msleep_interruptible(HZ);
-                       continue;
-               }
                /* Check for errors writing to the journal */
                if (sdp->sd_log_error) {
                        gfs2_lm(sdp,
@@ -1311,7 +1309,7 @@ int gfs2_logd(void *data)
                                "prevent further damage.\n",
                                sdp->sd_fsname, sdp->sd_log_error);
                        gfs2_withdraw(sdp);
-                       continue;
+                       break;
                }
 
                if (gfs2_jrnl_flush_reqd(sdp) || t == 0) {
@@ -1339,6 +1337,7 @@ int gfs2_logd(void *data)
                                gfs2_ail_flush_reqd(sdp) ||
                                gfs2_jrnl_flush_reqd(sdp) ||
                                sdp->sd_log_error ||
+                               gfs2_withdrawn(sdp) ||
                                kthread_should_stop(),
                                t);
        }
index 5201bb4..3a3189f 100644 (file)
@@ -1559,9 +1559,9 @@ int gfs2_quotad(void *data)
        unsigned long t = 0;
 
        while (!kthread_should_stop()) {
-
                if (gfs2_withdrawn(sdp))
-                       goto bypass;
+                       break;
+
                /* Update the master statfs file */
                if (sdp->sd_statfs_force_sync) {
                        int error = gfs2_statfs_sync(sdp->sd_vfs, 0);
@@ -1579,11 +1579,12 @@ int gfs2_quotad(void *data)
 
                try_to_freeze();
 
-bypass:
                t = min(quotad_timeo, statfs_timeo);
 
                t = wait_event_interruptible_timeout(sdp->sd_quota_wait,
-                               sdp->sd_statfs_force_sync,
+                               sdp->sd_statfs_force_sync ||
+                               gfs2_withdrawn(sdp) ||
+                               kthread_should_stop(),
                                t);
 
                if (sdp->sd_statfs_force_sync)