This patch adds a check in gfs2_ail1_start_one to see if our current
IO needs to be unplugged and replugged. If we don't unplug it once
in a while, our IO can get so clogged up that none of our pages for ail1
items can be written because they're all in PageWriteback but they can't be
written because the plug is never finished.

Signed-off-by: Bob Peterson <rpete...@redhat.com>
---
 fs/gfs2/log.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index abb051494b43..5fc706ea2472 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -91,7 +91,7 @@ void gfs2_remove_from_ail(struct gfs2_bufdata *bd)
 
 static int gfs2_ail1_start_one(struct gfs2_sbd *sdp,
                               struct writeback_control *wbc,
-                              struct gfs2_trans *tr)
+                              struct gfs2_trans *tr, struct blk_plug *plug)
 __releases(&sdp->sd_ail_lock)
 __acquires(&sdp->sd_ail_lock)
 {
@@ -133,6 +133,10 @@ __acquires(&sdp->sd_ail_lock)
                        continue;
                spin_unlock(&sdp->sd_ail_lock);
                ret = generic_writepages(mapping, wbc);
+               if (blk_needs_flush_plug(current)) {
+                       blk_finish_plug(plug);
+                       blk_start_plug(plug);
+               }
                spin_lock(&sdp->sd_ail_lock);
                if (ret == -ENODATA) /* if a jdata write into a new hole */
                        ret = 0; /* ignore it */
@@ -207,7 +211,7 @@ 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;
-               ret = gfs2_ail1_start_one(sdp, wbc, tr);
+               ret = gfs2_ail1_start_one(sdp, wbc, tr, &plug);
                if (ret) {
                        if (ret == -EBUSY)
                                goto restart;

Reply via email to