STABLE2 - gfs-kmod: GFS corruption after forced withdraw

Bob Peterson rpeterso@fedoraproject.org
Thu Oct 2 15:41:00 GMT 2008


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=39fab5d033b57b3b8804d88bae22be3cb04fac17
Commit:        39fab5d033b57b3b8804d88bae22be3cb04fac17
Parent:        67067a37a9acc356a42c5f69bd3f7f39284f8ce1
Author:        Bob Peterson <rpeterso@redhat.com>
AuthorDate:    Fri Aug 8 13:49:56 2008 -0500
Committer:     Bob Peterson <rpeterso@redhat.com>
CommitterDate: Thu Oct 2 10:40:30 2008 -0500

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 3a1896f..eaa0949 100644
--- a/gfs-kernel/src/gfs/log.c
+++ b/gfs-kernel/src/gfs/log.c
@@ -655,7 +655,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
@@ -689,12 +695,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))
@@ -1372,6 +1380,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);
@@ -1406,10 +1416,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