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

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Oct 5 18:57:15 CDT 2004


Author: zab
Date: 2004-10-05 18:57:13 -0500 (Tue, 05 Oct 2004)
New Revision: 313

Modified:
   trunk/fsck.ocfs2/dirblocks.c
   trunk/fsck.ocfs2/fsck.c
   trunk/fsck.ocfs2/include/fsck.h
   trunk/fsck.ocfs2/include/util.h
   trunk/fsck.ocfs2/pass1.c
   trunk/fsck.ocfs2/pass2.c
   trunk/libocfs2/bitmap.c
   trunk/libocfs2/include/ocfs2.h
Log:
o account for the blocks used by group descs and extent blocks
o bail if we find duplicate blocks until we know how to deal with them
o add -v and crazy-verbose printf()s
o get rid of old comments, add some newer ones
o the i_size check is totally hosed
o add a 'ocfs2_bitmap_get_set_bits()' to query bits set in a bitmap


Modified: trunk/fsck.ocfs2/dirblocks.c
===================================================================
--- trunk/fsck.ocfs2/dirblocks.c	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/fsck.ocfs2/dirblocks.c	2004-10-05 23:57:13 UTC (rev 313)
@@ -53,9 +53,6 @@
 	dbe->e_blkno = blkno;
 	dbe->e_blkcount = blkcount;
 
-	printf("inserting %"PRIu64" %"PRIu64" %"PRIu64"\n", dbe->e_ino, 
-			dbe->e_blkno, dbe->e_blkcount);
-
 	while (*p)
 	{
 		parent = *p;

Modified: trunk/fsck.ocfs2/fsck.c
===================================================================
--- trunk/fsck.ocfs2/fsck.c	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/fsck.ocfs2/fsck.c	2004-10-05 23:57:13 UTC (rev 313)
@@ -38,6 +38,8 @@
 #include "pass2.h"
 #include "util.h"
 
+int verbose = 0;
+
 static void print_usage(void)
 {
 	fprintf(stderr,
@@ -157,7 +159,7 @@
 
 	initialize_ocfs_error_table();
 
-	while((c = getopt(argc, argv, "b:B:np")) != EOF) {
+	while((c = getopt(argc, argv, "b:B:npv")) != EOF) {
 		switch (c) {
 			case 'b':
 				blkno = read_number(optarg);
@@ -197,6 +199,10 @@
 				ost->ost_answer = 1;
 				break;
 
+			case 'v':
+				verbose = 1;
+				break;
+
 			default:
 				print_usage();
 				return 1;

Modified: trunk/fsck.ocfs2/include/fsck.h
===================================================================
--- trunk/fsck.ocfs2/include/fsck.h	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/fsck.ocfs2/include/fsck.h	2004-10-05 23:57:13 UTC (rev 313)
@@ -53,5 +53,13 @@
 			ost_force:1;	/* -f supplied; force check */
 } o2fsck_state;
 
+/* The idea is to let someone off-site run fsck and have it give us 
+ * enough information to diagnose problems with */
+extern int verbose;
+#define verbosef(fmt, args...) do {					\
+	if (verbose)							\
+		printf("%s:%d | " fmt, __FUNCTION__, __LINE__, args);\
+} while (0)
+
 #endif /* __O2FSCK_FSCK_H__ */
 

Modified: trunk/fsck.ocfs2/include/util.h
===================================================================
--- trunk/fsck.ocfs2/include/util.h	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/fsck.ocfs2/include/util.h	2004-10-05 23:57:13 UTC (rev 313)
@@ -38,6 +38,8 @@
 
 /* no va_list variant of com_err */
 #define fatal_error(errcode, fmt...) do {				\
+	fflush(stdout);							\
+	fflush(stderr);							\
 	com_err("o2fsck", errcode, fmt);				\
 	exit(FSCK_ERROR);						\
 } while (0)

Modified: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/fsck.ocfs2/pass1.c	2004-10-05 23:57:13 UTC (rev 313)
@@ -39,21 +39,18 @@
 
 static const char *whoami = "pass1";
 
-/*
- * for now we're just building up info, we're not actually
- * writing to disk.
- *
- * for each inode:
- * - verify that i_mode is legal
- *
- * We collect the following for future passes:
- *
- * - a bitmap of inodes which are in use
- * - a bitmap of inodes which have bad fields
- * - a bitmap of data blocks on inodes
- * - a bitmap of data blocks duplicated between inodes
- */
+static void mark_block_used(o2fsck_state *ost, uint64_t blkno)
+{
+	int was_set;
+	ocfs2_bitmap_set(ost->ost_found_blocks, blkno, &was_set);
+	if (was_set) {
+		verbosef("duplicate block %"PRIu64"\n", blkno);
+		ocfs2_bitmap_set(ost->ost_dup_blocks, blkno, NULL);
+	}
+}
 
+/* XXX should walk down all the i_fields to make sure we're veryfying
+ * those that we can this early */
 static void o2fsck_verify_inode_fields(ocfs2_filesys *fs, o2fsck_state *ost, 
 				       uint64_t blkno, ocfs2_dinode *di)
 {
@@ -73,6 +70,8 @@
 		   strlen(OCFS2_INODE_SIGNATURE))) {
 		goto bad;
 	}
+	if (di->i_flags & OCFS2_SUPER_BLOCK_FL)
+		goto bad;
 
 	if (di->i_links_count)
 		o2fsck_icount_update(ost->ost_icount_in_inodes, di->i_blkno,
@@ -107,7 +106,6 @@
 	}
 
 	if (S_ISDIR(di->i_mode)) {
-		/* XXX record dir for dir block walk */
 		ocfs2_bitmap_set(ost->ost_dir_inodes, blkno, NULL);
 		o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, 0, 0);
 	} else if (S_ISREG(di->i_mode)) {
@@ -138,6 +136,14 @@
        ocfs2_dinode	*vb_di;
 };
 
+/* last_block and num_blocks would be different in a sparse file */
+static void vb_saw_block(struct verifying_blocks *vb, uint64_t bcount)
+{
+	vb->vb_num_blocks++;
+	if (bcount > vb->vb_last_block)
+		vb->vb_last_block = bcount;
+}
+
 static int verify_block(ocfs2_filesys *fs,
 			    uint64_t blkno,
 			    uint64_t bcount,
@@ -146,7 +152,6 @@
 	struct verifying_blocks *vb = priv_data;
 	ocfs2_dinode *di = vb->vb_di;
 	o2fsck_state *ost = vb->vb_ost;
-	int was_set;
 	
 	/* someday we may want to worry about holes in files here */
 
@@ -174,19 +179,13 @@
 		}
 	}
 
-	ocfs2_bitmap_set(ost->ost_found_blocks, blkno, &was_set);
-	if (was_set) {
-		fprintf(stderr, "duplicate block %"PRIu64"?\n", blkno);
-		ocfs2_bitmap_set(ost->ost_dup_blocks, blkno, NULL);
-	}
-
-	if (S_ISDIR(di->i_mode))
+	if (S_ISDIR(di->i_mode)) {
+		verbosef("adding dir block %"PRIu64"\n", blkno);
 		o2fsck_add_dir_block(&ost->ost_dirblocks, di->i_blkno, blkno,
 					bcount);
+	}
 
-	vb->vb_num_blocks++;
-	if (bcount > vb->vb_last_block)
-		vb->vb_last_block = bcount;
+	vb_saw_block(vb, bcount);
 
 	return 0;
 }
@@ -200,6 +199,32 @@
 	return (num_blocks + ((1 << c_to_b_bits) - 1)) >> c_to_b_bits;
 }
 
+static int check_gd_block(ocfs2_filesys *fs, uint64_t gd_blkno, int chain_num,
+			   void *priv_data)
+{
+	struct verifying_blocks *vb = priv_data;
+	verbosef("found gd block %"PRIu64"\n", gd_blkno);
+	/* don't have bcount */
+	mark_block_used(vb->vb_ost, gd_blkno);
+	vb_saw_block(vb, vb->vb_num_blocks);
+	return 0;
+}
+
+static int check_extent_blocks(ocfs2_filesys *fs, ocfs2_extent_rec *rec,
+				int tree_depth, uint32_t ccount,
+				uint64_t ref_blkno, int ref_recno,
+				void *priv_data)
+{
+	struct verifying_blocks *vb = priv_data;
+
+	if (tree_depth > 0) {
+		verbosef("found extent block %"PRIu64"\n", rec->e_blkno);
+		mark_block_used(vb->vb_ost, rec->e_blkno);
+	}
+
+	return 0;
+}
+
 static void o2fsck_check_blocks(ocfs2_filesys *fs, o2fsck_state *ost,
 				uint64_t blkno, ocfs2_dinode *di)
 {
@@ -214,12 +239,19 @@
 	 * metadata blocks in the extents as used and otherwise validate them
 	 * while we're at it. */
 
-	ret = ocfs2_block_iterate(fs, blkno, 0, verify_block, &vb);
-	if (ret == OCFS2_ET_INODE_CANNOT_BE_ITERATED) {
-		/* XXX I don't understand this.   just check the inode
-		 * fields as though there were no blocks? */
-		ret = 0;
+
+	if (di->i_flags & OCFS2_LOCAL_ALLOC_FL)
+		ret = 0; /* nothing to iterate over in this case */
+	else if (di->i_flags & OCFS2_CHAIN_FL)
+		ret = ocfs2_chain_iterate(fs, blkno, check_gd_block, &vb);
+	else {
+		ret = ocfs2_extent_iterate(fs, blkno, 0, NULL,
+					   check_extent_blocks, &vb);
+		if (ret == 0)
+			ret = ocfs2_block_iterate(fs, blkno, 0,
+    					   verify_block, &vb);
 	}
+
 	if (ret) {
 		fatal_error(ret, "while iterating over the blocks for inode "
 			         "%"PRIu64, di->i_blkno);	
@@ -248,11 +280,12 @@
 		/* XXX clear valid flag and stuff? */
 	}
 
+#if 0 /* boy, this is just broken */
 	if (vb.vb_num_blocks > 0)
 		expected = (vb.vb_last_block + 1) * fs->fs_blocksize;
 
 	/* i_size is checked for symlinks elsewhere */
-	if (!S_ISLNK(di->i_mode) && di->i_size != expected &&
+	if (!S_ISLNK(di->i_mode) && di->i_size > expected &&
 	    should_fix(ost, FIX_DEFYES, "inode %"PRIu64" has a size of "
 		       "%"PRIu64" but has %"PRIu64" bytes of actual data. "
 		       " Correct the file size?", di->i_blkno, di->i_size,
@@ -260,6 +293,7 @@
 		di->i_size = expected;
 		o2fsck_write_inode(fs, blkno, di);
 	}
+#endif
 
 	if (vb.vb_num_blocks > 0)
 		expected = clusters_holding_blocks(fs, vb.vb_last_block + 1);
@@ -325,6 +359,10 @@
 		o2fsck_check_blocks(fs, ost, blkno, di);
 	}
 
+	if (ocfs2_bitmap_get_set_bits(ost->ost_dup_blocks))
+		fatal_error(OCFS2_ET_INTERNAL_FAILURE, "duplicate blocks "
+				"found, need to learn to fix.");
+
 out_close_scan:
 	ocfs2_close_inode_scan(scan);
 out_free:

Modified: trunk/fsck.ocfs2/pass2.c
===================================================================
--- trunk/fsck.ocfs2/pass2.c	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/fsck.ocfs2/pass2.c	2004-10-05 23:57:13 UTC (rev 313)
@@ -405,11 +405,17 @@
 	while (offset < dd->fs->fs_blocksize) {
 		dirent = (struct ocfs2_dir_entry *)(dd->buf + offset);
 
-		/* I wonder if we should be checking that the padding
+		verbosef("checking dirent offset %d, ino %"PRIu64" rec_len "
+			"%"PRIu16" name_len %"PRIu8" file_type %"PRIu8"\n",
+			offset, dirent->inode, dirent->rec_len, 
+			dirent->name_len, dirent->file_type);
+
+		/* XXX I wonder if we should be checking that the padding
 		 * is 0 */
 
-		printf("dir entry %u %.*s\n", dirent->rec_len, dirent->name_len,
-						dirent->name);
+		/* XXX hmm, this isn't quite right.  sometimes when we
+		 * change we re-examine the current entry, other times
+		 * we move on past it. */
 
 		this_flags = fix_dirent_lengths(dd->ost, dbe, dirent, offset, 
 						 dd->fs->fs_blocksize - offset,
@@ -425,6 +431,8 @@
 		ret_flags |= fix_dirent_dots(dd->ost, dbe, dirent, offset, 
 					     dd->fs->fs_blocksize - offset);
 		ret_flags |= fix_dirent_name(dd->ost, dbe, dirent, offset);
+		/* XXX we need to check dirent->inode before calling into here
+		 * as it'll try and read it and assert if that fails */
 		ret_flags |= fix_dirent_filetype(dd->ost, dbe, dirent, offset);
 		ret_flags |= fix_dirent_linkage(dd->ost, dbe, dirent, offset);
 		ret_flags |= fix_dirent_dups(dd->ost, dbe, dirent, &strings,

Modified: trunk/libocfs2/bitmap.c
===================================================================
--- trunk/libocfs2/bitmap.c	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/libocfs2/bitmap.c	2004-10-05 23:57:13 UTC (rev 313)
@@ -118,6 +118,10 @@
 	return ret;
 }
 
+uint64_t ocfs2_bitmap_get_set_bits(ocfs2_bitmap *bitmap)
+{
+	return bitmap->b_set_bits;
+}
 
 /*
  * The remaining functions are private to the library.

Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h	2004-10-04 17:33:04 UTC (rev 312)
+++ trunk/libocfs2/include/ocfs2.h	2004-10-05 23:57:13 UTC (rev 313)
@@ -344,6 +344,7 @@
 			     int *oldval);
 errcode_t ocfs2_bitmap_test(ocfs2_bitmap *bitmap, uint64_t bitno,
 			    int *val);
+uint64_t ocfs2_bitmap_get_set_bits(ocfs2_bitmap *bitmap);
 
 errcode_t ocfs2_get_device_size(const char *file, int blocksize,
 				uint32_t *retblocks);



More information about the Ocfs2-tools-commits mailing list