[Ocfs2-tools-devel] [PATCH] debugfs.ocfs2: fix dump_block_check for big-endian

Goldwyn Rodrigues rgoldwyn at gmail.com
Wed Jul 6 15:19:39 PDT 2011


The block check or metaecc code expects the data to be in little-endian
format for calculating CRC and ECC. However, with big-endian machines,
the block is in big-endian format.

Convert the block to little-endian format before feeding to meta ecc
computation. After computing, change data format back to CPU.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn at suse.de>

---
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
index ad58126..d54c31a 100644
--- a/debugfs.ocfs2/dump.c
+++ b/debugfs.ocfs2/dump.c
@@ -166,10 +166,74 @@ void dump_block_check(FILE *out, struct
ocfs2_block_check *bc, void *block)
 {
 	struct ocfs2_block_check tmp = *bc;
 	int crc_fail;
+	enum dump_block_type bt = detect_block(block);
+
+	/* Swap block to little endian for compute_meta_ecc */
+	switch (bt) {
+		case DUMP_BLOCK_INODE:
+			ocfs2_swap_inode_from_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_EXTENT_BLOCK:
+			ocfs2_swap_extent_block_from_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_GROUP_DESCRIPTOR:
+			ocfs2_swap_group_desc_from_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_DIR_BLOCK:
+			ocfs2_swap_dir_entries_from_cpu(block,
+					gbls.fs->fs_blocksize);
+			break;
+		case DUMP_BLOCK_XATTR:
+			ocfs2_swap_xattr_block_from_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_REFCOUNT:
+			ocfs2_swap_refcount_block_from_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_DXROOT:
+			ocfs2_swap_dx_root_from_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_DXLEAF:
+			ocfs2_swap_dx_leaf_from_cpu(block);
+			break;
+		default:
+			fprintf(out, "Unable to determine block type");
+			return;
+	}

 	/* Re-compute based on what we got from disk */
 	ocfs2_compute_meta_ecc(gbls.fs, block, bc);

+	/* Swap block back to CPU */
+	switch (bt) {
+		case DUMP_BLOCK_INODE:
+			ocfs2_swap_inode_to_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_EXTENT_BLOCK:
+			ocfs2_swap_extent_block_to_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_GROUP_DESCRIPTOR:
+			ocfs2_swap_group_desc_to_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_DIR_BLOCK:
+			ocfs2_swap_dir_entries_to_cpu(block,
+					gbls.fs->fs_blocksize);
+			break;
+		case DUMP_BLOCK_XATTR:
+			ocfs2_swap_xattr_block_to_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_REFCOUNT:
+			ocfs2_swap_refcount_block_to_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_DXROOT:
+			ocfs2_swap_dx_root_to_cpu(gbls.fs, block);
+			break;
+		case DUMP_BLOCK_DXLEAF:
+			ocfs2_swap_dx_leaf_to_cpu(block);
+			break;
+		default:
+			break;
+	}
+
 	crc_fail = memcmp(bc, &tmp, sizeof(*bc));

 	fprintf(out, "\tCRC32: %.8"PRIx32"   ECC: %.4"PRIx16"\n",
diff --git a/debugfs.ocfs2/include/utils.h b/debugfs.ocfs2/include/utils.h
index 8b5c90c..ada699c 100644
--- a/debugfs.ocfs2/include/utils.h
+++ b/debugfs.ocfs2/include/utils.h
@@ -69,5 +69,6 @@ void init_stringlist(struct list_head *strlist);
 void free_stringlist(struct list_head *strlist);
 errcode_t add_to_stringlist(char *str, struct list_head *strlist);
 int del_from_stringlist(char *str, struct list_head *strlist);
+enum dump_block_type detect_block (char *buf);

 #endif		/* __UTILS_H__ */
diff --git a/debugfs.ocfs2/journal.c b/debugfs.ocfs2/journal.c
index abc0ebc..7fd32fe 100644
--- a/debugfs.ocfs2/journal.c
+++ b/debugfs.ocfs2/journal.c
@@ -29,8 +29,6 @@

 extern dbgfs_gbls gbls;

-static enum dump_block_type detect_block (char *buf);
-
 static void scan_journal(FILE *out, journal_superblock_t *jsb, char *buf,
 			 int len, uint64_t *blocknum, uint64_t *last_unknown)
 {
@@ -157,78 +155,3 @@ bail:
 	return ret;
 }

-/*
- * detect_block()
- *
- */
-static enum dump_block_type detect_block (char *buf)
-{
-	struct ocfs2_dinode *inode;
-	struct ocfs2_extent_block *extent;
-	struct ocfs2_group_desc *group;
-	struct ocfs2_dir_block_trailer *trailer;
-	struct ocfs2_xattr_block *xb;
-	struct ocfs2_refcount_block *rb;
-	struct ocfs2_dx_root_block *dx_root;
-	struct ocfs2_dx_leaf *dx_leaf;
-	enum dump_block_type ret = DUMP_BLOCK_UNKNOWN;
-
-	inode = (struct ocfs2_dinode *)buf;
-	if (!strncmp((char *)inode->i_signature, OCFS2_INODE_SIGNATURE,
-		     sizeof(inode->i_signature))) {
-		ret = DUMP_BLOCK_INODE;
-		goto bail;
-	}
-
-	extent = (struct ocfs2_extent_block *)buf;
-	if (!strncmp((char *)extent->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
-		     sizeof(extent->h_signature))) {
-		ret = DUMP_BLOCK_EXTENT_BLOCK;
-		goto bail;
-	}
-
-	group = (struct ocfs2_group_desc *)buf;
-	if (!strncmp((char *)group->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
-		     sizeof(group->bg_signature))) {
-		ret = DUMP_BLOCK_GROUP_DESCRIPTOR;
-		goto bail;
-	}
-
-	trailer = ocfs2_dir_trailer_from_block(gbls.fs, buf);
-	if (!strncmp((char *)trailer->db_signature, OCFS2_DIR_TRAILER_SIGNATURE,
-		     sizeof(trailer->db_signature))) {
-		ret = DUMP_BLOCK_DIR_BLOCK;
-		goto bail;
-	}
-
-	xb = (struct ocfs2_xattr_block *)buf;
-	if (!strncmp((char *)xb->xb_signature, OCFS2_XATTR_BLOCK_SIGNATURE,
-		     sizeof(xb->xb_signature))) {
-		ret = DUMP_BLOCK_XATTR;
-		goto bail;
-	}
-
-	rb = (struct ocfs2_refcount_block *)buf;
-	if (!strncmp((char *)rb->rf_signature, OCFS2_REFCOUNT_BLOCK_SIGNATURE,
-		     sizeof(rb->rf_signature))) {
-		ret = DUMP_BLOCK_REFCOUNT;
-		goto bail;
-	}
-
-	dx_root = (struct ocfs2_dx_root_block *)buf;
-	if (!strncmp((char *)dx_root->dr_signature, OCFS2_DX_ROOT_SIGNATURE,
-		     strlen(OCFS2_DX_ROOT_SIGNATURE))) {
-		ret = DUMP_BLOCK_DXROOT;
-		goto bail;
-	}
-
-	dx_leaf = (struct ocfs2_dx_leaf *)buf;
-	if (!strncmp((char *)dx_leaf->dl_signature, OCFS2_DX_LEAF_SIGNATURE,
-		     strlen(OCFS2_DX_LEAF_SIGNATURE))) {
-		ret = DUMP_BLOCK_DXLEAF;
-		goto bail;
-	}
-
-bail:
-	return ret;
-}				/* detect_block */
diff --git a/debugfs.ocfs2/utils.c b/debugfs.ocfs2/utils.c
index d22ae8e..1fb77b7 100644
--- a/debugfs.ocfs2/utils.c
+++ b/debugfs.ocfs2/utils.c
@@ -881,3 +881,80 @@ int del_from_stringlist(char *str, struct
list_head *strlist)
 	return 0;
 }

+/*
+ * detect_block()
+ *
+ */
+enum dump_block_type detect_block (char *buf)
+{
+	struct ocfs2_dinode *inode;
+	struct ocfs2_extent_block *extent;
+	struct ocfs2_group_desc *group;
+	struct ocfs2_dir_block_trailer *trailer;
+	struct ocfs2_xattr_block *xb;
+	struct ocfs2_refcount_block *rb;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dx_leaf *dx_leaf;
+	enum dump_block_type ret = DUMP_BLOCK_UNKNOWN;
+
+	inode = (struct ocfs2_dinode *)buf;
+	if (!strncmp((char *)inode->i_signature, OCFS2_INODE_SIGNATURE,
+		     sizeof(inode->i_signature)) ||
+		!strncmp((char *)inode->i_signature,
+		OCFS2_SUPER_BLOCK_SIGNATURE, sizeof(inode->i_signature))) {
+		ret = DUMP_BLOCK_INODE;
+		goto bail;
+	}
+
+	extent = (struct ocfs2_extent_block *)buf;
+	if (!strncmp((char *)extent->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
+		     sizeof(extent->h_signature))) {
+		ret = DUMP_BLOCK_EXTENT_BLOCK;
+		goto bail;
+	}
+
+	group = (struct ocfs2_group_desc *)buf;
+	if (!strncmp((char *)group->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
+		     sizeof(group->bg_signature))) {
+		ret = DUMP_BLOCK_GROUP_DESCRIPTOR;
+		goto bail;
+	}
+
+	trailer = ocfs2_dir_trailer_from_block(gbls.fs, buf);
+	if (!strncmp((char *)trailer->db_signature, OCFS2_DIR_TRAILER_SIGNATURE,
+		     sizeof(trailer->db_signature))) {
+		ret = DUMP_BLOCK_DIR_BLOCK;
+		goto bail;
+	}
+
+	xb = (struct ocfs2_xattr_block *)buf;
+	if (!strncmp((char *)xb->xb_signature, OCFS2_XATTR_BLOCK_SIGNATURE,
+		     sizeof(xb->xb_signature))) {
+		ret = DUMP_BLOCK_XATTR;
+		goto bail;
+	}
+
+	rb = (struct ocfs2_refcount_block *)buf;
+	if (!strncmp((char *)rb->rf_signature, OCFS2_REFCOUNT_BLOCK_SIGNATURE,
+		     sizeof(rb->rf_signature))) {
+		ret = DUMP_BLOCK_REFCOUNT;
+		goto bail;
+	}
+
+	dx_root = (struct ocfs2_dx_root_block *)buf;
+	if (!strncmp((char *)dx_root->dr_signature, OCFS2_DX_ROOT_SIGNATURE,
+		     strlen(OCFS2_DX_ROOT_SIGNATURE))) {
+		ret = DUMP_BLOCK_DXROOT;
+		goto bail;
+	}
+
+	dx_leaf = (struct ocfs2_dx_leaf *)buf;
+	if (!strncmp((char *)dx_leaf->dl_signature, OCFS2_DX_LEAF_SIGNATURE,
+		     strlen(OCFS2_DX_LEAF_SIGNATURE))) {
+		ret = DUMP_BLOCK_DXLEAF;
+		goto bail;
+	}
+
+bail:
+	return ret;
+}				/* detect_block */
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index fa91a54..d06b3f5 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -502,8 +502,11 @@ void ocfs2_init_dir_trailer(ocfs2_filesys *fs,
struct ocfs2_dinode *di,
 void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs,
 			       struct ocfs2_dx_root_block *dx_root);
 void ocfs2_swap_dx_leaf_to_cpu(struct ocfs2_dx_leaf *dx_leaf);
+void ocfs2_swap_dx_root_from_cpu(ocfs2_filesys *fs,
+		struct ocfs2_dx_root_block *dx_root);
 errcode_t ocfs2_read_dx_root(ocfs2_filesys *fs, uint64_t block,
 			     void *buf);
+void ocfs2_swap_dx_leaf_from_cpu(struct ocfs2_dx_leaf *dx_leaf);
 errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block,
 			     void *buf);
 int ocfs2_dir_indexed(struct ocfs2_dinode *di);
diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
index 4594000..bc60a26 100644
--- a/libocfs2/dirblock.c
+++ b/libocfs2/dirblock.c
@@ -295,7 +295,7 @@ void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs,
 		ocfs2_swap_extent_list_to_cpu(fs, dx_root, &dx_root->dr_list);
 }

-static void ocfs2_swap_dx_root_from_cpu(ocfs2_filesys *fs,
+void ocfs2_swap_dx_root_from_cpu(ocfs2_filesys *fs,
 				struct ocfs2_dx_root_block *dx_root)
 {
 	if (cpu_is_little_endian)
@@ -396,7 +396,7 @@ void ocfs2_swap_dx_leaf_to_cpu(struct
ocfs2_dx_leaf *dx_leaf)
 	ocfs2_swap_dx_entry_list_to_cpu(&dx_leaf->dl_list);
 }

-static void ocfs2_swap_dx_leaf_from_cpu(struct ocfs2_dx_leaf *dx_leaf)
+void ocfs2_swap_dx_leaf_from_cpu(struct ocfs2_dx_leaf *dx_leaf)
 {
 	if (cpu_is_little_endian)
 		return;

-- 
Goldwyn



More information about the Ocfs2-tools-devel mailing list