cluster: RHEL52 - gfs-kmod: GFS corruption after forced withdraw

Bob Peterson rpeterso@fedoraproject.org
Fri Feb 13 15:31:00 GMT 2009


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=21fa92bcc567386ffb548ce7a1a7efe42266d889
Commit:        21fa92bcc567386ffb548ce7a1a7efe42266d889
Parent:        7da342092f2df950d82e0fd7a7372757b821a27c
Author:        Bob Peterson <rpeterso@redhat.com>
AuthorDate:    Fri Aug 8 13:49:56 2008 -0500
Committer:     Bob Peterson <rpeterso@redhat.com>
CommitterDate: Thu Feb 12 17:19:23 2009 -0600

gfs-kmod: GFS corruption after forced withdraw

bz 452274

GFS file systems were being corrupted because some of the
functions in log.c were writing to the journal after the
file system had been withdrawn.
---
 gfs-kernel/src/gfs/log.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/gfs-kernel/src/gfs/log.c b/gfs-kernel/src/gfs/log.c
index 8082202..d8738fa 100644
--- a/gfs-kernel/src/gfs/log.c
+++ b/gfs-kernel/src/gfs/log.c
@@ -668,7 +668,13 @@ sync_trans(struct gfs_sbd *sdp, struct gfs_trans *tr)
 	     tmp != head;
 	     tmp = prev, prev = tmp->prev) {
 		lb = list_entry(tmp, struct gfs_log_buf, lb_list);
-		gfs_logbh_start(sdp, &lb->lb_bh);
+		if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) {
+			gfs_logbh_start(sdp, &lb->lb_bh);
+		} else {
+			list_del(&lb->lb_list);
+			log_free_buf(sdp, lb);
+			error = -EIO;
+		}
 	}
 
 	/* Wait on I/O
@@ -702,12 +708,14 @@ static int
 commit_trans(struct gfs_sbd *sdp, struct gfs_trans *tr)
 {
 	struct gfs_log_buf *lb;
-	int error;
+	int error = 0;
 
 	lb = log_get_header(sdp, tr, TRUE);
 
-	gfs_logbh_start(sdp, &lb->lb_bh);
-	error = gfs_logbh_wait(sdp, &lb->lb_bh);
+	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) {
+		gfs_logbh_start(sdp, &lb->lb_bh);
+		error = gfs_logbh_wait(sdp, &lb->lb_bh);
+	}
 	if (!error) {
 		spin_lock(&sdp->sd_log_seg_lock);
 		if (!(tr->tr_flags & TRF_DUMMY))
@@ -1385,6 +1393,8 @@ gfs_log_shutdown(struct gfs_sbd *sdp)
 	gfs_logbh_init(sdp, &lb->lb_bh, sdp->sd_log_head, bmem);
 	memset(bmem, 0, sdp->sd_sb.sb_bsize);
 	gfs_desc_out(&desc, lb->lb_bh.b_data);
+	if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
+		goto out;
 	gfs_logbh_start(sdp, &lb->lb_bh);
 	error = gfs_logbh_wait(sdp, &lb->lb_bh);
 	gfs_logbh_uninit(sdp, &lb->lb_bh);
@@ -1419,10 +1429,11 @@ gfs_log_shutdown(struct gfs_sbd *sdp)
 	gfs_log_header_out(&head,
 			   lb->lb_bh.b_data + GFS_BASIC_BLOCK -
 			   sizeof(struct gfs_log_header));
-	gfs_logbh_start(sdp, &lb->lb_bh);
-	gfs_logbh_wait(sdp, &lb->lb_bh);
-	gfs_logbh_uninit(sdp, &lb->lb_bh);
-
+	if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) {
+		gfs_logbh_start(sdp, &lb->lb_bh);
+		gfs_logbh_wait(sdp, &lb->lb_bh);
+		gfs_logbh_uninit(sdp, &lb->lb_bh);
+	}
    /* If a withdraw is called before we've a chance to relock the trans
     * lock, the sd_log_head points to the wrong place, and a umount will
     * fail on asserts because of this.



More information about the Cluster-cvs mailing list