All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] btrfs-corrupt-block btree data corruption
@ 2021-02-04 20:09 Boris Burkov
  2021-02-04 20:09 ` [PATCH 1/2] btrfs-progs: corrupt generic item data with btrfs-corrupt-block Boris Burkov
  2021-02-04 20:09 ` [PATCH 2/2] btrfs-progs: expand corrupt_file_extent in btrfs-corrupt-block Boris Burkov
  0 siblings, 2 replies; 5+ messages in thread
From: Boris Burkov @ 2021-02-04 20:09 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

Add some more generic corruption to btrfs-corrupt-block which allows
corrupting the data in metadata items.

Motivated by testing fsverity which requires rather specific corruption
of the metadata.

The first patch adds corrupting arbitrary regions of item data with -I.
The second patch adds corrupting holes and prealloc in extent data.

Boris Burkov (2):
  btrfs-progs: corrupt generic item data with btrfs-corrupt-block
  btrfs-progs: expand corrupt_file_extent in btrfs-corrupt-block

 btrfs-corrupt-block.c | 93 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 85 insertions(+), 8 deletions(-)

-- 
2.24.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] btrfs-progs: corrupt generic item data with btrfs-corrupt-block
  2021-02-04 20:09 [PATCH 0/2] btrfs-corrupt-block btree data corruption Boris Burkov
@ 2021-02-04 20:09 ` Boris Burkov
  2021-02-09  6:22   ` Sidong Yang
  2021-02-04 20:09 ` [PATCH 2/2] btrfs-progs: expand corrupt_file_extent in btrfs-corrupt-block Boris Burkov
  1 sibling, 1 reply; 5+ messages in thread
From: Boris Burkov @ 2021-02-04 20:09 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

btrfs-corrupt-block already has a mix of generic and specific corruption
options, but currently lacks the capacity for totally arbitrary
corruption in item data.

There is already a flag for corruption size (bytes/-b), so add a flag
for an offset and a value to memset the item with. Exercise the new
flags with a new variant for -I (item) corruption. Look up the item as
before, but instead of corrupting a field in the item struct, corrupt an
offset/size in the item data.

The motivating example for this is that in testing fsverity with btrfs,
we need to corrupt the generated Merkle tree--metadata item data which
is an opaque blob to btrfs.

Signed-off-by: Boris Burkov <boris@bur.io>
---
 btrfs-corrupt-block.c | 71 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 3 deletions(-)

diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 0c022a8e..bf1ce9c5 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -116,11 +116,13 @@ static void print_usage(int ret)
 	printf("\t-m   The metadata block to corrupt (must also specify -f for the field to corrupt)\n");
 	printf("\t-K <u64,u8,u64> Corrupt the given key (must also specify -f for the field and optionally -r for the root)\n");
 	printf("\t-f   The field in the item to corrupt\n");
-	printf("\t-I <u64,u8,u64> Corrupt an item corresponding to the passed key triplet (must also specify the field to corrupt and root for the item)\n");
+	printf("\t-I <u64,u8,u64> Corrupt an item corresponding to the passed key triplet (must also specify the field, or bytes, offset, and value to corrupt and root for the item)\n");
 	printf("\t-D <u64,u8,u64> Corrupt a dir item corresponding to the passed key triplet, must also specify a field\n");
 	printf("\t-d <u64,u8,u64> Delete item corresponding to passed key triplet\n");
 	printf("\t-r   Operate on this root\n");
 	printf("\t-C   Delete a csum for the specified bytenr.  When used with -b it'll delete that many bytes, otherwise it's just sectorsize\n");
+	printf("\t-v   Value to use for corrupting item data\n");
+	printf("\t-o   Offset to use for corrupting item data\n");
 	exit(ret);
 }
 
@@ -896,6 +898,50 @@ out:
 	return ret;
 }
 
+static int corrupt_btrfs_item_data(struct btrfs_root *root,
+				   struct btrfs_key *key,
+				   u64 bogus_offset, u64 bogus_size,
+				   char bogus_value)
+{
+	struct btrfs_trans_handle *trans;
+	struct btrfs_path *path;
+	int ret;
+	void *data;
+	struct extent_buffer *leaf;
+	int slot;
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	trans = btrfs_start_transaction(root, 1);
+	if (IS_ERR(trans)) {
+		fprintf(stderr, "Couldn't start transaction %ld\n",
+			PTR_ERR(trans));
+		ret = PTR_ERR(trans);
+		goto free_path;
+	}
+
+	ret = btrfs_search_slot(trans, root, key, path, 0, 1);
+	if (ret != 0) {
+		fprintf(stderr, "Error searching to node %d\n", ret);
+		goto commit_txn;
+	}
+	leaf = path->nodes[0];
+	slot = path->slots[0];
+	data = btrfs_item_ptr(leaf, slot, void);
+	// TODO: check offset/size legitimacy
+	data += bogus_offset;
+	memset_extent_buffer(leaf, bogus_value, (unsigned long)data, bogus_size);
+	btrfs_mark_buffer_dirty(leaf);
+
+commit_txn:
+	btrfs_commit_transaction(trans, root);
+free_path:
+	btrfs_free_path(path);
+	return ret;
+}
+
 static int delete_item(struct btrfs_root *root, struct btrfs_key *key)
 {
 	struct btrfs_trans_handle *trans;
@@ -1151,6 +1197,8 @@ int main(int argc, char **argv)
 	u64 root_objectid = 0;
 	u64 csum_bytenr = 0;
 	char field[FIELD_BUF_LEN];
+	u64 bogus_value = (u64)-1;
+	u64 bogus_offset = (u64)-1;
 
 	field[0] = '\0';
 	memset(&key, 0, sizeof(key));
@@ -1177,11 +1225,13 @@ int main(int argc, char **argv)
 			{ "delete", no_argument, NULL, 'd'},
 			{ "root", no_argument, NULL, 'r'},
 			{ "csum", required_argument, NULL, 'C'},
+			{ "value", required_argument, NULL, 'v'},
+			{ "offset", required_argument, NULL, 'o'},
 			{ "help", no_argument, NULL, GETOPT_VAL_HELP},
 			{ NULL, 0, NULL, 0 }
 		};
 
-		c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:I:D:d:r:C:",
+		c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:I:D:d:r:C:v:o:",
 				long_options, NULL);
 		if (c < 0)
 			break;
@@ -1244,6 +1294,12 @@ int main(int argc, char **argv)
 			case 'C':
 				csum_bytenr = arg_strtou64(optarg);
 				break;
+			case 'v':
+				bogus_value = arg_strtou64(optarg);
+				break;
+			case 'o':
+				bogus_offset = arg_strtou64(optarg);
+				break;
 			case GETOPT_VAL_HELP:
 			default:
 				print_usage(c != GETOPT_VAL_HELP);
@@ -1368,7 +1424,16 @@ int main(int argc, char **argv)
 		if (!root_objectid)
 			print_usage(1);
 
-		ret = corrupt_btrfs_item(target_root, &key, field);
+		if (*field != 0)
+			ret = corrupt_btrfs_item(target_root, &key, field);
+		else if (bogus_offset != (u64)-1 &&
+			 bytes != (u64)-1 &&
+			 bogus_value != (u64)-1)
+			ret = corrupt_btrfs_item_data(target_root, &key,
+						      bogus_offset, bytes,
+						      bogus_value);
+		else
+			print_usage(1);
 		goto out_close;
 	}
 	if (delete) {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] btrfs-progs: expand corrupt_file_extent in btrfs-corrupt-block
  2021-02-04 20:09 [PATCH 0/2] btrfs-corrupt-block btree data corruption Boris Burkov
  2021-02-04 20:09 ` [PATCH 1/2] btrfs-progs: corrupt generic item data with btrfs-corrupt-block Boris Burkov
@ 2021-02-04 20:09 ` Boris Burkov
  1 sibling, 0 replies; 5+ messages in thread
From: Boris Burkov @ 2021-02-04 20:09 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

To corrupt holes/prealloc/inline extents, we need to mess with
extent data items. This patch makes it possible to modify
disk_bytenr with a specific value (useful for hole corruptions)
and to modify the type field (useful for prealloc corruptions)

Signed-off-by: Boris Burkov <boris@bur.io>
---
 btrfs-corrupt-block.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index bf1ce9c5..40d8ad8e 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -323,6 +323,7 @@ enum btrfs_inode_field {
 
 enum btrfs_file_extent_field {
 	BTRFS_FILE_EXTENT_DISK_BYTENR,
+	BTRFS_FILE_EXTENT_TYPE,
 	BTRFS_FILE_EXTENT_BAD,
 };
 
@@ -377,6 +378,8 @@ static enum btrfs_file_extent_field convert_file_extent_field(char *field)
 {
 	if (!strncmp(field, "disk_bytenr", FIELD_BUF_LEN))
 		return BTRFS_FILE_EXTENT_DISK_BYTENR;
+	if (!strncmp(field, "type", FIELD_BUF_LEN))
+		return BTRFS_FILE_EXTENT_TYPE;
 	return BTRFS_FILE_EXTENT_BAD;
 }
 
@@ -673,14 +676,14 @@ out:
 
 static int corrupt_file_extent(struct btrfs_trans_handle *trans,
 			       struct btrfs_root *root, u64 inode, u64 extent,
-			       char *field)
+			       char *field, u64 bogus)
 {
 	struct btrfs_file_extent_item *fi;
 	struct btrfs_path *path;
 	struct btrfs_key key;
 	enum btrfs_file_extent_field corrupt_field;
-	u64 bogus;
 	u64 orig;
+	u8 bogus_type = bogus;
 	int ret = 0;
 
 	corrupt_field = convert_file_extent_field(field);
@@ -712,9 +715,18 @@ static int corrupt_file_extent(struct btrfs_trans_handle *trans,
 	switch (corrupt_field) {
 	case BTRFS_FILE_EXTENT_DISK_BYTENR:
 		orig = btrfs_file_extent_disk_bytenr(path->nodes[0], fi);
-		bogus = generate_u64(orig);
+		if (bogus == (u64)-1)
+			bogus = generate_u64(orig);
 		btrfs_set_file_extent_disk_bytenr(path->nodes[0], fi, bogus);
 		break;
+	case BTRFS_FILE_EXTENT_TYPE:
+		if (bogus == (u64)-1) {
+			fprintf(stderr, "Specify a new extent type value (-v)\n");
+			ret = -EINVAL;
+			goto out;
+		}
+		btrfs_set_file_extent_type(path->nodes[0], fi, bogus_type);
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -1394,9 +1406,9 @@ int main(int argc, char **argv)
 			printf("corrupting inode\n");
 			ret = corrupt_inode(trans, root, inode, field);
 		} else {
-			printf("corrupting file extent\n");
 			ret = corrupt_file_extent(trans, root, inode,
-						  file_extent, field);
+						  file_extent, field,
+						  bogus_value);
 		}
 		btrfs_commit_transaction(trans, root);
 		goto out_close;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] btrfs-progs: corrupt generic item data with btrfs-corrupt-block
  2021-02-04 20:09 ` [PATCH 1/2] btrfs-progs: corrupt generic item data with btrfs-corrupt-block Boris Burkov
@ 2021-02-09  6:22   ` Sidong Yang
  2021-02-09 18:02     ` Boris Burkov
  0 siblings, 1 reply; 5+ messages in thread
From: Sidong Yang @ 2021-02-09  6:22 UTC (permalink / raw)
  To: Boris Burkov; +Cc: linux-btrfs, kernel-team

On Thu, Feb 04, 2021 at 12:09:31PM -0800, Boris Burkov wrote:

Hi Boris, I have a question for this code.

> btrfs-corrupt-block already has a mix of generic and specific corruption
> options, but currently lacks the capacity for totally arbitrary
> corruption in item data.
> 
> There is already a flag for corruption size (bytes/-b), so add a flag
> for an offset and a value to memset the item with. Exercise the new
> flags with a new variant for -I (item) corruption. Look up the item as
> before, but instead of corrupting a field in the item struct, corrupt an
> offset/size in the item data.
> 
> The motivating example for this is that in testing fsverity with btrfs,
> we need to corrupt the generated Merkle tree--metadata item data which
> is an opaque blob to btrfs.
> 
> Signed-off-by: Boris Burkov <boris@bur.io>
> ---
>  btrfs-corrupt-block.c | 71 +++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 68 insertions(+), 3 deletions(-)
> 
> diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
> index 0c022a8e..bf1ce9c5 100644
> --- a/btrfs-corrupt-block.c
> +++ b/btrfs-corrupt-block.c
> @@ -116,11 +116,13 @@ static void print_usage(int ret)
>  	printf("\t-m   The metadata block to corrupt (must also specify -f for the field to corrupt)\n");
>  	printf("\t-K <u64,u8,u64> Corrupt the given key (must also specify -f for the field and optionally -r for the root)\n");
>  	printf("\t-f   The field in the item to corrupt\n");
> -	printf("\t-I <u64,u8,u64> Corrupt an item corresponding to the passed key triplet (must also specify the field to corrupt and root for the item)\n");
> +	printf("\t-I <u64,u8,u64> Corrupt an item corresponding to the passed key triplet (must also specify the field, or bytes, offset, and value to corrupt and root for the item)\n");
>  	printf("\t-D <u64,u8,u64> Corrupt a dir item corresponding to the passed key triplet, must also specify a field\n");
>  	printf("\t-d <u64,u8,u64> Delete item corresponding to passed key triplet\n");
>  	printf("\t-r   Operate on this root\n");
>  	printf("\t-C   Delete a csum for the specified bytenr.  When used with -b it'll delete that many bytes, otherwise it's just sectorsize\n");
> +	printf("\t-v   Value to use for corrupting item data\n");
> +	printf("\t-o   Offset to use for corrupting item data\n");
>  	exit(ret);
>  }
>  
> @@ -896,6 +898,50 @@ out:
>  	return ret;
>  }
>  
> +static int corrupt_btrfs_item_data(struct btrfs_root *root,
> +				   struct btrfs_key *key,
> +				   u64 bogus_offset, u64 bogus_size,
> +				   char bogus_value)
> +{
> +	struct btrfs_trans_handle *trans;
> +	struct btrfs_path *path;
> +	int ret;
> +	void *data;
> +	struct extent_buffer *leaf;
> +	int slot;
> +
> +	path = btrfs_alloc_path();
> +	if (!path)
> +		return -ENOMEM;
> +
> +	trans = btrfs_start_transaction(root, 1);
> +	if (IS_ERR(trans)) {
> +		fprintf(stderr, "Couldn't start transaction %ld\n",
> +			PTR_ERR(trans));
> +		ret = PTR_ERR(trans);
> +		goto free_path;
> +	}
> +
> +	ret = btrfs_search_slot(trans, root, key, path, 0, 1);
> +	if (ret != 0) {
> +		fprintf(stderr, "Error searching to node %d\n", ret);
> +		goto commit_txn;

This is error case. but this code goes to commit transaction. I think there is
an option to abort transaction. This code has pros than aborting?

> +	}
> +	leaf = path->nodes[0];
> +	slot = path->slots[0];
> +	data = btrfs_item_ptr(leaf, slot, void);
> +	// TODO: check offset/size legitimacy
> +	data += bogus_offset;
> +	memset_extent_buffer(leaf, bogus_value, (unsigned long)data, bogus_size);
> +	btrfs_mark_buffer_dirty(leaf);
> +
> +commit_txn:
> +	btrfs_commit_transaction(trans, root);
> +free_path:
> +	btrfs_free_path(path);
> +	return ret;
> +}
> +
>  static int delete_item(struct btrfs_root *root, struct btrfs_key *key)
>  {
>  	struct btrfs_trans_handle *trans;
> @@ -1151,6 +1197,8 @@ int main(int argc, char **argv)
>  	u64 root_objectid = 0;
>  	u64 csum_bytenr = 0;
>  	char field[FIELD_BUF_LEN];
> +	u64 bogus_value = (u64)-1;
> +	u64 bogus_offset = (u64)-1;
>  
>  	field[0] = '\0';
>  	memset(&key, 0, sizeof(key));
> @@ -1177,11 +1225,13 @@ int main(int argc, char **argv)
>  			{ "delete", no_argument, NULL, 'd'},
>  			{ "root", no_argument, NULL, 'r'},
>  			{ "csum", required_argument, NULL, 'C'},
> +			{ "value", required_argument, NULL, 'v'},
> +			{ "offset", required_argument, NULL, 'o'},
>  			{ "help", no_argument, NULL, GETOPT_VAL_HELP},
>  			{ NULL, 0, NULL, 0 }
>  		};
>  
> -		c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:I:D:d:r:C:",
> +		c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:I:D:d:r:C:v:o:",
>  				long_options, NULL);
>  		if (c < 0)
>  			break;
> @@ -1244,6 +1294,12 @@ int main(int argc, char **argv)
>  			case 'C':
>  				csum_bytenr = arg_strtou64(optarg);
>  				break;
> +			case 'v':
> +				bogus_value = arg_strtou64(optarg);
> +				break;
> +			case 'o':
> +				bogus_offset = arg_strtou64(optarg);
> +				break;
>  			case GETOPT_VAL_HELP:
>  			default:
>  				print_usage(c != GETOPT_VAL_HELP);
> @@ -1368,7 +1424,16 @@ int main(int argc, char **argv)
>  		if (!root_objectid)
>  			print_usage(1);
>  
> -		ret = corrupt_btrfs_item(target_root, &key, field);
> +		if (*field != 0)
> +			ret = corrupt_btrfs_item(target_root, &key, field);
> +		else if (bogus_offset != (u64)-1 &&
> +			 bytes != (u64)-1 &&
> +			 bogus_value != (u64)-1)
> +			ret = corrupt_btrfs_item_data(target_root, &key,
> +						      bogus_offset, bytes,
> +						      bogus_value);
> +		else
> +			print_usage(1);
>  		goto out_close;
>  	}
>  	if (delete) {
> -- 
> 2.24.1
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] btrfs-progs: corrupt generic item data with btrfs-corrupt-block
  2021-02-09  6:22   ` Sidong Yang
@ 2021-02-09 18:02     ` Boris Burkov
  0 siblings, 0 replies; 5+ messages in thread
From: Boris Burkov @ 2021-02-09 18:02 UTC (permalink / raw)
  To: Sidong Yang; +Cc: linux-btrfs, kernel-team

On Tue, Feb 09, 2021 at 06:22:47AM +0000, Sidong Yang wrote:
> On Thu, Feb 04, 2021 at 12:09:31PM -0800, Boris Burkov wrote:
> 
> Hi Boris, I have a question for this code.
> 
> > btrfs-corrupt-block already has a mix of generic and specific corruption
> > options, but currently lacks the capacity for totally arbitrary
> > corruption in item data.
> > 
> > There is already a flag for corruption size (bytes/-b), so add a flag
> > for an offset and a value to memset the item with. Exercise the new
> > flags with a new variant for -I (item) corruption. Look up the item as
> > before, but instead of corrupting a field in the item struct, corrupt an
> > offset/size in the item data.
> > 
> > The motivating example for this is that in testing fsverity with btrfs,
> > we need to corrupt the generated Merkle tree--metadata item data which
> > is an opaque blob to btrfs.
> > 
> > Signed-off-by: Boris Burkov <boris@bur.io>
> > ---
> >  btrfs-corrupt-block.c | 71 +++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 68 insertions(+), 3 deletions(-)
> > 
> > diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
> > index 0c022a8e..bf1ce9c5 100644
> > --- a/btrfs-corrupt-block.c
> > +++ b/btrfs-corrupt-block.c
> > @@ -116,11 +116,13 @@ static void print_usage(int ret)
> >  	printf("\t-m   The metadata block to corrupt (must also specify -f for the field to corrupt)\n");
> >  	printf("\t-K <u64,u8,u64> Corrupt the given key (must also specify -f for the field and optionally -r for the root)\n");
> >  	printf("\t-f   The field in the item to corrupt\n");
> > -	printf("\t-I <u64,u8,u64> Corrupt an item corresponding to the passed key triplet (must also specify the field to corrupt and root for the item)\n");
> > +	printf("\t-I <u64,u8,u64> Corrupt an item corresponding to the passed key triplet (must also specify the field, or bytes, offset, and value to corrupt and root for the item)\n");
> >  	printf("\t-D <u64,u8,u64> Corrupt a dir item corresponding to the passed key triplet, must also specify a field\n");
> >  	printf("\t-d <u64,u8,u64> Delete item corresponding to passed key triplet\n");
> >  	printf("\t-r   Operate on this root\n");
> >  	printf("\t-C   Delete a csum for the specified bytenr.  When used with -b it'll delete that many bytes, otherwise it's just sectorsize\n");
> > +	printf("\t-v   Value to use for corrupting item data\n");
> > +	printf("\t-o   Offset to use for corrupting item data\n");
> >  	exit(ret);
> >  }
> >  
> > @@ -896,6 +898,50 @@ out:
> >  	return ret;
> >  }
> >  
> > +static int corrupt_btrfs_item_data(struct btrfs_root *root,
> > +				   struct btrfs_key *key,
> > +				   u64 bogus_offset, u64 bogus_size,
> > +				   char bogus_value)
> > +{
> > +	struct btrfs_trans_handle *trans;
> > +	struct btrfs_path *path;
> > +	int ret;
> > +	void *data;
> > +	struct extent_buffer *leaf;
> > +	int slot;
> > +
> > +	path = btrfs_alloc_path();
> > +	if (!path)
> > +		return -ENOMEM;
> > +
> > +	trans = btrfs_start_transaction(root, 1);
> > +	if (IS_ERR(trans)) {
> > +		fprintf(stderr, "Couldn't start transaction %ld\n",
> > +			PTR_ERR(trans));
> > +		ret = PTR_ERR(trans);
> > +		goto free_path;
> > +	}
> > +
> > +	ret = btrfs_search_slot(trans, root, key, path, 0, 1);
> > +	if (ret != 0) {
> > +		fprintf(stderr, "Error searching to node %d\n", ret);
> > +		goto commit_txn;
> 
> This is error case. but this code goes to commit transaction. I think there is
> an option to abort transaction. This code has pros than aborting?
> 

Good question. To be perfectly honest, I copied this pattern from some
of the other corruption functions around, and don't have a good answer.
Looking at it now, I don't see any harm in either approach (we don't
have any work to commit since it was just search_slot that failed) but
abort does seem less surprising.

> > +	}
> > +	leaf = path->nodes[0];
> > +	slot = path->slots[0];
> > +	data = btrfs_item_ptr(leaf, slot, void);
> > +	// TODO: check offset/size legitimacy
> > +	data += bogus_offset;
> > +	memset_extent_buffer(leaf, bogus_value, (unsigned long)data, bogus_size);
> > +	btrfs_mark_buffer_dirty(leaf);
> > +
> > +commit_txn:
> > +	btrfs_commit_transaction(trans, root);
> > +free_path:
> > +	btrfs_free_path(path);
> > +	return ret;
> > +}
> > +
> >  static int delete_item(struct btrfs_root *root, struct btrfs_key *key)
> >  {
> >  	struct btrfs_trans_handle *trans;
> > @@ -1151,6 +1197,8 @@ int main(int argc, char **argv)
> >  	u64 root_objectid = 0;
> >  	u64 csum_bytenr = 0;
> >  	char field[FIELD_BUF_LEN];
> > +	u64 bogus_value = (u64)-1;
> > +	u64 bogus_offset = (u64)-1;
> >  
> >  	field[0] = '\0';
> >  	memset(&key, 0, sizeof(key));
> > @@ -1177,11 +1225,13 @@ int main(int argc, char **argv)
> >  			{ "delete", no_argument, NULL, 'd'},
> >  			{ "root", no_argument, NULL, 'r'},
> >  			{ "csum", required_argument, NULL, 'C'},
> > +			{ "value", required_argument, NULL, 'v'},
> > +			{ "offset", required_argument, NULL, 'o'},
> >  			{ "help", no_argument, NULL, GETOPT_VAL_HELP},
> >  			{ NULL, 0, NULL, 0 }
> >  		};
> >  
> > -		c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:I:D:d:r:C:",
> > +		c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:I:D:d:r:C:v:o:",
> >  				long_options, NULL);
> >  		if (c < 0)
> >  			break;
> > @@ -1244,6 +1294,12 @@ int main(int argc, char **argv)
> >  			case 'C':
> >  				csum_bytenr = arg_strtou64(optarg);
> >  				break;
> > +			case 'v':
> > +				bogus_value = arg_strtou64(optarg);
> > +				break;
> > +			case 'o':
> > +				bogus_offset = arg_strtou64(optarg);
> > +				break;
> >  			case GETOPT_VAL_HELP:
> >  			default:
> >  				print_usage(c != GETOPT_VAL_HELP);
> > @@ -1368,7 +1424,16 @@ int main(int argc, char **argv)
> >  		if (!root_objectid)
> >  			print_usage(1);
> >  
> > -		ret = corrupt_btrfs_item(target_root, &key, field);
> > +		if (*field != 0)
> > +			ret = corrupt_btrfs_item(target_root, &key, field);
> > +		else if (bogus_offset != (u64)-1 &&
> > +			 bytes != (u64)-1 &&
> > +			 bogus_value != (u64)-1)
> > +			ret = corrupt_btrfs_item_data(target_root, &key,
> > +						      bogus_offset, bytes,
> > +						      bogus_value);
> > +		else
> > +			print_usage(1);
> >  		goto out_close;
> >  	}
> >  	if (delete) {
> > -- 
> > 2.24.1
> > 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-02-09 19:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-04 20:09 [PATCH 0/2] btrfs-corrupt-block btree data corruption Boris Burkov
2021-02-04 20:09 ` [PATCH 1/2] btrfs-progs: corrupt generic item data with btrfs-corrupt-block Boris Burkov
2021-02-09  6:22   ` Sidong Yang
2021-02-09 18:02     ` Boris Burkov
2021-02-04 20:09 ` [PATCH 2/2] btrfs-progs: expand corrupt_file_extent in btrfs-corrupt-block Boris Burkov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.