cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
From: Bob Peterson <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [GFS2 PATCH] gfs2: purge ail1 and ail2 lists on withdraw
Date: Thu, 13 Sep 2018 14:24:47 -0400 (EDT)	[thread overview]
Message-ID: <2113925841.12987130.1536863087425.JavaMail.zimbra@redhat.com> (raw)
In-Reply-To: <292195193.12986730.1536862981666.JavaMail.zimbra@redhat.com>

Hi,

I don't know if this is the right approach, but it does seem to help
prevent gfs2 file system corruption due to journal replay.
I wanted to post it early to get people's thoughts.
---
This patch purges the ail1 and ail2 lists forceably whenever gfs2
does a file system withdraw. This should help mitigate file system
damage caused by buffers that are in transit or in transactions.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
---
 fs/gfs2/log.c  | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/gfs2/log.h  |  2 +-
 fs/gfs2/util.c |  4 ++++
 3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index ee20ea42e7b5..5c9a1057cb48 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -958,6 +958,70 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
 	sdp->sd_log_tail = sdp->sd_log_head;
 }
 
+static void gfs2_ordered_purge(struct gfs2_sbd *sdp)
+{
+	struct gfs2_inode *ip;
+
+	spin_lock(&sdp->sd_ordered_lock);
+	while (!list_empty(&sdp->sd_log_le_ordered)) {
+		ip = list_first_entry(&sdp->sd_log_le_ordered,
+				      struct gfs2_inode, i_ordered);
+		list_del(&ip->i_ordered);
+		clear_bit(GIF_ORDERED, &ip->i_flags);
+		if (ip->i_inode.i_mapping->nrpages) {
+			spin_unlock(&sdp->sd_ordered_lock);
+			filemap_flush(ip->i_inode.i_mapping);
+			spin_lock(&sdp->sd_ordered_lock);
+		}
+	}
+	spin_unlock(&sdp->sd_ordered_lock);
+}
+
+static void tr_list_purge(struct gfs2_sbd *sdp, struct list_head *head)
+__releases(&sdp->sd_ail_lock)
+__acquires(&sdp->sd_ail_lock)
+{
+	struct gfs2_bufdata *bd;
+	struct buffer_head *bh;
+
+	while (!list_empty(head)) {
+		bd = list_first_entry(head, struct gfs2_bufdata,
+				      bd_ail_st_list);
+		bh = bd->bd_bh;
+		if (buffer_locked(bh)) {
+			spin_unlock(&sdp->sd_ail_lock);
+			wait_on_buffer(bh);
+			spin_lock(&sdp->sd_ail_lock);
+		} else {
+			clear_buffer_dirty(bh);
+		}
+		gfs2_remove_from_ail(bd);
+	}
+}
+
+static void ail_list_purge(struct gfs2_sbd *sdp, struct list_head *head)
+{
+	struct gfs2_trans *tr;
+
+	while (!list_empty(head)) {
+		tr = list_first_entry(head, struct gfs2_trans, tr_list);
+		list_del(&tr->tr_list);
+		tr_list_purge(sdp, &tr->tr_ail1_list);
+		tr_list_purge(sdp, &tr->tr_ail2_list);
+		kfree(tr);
+	}
+}
+
+void gfs2_ail_purge(struct gfs2_sbd *sdp)
+{
+	gfs2_ordered_purge(sdp);
+
+	spin_lock(&sdp->sd_ail_lock);
+	ail_list_purge(sdp, &sdp->sd_ail1_list);
+	ail_list_purge(sdp, &sdp->sd_ail2_list);
+	spin_unlock(&sdp->sd_ail_lock);
+}
+
 static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp)
 {
 	return (atomic_read(&sdp->sd_log_pinned) +
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index 20241436126d..28052dc8d282 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -76,7 +76,7 @@ extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
 			   u32 type);
 extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
 extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc);
-
+extern void gfs2_ail_purge(struct gfs2_sbd *sdp);
 extern void gfs2_log_shutdown(struct gfs2_sbd *sdp);
 extern int gfs2_logd(void *data);
 extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd);
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index b5a6e958432d..550918039139 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -19,6 +19,7 @@
 #include "gfs2.h"
 #include "incore.h"
 #include "glock.h"
+#include "log.h"
 #include "rgrp.h"
 #include "util.h"
 
@@ -62,6 +63,9 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...)
 		fs_err(sdp, "about to withdraw this file system\n");
 		BUG_ON(sdp->sd_args.ar_debug);
 
+		/* Purge our ail1 and ail2 lists: we can't trust them anyway */
+		gfs2_ail_purge(sdp);
+
 		kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE);
 
 		if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))



           reply	other threads:[~2018-09-13 18:24 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <292195193.12986730.1536862981666.JavaMail.zimbra@redhat.com>]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2113925841.12987130.1536863087425.JavaMail.zimbra@redhat.com \
    --to=rpeterso@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).