Re: [PATCH] Btrfs-progs: fsck: disable --init-extent-tree option when using snapshots

Shilong Wang
2014-03-10T12:12:42Z

Hi Josef,

As i haven't thought any better ideas to rebuild extent tree which contains
extent that owns 'FULL BACKREF' flag.

Considering an extent's refs can be equal or more than 1 if this extent has
*FULL BACKREF* flag, so we could not make sure an extent's flag by only
searching fs/file tree any more.

So until now, i just disable this option if snapshots exists, please correct me
if i miss something here. Or you have any better ideas to solve this problem.~_~

Thanks,
Wang
2014-03-10 18:39 GMT+08:00 Wang Shilong <wangsl.fnst@cn.fujitsu.com>:
> We haven't supported to rebuild extent tree if there are any *FULL BACKREF*
> with broken filesystem, disable this option when detecting snapshots.
>
> Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
> ---
> cmds-check.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 62 insertions(+)
>
> diff --git a/cmds-check.c b/cmds-check.c
> index d1cafe1..ddee897 100644
> --- a/cmds-check.c
> +++ b/cmds-check.c
> @@ -6143,6 +6143,56 @@ static int reset_block_groups(struct btrfs_fs_info *fs_info)
> return 0;
> }
>
> +static int is_snapshot_exist(struct btrfs_fs_info *fs_info)
> +{
> + struct btrfs_root *root = fs_info->tree_root;
> + struct btrfs_path *path;
> + struct extent_buffer *leaf;
> + struct btrfs_key key;
> + int ret;
> + int found = 0;
> +
> + path = btrfs_alloc_path();
> + if (!path)
> + return -ENOMEM;
> +
> + key.objectid = BTRFS_FIRST_FREE_OBJECTID;
> + key.type = BTRFS_ROOT_ITEM_KEY;
> + key.offset = 0;
> +
> + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
> + if (ret < 0)
> + goto out;
> +
> + while (1) {
> + if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
> + ret = btrfs_next_leaf(root, path);
> + if (ret)
> + goto out;
> + }
> + leaf = path->nodes[0];
> + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
> +
> + if (key.type != BTRFS_ROOT_ITEM_KEY ||
> + key.objectid < BTRFS_FIRST_FREE_OBJECTID) {
> + path->slots[0]++;
> + continue;
> + }
> + if (key.offset > 0) {
> + found = 1;
> + break;
> + }
> + path->slots[0]++;
> + }
> +out:
> + btrfs_free_path(path);
> + if (found)
> + return 1;
> + else if (ret >= 0)
> + return 0;
> + return ret;
> +}
> +
> static int reset_balance(struct btrfs_trans_handle *trans,
> struct btrfs_fs_info *fs_info)
> {
> @@ -6537,6 +6587,18 @@ int cmd_check(int argc, char **argv)
> ret = -EIO;
> goto close_out;
> }
> + if (init_extent_tree) {
> + ret = is_snapshot_exist(info);
> + if (ret < 0) {
> + fprintf(stderr, "ERROR: fail to check if there are snapshots in btrfs filesystem\n");
> + ret = 1;
> + goto close_out;
> + } else if (ret) {
> + fprintf(stderr, "Snapshots detected, unable to rebuild extent tree for such case.\n");
> + ret = 1;
> + goto close_out;
> + }
> + }
>
> if (init_extent_tree || init_csum_tree) {
> struct btrfs_trans_handle *trans;
> --
> 1.9.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html