This is the mail archive of the cluster-cvs@sourceware.org mailing list for the cluster.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

gfs2-utils: master - fsck.gfs2 writing bitmap when -n specified


Gitweb:        http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitdiff;h=6f706bf2d51acdf0c00e93f3f55baf49e4f5114c
Commit:        6f706bf2d51acdf0c00e93f3f55baf49e4f5114c
Parent:        47b37cfb7beba33018d18d96eb754910112615a8
Author:        Bob Peterson <rpeterso@redhat.com>
AuthorDate:    Fri Jun 19 15:55:45 2009 -0500
Committer:     Bob Peterson <rpeterso@redhat.com>
CommitterDate: Fri Jun 19 15:55:45 2009 -0500

fsck.gfs2 writing bitmap when -n specified

bz 500483

The previous patch was updating the bitmap for all data blocks.
That's not desired, especially when -n is specified.  This version
checks the type in the existing bitmap first to see whether it
needs changing, and if so, it asks permission to do so.

This required the use of a function that was once in libgfs2 but
it eventually found its way to gfs2_edit.  Now it's back in libgfs2
so multiple utils can use it.
---
 gfs2/edit/hexedit.c    |   61 ------------------------------------------------
 gfs2/fsck/pass1.c      |   53 +++++++++++++++++++++++++++++++----------
 gfs2/libgfs2/fs_bits.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++
 gfs2/libgfs2/libgfs2.h |    2 +
 4 files changed, 103 insertions(+), 74 deletions(-)

diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index e8c6030..f9b9bb4 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -446,67 +446,6 @@ static int get_block_type(const char *lpBuffer)
 	return ret_type;
 }
 
-/*
- * fs_get_bitmap - get value of FS bitmap
- * @sdp: super block
- * @blkno: block number relative to file system
- *
- * This function gets the value of a bit of the
- * file system bitmap.
- * Possible state values for a block in the bitmap are:
- *  GFS_BLKST_FREE     (0)
- *  GFS_BLKST_USED     (1)
- *  GFS_BLKST_INVALID  (2)
- *  GFS_BLKST_DINODE   (3)
- *
- * Returns: state on success, -1 on error
- */
-static int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
-					struct rgrp_list *rgd)
-{
-	int           i, val;
-	uint32_t        rgrp_block;
-	struct gfs2_bitmap	*bits = NULL;
-	unsigned int  bit;
-	unsigned char *byte;
-	int local_rgd = 0;
-
-	if(gfs2_check_range(sdp, blkno))
-		return -1;
-	if(rgd == NULL) {
-		local_rgd = 1;
-		rgd = gfs2_blk2rgrpd(sdp, blkno);
-	}
-	if(rgd == NULL)
-		return -1;
-	if(gfs2_rgrp_read(sdp, rgd))
-		return -1;
-
-	rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
-
-	for(i= 0; i < rgd->ri.ri_length; i++){
-		bits = &(rgd->bits[i]);
-		if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY)){
-			break;
-		}
-	}
-
-	if(i >= rgd->ri.ri_length){
-		gfs2_rgrp_relse(rgd, not_updated);
-		return -1;
-	}
-
-	byte = (unsigned char *)(rgd->bh[i]->b_data + bits->bi_offset) +
-		(rgrp_block/GFS2_NBBY - bits->bi_start);
-	bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
-
-	val = ((*byte >> bit) & GFS2_BIT_MASK);
-	if(local_rgd)
-		gfs2_rgrp_relse(rgd, not_updated);
-
-	return val;
-}
-
 /* ------------------------------------------------------------------------ */
 /* display_block_type                                                       */
 /* returns: metatype if block is a GFS2 structure block type                */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 1a635b6..2bcf1f8 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -137,7 +137,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
 {
 	struct gfs2_block_query q = {0};
 	struct block_count *bc = (struct block_count *) private;
-	int error = 0;
+	int error = 0, btype;
 
 	if (gfs2_check_range(ip->i_sbd, block)) {
 		log_err( _("Bad data block pointer (out of range)\n"));
@@ -168,17 +168,14 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
 		   won't have metadata headers.  In that case, the block is
 		   marked as duplicate, but also as a data block. */
 		error = 1;
-		log_err( _("Block %" PRIu64 " (0x%"PRIx64 ") previous "
-			   "reference was invalid, so it likely is a data "
-			   "block.\n"),
-			block, block);
 		gfs2_block_unmark(ip->i_sbd, bl, block, gfs2_meta_inval);
 		gfs2_block_mark(ip->i_sbd, bl, block, gfs2_dup_block);
 	}
-	log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to data block\n"), block,
-			  block);
+	log_debug( _("Marking block %llu (0x%llx) as data block\n"),
+		   (unsigned long long)block, (unsigned long long)block);
 	gfs2_block_mark(ip->i_sbd, bl, block, gfs2_block_used);
-	/* This is confusing, so I'll clarify.  There are two bitmaps:
+
+	/* This is also confusing, so I'll clarify.  There are two bitmaps:
 	   (1) The gfs2_bmap that fsck uses to keep track of what block
 	   type has been discovered, and (2) The rgrp bitmap.  Function
 	   gfs2_block_set is used to set the former and gfs2_set_bitmap
@@ -188,8 +185,29 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
 	   metadata when we're traversing the metadata with gfs2_next_rg_meta
 	   in func pass1().  If that happens, it will look at the block,
 	   say "hey this isn't metadata" and mark it incorrectly as an
-	   invalid metadata block and free it. */
-	gfs2_set_bitmap(ip->i_sbd, block, GFS2_BLKST_USED);
+	   invalid metadata block and free it.  Ordinarily, fsck will wait
+	   until pass5 to sync (2) so that it agrees with (1).  However, in
+	   this case, it's better to do it upfront.  The duplicate solving
+	   code in pass1b.c is better at resolving metadata referencing a
+	   data block than it is at resolving a data block referencing a
+	   metadata block. */
+	btype = gfs2_get_bitmap(ip->i_sbd, block, NULL);
+	if (btype != GFS2_BLKST_USED) {
+		const char *allocdesc[] = {"free space", "data", "unlinked",
+					   "metadata", "reserved"};
+
+		errors_found++;
+		log_err( _("Block %llu (0x%llx) seems to be data, but is "
+			   "marked as %s.\n", (unsigned long long)block,
+			   (unsigned long long)block, allocdesc[btype]));
+		if(query(&opts, _("Okay to mark it as 'data'? (y/n)"))) {
+			errors_corrected++;
+			gfs2_set_bitmap(ip->i_sbd, block, GFS2_BLKST_USED);
+			log_err( _("The block was reassigned as data.\n"));
+		} else {
+			log_err( _("The invalid block was ignored.\n"));
+		}
+	}
 	bc->data_count++;
 	return error;
 }
@@ -824,13 +842,22 @@ static int scan_meta(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
 			  uint64_t block)
 {
 	if (gfs2_check_meta(bh, 0)) {
-		log_info( _("Found invalid metadata at #%" PRIu64 " (0x%" PRIx64 ")\n"),
-				  block, block);
+		errors_found++;
+
+		log_info( _("Found invalid metadata at #%llu (0x%llx)\n"),
+			  (unsigned long long)block,
+			  (unsigned long long)block);
 		if(gfs2_block_set(sdp, bl, block, gfs2_meta_inval)) {
 			stack;
 			return -1;
 		}
-		gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
+		if(query(&opts, _("Okay to free the invalid block? (y/n)"))) {
+			errors_corrected++;
+			gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
+			log_err( _("The invalid block was freed.\n"));
+		} else {
+			log_err( _("The invalid block was ignored.\n"));
+		}
 		return 0;
 	}
 
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index fd9c655..98e5729 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -144,3 +144,64 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
 	gfs2_rgrp_relse(rgd, updated);
 	return 0;
 }
+
+/*
+ * fs_get_bitmap - get value of FS bitmap
+ * @sdp: super block
+ * @blkno: block number relative to file system
+ *
+ * This function gets the value of a bit of the
+ * file system bitmap.
+ * Possible state values for a block in the bitmap are:
+ *  GFS_BLKST_FREE     (0)
+ *  GFS_BLKST_USED     (1)
+ *  GFS_BLKST_INVALID  (2)
+ *  GFS_BLKST_DINODE   (3)
+ *
+ * Returns: state on success, -1 on error
+ */
+static int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
+					struct rgrp_list *rgd)
+{
+	int           i, val;
+	uint32_t        rgrp_block;
+	struct gfs2_bitmap	*bits = NULL;
+	unsigned int  bit;
+	unsigned char *byte;
+	int local_rgd = 0;
+
+	if(gfs2_check_range(sdp, blkno))
+		return -1;
+	if(rgd == NULL) {
+		local_rgd = 1;
+		rgd = gfs2_blk2rgrpd(sdp, blkno);
+	}
+	if(rgd == NULL)
+		return -1;
+	if(gfs2_rgrp_read(sdp, rgd))
+		return -1;
+
+	rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
+
+	for(i= 0; i < rgd->ri.ri_length; i++){
+		bits = &(rgd->bits[i]);
+		if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY)){
+			break;
+		}
+	}
+
+	if(i >= rgd->ri.ri_length){
+		gfs2_rgrp_relse(rgd, not_updated);
+		return -1;
+	}
+
+	byte = (unsigned char *)(rgd->bh[i]->b_data + bits->bi_offset) +
+		(rgrp_block/GFS2_NBBY - bits->bi_start);
+	bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
+
+	val = ((*byte >> bit) & GFS2_BIT_MASK);
+	if(local_rgd)
+		gfs2_rgrp_relse(rgd, not_updated);
+
+	return val;
+}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index b64edd5..35560c8 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -426,6 +426,8 @@ extern uint32_t gfs2_blkalloc_internal(struct rgrp_list *rgd, uint32_t goal,
 extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
 
 /* functions with blk #'s that are file system relative */
+extern int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
+			   struct rgrp_list *rgd);
 extern int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state);
 
 /* fs_geometry.c */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]