diff --git a/check/main.c b/check/main.c index 28a1aeca..d10cf051 100644 --- a/check/main.c +++ b/check/main.c @@ -86,6 +86,7 @@ bool no_holes = false; bool is_free_space_tree = false; bool init_extent_tree = false; bool check_data_csum = false; +static bool found_free_ino_cache = false; struct cache_tree *roots_info_cache = NULL; enum btrfs_check_mode { @@ -606,6 +607,8 @@ static void print_inode_error(struct btrfs_root *root, struct inode_record *rec) fprintf(stderr, "root %llu inode %llu errors %x", root_objectid, rec->ino, rec->errors); + if (errors & I_ERR_DEPRECATED_FREE_INO) + fprintf(stderr, ", deprecated free inode cache"); if (errors & I_ERR_NO_INODE_ITEM) fprintf(stderr, ", no inode item"); if (errors & I_ERR_NO_ORPHAN_ITEM) @@ -773,9 +776,6 @@ static struct inode_record *get_inode_rec(struct cache_tree *inode_cache, node->cache.size = 1; node->data = rec; - if (ino == BTRFS_FREE_INO_OBJECTID) - rec->found_link = 1; - ret = insert_cache_extent(inode_cache, &node->cache); if (ret) { free(rec); @@ -3224,6 +3224,10 @@ static int check_inode_recs(struct btrfs_root *root, } } + if (rec->ino == BTRFS_FREE_INO_OBJECTID) { + rec->errors |= I_ERR_DEPRECATED_FREE_INO; + found_free_ino_cache = true; + } if (!rec->found_inode_item) rec->errors |= I_ERR_NO_INODE_ITEM; if (rec->found_link != rec->nlink) @@ -10832,6 +10836,9 @@ static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv) ret = do_check_fs_roots(&root_cache); task_stop(g_task_ctx.info); + if (found_free_ino_cache) + pr_verbose(LOG_DEFAULT, + "deprecated inode cache can be removed by 'btrfs rescue clear-ino-cache'\n"); err |= !!ret; if (ret) { error("errors found in fs roots"); diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c index 4b6facca..34af77f8 100644 --- a/check/mode-lowmem.c +++ b/check/mode-lowmem.c @@ -44,6 +44,7 @@ static u64 last_allocated_chunk; static u64 total_used = 0; +static bool found_free_ino_cache = false; static int calc_extent_flag(struct btrfs_root *root, struct extent_buffer *eb, u64 *flags_ret) @@ -2629,6 +2630,12 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path) return err; } + if (inode_id == BTRFS_FREE_INO_OBJECTID) { + warning("subvolume %lld has deprecated inode cache", + root->root_key.objectid); + found_free_ino_cache = true; + } + is_orphan = has_orphan_item(root, inode_id); ii = btrfs_item_ptr(node, slot, struct btrfs_inode_item); isize = btrfs_inode_size(node, ii); @@ -5616,6 +5623,9 @@ next: out: btrfs_release_path(&path); + if (found_free_ino_cache) + pr_verbose(LOG_DEFAULT, + "deprecated inode cache can be removed by 'btrfs rescue clear-ino-cache'\n"); return err; } diff --git a/check/mode-original.h b/check/mode-original.h index ac8de57c..949d7551 100644 --- a/check/mode-original.h +++ b/check/mode-original.h @@ -189,6 +189,7 @@ struct unaligned_extent_rec_t { #define I_ERR_INVALID_GEN (1U << 20) #define I_ERR_INVALID_NLINK (1U << 21) #define I_ERR_INVALID_XATTR (1U << 22) +#define I_ERR_DEPRECATED_FREE_INO (1U << 23) struct inode_record { struct list_head backrefs;