From ed3a206c8f4d71469db5899a5a4d6659b315489e Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 9 Dec 2014 16:27:24 +0800 Subject: [PATCH] btrfs-progs: Record highest inode number before repair. Record highest inode number before inode repair. This is especially important for corrupted leaf case. Under that case, if use btrfs_find_free_objectid, it may find a ino existing in corrupted leaf but dropped by btree_recover. If that happens, created dir will be referenced incorrectly since there may be inode_ref or dir_index/item refers to it. So we must record the highest inode number according to the inode_cache. Inode_cache is OK since when a inode_ref or dir_index/item is found even the referenced source is not found, it will be created. If we record the highest inode number of inode_cache, and use highest_inode + 1 as 'lost+found' dir, it will ensure the newly created dir not conflicting with any possible inode. This provides the basis for nlink or inode rebuild for repairing btrfs with leaf/node corruption. Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- cmds-check.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmds-check.c b/cmds-check.c index d57363c1..3d3d8d79 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -1926,6 +1926,21 @@ static int check_inode_recs(struct btrfs_root *root, return 0; } + /* + * We need to record the highest inode number for later 'lost+found' + * dir creation. + * We must select a ino not used/refered by any existing inode, or + * 'lost+found' ino may be a missing ino in a corrupted leaf, + * this may cause 'lost+found' dir has wrong nlinks. + */ + cache = last_cache_extent(inode_cache); + if (cache) { + node = container_of(cache, struct ptr_node, cache); + rec = node->data; + if (rec->ino > root->highest_inode) + root->highest_inode = rec->ino; + } + /* * We need to repair backrefs first because we could change some of the * errors in the inode recs.