mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-17 20:05:24 +00:00
Add semantic checks to btrfsck for files and directories
This patch makes btrfsck check more things, including directory items, file extents, checksumming, inode link counts etc. The code for these checks is similar to the code verifies extent back references. The main difference is that shared tree blocks are treated specially. The partial checking results(unresolved references and/or errors) of shared sub-trees are cached. This avoids scanning the shared blocks several times. Thank you, Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
This commit is contained in:
parent
50e571e5b7
commit
9a6930e9be
2
ctree.c
2
ctree.c
@ -62,7 +62,7 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
|
||||
int i;
|
||||
for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
|
||||
if (!p->nodes[i])
|
||||
break;
|
||||
continue;
|
||||
free_extent_buffer(p->nodes[i]);
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
3
ctree.h
3
ctree.h
@ -1528,6 +1528,9 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
|
||||
u64 root_objectid, u64 ref_generation,
|
||||
u64 owner, u64 empty_size, u64 hint_byte,
|
||||
u64 search_end, struct btrfs_key *ins, int data);
|
||||
int btrfs_lookup_extent_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, u64 bytenr,
|
||||
u64 num_bytes, u32 *refs);
|
||||
int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
struct extent_buffer *orig_buf, struct extent_buffer *buf,
|
||||
u32 *nr_extents);
|
||||
|
@ -44,6 +44,11 @@ int insert_cache_extent(struct cache_tree *tree, u64 start, u64 size);
|
||||
int insert_existing_cache_extent(struct cache_tree *tree,
|
||||
struct cache_extent *pe);
|
||||
|
||||
static inline int cache_tree_empty(struct cache_tree *tree)
|
||||
{
|
||||
return RB_EMPTY_ROOT(&tree->root);
|
||||
}
|
||||
|
||||
static inline void free_cache_extent(struct cache_extent *pe)
|
||||
{
|
||||
free(pe);
|
||||
|
@ -801,9 +801,9 @@ int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lookup_extent_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, u64 bytenr,
|
||||
u64 num_bytes, u32 *refs)
|
||||
int btrfs_lookup_extent_ref(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, u64 bytenr,
|
||||
u64 num_bytes, u32 *refs)
|
||||
{
|
||||
struct btrfs_path *path;
|
||||
int ret;
|
||||
@ -2110,8 +2110,8 @@ static void noinline reada_walk_down(struct btrfs_root *root,
|
||||
}
|
||||
blocksize = btrfs_level_size(root, level - 1);
|
||||
if (i != slot) {
|
||||
ret = lookup_extent_ref(NULL, root, bytenr,
|
||||
blocksize, &refs);
|
||||
ret = btrfs_lookup_extent_ref(NULL, root, bytenr,
|
||||
blocksize, &refs);
|
||||
BUG_ON(ret);
|
||||
if (refs != 1) {
|
||||
skipped++;
|
||||
@ -2150,9 +2150,9 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
|
||||
|
||||
WARN_ON(*level < 0);
|
||||
WARN_ON(*level >= BTRFS_MAX_LEVEL);
|
||||
ret = lookup_extent_ref(trans, root,
|
||||
path->nodes[*level]->start,
|
||||
path->nodes[*level]->len, &refs);
|
||||
ret = btrfs_lookup_extent_ref(trans, root,
|
||||
path->nodes[*level]->start,
|
||||
path->nodes[*level]->len, &refs);
|
||||
BUG_ON(ret);
|
||||
if (refs > 1)
|
||||
goto out;
|
||||
@ -2179,7 +2179,8 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
|
||||
bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
|
||||
ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
|
||||
blocksize = btrfs_level_size(root, *level - 1);
|
||||
ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs);
|
||||
ret = btrfs_lookup_extent_ref(trans, root, bytenr, blocksize,
|
||||
&refs);
|
||||
BUG_ON(ret);
|
||||
if (refs != 1) {
|
||||
parent = path->nodes[*level];
|
||||
|
Loading…
Reference in New Issue
Block a user