[Ocfs2-commits] mfasheh commits r2926 - branches/ocfs2-1.2/fs/ocfs2

svn-commits@oss.oracle.com svn-commits at oss.oracle.com
Wed Jul 12 15:12:45 CDT 2006


Author: mfasheh
Signed-off-by: smushran
Date: 2006-07-12 15:12:44 -0500 (Wed, 12 Jul 2006)
New Revision: 2926

Modified:
   branches/ocfs2-1.2/fs/ocfs2/ocfs2.h
   branches/ocfs2-1.2/fs/ocfs2/proc.c
   branches/ocfs2-1.2/fs/ocfs2/suballoc.c
   branches/ocfs2-1.2/fs/ocfs2/super.c
Log:
Better group descriptor consistency checks:

Try to catch corrupted group descriptors with some stronger checks placed in
a couple of strategic locations. Detect a failed resizefs and refuse to
allocate past what bitmap i_clusters allows.
    
Signed-off-by: smushran



Modified: branches/ocfs2-1.2/fs/ocfs2/ocfs2.h
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/ocfs2.h	2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/ocfs2.h	2006-07-12 20:12:44 UTC (rev 2926)
@@ -210,7 +210,6 @@
 	struct ocfs2_node_map recovery_map;
 	struct ocfs2_node_map umount_map;
 
-	u32 num_clusters;
 	u64 root_blkno;
 	u64 system_dir_blkno;
 	u64 bitmap_blkno;

Modified: branches/ocfs2-1.2/fs/ocfs2/proc.c
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/proc.c	2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/proc.c	2006-07-12 20:12:44 UTC (rev 2926)
@@ -75,12 +75,6 @@
 			   int count,
 			   int *eof,
 			   void *data);
-static int ocfs2_proc_statistics(char *page,
-				 char **start,
-				 off_t off,
-				 int count,
-				 int *eof,
-				 void *data);
 static int ocfs2_proc_device(char *page,
 			     char **start,
 			     off_t off,
@@ -125,7 +119,6 @@
 	{ "nodenum", NULL, ocfs2_proc_nodenum, NULL, S_IFREG | S_IRUGO, },
 	{ "uuid", NULL, ocfs2_proc_uuid, NULL, S_IFREG | S_IRUGO, },
 	{ "slotnum", NULL, ocfs2_proc_slotnum, NULL, S_IFREG | S_IRUGO, },
-	{ "statistics", NULL, ocfs2_proc_statistics, NULL, S_IFREG | S_IRUGO, },
 	{ "device", NULL, ocfs2_proc_device, NULL, S_IFREG | S_IRUGO, },
 	{ "nodes", NULL, ocfs2_proc_nodes, NULL, S_IFREG | S_IRUGO, },
 	{ "allocstat", NULL, ocfs2_proc_alloc_stat, NULL, S_IFREG | S_IRUGO, },
@@ -378,31 +371,6 @@
 	return ret;
 }
 
-static int ocfs2_proc_statistics(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len;
-	int ret = 0;
-	struct ocfs2_super *osb = data;
-
-	mlog_entry_void();
-
-#define PROC_STATS				\
-  "Number of nodes          : %u\n"		\
-  "Cluster size             : %d\n"		\
-  "Volume size              : %"MLFu64"\n"	\
-  "Open Transactions:       : %u\n"
-
-	len = sprintf(page, PROC_STATS, osb->num_nodes, osb->s_clustersize,
-		      ocfs2_clusters_to_bytes(osb->sb, osb->num_clusters),
-		      atomic_read(&osb->journal->j_num_trans));
-
-	ret = ocfs2_proc_calc_metrics(page, start, off, count, eof, len);
-
-	mlog_exit(ret);
-	return ret;
-}
-
 static int ocfs2_proc_device(char *page, char **start, off_t off,
 			     int count, int *eof, void *data)
 {

Modified: branches/ocfs2-1.2/fs/ocfs2/suballoc.c
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/suballoc.c	2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/suballoc.c	2006-07-12 20:12:44 UTC (rev 2926)
@@ -85,11 +85,6 @@
 				     u64 *bg_blkno);
 static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
 					 int nr);
-static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,
-					     struct buffer_head *bg_bh,
-					     unsigned int bits_wanted,
-					     u16 *bit_off,
-					     u16 *bits_found);
 static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle,
 					     struct inode *alloc_inode,
 					     struct ocfs2_group_desc *bg,
@@ -143,6 +138,64 @@
 	return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc);
 }
 
+/* somewhat more expensive than our other checks, so use sparingly. */
+static int ocfs2_check_group_descriptor(struct super_block *sb,
+					struct ocfs2_dinode *di,
+					struct ocfs2_group_desc *gd)
+{
+	unsigned int max_bits;
+
+	if (!OCFS2_IS_VALID_GROUP_DESC(gd)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(sb, gd);
+		return -EIO;
+	}
+
+	if (di->i_blkno != gd->bg_parent_dinode) {
+		ocfs2_error(sb, "Group descriptor # %llu has bad parent "
+			    "pointer (%llu, expected %llu)",
+			    (unsigned long long)le64_to_cpu(gd->bg_blkno),
+			    (unsigned long long)le64_to_cpu(gd->bg_parent_dinode),
+			    (unsigned long long)le64_to_cpu(di->i_blkno));
+		return -EIO;
+	}
+
+	max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc);
+	if (le16_to_cpu(gd->bg_bits) > max_bits) {
+		ocfs2_error(sb, "Group descriptor # %llu has bit count of %u",
+			    (unsigned long long)le64_to_cpu(gd->bg_blkno),
+			    le16_to_cpu(gd->bg_bits));
+		return -EIO;
+	}
+
+	if (le16_to_cpu(gd->bg_chain) >=
+	    le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) {
+		ocfs2_error(sb, "Group descriptor # %llu has bad chain %u",
+			    (unsigned long long)le64_to_cpu(gd->bg_blkno),
+			    le16_to_cpu(gd->bg_chain));
+		return -EIO;
+	}
+
+	if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) {
+		ocfs2_error(sb, "Group descriptor # %llu has bit count %u but "
+			    "claims that %u are free",
+			    (unsigned long long)le64_to_cpu(gd->bg_blkno),
+			    le16_to_cpu(gd->bg_bits),
+			    le16_to_cpu(gd->bg_free_bits_count));
+		return -EIO;
+	}
+
+	if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) {
+		ocfs2_error(sb, "Group descriptor # %llu has bit count %u but "
+			    "max bitmap bits of %u",
+			    (unsigned long long)le64_to_cpu(gd->bg_blkno),
+			    le16_to_cpu(gd->bg_bits),
+			    8 * le16_to_cpu(gd->bg_size));
+		return -EIO;
+	}
+
+	return 0;
+}
+
 static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle,
 				  struct inode *alloc_inode,
 				  struct buffer_head *bg_bh,
@@ -662,6 +715,7 @@
 static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,
 					     struct buffer_head *bg_bh,
 					     unsigned int bits_wanted,
+					     unsigned int total_bits,
 					     u16 *bit_off,
 					     u16 *bits_found)
 {
@@ -678,10 +732,8 @@
 	found = start = best_offset = best_size = 0;
 	bitmap = bg->bg_bitmap;
 
-	while((offset = ocfs2_find_next_zero_bit(bitmap,
-						 le16_to_cpu(bg->bg_bits),
-						 start)) != -1) {
-		if (offset == le16_to_cpu(bg->bg_bits))
+	while((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) != -1) {
+		if (offset == total_bits)
 			break;
 
 		if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) {
@@ -909,14 +961,35 @@
 {
 	int search = -ENOSPC;
 	int ret;
-	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) group_bh->b_data;
+	struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *) group_bh->b_data;
 	u16 tmp_off, tmp_found;
+	unsigned int max_bits, gd_cluster_off;
 
 	BUG_ON(!ocfs2_is_cluster_bitmap(inode));
 
-	if (bg->bg_free_bits_count) {
+	if (gd->bg_free_bits_count) {
+		max_bits = le16_to_cpu(gd->bg_bits);
+
+		/* Tail groups in cluster bitmaps which aren't cpg
+		 * aligned are prone to partial extention by a failed
+		 * fs resize. If the file system resize never got to
+		 * update the dinode cluster count, then we don't want
+		 * to trust any clusters past it, regardless of what
+		 * the group descriptor says. */
+		gd_cluster_off = ocfs2_blocks_to_clusters(inode->i_sb,
+							  le64_to_cpu(gd->bg_blkno));
+		if ((gd_cluster_off + max_bits) >
+		    OCFS2_I(inode)->ip_clusters) {
+			max_bits = OCFS2_I(inode)->ip_clusters - gd_cluster_off;
+			mlog(0, "Desc %llu, bg_bits %u, clusters %u, use %u\n",
+			     (unsigned long long)le64_to_cpu(gd->bg_blkno),
+			     le16_to_cpu(gd->bg_bits),
+			     OCFS2_I(inode)->ip_clusters, max_bits);
+		}
+
 		ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
 							group_bh, bits_wanted,
+							max_bits,
 							&tmp_off, &tmp_found);
 		if (ret)
 			return ret;
@@ -949,6 +1022,7 @@
 	if (bg->bg_free_bits_count)
 		ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
 							group_bh, bits_wanted,
+							le16_to_cpu(bg->bg_bits),
 							bit_off, bits_found);
 
 	return ret;
@@ -985,9 +1059,9 @@
 		goto bail;
 	}
 	bg = (struct ocfs2_group_desc *) group_bh->b_data;
-	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
-		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
-		status = -EIO;
+	status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg);
+	if (status) {
+		mlog_errno(status);
 		goto bail;
 	}
 
@@ -1015,9 +1089,9 @@
 			goto bail;
 		}
 		bg = (struct ocfs2_group_desc *) group_bh->b_data;
-		if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
-			OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
-			status = -EIO;
+		status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg);
+		if (status) {
+			mlog_errno(status);
 			goto bail;
 		}
 	}
@@ -1492,9 +1566,9 @@
 	}
 
 	group = (struct ocfs2_group_desc *) group_bh->b_data;
-	if (!OCFS2_IS_VALID_GROUP_DESC(group)) {
-		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, group);
-		status = -EIO;
+	status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group);
+	if (status) {
+		mlog_errno(status);
 		goto bail;
 	}
 	BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits));

Modified: branches/ocfs2-1.2/fs/ocfs2/super.c
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/super.c	2006-07-12 19:58:24 UTC (rev 2925)
+++ branches/ocfs2-1.2/fs/ocfs2/super.c	2006-07-12 20:12:44 UTC (rev 2926)
@@ -1485,8 +1485,13 @@
 
 	osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno;
 
+	/* We don't have a cluster lock on the bitmap here because
+	 * we're only interested in static information and the extra
+	 * complexity at mount time isn't worth it. Don't pass the
+	 * inode in to the read function though as we don't want it to
+	 * be put in the cache. */
 	status = ocfs2_read_block(osb, osb->bitmap_blkno, &bitmap_bh, 0,
-				  inode);
+				  NULL);
 	iput(inode);
 	if (status < 0) {
 		mlog_errno(status);
@@ -1495,7 +1500,6 @@
 
 	di = (struct ocfs2_dinode *) bitmap_bh->b_data;
 	osb->bitmap_cpg = le16_to_cpu(di->id2.i_chain.cl_cpg);
-	osb->num_clusters = le32_to_cpu(di->id1.bitmap1.i_total);
 	brelse(bitmap_bh);
 	mlog(0, "cluster bitmap inode: %"MLFu64", clusters per group: %u\n",
 	     osb->bitmap_blkno, osb->bitmap_cpg);




More information about the Ocfs2-commits mailing list