@@ -908,6 +908,8 @@ static int process_inode_item(struct extent_buffer *eb,
if (S_ISLNK(rec->imode) &&
flags & (BTRFS_INODE_IMMUTABLE | BTRFS_INODE_APPEND))
rec->errors |= I_ERR_ODD_INODE_FLAGS;
+ if (S_ISDIR(rec->imode) && rec->ino == BTRFS_FIRST_FREE_OBJECTID)
+ rec->found_link = 1;
/*
* We don't have accurate root info to determine the correct
* inode generation uplimit, use super_generation + 1 anyway
@@ -1421,6 +1423,16 @@ static int process_dir_item(struct extent_buffer *eb,
goto next;
}
+ if ((location.type == BTRFS_INODE_ITEM_KEY ||
+ location.type == BTRFS_ROOT_ITEM_KEY) && filetype == BTRFS_FT_DIR &&
+ key->type == BTRFS_DIR_ITEM_KEY) {
+ struct inode_record *dir_rec = get_inode_rec(inode_cache,
+ key->objectid, 1);
+ BUG_ON(IS_ERR(rec));
+ dir_rec->found_link++;
+ maybe_free_inode_rec(inode_cache, dir_rec);
+ }
+
if (location.type == BTRFS_INODE_ITEM_KEY) {
add_inode_backref(inode_cache, location.objectid,
key->objectid, key->offset, namebuf,
@@ -1893,7 +1905,7 @@ static int check_root_dir(struct inode_record *rec)
goto out;
}
- if (rec->nlink != 1 || rec->found_link != 0) {
+ if (rec->nlink != rec->found_link) {
rec->errors |= I_ERR_LINK_COUNT_WRONG;
goto out;
}
This commit makes progs compatible with a kernel that has implemented subdirectory tracking in nlink. To achieve this the logic is modified such that found_link is incremented for the parent dir for every DIR_ITEM found which points to a subdirectory. Another change is to always set found_link to 1 when parsing INODE_ITEM which corresponds to a subvolume/snapshot root. This is to account for the fact that such inodes are the root in their respective fs trees so they won't have their found_link count bumped when parsing their DIR_ITEM in the parent directory. Signed-off-by: Nikolay Borisov <nborisov@suse.com> --- check/main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)