All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] btrfs-progs: introduce inspect-internal map-logical command
@ 2022-05-20  7:23 Qu Wenruo
  2022-05-20  8:44 ` Johannes Thumshirn
  2022-05-20 18:12 ` David Sterba
  0 siblings, 2 replies; 4+ messages in thread
From: Qu Wenruo @ 2022-05-20  7:23 UTC (permalink / raw)
  To: linux-btrfs

This is a simpler version compared to btrfs-map-logical.

The differences are:

- No extent check
  Thus any bytenr which has chunk mapping can be mapped.

- No length specification
  Now it's fixed to sectorsize.
  Previously we use nodesize in btrfs-map-logical, which would only
  make the output more complex due as it may cross stripe boundary
  for data extent.

  Considering the main users of this functionality is data corruption,
  thus we really just want to resolve a single sector.

- No data write support nor mirror specification
  We always output all mirrors and call it a day.

- Ignore RAID56 parity manually

We still keep the old btrfs-map-logical, just in case there are some
usage of certain parameters.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 Documentation/btrfs-inspect-internal.rst |  7 +++
 cmds/inspect.c                           | 78 ++++++++++++++++++++++++
 2 files changed, 85 insertions(+)

diff --git a/Documentation/btrfs-inspect-internal.rst b/Documentation/btrfs-inspect-internal.rst
index 710a34fb0cb9..8a9264d3dc5b 100644
--- a/Documentation/btrfs-inspect-internal.rst
+++ b/Documentation/btrfs-inspect-internal.rst
@@ -169,6 +169,13 @@ logical-resolve [-Pvo] [-s <bufsize>] <logical> <path>
         -v
                 (deprecated) alias for global *-v* option
 
+map-logical <logical> <device>
+        map the sector at given *logical* address in the linear filesystem space into
+        physical address.
+
+        .. note::
+                For RAID56, this will only map the data stripe.
+
 min-dev-size [options] <path>
         (needs root privileges)
 
diff --git a/cmds/inspect.c b/cmds/inspect.c
index 1534f2040f4e..271adf8c6fd4 100644
--- a/cmds/inspect.c
+++ b/cmds/inspect.c
@@ -29,6 +29,7 @@
 #include "kernel-shared/ctree.h"
 #include "common/send-utils.h"
 #include "kernel-shared/disk-io.h"
+#include "kernel-shared/volumes.h"
 #include "cmds/commands.h"
 #include "common/help.h"
 #include "common/open-utils.h"
@@ -125,6 +126,7 @@ static int cmd_inspect_inode_resolve(const struct cmd_struct *cmd,
 }
 static DEFINE_SIMPLE_COMMAND(inspect_inode_resolve, "inode-resolve");
 
+
 static const char * const cmd_inspect_logical_resolve_usage[] = {
 	"btrfs inspect-internal logical-resolve [-Pvo] [-s bufsize] <logical> <path>",
 	"Get file system paths for the given logical address",
@@ -348,6 +350,81 @@ out:
 }
 static DEFINE_SIMPLE_COMMAND(inspect_subvolid_resolve, "subvolid-resolve");
 
+static const char * const cmd_inspect_map_logical_usage[] = {
+	"btrfs inspect-internal map-logical <logical> <device>",
+	"Get the physical offset of a sector.",
+	NULL
+};
+
+static int print_mapping_info(struct btrfs_fs_info *fs_info, u64 logical)
+{
+	struct cache_extent *ce;
+	struct map_lookup *map;
+	int num_copies;
+	int cur_mirror;
+	int ret;
+
+	ce = search_cache_extent(&fs_info->mapping_tree.cache_tree, logical);
+	if (!ce) {
+		error("no chunk mapping found for logical %llu", logical);
+		return -ENOENT;
+	}
+	map = container_of(ce, struct map_lookup, ce);
+	/* For RAID56, we only return the data stripe. */
+	if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
+		num_copies = 1;
+	else
+		num_copies = btrfs_num_copies(fs_info, logical,
+					      fs_info->sectorsize);
+
+	for (cur_mirror = 1; cur_mirror <= num_copies; cur_mirror++) {
+		struct btrfs_multi_bio *multi = NULL;
+		u64 len = fs_info->sectorsize;
+
+		ret = btrfs_map_block(fs_info, READ, logical, &len, &multi,
+				      cur_mirror, NULL);
+		if (ret < 0) {
+			errno = -ret;
+			error("failed to map logical %llu: %m", logical);
+			return ret;
+		}
+		/* We're using READ, which should only return one mirror. */
+		ASSERT(multi && multi->num_stripes == 1);
+		printf("mirror %d logical %llu phyiscal %llu device %s\n",
+			cur_mirror, logical, multi->stripes[0].physical,
+			multi->stripes[0].dev->name);
+		free(multi);
+	}
+	return 0;
+}
+
+static int cmd_inspect_map_logical(const struct cmd_struct *cmd, int argc,
+				   char **argv)
+{
+	struct open_ctree_flags ocf = {0};
+	struct btrfs_fs_info *fs_info;
+	u64 logical;
+	int ret;
+
+	clean_args_no_options(cmd, argc, argv);
+
+	if (check_argc_exact(argc - optind, 2))
+		return 1;
+
+	ocf.filename = argv[optind + 1];
+	ocf.flags = OPEN_CTREE_CHUNK_ROOT_ONLY;
+	logical = arg_strtou64(argv[optind]);
+
+	fs_info = open_ctree_fs_info(&ocf);
+	if (!fs_info) {
+		error("failed to open btrfs on %s", ocf.filename);
+		return 1;
+	}
+	ret = print_mapping_info(fs_info, logical);
+	return !!ret;
+}
+static DEFINE_SIMPLE_COMMAND(inspect_map_logical, "map-logical");
+
 static const char* const cmd_inspect_rootid_usage[] = {
 	"btrfs inspect-internal rootid <path>",
 	"Get tree ID of the containing subvolume of path.",
@@ -690,6 +767,7 @@ static const struct cmd_group inspect_cmd_group = {
 		&cmd_struct_inspect_inode_resolve,
 		&cmd_struct_inspect_logical_resolve,
 		&cmd_struct_inspect_subvolid_resolve,
+		&cmd_struct_inspect_map_logical,
 		&cmd_struct_inspect_rootid,
 		&cmd_struct_inspect_min_dev_size,
 		&cmd_struct_inspect_dump_tree,
-- 
2.36.1


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

* Re: [PATCH] btrfs-progs: introduce inspect-internal map-logical command
  2022-05-20  7:23 [PATCH] btrfs-progs: introduce inspect-internal map-logical command Qu Wenruo
@ 2022-05-20  8:44 ` Johannes Thumshirn
  2022-05-20 18:12 ` David Sterba
  1 sibling, 0 replies; 4+ messages in thread
From: Johannes Thumshirn @ 2022-05-20  8:44 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs

On 20/05/2022 09:24, Qu Wenruo wrote:
[..]
>  
> +
Nit: stray newline

>  static const char * const cmd_inspect_logical_resolve_usage[] = {
>  	"btrfs inspect-internal logical-resolve [-Pvo] [-s bufsize] <logical> <path>",
>  	"Get file system paths for the given logical address",
> @@ -348,6 +350,81 @@ out:
>  }

Otherwise looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

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

* Re: [PATCH] btrfs-progs: introduce inspect-internal map-logical command
  2022-05-20  7:23 [PATCH] btrfs-progs: introduce inspect-internal map-logical command Qu Wenruo
  2022-05-20  8:44 ` Johannes Thumshirn
@ 2022-05-20 18:12 ` David Sterba
  2022-05-21  1:13   ` Qu Wenruo
  1 sibling, 1 reply; 4+ messages in thread
From: David Sterba @ 2022-05-20 18:12 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs

On Fri, May 20, 2022 at 03:23:26PM +0800, Qu Wenruo wrote:
> This is a simpler version compared to btrfs-map-logical.
> 
> The differences are:
> 
> - No extent check
>   Thus any bytenr which has chunk mapping can be mapped.
> 
> - No length specification
>   Now it's fixed to sectorsize.
>   Previously we use nodesize in btrfs-map-logical, which would only
>   make the output more complex due as it may cross stripe boundary
>   for data extent.
> 
>   Considering the main users of this functionality is data corruption,
>   thus we really just want to resolve a single sector.
> 
> - No data write support nor mirror specification
>   We always output all mirrors and call it a day.
> 
> - Ignore RAID56 parity manually
> 
> We still keep the old btrfs-map-logical, just in case there are some
> usage of certain parameters.
> 
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>  Documentation/btrfs-inspect-internal.rst |  7 +++
>  cmds/inspect.c                           | 78 ++++++++++++++++++++++++
>  2 files changed, 85 insertions(+)
> 
> diff --git a/Documentation/btrfs-inspect-internal.rst b/Documentation/btrfs-inspect-internal.rst
> index 710a34fb0cb9..8a9264d3dc5b 100644
> --- a/Documentation/btrfs-inspect-internal.rst
> +++ b/Documentation/btrfs-inspect-internal.rst
> @@ -169,6 +169,13 @@ logical-resolve [-Pvo] [-s <bufsize>] <logical> <path>
>          -v
>                  (deprecated) alias for global *-v* option
>  
> +map-logical <logical> <device>
> +        map the sector at given *logical* address in the linear filesystem space into
> +        physical address.
> +
> +        .. note::
> +                For RAID56, this will only map the data stripe.
> +
>  min-dev-size [options] <path>
>          (needs root privileges)
>  
> diff --git a/cmds/inspect.c b/cmds/inspect.c
> index 1534f2040f4e..271adf8c6fd4 100644
> --- a/cmds/inspect.c
> +++ b/cmds/inspect.c
> @@ -29,6 +29,7 @@
>  #include "kernel-shared/ctree.h"
>  #include "common/send-utils.h"
>  #include "kernel-shared/disk-io.h"
> +#include "kernel-shared/volumes.h"
>  #include "cmds/commands.h"
>  #include "common/help.h"
>  #include "common/open-utils.h"
> @@ -125,6 +126,7 @@ static int cmd_inspect_inode_resolve(const struct cmd_struct *cmd,
>  }
>  static DEFINE_SIMPLE_COMMAND(inspect_inode_resolve, "inode-resolve");
>  
> +
>  static const char * const cmd_inspect_logical_resolve_usage[] = {
>  	"btrfs inspect-internal logical-resolve [-Pvo] [-s bufsize] <logical> <path>",
>  	"Get file system paths for the given logical address",
> @@ -348,6 +350,81 @@ out:
>  }
>  static DEFINE_SIMPLE_COMMAND(inspect_subvolid_resolve, "subvolid-resolve");
>  
> +static const char * const cmd_inspect_map_logical_usage[] = {
> +	"btrfs inspect-internal map-logical <logical> <device>",
> +	"Get the physical offset of a sector.",
> +	NULL
> +};
> +
> +static int print_mapping_info(struct btrfs_fs_info *fs_info, u64 logical)
> +{
> +	struct cache_extent *ce;
> +	struct map_lookup *map;
> +	int num_copies;
> +	int cur_mirror;
> +	int ret;
> +
> +	ce = search_cache_extent(&fs_info->mapping_tree.cache_tree, logical);
> +	if (!ce) {
> +		error("no chunk mapping found for logical %llu", logical);
> +		return -ENOENT;
> +	}
> +	map = container_of(ce, struct map_lookup, ce);
> +	/* For RAID56, we only return the data stripe. */
> +	if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
> +		num_copies = 1;
> +	else
> +		num_copies = btrfs_num_copies(fs_info, logical,
> +					      fs_info->sectorsize);
> +
> +	for (cur_mirror = 1; cur_mirror <= num_copies; cur_mirror++) {
> +		struct btrfs_multi_bio *multi = NULL;
> +		u64 len = fs_info->sectorsize;
> +
> +		ret = btrfs_map_block(fs_info, READ, logical, &len, &multi,
> +				      cur_mirror, NULL);
> +		if (ret < 0) {
> +			errno = -ret;
> +			error("failed to map logical %llu: %m", logical);
> +			return ret;
> +		}
> +		/* We're using READ, which should only return one mirror. */
> +		ASSERT(multi && multi->num_stripes == 1);
> +		printf("mirror %d logical %llu phyiscal %llu device %s\n",
> +			cur_mirror, logical, multi->stripes[0].physical,
> +			multi->stripes[0].dev->name);
> +		free(multi);
> +	}
> +	return 0;
> +}
> +
> +static int cmd_inspect_map_logical(const struct cmd_struct *cmd, int argc,
> +				   char **argv)
> +{
> +	struct open_ctree_flags ocf = {0};
> +	struct btrfs_fs_info *fs_info;
> +	u64 logical;
> +	int ret;
> +
> +	clean_args_no_options(cmd, argc, argv);
> +
> +	if (check_argc_exact(argc - optind, 2))
> +		return 1;
> +
> +	ocf.filename = argv[optind + 1];
> +	ocf.flags = OPEN_CTREE_CHUNK_ROOT_ONLY;
> +	logical = arg_strtou64(argv[optind]);
> +
> +	fs_info = open_ctree_fs_info(&ocf);

So this is for images, not for mounted filesystem. The inspect-internal
group has both but for the map-logical we could do both.

I'd expect the primary use to be for the mounted fs.  The question is
what for am I supposed to use map-logical for? See where a file is
located, ok, that I'd like to see on a mounted filesystem. Running that
on the block device while still mounted is unreliable.

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

* Re: [PATCH] btrfs-progs: introduce inspect-internal map-logical command
  2022-05-20 18:12 ` David Sterba
@ 2022-05-21  1:13   ` Qu Wenruo
  0 siblings, 0 replies; 4+ messages in thread
From: Qu Wenruo @ 2022-05-21  1:13 UTC (permalink / raw)
  To: dsterba, Qu Wenruo, linux-btrfs



On 2022/5/21 02:12, David Sterba wrote:
> On Fri, May 20, 2022 at 03:23:26PM +0800, Qu Wenruo wrote:
>> This is a simpler version compared to btrfs-map-logical.
>>
>> The differences are:
>>
>> - No extent check
>>    Thus any bytenr which has chunk mapping can be mapped.
>>
>> - No length specification
>>    Now it's fixed to sectorsize.
>>    Previously we use nodesize in btrfs-map-logical, which would only
>>    make the output more complex due as it may cross stripe boundary
>>    for data extent.
>>
>>    Considering the main users of this functionality is data corruption,
>>    thus we really just want to resolve a single sector.
>>
>> - No data write support nor mirror specification
>>    We always output all mirrors and call it a day.
>>
>> - Ignore RAID56 parity manually
>>
>> We still keep the old btrfs-map-logical, just in case there are some
>> usage of certain parameters.
>>
>> Signed-off-by: Qu Wenruo <wqu@suse.com>
>> ---
>>   Documentation/btrfs-inspect-internal.rst |  7 +++
>>   cmds/inspect.c                           | 78 ++++++++++++++++++++++++
>>   2 files changed, 85 insertions(+)
>>
>> diff --git a/Documentation/btrfs-inspect-internal.rst b/Documentation/btrfs-inspect-internal.rst
>> index 710a34fb0cb9..8a9264d3dc5b 100644
>> --- a/Documentation/btrfs-inspect-internal.rst
>> +++ b/Documentation/btrfs-inspect-internal.rst
>> @@ -169,6 +169,13 @@ logical-resolve [-Pvo] [-s <bufsize>] <logical> <path>
>>           -v
>>                   (deprecated) alias for global *-v* option
>>
>> +map-logical <logical> <device>
>> +        map the sector at given *logical* address in the linear filesystem space into
>> +        physical address.
>> +
>> +        .. note::
>> +                For RAID56, this will only map the data stripe.
>> +
>>   min-dev-size [options] <path>
>>           (needs root privileges)
>>
>> diff --git a/cmds/inspect.c b/cmds/inspect.c
>> index 1534f2040f4e..271adf8c6fd4 100644
>> --- a/cmds/inspect.c
>> +++ b/cmds/inspect.c
>> @@ -29,6 +29,7 @@
>>   #include "kernel-shared/ctree.h"
>>   #include "common/send-utils.h"
>>   #include "kernel-shared/disk-io.h"
>> +#include "kernel-shared/volumes.h"
>>   #include "cmds/commands.h"
>>   #include "common/help.h"
>>   #include "common/open-utils.h"
>> @@ -125,6 +126,7 @@ static int cmd_inspect_inode_resolve(const struct cmd_struct *cmd,
>>   }
>>   static DEFINE_SIMPLE_COMMAND(inspect_inode_resolve, "inode-resolve");
>>
>> +
>>   static const char * const cmd_inspect_logical_resolve_usage[] = {
>>   	"btrfs inspect-internal logical-resolve [-Pvo] [-s bufsize] <logical> <path>",
>>   	"Get file system paths for the given logical address",
>> @@ -348,6 +350,81 @@ out:
>>   }
>>   static DEFINE_SIMPLE_COMMAND(inspect_subvolid_resolve, "subvolid-resolve");
>>
>> +static const char * const cmd_inspect_map_logical_usage[] = {
>> +	"btrfs inspect-internal map-logical <logical> <device>",
>> +	"Get the physical offset of a sector.",
>> +	NULL
>> +};
>> +
>> +static int print_mapping_info(struct btrfs_fs_info *fs_info, u64 logical)
>> +{
>> +	struct cache_extent *ce;
>> +	struct map_lookup *map;
>> +	int num_copies;
>> +	int cur_mirror;
>> +	int ret;
>> +
>> +	ce = search_cache_extent(&fs_info->mapping_tree.cache_tree, logical);
>> +	if (!ce) {
>> +		error("no chunk mapping found for logical %llu", logical);
>> +		return -ENOENT;
>> +	}
>> +	map = container_of(ce, struct map_lookup, ce);
>> +	/* For RAID56, we only return the data stripe. */
>> +	if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
>> +		num_copies = 1;
>> +	else
>> +		num_copies = btrfs_num_copies(fs_info, logical,
>> +					      fs_info->sectorsize);
>> +
>> +	for (cur_mirror = 1; cur_mirror <= num_copies; cur_mirror++) {
>> +		struct btrfs_multi_bio *multi = NULL;
>> +		u64 len = fs_info->sectorsize;
>> +
>> +		ret = btrfs_map_block(fs_info, READ, logical, &len, &multi,
>> +				      cur_mirror, NULL);
>> +		if (ret < 0) {
>> +			errno = -ret;
>> +			error("failed to map logical %llu: %m", logical);
>> +			return ret;
>> +		}
>> +		/* We're using READ, which should only return one mirror. */
>> +		ASSERT(multi && multi->num_stripes == 1);
>> +		printf("mirror %d logical %llu phyiscal %llu device %s\n",
>> +			cur_mirror, logical, multi->stripes[0].physical,
>> +			multi->stripes[0].dev->name);
>> +		free(multi);
>> +	}
>> +	return 0;
>> +}
>> +
>> +static int cmd_inspect_map_logical(const struct cmd_struct *cmd, int argc,
>> +				   char **argv)
>> +{
>> +	struct open_ctree_flags ocf = {0};
>> +	struct btrfs_fs_info *fs_info;
>> +	u64 logical;
>> +	int ret;
>> +
>> +	clean_args_no_options(cmd, argc, argv);
>> +
>> +	if (check_argc_exact(argc - optind, 2))
>> +		return 1;
>> +
>> +	ocf.filename = argv[optind + 1];
>> +	ocf.flags = OPEN_CTREE_CHUNK_ROOT_ONLY;
>> +	logical = arg_strtou64(argv[optind]);
>> +
>> +	fs_info = open_ctree_fs_info(&ocf);
>
> So this is for images, not for mounted filesystem. The inspect-internal
> group has both but for the map-logical we could do both.

I'm afraid the map-logical tool will have the same requirement for
dump-tree, the preferred method is to run on unmounted device/image.

Running on mounted device is possible, but not recommended.

>
> I'd expect the primary use to be for the mounted fs.  The question is
> what for am I supposed to use map-logical for?

Mostly for fstests, to corrupt extents.

Thus we're completely capable to run it unmounted.

Thanks,
Qu

> See where a file is
> located, ok, that I'd like to see on a mounted filesystem. Running that
> on the block device while still mounted is unreliable.

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

end of thread, other threads:[~2022-05-21  1:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-20  7:23 [PATCH] btrfs-progs: introduce inspect-internal map-logical command Qu Wenruo
2022-05-20  8:44 ` Johannes Thumshirn
2022-05-20 18:12 ` David Sterba
2022-05-21  1:13   ` Qu Wenruo

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.