mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Btrfs: detect corruption when non-root leaf has zero item
Right now we treat leaf which has zero item as a valid one because we could have an empty tree, that is, a root that is also a leaf without any item, however, in the same case but when the leaf is not a root, we can end up with hitting the BUG_ON(1) in btrfs_extend_item() called by setup_inline_extent_backref(). This makes us check the situation as a corruption if leaf is not its own root. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
		
							parent
							
								
									053ab70f06
								
							
						
					
					
						commit
						1ba98d086f
					
				
					 1 changed files with 22 additions and 1 deletions
				
			
		| 
						 | 
					@ -560,8 +560,29 @@ static noinline int check_leaf(struct btrfs_root *root,
 | 
				
			||||||
	u32 nritems = btrfs_header_nritems(leaf);
 | 
						u32 nritems = btrfs_header_nritems(leaf);
 | 
				
			||||||
	int slot;
 | 
						int slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nritems == 0)
 | 
						if (nritems == 0) {
 | 
				
			||||||
 | 
							struct btrfs_root *check_root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							key.objectid = btrfs_header_owner(leaf);
 | 
				
			||||||
 | 
							key.type = BTRFS_ROOT_ITEM_KEY;
 | 
				
			||||||
 | 
							key.offset = (u64)-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							check_root = btrfs_get_fs_root(root->fs_info, &key, false);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * The only reason we also check NULL here is that during
 | 
				
			||||||
 | 
							 * open_ctree() some roots has not yet been set up.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (!IS_ERR_OR_NULL(check_root)) {
 | 
				
			||||||
 | 
								/* if leaf is the root, then it's fine */
 | 
				
			||||||
 | 
								if (leaf->start !=
 | 
				
			||||||
 | 
								    btrfs_root_bytenr(&check_root->root_item)) {
 | 
				
			||||||
 | 
									CORRUPT("non-root leaf's nritems is 0",
 | 
				
			||||||
 | 
										leaf, root, 0);
 | 
				
			||||||
 | 
									return -EIO;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check the 0 item */
 | 
						/* Check the 0 item */
 | 
				
			||||||
	if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
 | 
						if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue