* [PATCH 2/3] btrfs-progs: ins: logical-resolve: Print message when path cannot be resolved
2018-07-25 8:20 [PATCH 0/3] btrfs-progs: ins: Update for logical-resolve command Misono Tomohiro
2018-07-25 8:20 ` [PATCH 1/3] btrfs-progs: ins: logical-resolve: Set correct error value Misono Tomohiro
@ 2018-07-25 8:20 ` Misono Tomohiro
2018-08-03 15:06 ` David Sterba
2018-07-25 8:20 ` [PATCH v2 3/3] btrfs-progs: ins: logical-resolve: Add v2 ioctl support Misono Tomohiro
2 siblings, 1 reply; 7+ messages in thread
From: Misono Tomohiro @ 2018-07-25 8:20 UTC (permalink / raw)
To: linux-btrfs
Since BTRFS_IOC_INO_PATHS requires fd of subvolume, logical-resolve
cannot find the path when mount point is not FS_TREE
(because the subvolume path cannot be opened).
In that case, print message to try -P option instead.
Signed-off-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
---
cmds-inspect.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/cmds-inspect.c b/cmds-inspect.c
index ac77a5ee..21aa2903 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -137,16 +137,18 @@ static const char * const cmd_inspect_logical_resolve_usage[] = {
static int cmd_inspect_logical_resolve(int argc, char **argv)
{
int ret;
- int fd;
+ int fd = -1;
int i;
int verbose = 0;
int getpath = 1;
int bytes_left;
+ u64 rootid;
struct btrfs_ioctl_logical_ino_args loi;
struct btrfs_data_container *inodes;
u64 size = 4096;
char full_path[PATH_MAX];
char *path_ptr;
+ char *mount_path = NULL;
DIR *dirstream = NULL;
optind = 0;
@@ -178,6 +180,35 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
if (!inodes)
return 1;
+ /* Check if mount root is FS_ROOT */
+ if (getpath) {
+ ret = find_mount_root(argv[optind + 1], &mount_path);
+ if (ret) {
+ error("cannot find mount root: %m");
+ goto out;
+ }
+
+ fd = btrfs_open_file_or_dir(mount_path, &dirstream, 1);
+ if (fd < 0) {
+ ret = 1;
+ goto out;
+ }
+
+ ret = lookup_path_rootid(fd, &rootid);
+ if (ret) {
+ error("failed to lookup root id: %m");
+ goto out;
+ }
+
+ if (rootid != BTRFS_FS_TREE_OBJECTID) {
+ ret = 1;
+printf("cannot resolve path when subvolume is mounted directly. try -P option\n");
+ goto out;
+ }
+
+ close_file_or_dir(fd, dirstream);
+ }
+
memset(inodes, 0, sizeof(*inodes));
loi.logical = arg_strtou64(argv[optind]);
loi.size = size;
@@ -259,6 +290,7 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
out:
close_file_or_dir(fd, dirstream);
free(inodes);
+ free(mount_path);
return !!ret;
}
--
2.14.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] btrfs-progs: ins: logical-resolve: Add v2 ioctl support
2018-07-25 8:20 [PATCH 0/3] btrfs-progs: ins: Update for logical-resolve command Misono Tomohiro
2018-07-25 8:20 ` [PATCH 1/3] btrfs-progs: ins: logical-resolve: Set correct error value Misono Tomohiro
2018-07-25 8:20 ` [PATCH 2/3] btrfs-progs: ins: logical-resolve: Print message when path cannot be resolved Misono Tomohiro
@ 2018-07-25 8:20 ` Misono Tomohiro
2 siblings, 0 replies; 7+ messages in thread
From: Misono Tomohiro @ 2018-07-25 8:20 UTC (permalink / raw)
To: linux-btrfs
Add --ignore-offset option to logical-resolve command
to show how BTRFS_IOC_LOGICAL_INO_V2 ioctl works
(return every ref to the extent of given logical address).
Documentation is also updated to make meaning more clear.
See below example for more detailed explanation.
[Example]
$ mkfs.btrfs -f $DEV
$ mount $DEV /mnt
$ dd if=/dev/urandom of=/mnt/file bs=4k count=100
$ sync
// split above extent
$ dd if=/dev/urandom of=/mnt/file bs=4k seek=10 count=1 conv=notrunc
$ sync
$ filefrag -v /mnt/file
Filesystem type is: 9123683e
File size of /mnt/file is 409600 (100 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 9: 3392.. 3401: 10:
1: 10.. 10: 3328.. 3328: 1: 3402:
2: 11.. 99: 3403.. 3491: 89: 3329: last,eof
/mnt/file: 3 extents found
// Actually extent 0 and 2 point to the same extent (with different offset):
$ btrfs inspect-internal dump-tree $DEV | \
grep -A 2 "$((3392*4096) EXTENT_ITEM"
item 2 key (13893632 EXTENT_ITEM 409600) itemoff 16153 itemsize 53
refs 2 gen 7 flags DATA
extent data backref root FS_TREE objectid 257 offset 0 count 2
$ btrfs inspect-internal dump-tree $DEV | \
grep -A 4 "257 EXTENT_ITEM"
item 7 key (257 EXTENT_DATA 0) itemoff 15733 itemsize 53
generation 7 type 1 (regular)
extent data disk byte 13893632 nr 409600
extent data offset 0 nr 40960 ram 409600
extent compression 0 (none)
item 8 key (257 EXTENT_DATA 40960) itemoff 15680 itemsize 53
generation 8 type 1 (regular)
extent data disk byte 13631488 nr 4096
extent data offset 0 nr 4096 ram 4096
extent compression 0 (none)
item 9 key (257 EXTENT_DATA 45056) itemoff 15627 itemsize 53
generation 7 type 1 (regular)
extent data disk byte 13893632 nr 409600
extent data offset 45056 nr 364544 ram 409600
extent compression 0 (none)
// v1 ioctl only returns the refs pointing given address block
$ btrfs inspect-internal logical-resolve -P $((3392*4096)) /mnt
inode 257 offset 0 root 5
$ btrfs inspect-internal logical-resolve -P $((3403*4096)) /mnt
inode 257 offset 45056 root 5
// v2 ioctl returns all refs pointing at least one block of given extent
$ btrfs inspect-internal logical-resolve -P --ignore-offset \
$((3392*4096)) /mnt
inode 257 offset 0 root 5
inode 257 offset 45056 root 5
Signed-off-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
---
v1 -> v2
- add explnation
- add build assert
- use long option istead of -i
Documentation/btrfs-inspect-internal.asciidoc | 15 +++++++++++---
cmds-inspect.c | 29 ++++++++++++++++++++++++---
ioctl.h | 11 +++++++++-
libbtrfsutil/btrfs.h | 10 ++++++++-
4 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/Documentation/btrfs-inspect-internal.asciidoc b/Documentation/btrfs-inspect-internal.asciidoc
index e2db6466..5f80323e 100644
--- a/Documentation/btrfs-inspect-internal.asciidoc
+++ b/Documentation/btrfs-inspect-internal.asciidoc
@@ -112,19 +112,28 @@ at 'path', ie. all hardlinks
-v::::
verbose mode, print count of returned paths and ioctl() return value
-*logical-resolve* [-Pv] [-s <bufsize>] <logical> <path>::
+*logical-resolve* [options] <logical> <path>::
(needs root privileges)
+
-resolve paths to all files at given 'logical' address in the linear filesystem space
+get all inode information whose extents containing the given 'logical'
+address blcok and then resolve each filesystem path
+
`Options`
+
-P::::
-skip the path resolving and print the inodes instead
+skip the path resolving and print the inode number, owner's subvolume id
+and offset in the extent
-v::::
verbose mode, print count of returned paths and all ioctl() return values
-s <bufsize>::::
set internal buffer for storing the file names to 'bufsize', default is 4096, maximum 64k
+--ignore-offset::::
+return all inode information which points to the extent
+containing the given logical address block regardless of offset.
+i.e. with this option, all files which includes at least one block of
+the extent will be shown, even if given logical address block is not
+included
+This requires version 2 ioctl support (BTRFS_IOC_LOGICAL_INO_V2, since 4.15)
*min-dev-size* [options] <path>::
(needs root privileges)
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 21aa2903..c261e773 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -124,13 +124,20 @@ static int cmd_inspect_inode_resolve(int argc, char **argv)
}
static const char * const cmd_inspect_logical_resolve_usage[] = {
- "btrfs inspect-internal logical-resolve [-Pv] [-s bufsize] <logical> <path>",
+ "btrfs inspect-internal logical-resolve [options] <logical> <path>",
"Get file system paths for the given logical address",
"-P skip the path resolving and print the inodes instead",
"-v verbose mode",
"-s bufsize set inode container's size. This is used to increase inode",
" container's size in case it is not enough to read all the ",
" resolved results. The max value one can set is 64k",
+ "--ignore-offset",
+ " return all inode information which points to the extent",
+ " containing the given logical address block regardless of",
+ " offset. i.e. with this option, all files which includes",
+ " at least one block of the extent will be shown, even if",
+ " given logical address block is not included",
+ " (requires version 2 ioctl support)",
NULL
};
@@ -143,7 +150,9 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
int getpath = 1;
int bytes_left;
u64 rootid;
+ int ignore_offset = 0;
struct btrfs_ioctl_logical_ino_args loi;
+ unsigned long ioctl_num = BTRFS_IOC_LOGICAL_INO;
struct btrfs_data_container *inodes;
u64 size = 4096;
char full_path[PATH_MAX];
@@ -153,7 +162,13 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
optind = 0;
while (1) {
- int c = getopt(argc, argv, "Pvs:");
+ int c;
+ static const struct option long_options[] = {
+ { "ignore-offset", no_argument, NULL, 'i' },
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long(argc, argv, "Pvs:", long_options, NULL);
if (c < 0)
break;
@@ -167,6 +182,9 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
case 's':
size = arg_strtou64(optarg);
break;
+ case 'i':
+ ignore_offset = 1;
+ break;
default:
usage(cmd_inspect_logical_resolve_usage);
}
@@ -214,13 +232,18 @@ printf("cannot resolve path when subvolume is mounted directly. try -P option\n"
loi.size = size;
loi.inodes = ptr_to_u64(inodes);
+ if (ignore_offset) {
+ loi.flags = BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET;
+ ioctl_num = BTRFS_IOC_LOGICAL_INO_V2;
+ }
+
fd = btrfs_open_dir(argv[optind + 1], &dirstream, 1);
if (fd < 0) {
ret = 12;
goto out;
}
- ret = ioctl(fd, BTRFS_IOC_LOGICAL_INO, &loi);
+ ret = ioctl(fd, ioctl_num, &loi);
if (ret < 0) {
error("logical ino ioctl: %m");
goto out;
diff --git a/ioctl.h b/ioctl.h
index 709e996f..2d6f5d1a 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -491,10 +491,17 @@ BUILD_ASSERT(sizeof(struct btrfs_ioctl_ino_path_args) == 56);
struct btrfs_ioctl_logical_ino_args {
__u64 logical; /* in */
__u64 size; /* in */
- __u64 reserved[4];
+ __u64 reserved[3]; /* must be 0 for now */
+ __u64 flags; /* in, v2 only */
/* struct btrfs_data_container *inodes; out */
__u64 inodes;
};
+BUILD_ASSERT(offsetof(struct btrfs_ioctl_logical_ino_args, flags) == 40);
+/*
+ * Return every ref to the extent, not just those containing logical block.
+ * Requires logical == extent bytenr.
+ */
+#define BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET (1ULL << 0)
enum btrfs_dev_stat_values {
/* disk I/O failure stats */
@@ -828,6 +835,8 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
struct btrfs_ioctl_feature_flags[3])
#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \
struct btrfs_ioctl_vol_args_v2)
+#define BTRFS_IOC_LOGICAL_INO_V2 _IOWR(BTRFS_IOCTL_MAGIC, 59, \
+ struct btrfs_ioctl_logical_ino_args)
#ifdef __cplusplus
}
#endif
diff --git a/libbtrfsutil/btrfs.h b/libbtrfsutil/btrfs.h
index c293f6bf..b4debba7 100644
--- a/libbtrfsutil/btrfs.h
+++ b/libbtrfsutil/btrfs.h
@@ -609,10 +609,16 @@ struct btrfs_ioctl_ino_path_args {
struct btrfs_ioctl_logical_ino_args {
__u64 logical; /* in */
__u64 size; /* in */
- __u64 reserved[4];
+ __u64 reserved[3]; /* must be 0 for now */
+ __u64 flags; /* in, v2 only */
/* struct btrfs_data_container *inodes; out */
__u64 inodes;
};
+/*
+ * Return every ref to the extent, not just those containing logical block.
+ * Requires logical == extent bytenr.
+ */
+#define BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET (1ULL << 0)
enum btrfs_dev_stat_values {
/* disk I/O failure stats */
@@ -836,5 +842,7 @@ enum btrfs_err_code {
struct btrfs_ioctl_feature_flags[3])
#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \
struct btrfs_ioctl_vol_args_v2)
+#define BTRFS_IOC_LOGICAL_INO_V2 _IOWR(BTRFS_IOCTL_MAGIC, 59, \
+ struct btrfs_ioctl_logical_ino_args)
#endif /* _LINUX_BTRFS_H */
--
2.14.4
^ permalink raw reply related [flat|nested] 7+ messages in thread