From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Mon, 9 Dec 2019 09:36:57 -0600 Subject: [Cluster-devel] [GFS2 v8 PATCH 19/22] gfs2: Withdraw in gfs2_ail1_flush if write_cache_pages returns error In-Reply-To: <20191209153700.700208-1-rpeterso@redhat.com> References: <20191209153700.700208-1-rpeterso@redhat.com> Message-ID: <20191209153700.700208-20-rpeterso@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Before this patch, function gfs2_ail1_start_one would return any errors it received from write_cache_pages (except -EBUSY) but it did not withdraw. Since function gfs2_ail1_flush just checks for the bad return code and loops, the loop might potentially never end. This patch adds some logic to allow it to exit the loop and withdraw properly when errors are received from write_cache_pages. Signed-off-by: Bob Peterson --- fs/gfs2/log.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 799119fa3ecc..33ddf7ccfea9 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -100,6 +100,7 @@ __acquires(&sdp->sd_ail_lock) struct address_space *mapping; struct gfs2_bufdata *bd, *s; struct buffer_head *bh; + int ret = 0; list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) { bh = bd->bd_bh; @@ -132,10 +133,16 @@ __acquires(&sdp->sd_ail_lock) if (!mapping) continue; spin_unlock(&sdp->sd_ail_lock); - generic_writepages(mapping, wbc); + ret = generic_writepages(mapping, wbc); spin_lock(&sdp->sd_ail_lock); + if (ret == -EBUSY) + return 1; /* need to retry */ + if (ret < 0) { + set_bit(SDF_WITHDRAWING, &sdp->sd_flags); + return ret; + } if (wbc->nr_to_write <= 0) - break; + return 0; return 1; } @@ -157,6 +164,7 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) struct list_head *head = &sdp->sd_ail1_list; struct gfs2_trans *tr; struct blk_plug plug; + int ret; trace_gfs2_ail_flush(sdp, wbc, 1); blk_start_plug(&plug); @@ -165,7 +173,10 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) list_for_each_entry_reverse(tr, head, tr_list) { if (wbc->nr_to_write <= 0) break; - if (gfs2_ail1_start_one(sdp, wbc, tr) && !gfs2_withdrawn(sdp)) + ret = gfs2_ail1_start_one(sdp, wbc, tr); + if (ret < 0) + break; + else if (ret) goto restart; } spin_unlock(&sdp->sd_ail_lock); -- 2.23.0