btrfs-progs: Record highest inode number before repair.
authorQu Wenruo <quwenruo@cn.fujitsu.com>
Tue, 9 Dec 2014 08:27:24 +0000 (16:27 +0800)
committerDavid Sterba <dsterba@suse.cz>
Wed, 10 Dec 2014 10:55:17 +0000 (11:55 +0100)
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 <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
cmds-check.c

index d57363c..3d3d8d7 100644 (file)
@@ -1927,6 +1927,21 @@ static int check_inode_recs(struct btrfs_root *root,
        }
 
        /*
+        * 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.
         *