⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ext3-extents-sanity-checks.patch

📁 非常经典的一个分布式系统
💻 PATCH
字号:
Index: linux-2.6.9-42.0.10.EL_lustre.1.4.10/fs/ext3/extents.c===================================================================--- linux-2.6.9-42.0.10.EL_lustre.1.4.10.orig/fs/ext3/extents.c	2007-07-17 22:14:08.000000000 +0200+++ linux-2.6.9-42.0.10.EL_lustre.1.4.10/fs/ext3/extents.c	2007-07-17 22:40:57.000000000 +0200@@ -44,26 +44,56 @@ #include <asm/uaccess.h>  -static inline int ext3_ext_check_header(struct ext3_extent_header *eh)-{-	if (eh->eh_magic != EXT3_EXT_MAGIC) {-		printk(KERN_ERR "EXT3-fs: invalid magic = 0x%x\n",-		       (unsigned)eh->eh_magic);-		return -EIO;+static int __ext3_ext_check_header(const char *function, struct inode *inode,+				struct ext3_extent_header *eh, int depth,+				int max)+{+	const char *error_msg = NULL;++	if (unlikely(eh->eh_magic != EXT3_EXT_MAGIC)) {+		error_msg = "invalid magic";+		goto corrupted;+	}+	if (unlikely(eh->eh_depth != depth)) {+		error_msg = "unexpected eh_depth";+		goto corrupted;+	}+	if (unlikely(eh->eh_max == 0)) {+		error_msg = "too small eh_max";+		goto corrupted; 	}-	if (eh->eh_max == 0) {-		printk(KERN_ERR "EXT3-fs: invalid eh_max = %u\n",-		       (unsigned)eh->eh_max);-		return -EIO;+#ifdef AGRESSIVE_TEST+	if (eh->eh_max > 3) {+		/* inode probably got its extent without defining+		 * AGRESSIVE_TEST */+		max = eh->eh_max; 	}-	if (eh->eh_entries > eh->eh_max) {-		printk(KERN_ERR "EXT3-fs: invalid eh_entries = %u\n",-		       (unsigned)eh->eh_entries);-		return -EIO;+#endif+	if (unlikely(eh->eh_max > max)) {+		error_msg = "too large eh_max";+		goto corrupted;+	}+	if (unlikely(eh->eh_entries > eh->eh_max)) {+		error_msg = "invalid eh_entries";+		goto corrupted; 	} 	return 0;++corrupted:+	ext3_error(inode->i_sb, function,+			"bad header in inode #%lu: %s - magic %x, "+			"entries %u, max %u(%u), depth %u(%u)",+			inode->i_ino, error_msg, eh->eh_magic,+			eh->eh_entries, eh->eh_max, max,+			eh->eh_depth, depth);++	return -EIO; } +#define ext3_ext_check_header(inode,eh,depth,max)	\+	__ext3_ext_check_header(__FUNCTION__,inode,eh,depth,max)++ static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) { 	int err;@@ -227,6 +257,26 @@ static inline int ext3_ext_space_root_id 	return size; } +static inline int+ext3_ext_max_entries(struct ext3_extents_tree *tree, int root, int depth)+{+	int max;++	if (root) {+		if (depth == 0)+			max = ext3_ext_space_root(tree);+		else+			max = ext3_ext_space_root_idx(tree);+	} else {+		if (depth == 0)+			max = ext3_ext_space_block(tree);+		else+			max = ext3_ext_space_block_idx(tree);+	}++	return max;+}+ static void ext3_ext_show_path(struct ext3_extents_tree *tree, 			       struct ext3_ext_path *path) {@@ -297,10 +347,6 @@ ext3_ext_binsearch_idx(struct ext3_exten 	struct ext3_extent_idx *ix; 	int l = 0, k, r; -	EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC);-	EXT_ASSERT(eh->eh_entries <= eh->eh_max);-	EXT_ASSERT(eh->eh_entries > 0);- 	ext_debug(tree, "binsearch for %d(idx):  ", block);  	path->p_idx = ix = EXT_FIRST_INDEX(eh);@@ -360,9 +406,6 @@ ext3_ext_binsearch(struct ext3_extents_t 	struct ext3_extent *ex; 	int l = 0, k, r; -	EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC);-	EXT_ASSERT(eh->eh_entries <= eh->eh_max);- 	if (eh->eh_entries == 0) { 		/* 		 * this leaf is empty yet:@@ -437,6 +480,7 @@ ext3_ext_find_extent(struct ext3_extents 	struct ext3_extent_header *eh; 	struct buffer_head *bh; 	int depth, i, ppos = 0;+	int max;  	EXT_ASSERT(tree); 	EXT_ASSERT(tree->inode);@@ -444,17 +488,15 @@ ext3_ext_find_extent(struct ext3_extents  	eh = EXT_ROOT_HDR(tree); 	EXT_ASSERT(eh);-	if (ext3_ext_check_header(eh)) {+	i = depth = EXT_DEPTH(tree);+	max = ext3_ext_max_entries(tree, 1, i);+	if (ext3_ext_check_header(tree->inode, eh, i, max)) { 		/* don't free previously allocated path 		 * -- caller should take care */ 		path = NULL; 		goto err; 	} -	i = depth = EXT_DEPTH(tree);-	EXT_ASSERT(eh->eh_max);-	EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC);-	 	/* account possible depth increase */ 	if (!path) { 		path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2),@@ -485,7 +527,8 @@ ext3_ext_find_extent(struct ext3_extents 		path[ppos].p_hdr = eh; 		i--; -		if (ext3_ext_check_header(eh))+		max = ext3_ext_max_entries(tree, 0, i);+		if (ext3_ext_check_header(tree->inode, eh, i, max)) 			goto err; 	} @@ -494,9 +537,6 @@ ext3_ext_find_extent(struct ext3_extents 	path[ppos].p_ext = NULL; 	path[ppos].p_idx = NULL; -	if (ext3_ext_check_header(eh))-		goto err;- 	/* find extent */ 	ext3_ext_binsearch(tree, path + ppos, block); @@ -993,7 +1033,7 @@ ext3_ext_search_right(struct ext3_extent 	struct ext3_extent_idx *ix; 	struct ext3_extent *ex; 	unsigned long block;-	int depth;+	int depth, max;  	BUG_ON(path == NULL); 	depth = path->p_depth;@@ -1051,7 +1091,9 @@ ext3_ext_search_right(struct ext3_extent 		if (bh == NULL) 			return -EIO; 		eh = EXT_BLOCK_HDR(bh);-		if (ext3_ext_check_header(eh)) {+		max = ext3_ext_max_entries(tree, 0, depth);+		if (ext3_ext_check_header(tree->inode, eh,+					  path->p_depth - depth, max)) { 			brelse(bh); 			return -EIO; 		}@@ -1064,7 +1106,8 @@ ext3_ext_search_right(struct ext3_extent 	if (bh == NULL) 		return -EIO; 	eh = EXT_BLOCK_HDR(bh);-	if (ext3_ext_check_header(eh)) {+	max = ext3_ext_max_entries(tree, 0, depth);+	if (ext3_ext_check_header(tree->inode, eh, 0, max)) { 		brelse(bh); 		return -EIO; 	}@@ -1694,6 +1737,8 @@ ext3_ext_rm_leaf(handle_t *handle, struc 	ext_debug(tree, "remove [%lu:%lu] in leaf\n", start, end); 	if (!path[depth].p_hdr) 		path[depth].p_hdr = EXT_BLOCK_HDR(path[depth].p_bh);++	/* the header must be checked already in ext3_ext_remove_space() */ 	eh = path[depth].p_hdr; 	EXT_ASSERT(eh); 	EXT_ASSERT(eh->eh_entries <= eh->eh_max);@@ -1856,7 +1901,7 @@ int ext3_ext_remove_space(struct ext3_ex 	int depth = EXT_DEPTH(tree); 	struct ext3_ext_path *path; 	handle_t *handle;-	int i = 0, err = 0;+	int i = 0, err = 0, max;  	ext_debug(tree, "space to be removed: %lu:%lu\n", start, end); @@ -1879,7 +1924,13 @@ int ext3_ext_remove_space(struct ext3_ex 	} 	memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1)); 	path[i].p_hdr = EXT_ROOT_HDR(tree);-	++	max = ext3_ext_max_entries(tree, 1, depth);+	if (ext3_ext_check_header(inode, path[i].p_hdr, depth, max)) {+		err = -EIO;+		goto out;+	}+ 	while (i >= 0 && err == 0) { 		if (i == depth) { 			/* this is leaf block */@@ -1889,16 +1940,13 @@ int ext3_ext_remove_space(struct ext3_ex 			i--; 			continue; 		}-		+ 		/* this is index block */ 		if (!path[i].p_hdr) { 			ext_debug(tree, "initialize header\n"); 			path[i].p_hdr = EXT_BLOCK_HDR(path[i].p_bh); 		} -		EXT_ASSERT(path[i].p_hdr->eh_entries <= path[i].p_hdr->eh_max);-		EXT_ASSERT(path[i].p_hdr->eh_magic == EXT3_EXT_MAGIC);-		 		if (!path[i].p_idx) { 			/* this level hasn't touched yet */ 			path[i].p_idx =@@ -1925,6 +1973,14 @@ int ext3_ext_remove_space(struct ext3_ex 				err = -EIO; 				break; 			}+			BUG_ON(i + 1 > depth);+			max = ext3_ext_max_entries(tree, 0, depth - i - 1);+			if (ext3_ext_check_header(inode,+						EXT_BLOCK_HDR(path[i+1].p_bh),+						depth - i - 1, max)) {+				err = -EIO;+				break;+			} 			/* put actual number of indexes to know is this 			 * number got changed at the next iteration */ 			path[i].p_block = path[i].p_hdr->eh_entries;@@ -1945,7 +2001,7 @@ int ext3_ext_remove_space(struct ext3_ex 	}  	/* TODO: flexible tree reduction should be here */-	if (path->p_hdr->eh_entries == 0) {+	if (err == 0 && path->p_hdr->eh_entries == 0) { 		/* 		 * truncate to zero freed all the tree 		 * so, we need to correct eh_depth@@ -1959,6 +2015,7 @@ int ext3_ext_remove_space(struct ext3_ex 	} 	ext3_ext_tree_changed(tree); +out: 	kfree(path); 	ext3_journal_stop(handle); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -