GFS2: Wake up io waiters whenever a flush is done
authorBob Peterson <rpeterso@redhat.com>
Sat, 7 Jan 2017 03:14:28 +0000 (22:14 -0500)
committerBob Peterson <rpeterso@redhat.com>
Sat, 7 Jan 2017 03:14:28 +0000 (22:14 -0500)
Before this patch, if a process called function gfs2_log_reserve to
reserve some journal blocks, but the journal not enough blocks were
free, it would call io_schedule. However, in the log flush daemon,
it woke up the waiters only if an gfs2_ail_flush was no longer
required. This resulted in situations where processes would wait
forever because the number of blocks required was so high that it
pushed the journal into a perpetual state of flush being required.

This patch changes the logd daemon so that it wakes up io waiters
every time the log is actually flushed.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
fs/gfs2/log.c

index 4df349c7f022cf742c516abf0e185ac0715b1138..5028a9d00c17d0da0807e93d8c3b48ac264f2985 100644 (file)
@@ -918,12 +918,15 @@ int gfs2_logd(void *data)
        struct gfs2_sbd *sdp = data;
        unsigned long t = 1;
        DEFINE_WAIT(wait);
+       bool did_flush;
 
        while (!kthread_should_stop()) {
 
+               did_flush = false;
                if (gfs2_jrnl_flush_reqd(sdp) || t == 0) {
                        gfs2_ail1_empty(sdp);
                        gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+                       did_flush = true;
                }
 
                if (gfs2_ail_flush_reqd(sdp)) {
@@ -931,9 +934,10 @@ int gfs2_logd(void *data)
                        gfs2_ail1_wait(sdp);
                        gfs2_ail1_empty(sdp);
                        gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
+                       did_flush = true;
                }
 
-               if (!gfs2_ail_flush_reqd(sdp))
+               if (!gfs2_ail_flush_reqd(sdp) || did_flush)
                        wake_up(&sdp->sd_log_waitq);
 
                t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;