Function gfs2_ail_flush_reqd checks the SDF_FORCE_AIL_FLUSH flag to determine if an AIL flush should be forced in low-memory situations. However, it also immediately clears the flag, and when called repeatedly as in function gfs2_logd, the flag will be lost. Fix that by pulling the SDF_FORCE_AIL_FLUSH flag check out of gfs2_ail_flush_reqd.
In addition, in gfs2_writepages, logd needs to be woken up after setting the SDF_FORCE_AIL_FLUSH flag. Fixes: b066a4eebd4f ("gfs2: forcibly flush ail to relieve memory pressure") Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com> --- fs/gfs2/aops.c | 4 +++- fs/gfs2/log.c | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 5f02542370c4..d15a10a18962 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -189,8 +189,10 @@ static int gfs2_writepages(struct address_space *mapping, * pages held in the ail that it can't find. */ ret = iomap_writepages(mapping, wbc, &wpc, &gfs2_writeback_ops); - if (ret == 0) + if (ret == 0) { set_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags); + wake_up(&sdp->sd_logd_waitq); + } return ret; } diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index d3da259820e3..aaca22f2aa2d 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -1282,9 +1282,6 @@ static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) { unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); - if (test_and_clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags)) - return 1; - return used_blocks + atomic_read(&sdp->sd_log_blks_needed) >= atomic_read(&sdp->sd_log_thresh2); } @@ -1325,7 +1322,9 @@ int gfs2_logd(void *data) GFS2_LFC_LOGD_JFLUSH_REQD); } - if (gfs2_ail_flush_reqd(sdp)) { + if (test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) || + gfs2_ail_flush_reqd(sdp)) { + clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags); gfs2_ail1_start(sdp); gfs2_ail1_wait(sdp); gfs2_ail1_empty(sdp, 0); @@ -1338,6 +1337,7 @@ int gfs2_logd(void *data) try_to_freeze(); t = wait_event_interruptible_timeout(sdp->sd_logd_waitq, + test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) || gfs2_ail_flush_reqd(sdp) || gfs2_jrnl_flush_reqd(sdp) || kthread_should_stop(), -- 2.40.1