[Ocfs2-tools-commits] zab commits r387 - in trunk: fsck.ocfs2 fsck.ocfs2/include libocfs2 libocfs2/include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Nov 10 21:04:24 CST 2004


Author: zab
Date: 2004-11-10 21:04:23 -0600 (Wed, 10 Nov 2004)
New Revision: 387

Modified:
   trunk/fsck.ocfs2/Makefile
   trunk/fsck.ocfs2/icount.c
   trunk/fsck.ocfs2/include/util.h
   trunk/fsck.ocfs2/pass0.c
   trunk/fsck.ocfs2/pass1.c
   trunk/fsck.ocfs2/pass4.c
   trunk/fsck.ocfs2/util.c
   trunk/libocfs2/Makefile
   trunk/libocfs2/bitmap.c
   trunk/libocfs2/chainalloc.c
   trunk/libocfs2/include/bitmap.h
Log:
o get rid of more fatal errors
o introduce some state when io fails so we can keep the fs dirty later
o be more careful when iterating over potentially uninitialized inodes
o yet more restrictive debugging
o remove the requirement of byte-alignment of bit regions in libocfs2.. mkfs
  puts the system inode at block 4 and so its bitmap isn't byte aligned.  the
  fs may well do the same.


Modified: trunk/fsck.ocfs2/Makefile
===================================================================
--- trunk/fsck.ocfs2/Makefile	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/Makefile	2004-11-11 03:04:23 UTC (rev 387)
@@ -8,7 +8,7 @@
 LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
 
 ifdef OCFS_DEBUG
-OPTS += -O -g
+OPTS += -ggdb
 else
 OPTS += -O2
 endif

Modified: trunk/fsck.ocfs2/icount.c
===================================================================
--- trunk/fsck.ocfs2/icount.c	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/icount.c	2004-11-11 03:04:23 UTC (rev 387)
@@ -117,16 +117,20 @@
 {
 	icount_node *in;
 	int was_set;
+	uint16_t ret = 0;
 
 	ocfs2_bitmap_test(icount->ic_single_bm, blkno, &was_set);
-	if (was_set)
-		return 1;
+	if (was_set) {
+		ret = 1;
+		goto out;
+	}
 
 	in = icount_search(icount, blkno);
 	if (in)
-		return in->in_icount;
+		ret = in->in_icount;
 
-	return 0;
+out:
+	return ret;
 }
 
 /* again, simple before efficient.  We just find the old value and

Modified: trunk/fsck.ocfs2/include/util.h
===================================================================
--- trunk/fsck.ocfs2/include/util.h	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/include/util.h	2004-11-11 03:04:23 UTC (rev 387)
@@ -25,6 +25,7 @@
 #define __O2FSCK_UTIL_H__
 
 #include <stdlib.h>
+#include "fsck.h"
 
 /* we duplicate e2fsck's error codes to make everyone's life easy */
 #define FSCK_OK          0      /* No errors */
@@ -42,7 +43,7 @@
 	exit(FSCK_ERROR);						\
 } while (0)
 
-void o2fsck_write_inode(ocfs2_filesys *fs, uint64_t blkno, ocfs2_dinode *di);
+void o2fsck_write_inode(o2fsck_state *ost, uint64_t blkno, ocfs2_dinode *di);
 
 #endif /* __O2FSCK_UTIL_H__ */
 

Modified: trunk/fsck.ocfs2/pass0.c
===================================================================
--- trunk/fsck.ocfs2/pass0.c	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/pass0.c	2004-11-11 03:04:23 UTC (rev 387)
@@ -302,7 +302,8 @@
 
 	cl = &di->id2.i_chain;
 
-	verbosef("cl count %u next %u\n", cl->cl_count, cl->cl_next_free_rec);
+	verbosef("cl cpg %u bpc %u count %u next %u\n", 
+		 cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec);
 
 	max_count = ocfs2_chain_recs_per_inode(ost->ost_fs->fs_blocksize);
 

Modified: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/pass1.c	2004-11-11 03:04:23 UTC (rev 387)
@@ -167,7 +167,7 @@
 		   "allocated?",
 		   blkno, di->i_suballoc_node, node)) {
 		di->i_suballoc_node = node;
-		o2fsck_write_inode(ost->ost_fs, di->i_blkno, di);
+		o2fsck_write_inode(ost, di->i_blkno, di);
 	}
 out:
 	return;
@@ -193,12 +193,13 @@
 	/* XXX need to compare the lifetime of inodes (uninitialized?
 	 * in use?  orphaned?  deleted?  garbage?) to understand what
 	 * fsck can do to fix it up */
-	if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
-		   strlen(OCFS2_INODE_SIGNATURE)) &&
-	    prompt(ost, PY, "Inode %"PRIu64" doesn't have a valid signature. "
-		   "Clear it?", blkno)) {
-		clear = 1;
-		goto out;
+
+	if (di->i_blkno != blkno &&
+	    prompt(ost, PY, "Inode read from block %"PRIu64" has i_blkno set "
+		   "to %"PRIu64".  Set the inode's i_blkno value to reflect "
+		   "its location on disk?", blkno, di->i_blkno)) {
+		di->i_blkno = blkno;
+		o2fsck_write_inode(ost, blkno, di);
 	}
 
 	if (di->i_links_count)
@@ -215,14 +216,14 @@
 		o2fsck_icount_set(ost->ost_icount_in_inodes, di->i_blkno,
 				  di->i_links_count);
 
-		o2fsck_write_inode(fs, blkno, di);
+		o2fsck_write_inode(ost, blkno, di);
 	}
 
 	if (di->i_dtime && prompt(ost, PY, "Inode %"PRIu64" is in use but has "
 				  "a non-zero dtime.  Reset the dtime to 0?",  
 				   di->i_blkno)) {
 		di->i_dtime = 0ULL;
-		o2fsck_write_inode(fs, blkno, di);
+		o2fsck_write_inode(ost, blkno, di);
 	}
 
 	if (S_ISDIR(di->i_mode)) {
@@ -247,7 +248,7 @@
 out:
 	if (clear) {
 		di->i_flags &= ~OCFS2_SUPER_BLOCK_FL;
-		o2fsck_write_inode(fs, blkno, di);
+		o2fsck_write_inode(ost, blkno, di);
 	}
 }
 
@@ -342,7 +343,7 @@
 			   "the length on disk?",
 			   di->i_blkno, vb->vb_link_len, di->i_size)) {
 			di->i_size = vb->vb_link_len;
-			o2fsck_write_inode(ost->ost_fs, di->i_blkno, di);
+			o2fsck_write_inode(ost, di->i_blkno, di);
 			return;
 		}
 	}
@@ -481,7 +482,7 @@
 		o2fsck_icount_set(ost->ost_icount_in_inodes, di->i_blkno,
 				  di->i_links_count);
 		di->i_dtime = time(0);
-		o2fsck_write_inode(fs, di->i_blkno, di);
+		o2fsck_write_inode(ost, di->i_blkno, di);
 		/* XXX clear valid flag and stuff? */
 	}
 
@@ -495,7 +496,7 @@
 		    "%"PRIu64" bytes of actual data. Correct the file size?",
 		    di->i_blkno, di->i_size, expected)) {
 		di->i_size = expected;
-		o2fsck_write_inode(fs, blkno, di);
+		o2fsck_write_inode(ost, blkno, di);
 	}
 #endif
 
@@ -507,7 +508,7 @@
 		   "blocks fit in %"PRIu64" clusters.  Correct the number of "
 		   "clusters?", di->i_blkno, di->i_clusters, expected)) {
 		di->i_clusters = expected;
-		o2fsck_write_inode(fs, blkno, di);
+		o2fsck_write_inode(ost, blkno, di);
 	}
 }
 
@@ -549,6 +550,7 @@
 	ocfs2_dinode *di;
 	ocfs2_inode_scan *scan;
 	ocfs2_filesys *fs = ost->ost_fs;
+	int valid;
 
 	printf("Pass 1: Checking inodes and blocks.\n");
 
@@ -582,19 +584,23 @@
 		if (blkno == 0)
 			break;
 
+		valid = 0;
+
 		/* scanners have to skip over uninitialized inodes */
-		if (di->i_flags & OCFS2_VALID_FL) {
+		if (!memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
+		    strlen(OCFS2_INODE_SIGNATURE)) &&
+		    di->i_flags & OCFS2_VALID_FL) {
 			o2fsck_verify_inode_fields(fs, ost, blkno, di);
 
 			/* XXX be able to mark the blocks in the inode as 
 			 * bad if the inode was bad */
 			o2fsck_check_blocks(fs, ost, blkno, di);
+			valid = di->i_flags & OCFS2_VALID_FL;
 		}
 
 		verbosef("blkno %"PRIu64" ino %"PRIu64"\n", blkno,
 				di->i_blkno);
-		update_inode_alloc(ost, di, blkno, 
-				   di->i_flags & OCFS2_VALID_FL);
+		update_inode_alloc(ost, di, blkno, valid);
 	}
 
 	if (ocfs2_bitmap_get_set_bits(ost->ost_dup_blocks))

Modified: trunk/fsck.ocfs2/pass4.c
===================================================================
--- trunk/fsck.ocfs2/pass4.c	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/pass4.c	2004-11-11 03:04:23 UTC (rev 387)
@@ -73,7 +73,7 @@
 		di->i_links_count = refs;
 		o2fsck_icount_set(ost->ost_icount_in_inodes, di->i_blkno,
 				  refs);
-		o2fsck_write_inode(ost->ost_fs, di->i_blkno, di);
+		o2fsck_write_inode(ost, di->i_blkno, di);
 	}
 
 out:

Modified: trunk/fsck.ocfs2/util.c
===================================================================
--- trunk/fsck.ocfs2/util.c	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/util.c	2004-11-11 03:04:23 UTC (rev 387)
@@ -30,16 +30,23 @@
 
 #include "util.h"
 
-void o2fsck_write_inode(ocfs2_filesys *fs, uint64_t blkno, ocfs2_dinode *di)
+void o2fsck_write_inode(o2fsck_state *ost, uint64_t blkno, ocfs2_dinode *di)
 {
 	errcode_t ret;
+	char *whoami = "o2fsck_write_inode";
 
-	if (blkno != di->i_blkno)
-		fatal_error(0, "Asked to write inode with i_blkno %"PRIu64
-				" to different block %"PRIu64".\n", 
-				di->i_blkno, blkno);
+	if (blkno != di->i_blkno) {
+		com_err(whoami, OCFS2_ET_INTERNAL_FAILURE, "when asked to "
+			"write an inode with an i_blkno of %"PRIu64" to block "
+			"%"PRIu64, di->i_blkno, blkno);
+		ost->ost_write_error = 1;
+		return;
+	}
 
-	ret = ocfs2_write_inode(fs, blkno, (char *)di);
-	if (ret)
-		fatal_error(ret, "while writing inode %"PRIu64, di->i_blkno);
+	ret = ocfs2_write_inode(ost->ost_fs, blkno, (char *)di);
+	if (ret) {
+		com_err(whoami, ret, "while writing inode %"PRIu64, 
+		        di->i_blkno);
+		ost->ost_write_error = 1;
+	}
 }

Modified: trunk/libocfs2/Makefile
===================================================================
--- trunk/libocfs2/Makefile	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/Makefile	2004-11-11 03:04:23 UTC (rev 387)
@@ -6,7 +6,7 @@
 	-Wmissing-declarations
 
 ifdef OCFS_DEBUG
-OPTS += -O -g
+OPTS += -ggdb
 else
 OPTS += -O2
 endif

Modified: trunk/libocfs2/bitmap.c
===================================================================
--- trunk/libocfs2/bitmap.c	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/bitmap.c	2004-11-11 03:04:23 UTC (rev 387)
@@ -212,18 +212,9 @@
 	return ret;
 }
 
-static void ocfs2_region_align(uint64_t *start_bit, int *total_bits)
+static size_t ocfs2_align_total(int total_bits)
 {
-	uint64_t byte_mask = ~7ULL;
-
-	if (start_bit)
-		*start_bit &= byte_mask;
-
-	if (total_bits) {
-		*total_bits += 7;
-		*total_bits &= (int)byte_mask;
-	}
-
+	return (total_bits + 7) / 8;
 }
 
 errcode_t ocfs2_bitmap_alloc_region(ocfs2_bitmap *bitmap,
@@ -237,16 +228,16 @@
 	if (total_bits < 0)
 		return OCFS2_ET_INVALID_BIT;
 
-	ocfs2_region_align(&start_bit, &total_bits);
-
 	ret = ocfs2_malloc0(sizeof(struct ocfs2_bitmap_region), &br);
 	if (ret)
 		return ret;
 
+
+	br->br_bytes = ocfs2_align_total(total_bits);
 	br->br_start_bit = start_bit;
 	br->br_total_bits = total_bits;
 
-	ret = ocfs2_malloc0(br->br_total_bits / 8, &br->br_bitmap);
+	ret = ocfs2_malloc0(br->br_bytes, &br->br_bitmap);
 	if (ret)
 		ocfs2_free(&br);
 	else
@@ -267,20 +258,20 @@
 				      int total_bits)
 {
 	errcode_t ret;
+	size_t new_bytes;
 
 	if ((br->br_start_bit + total_bits) > bitmap->b_total_bits)
 		return OCFS2_ET_INVALID_BIT;
 
-	ocfs2_region_align(NULL, &total_bits);
+	new_bytes = ocfs2_align_total(total_bits);
 
-	if (total_bits > br->br_total_bits) {
-		ret = ocfs2_realloc0(total_bits / 8,
-				     &br->br_bitmap,
-				     br->br_total_bits / 8);
+	if (new_bytes > br->br_bytes) {
+		ret = ocfs2_realloc0(new_bytes, &br->br_bitmap, br->br_bytes);
 		if (ret)
 			return ret;
-		br->br_total_bits = total_bits;
+		br->br_bytes = new_bytes;
 	}
+	br->br_total_bits = total_bits;
 
 	return 0;
 }
@@ -315,7 +306,8 @@
 {
 	errcode_t ret;
 	uint64_t new_bits;
-	int prev_bits;
+	size_t prev_bytes;
+	uint8_t *pbm, *nbm, offset, diff;
 
 	if ((prev->br_start_bit + prev->br_total_bits) !=
 	    next->br_start_bit)
@@ -330,15 +322,46 @@
 	if (new_bits > INT_MAX)
 		return OCFS2_ET_INVALID_BIT;
 
-	prev_bits = prev->br_total_bits;
+	/* grab before realloc changes them */
+	prev_bytes = prev->br_bytes;
+	offset = prev->br_total_bits % 8;
+
 	ret = ocfs2_bitmap_realloc_region(bitmap, prev, (int)new_bits);
 	if (ret)
 		return ret;
 
-	memcpy(prev->br_bitmap + (prev_bits / 8), next->br_bitmap,
-	       next->br_total_bits / 8);
+	/* if prev's last bit ends on a byte boundary then we can just
+	 * copy everything over */
+	if (offset == 0) {
+		memcpy(prev->br_bitmap + prev_bytes, next->br_bitmap, 
+				next->br_bytes);
+		goto done;
+	}
+
+	/* otherwise we have to shift next in.  we're about to free
+	 * next, so we consume it as we go. */
+	pbm = &prev->br_bitmap[prev_bytes - 1];
+	nbm = &next->br_bitmap[0];
+	diff = 8 - offset;
+	while(next->br_bytes-- && next->br_total_bits > 0) {
+		/* mask off just the offset bytes in the prev */
+		*pbm &= ((1 << offset) - 1);
+		/* move 'diff' LSB from next into prevs MSB */
+		*pbm |= (*nbm & ((1 << diff) - 1)) << offset;
+		pbm++;
+		next->br_total_bits -= diff;
+
+		if (next->br_total_bits > 0) {
+			/* then set prev's LSB to the next offset MSB.  this relies
+			 * on 0s being shifted into the MSB */
+			*pbm = *nbm >> diff;
+			nbm++;
+			next->br_total_bits -= offset;
+		}
+	}
+
+done:
 	prev->br_set_bits = prev->br_set_bits + next->br_set_bits;
-
 	rb_erase(&next->br_node, &bitmap->b_regions);
 	ocfs2_bitmap_free_region(next);
 

Modified: trunk/libocfs2/chainalloc.c
===================================================================
--- trunk/libocfs2/chainalloc.c	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/chainalloc.c	2004-11-11 03:04:23 UTC (rev 387)
@@ -94,7 +94,7 @@
 	cr->cr_ag = (ocfs2_group_desc *)gd_buf;
 
 	cb->cb_errcode = OCFS2_ET_CORRUPT_GROUP_DESC;
-	if (cr->cr_ag->bg_bits % 8)
+	if (cr->cr_ag->bg_size != ocfs2_group_bitmap_size(fs->fs_blocksize))
 		goto out_free_cr;
 
 	cb->cb_errcode = ocfs2_bitmap_alloc_region(bitmap,
@@ -105,10 +105,8 @@
 		goto out_free_cr;
 
 	br->br_private = cr;
-	memcpy(br->br_bitmap, cr->cr_ag->bg_bitmap,
-	       cr->cr_ag->bg_bits / 8);
-	br->br_set_bits = cr->cr_ag->bg_bits -
-		cr->cr_ag->bg_free_bits_count;
+	memcpy(br->br_bitmap, cr->cr_ag->bg_bitmap, br->br_bytes);
+	br->br_set_bits = cr->cr_ag->bg_bits - cr->cr_ag->bg_free_bits_count;
 
 	cb->cb_errcode = ocfs2_bitmap_insert_region(bitmap, br);
 	if (cb->cb_errcode)
@@ -152,12 +150,10 @@
 	ocfs2_filesys *fs = private_data;
 	errcode_t ret = 0;
 
-	printf("want to write desc %"PRIu64"\n", cr->cr_ag->bg_blkno);
-
 	if (!cr->cr_dirty)
 		return 0;
 
-	memcpy(cr->cr_ag->bg_bitmap, br->br_bitmap, cr->cr_ag->bg_bits / 8);
+	memcpy(cr->cr_ag->bg_bitmap, br->br_bitmap, br->br_bytes);
 
 	ret = ocfs2_write_group_desc(fs, cr->cr_ag->bg_blkno, 
 				     (char *)cr->cr_ag);

Modified: trunk/libocfs2/include/bitmap.h
===================================================================
--- trunk/libocfs2/include/bitmap.h	2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/include/bitmap.h	2004-11-11 03:04:23 UTC (rev 387)
@@ -32,11 +32,11 @@
 
 struct ocfs2_bitmap_region {
 	struct rb_node br_node;
-	uint64_t br_start_bit;		/* Bit offset.  Must be
-					   byte-aligned */
+	uint64_t br_start_bit;		/* Bit offset. */
 	int br_total_bits;		/* set_bit() and friends can't
 					   handle bitmaps larger than
 					   int offsets */
+	size_t br_bytes;
 	int br_set_bits;
 	char *br_bitmap;
 	void *br_private;



More information about the Ocfs2-tools-commits mailing list