Add -i (ignore offset) option to logical-resolve command
to show how BTRFS_IOC_LOGICAL_INO_V2 ioctl works
(returns every ref to the extent of given logical address).
[Example]
$ mkfs.btrfs -f $DEV
$ mount $DEV /mnt
$ dd if=/dev/urandom of=/mnt/file bs=4k count=100
# split above extent
$ dd if=/dev/urandom of=/mnt/file bs=4k seek=10 count=1 conv=notrunc
$ btrfs filesystem sync
# v1
$ btrfs inspect-internal logical-resolve -P 13631488 /mnt
inode 257 offset 0 root 5
# v2
$ btrfs inspect-internal logical-resolve -iP 13631488 /mnt
inode 257 offset 0 root 5
inode 257 offset 45056 root 5
Signed-off-by: Misono Tomohiro <misono.tomohiro@xxxxxxxxxxxxxx>
---
Documentation/btrfs-inspect-internal.asciidoc | 4 ++++
cmds-inspect.c | 17 +++++++++++++++--
ioctl.h | 10 +++++++++-
libbtrfsutil/btrfs.h | 10 +++++++++-
4 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/Documentation/btrfs-inspect-internal.asciidoc b/Documentation/btrfs-inspect-internal.asciidoc
index e2db6466..a55c9add 100644
--- a/Documentation/btrfs-inspect-internal.asciidoc
+++ b/Documentation/btrfs-inspect-internal.asciidoc
@@ -125,6 +125,10 @@ skip the path resolving and print the inodes instead
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
+-i::::
+ignore offset and return all the ref information
+which points to the extent containing given logical address.
+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 2fc50c1a..d47eeacb 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -131,6 +131,9 @@ static const char * const cmd_inspect_logical_resolve_usage[] = {
"-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",
+ "-i ignore offset and return all the ref information",
+ " which points to the extent containing given logical address",
+ " (requires version 2 ioctl support)",
NULL
};
@@ -142,7 +145,9 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
int verbose = 0;
int getpath = 1;
int bytes_left;
+ 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];
@@ -151,7 +156,7 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
optind = 0;
while (1) {
- int c = getopt(argc, argv, "Pvs:");
+ int c = getopt(argc, argv, "Pvs:i");
if (c < 0)
break;
@@ -165,6 +170,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);
}
@@ -183,13 +191,18 @@ static int cmd_inspect_logical_resolve(int argc, char **argv)
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..74f30c20 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -491,10 +491,16 @@ 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;
};
+/*
+ * 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 +834,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
--
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