Message ID | a5545edbef2d2b1800a5ea83d9c14773b5b1fbe7.1532501096.git.misono.tomohiro@jp.fujitsu.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs-progs: ins: Update for logical-resolve command | expand |
On Wed, Jul 25, 2018 at 05:20:17PM +0900, Misono Tomohiro wrote: > Since BTRFS_IOC_INO_PATHS requires fd of subvolume, Does it? AFAICS btrfs_ioctl_ino_to_path gets root that's the containing subvolume of the path given by the user. > logical-resolve > cannot find the path when mount point is not FS_TREE > (because the subvolume path cannot be opened). Sorry, I don't understand what's the problem here. What you write sounds like there's a reproducer. If yes, please post it. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 2018/08/04 0:06, David Sterba wrote: > On Wed, Jul 25, 2018 at 05:20:17PM +0900, Misono Tomohiro wrote: >> Since BTRFS_IOC_INO_PATHS requires fd of subvolume, > > Does it? AFAICS btrfs_ioctl_ino_to_path gets root that's the containing > subvolume of the path given by the user. It is reverse; it returns all paths of given inode number in given subvolume fd. > >> logical-resolve >> cannot find the path when mount point is not FS_TREE >> (because the subvolume path cannot be opened). > > Sorry, I don't understand what's the problem here. What you write sounds > like there's a reproducer. If yes, please post it. Sure. If mountpoint is FS_TREE, everything is ok: $ mkfs.btrfs -fq $DEV $ mount $DEV /mnt // create snapshot and hardlink $ btrfs sub create /mnt/sub $ dd if=/dev/urandom of=/mnt/sub/file bs=1k count=1000 $ btrfs sub snap /mnt/sub /mnt/snap $ ln /mnt/sub/file /mnt/sub/file2 $ tree --inodes /mnt /mnt |-- [ 256] snap | `-- [ 257] file `-- [ 256] sub |-- [ 257] file `-- [ 257] file2 inode-resolve returns all paths of given inode number in given subvolume: (it calls IOC_INO_PATHS) $ btrfs ins inode-resolve 257 /mnt/sub /mnt/sub/file /mnt/sub/file2 $ btrfs ins inode-resolve 257 /mnt/snap /mnt/snap/file logical-resolve returns all paths containing given logical address in fs: (it calls IOC_INO_PATHS after IOC_LOGICAL_INO) $ filefrag -v /mnt/sub/file Filesystem type is: 9123683e File size of /mnt/sub/file is 1024000 (250 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 249: 3392.. 3641: 250: last,shared,eof /mnt/sub/file: 1 extent found $ btrfs ins logical-resolve $((3392*4096)) /mnt /mnt/snap/file /mnt/sub/file /mnt/sub/file2 However, when mountpoint is not FS_TREE, above logical-resolve fails: $ umount /mnt $ mount -o subvol=sub $DEV /mnt $ btrfs ins logical-resolve $((3392*4096)) /mnt ERROR: cannot access '/mnt/snap': No such file or directory The reasons are (1) btrfs_list_path_for_root() returns paths from FS_TREE (2) subvolume path cannot be opened and therefore cannot call IOC_INO_PATHS (1) may be fixed for mounted subvolume, but if a subvolume is not accessible at all, there is no way to call IOC_INO_PATHS. To solve this, we need to pass arbitrary treeid just like INO_LOOKUP ioctl. Thanks, Misono -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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; }
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(-)