diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2010-09-09 21:41:48 +0800 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-09-23 20:26:50 -0400 |
commit | d44860cee56e81e5da35fdf4ce339167a3a785bc (patch) | |
tree | d060fcc1db4df8716d87df57253c91b5bdf230f7 /btrfsck.c | |
parent | 7da27f91fc103e53756798947d73c955750a2814 (diff) |
Fix inode link count checks in btrfsck
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'btrfsck.c')
-rw-r--r-- | btrfsck.c | 8 |
1 files changed, 6 insertions, 2 deletions
@@ -423,7 +423,6 @@ static struct inode_backref *get_inode_backref(struct inode_record *rec, memcpy(backref->name, name, namelen); backref->name[namelen] = '\0'; list_add_tail(&backref->list, &rec->backrefs); - rec->found_link++; return backref; } @@ -451,6 +450,7 @@ static int add_inode_backref(struct cache_tree *inode_cache, backref->filetype = filetype; backref->found_dir_index = 1; } else if (itemtype == BTRFS_DIR_ITEM_KEY) { + rec->found_link++; if (backref->found_dir_item) backref->errors |= REF_ERR_DUP_DIR_ITEM; if (backref->found_dir_index && backref->filetype != filetype) @@ -478,6 +478,7 @@ static int merge_inode_recs(struct inode_record *src, struct inode_record *dst, struct cache_tree *dst_cache) { struct inode_backref *backref; + u32 dir_count = 0; dst->merging = 1; list_for_each_entry(backref, &src->backrefs, list) { @@ -488,6 +489,7 @@ static int merge_inode_recs(struct inode_record *src, struct inode_record *dst, BTRFS_DIR_INDEX_KEY, backref->errors); } if (backref->found_dir_item) { + dir_count++; add_inode_backref(dst_cache, dst->ino, backref->dir, 0, backref->name, backref->namelen, backref->filetype, @@ -512,6 +514,8 @@ static int merge_inode_recs(struct inode_record *src, struct inode_record *dst, if (dst->first_extent_gap > src->first_extent_gap) dst->first_extent_gap = src->first_extent_gap; + BUG_ON(src->found_link < dir_count); + dst->found_link += src->found_link - dir_count; dst->found_size += src->found_size; if (src->extent_start != (u64)-1) { if (dst->extent_start == (u64)-1) { @@ -1164,7 +1168,7 @@ static int check_root_dir(struct inode_record *rec) if (!rec->found_inode_item || rec->errors) goto out; - if (rec->nlink != 1 || rec->found_link != 1) + if (rec->nlink != 1 || rec->found_link != 0) goto out; if (list_empty(&rec->backrefs)) goto out; |