RE: [PATCH] Btrfs-progs: rebuild the crc tree with --init-csum-tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Others might be thinking this to so I better ask:
Does this just read the first copy in the case of dup, raid1, etc. and plow on?
I'm
 not sure how you would handle a mismatch due to a hardware error. 
Perhaps read all the copies and create another subvolume containing the 
mismatched copies?

Thanks,
Kyle

> From: jbacik@xxxxxx
> To: linux-btrfs@xxxxxxxxxxxxxxx
> Subject: [PATCH] Btrfs-progs: rebuild the crc tree with --init-csum-tree
> Date: Wed, 1 Oct 2014 10:34:51 -0400
> 
> We have --init-csum-tree, which just empties the csum tree.  I'm not sure why we
> would ever need this, but we definitely need to be able to rebuild the csum tree
> in some cases.  This patch adds the ability to completely rebuild the crc tree
> by reading all of the data and adding csum entries for them.  This patch doesn't
> pay attention to NODATASUM inodes, it'll happily add csums for everything.
> Thanks,
> 
> Signed-off-by: Josef Bacik <jbacik@xxxxxx>
> ---
>  cmds-check.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
> 
> diff --git a/cmds-check.c b/cmds-check.c
> index 03b0fbd..3141aa4 100644
> --- a/cmds-check.c
> +++ b/cmds-check.c
> @@ -6625,6 +6625,98 @@ out:
>  	return ret;
>  }
>  
> +static int populate_csum(struct btrfs_trans_handle *trans,
> +			 struct btrfs_root *csum_root, char *buf, u64 start,
> +			 u64 len)
> +{
> +	u64 offset = 0;
> +	u64 sectorsize;
> +	int ret = 0;
> +
> +	while (offset < len) {
> +		sectorsize = csum_root->sectorsize;
> +		ret = read_extent_data(csum_root, buf, start + offset,
> +				       &sectorsize, 0);
> +		if (ret)
> +			break;
> +		ret = btrfs_csum_file_block(trans, csum_root, start + len,
> +					    start + offset, buf, sectorsize);
> +		if (ret)
> +			break;
> +		offset += sectorsize;
> +	}
> +	return ret;
> +}
> +
> +static int fill_csum_tree(struct btrfs_trans_handle *trans,
> +			  struct btrfs_root *csum_root)
> +{
> +	struct btrfs_root *extent_root = csum_root->fs_info->extent_root;
> +	struct btrfs_path *path;
> +	struct btrfs_extent_item *ei;
> +	struct extent_buffer *leaf;
> +	char *buf;
> +	struct btrfs_key key;
> +	int ret;
> +
> +	path = btrfs_alloc_path();
> +	if (!path)
> +		return -ENOMEM;
> +
> +	key.objectid = 0;
> +	key.type = BTRFS_EXTENT_ITEM_KEY;
> +	key.offset = 0;
> +
> +	ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0);
> +	if (ret < 0) {
> +		btrfs_free_path(path);
> +		return ret;
> +	}
> +
> +	buf = malloc(csum_root->sectorsize);
> +	if (!buf) {
> +		btrfs_free_path(path);
> +		return -ENOMEM;
> +	}
> +
> +	while (1) {
> +		if (path->slots[0]>= btrfs_header_nritems(path->nodes[0])) {
> +			ret = btrfs_next_leaf(extent_root, path);
> +			if (ret < 0)
> +				break;
> +			if (ret) {
> +				ret = 0;
> +				break;
> +			}
> +		}
> +		leaf = path->nodes[0];
> +
> +		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
> +		if (key.type != BTRFS_EXTENT_ITEM_KEY) {
> +			path->slots[0]++;
> +			continue;
> +		}
> +
> +		ei = btrfs_item_ptr(leaf, path->slots[0],
> +				    struct btrfs_extent_item);
> +		if (!(btrfs_extent_flags(leaf, ei) &
> +		      BTRFS_EXTENT_FLAG_DATA)) {
> +			path->slots[0]++;
> +			continue;
> +		}
> +
> +		ret = populate_csum(trans, csum_root, buf, key.objectid,
> +				    key.offset);
> +		if (ret)
> +			break;
> +		path->slots[0]++;
> +	}
> +
> +	btrfs_free_path(path);
> +	free(buf);
> +	return ret;
> +}
> +
>  static struct option long_options[] = {
>  	{ "super", 1, NULL, 's' },
>  	{ "repair", 0, NULL, 0 },
> @@ -6794,6 +6886,12 @@ int cmd_check(int argc, char **argv)
>  				ret = -EIO;
>  				goto close_out;
>  			}
> +
> +			ret = fill_csum_tree(trans, info->csum_root);
> +			if (ret) {
> +				fprintf(stderr, "crc refilling failed\n");
> +				return -EIO;
> +			}
>  		}
>  		/*
>  		 * Ok now we commit and run the normal fsck, which will add
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
 		 	   		  --
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux