return 0;
}
+
+static int __ino_to_path_fd(u64 inum, int fd, int verbose, const char *prepend)
+{
+ int ret;
+ int i;
+ struct btrfs_ioctl_ino_path_args ipa;
+ struct btrfs_data_container *fspath;
+
+ fspath = malloc(4096);
+ if (!fspath)
+ return 1;
+
+ ipa.inum = inum;
+ ipa.size = 4096;
+ ipa.fspath = (u64)fspath;
+
+ ret = ioctl(fd, BTRFS_IOC_INO_PATHS, &ipa);
+ if (ret) {
+ printf("ioctl ret=%d, error: %s\n", ret, strerror(errno));
+ goto out;
+ }
+
+ if (verbose)
+ printf("ioctl ret=%d, bytes_left=%lu, bytes_missing=%lu, "
+ "cnt=%d, missed=%d\n", ret,
+ (unsigned long)fspath->bytes_left,
+ (unsigned long)fspath->bytes_missing,
+ fspath->elem_cnt, fspath->elem_missed);
+
+ for (i = 0; i < fspath->elem_cnt; ++i) {
+ char **str = (char **)fspath->val;
+ str[i] += (unsigned long)fspath->val;
+ if (prepend)
+ printf("%s/%s\n", prepend, str[i]);
+ else
+ printf("%s\n", str[i]);
+ }
+
+out:
+ free(fspath);
+ return ret;
+}
+
+int do_ino_to_path(int nargs, char **argv)
+{
+ int fd;
+ int verbose = 0;
+
+ optind = 1;
+ while (1) {
+ int c = getopt(nargs, argv, "v");
+ if (c < 0)
+ break;
+ switch (c) {
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ fprintf(stderr, "invalid arguments for ipath\n");
+ return 1;
+ }
+ }
+ if (nargs - optind != 2) {
+ fprintf(stderr, "invalid arguments for ipath\n");
+ return 1;
+ }
+
+ fd = open_file_or_dir(argv[optind+1]);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: can't access '%s'\n", argv[optind+1]);
+ return 12;
+ }
+
+ return __ino_to_path_fd(atoll(argv[optind]), fd, verbose,
+ argv[optind+1]);
+}
+
+int do_logical_to_ino(int nargs, char **argv)
+{
+ int ret;
+ int fd;
+ int i;
+ int verbose = 0;
+ int getpath = 1;
+ int bytes_left;
+ struct btrfs_ioctl_logical_ino_args loi;
+ struct btrfs_data_container *inodes;
+ char full_path[4096];
+ char *path_ptr;
+
+ optind = 1;
+ while (1) {
+ int c = getopt(nargs, argv, "Pv");
+ if (c < 0)
+ break;
+ switch (c) {
+ case 'P':
+ getpath = 0;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ fprintf(stderr, "invalid arguments for ipath\n");
+ return 1;
+ }
+ }
+ if (nargs - optind != 2) {
+ fprintf(stderr, "invalid arguments for ipath\n");
+ return 1;
+ }
+
+ inodes = malloc(4096);
+ if (!inodes)
+ return 1;
+
+ loi.logical = atoll(argv[optind]);
+ loi.size = 4096;
+ loi.inodes = (u64)inodes;
+
+ fd = open_file_or_dir(argv[optind+1]);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: can't access '%s'\n", argv[optind+1]);
+ ret = 12;
+ goto out;
+ }
+
+ ret = ioctl(fd, BTRFS_IOC_LOGICAL_INO, &loi);
+ if (ret) {
+ printf("ioctl ret=%d, error: %s\n", ret, strerror(errno));
+ goto out;
+ }
+
+ if (verbose)
+ printf("ioctl ret=%d, bytes_left=%lu, bytes_missing=%lu, "
+ "cnt=%d, missed=%d\n", ret,
+ (unsigned long)inodes->bytes_left,
+ (unsigned long)inodes->bytes_missing,
+ inodes->elem_cnt, inodes->elem_missed);
+
+ bytes_left = sizeof(full_path);
+ ret = snprintf(full_path, bytes_left, "%s/", argv[optind+1]);
+ path_ptr = full_path + ret;
+ bytes_left -= ret + 1;
+ BUG_ON(bytes_left < 0);
+
+ for (i = 0; i < inodes->elem_cnt; i += 3) {
+ u64 inum = inodes->val[i];
+ u64 offset = inodes->val[i+1];
+ u64 root = inodes->val[i+2];
+ int path_fd;
+ char *name;
+
+ if (getpath) {
+ name = path_for_root(fd, root);
+ if (IS_ERR(name))
+ return PTR_ERR(name);
+ if (!name) {
+ path_ptr[-1] = '\0';
+ path_fd = fd;
+ } else {
+ path_ptr[-1] = '/';
+ ret = snprintf(path_ptr, bytes_left, "%s",
+ name);
+ BUG_ON(ret >= bytes_left);
+ free(name);
+ path_fd = open_file_or_dir(full_path);
+ if (path_fd < 0) {
+ fprintf(stderr, "ERROR: can't access "
+ "'%s'\n", full_path);
+ goto out;
+ }
+ }
+ __ino_to_path_fd(inum, path_fd, verbose, full_path);
+ } else {
+ printf("inode %llu offset %llu root %llu\n", inum,
+ offset, root);
+ }
+ }
+
+out:
+ free(inodes);
+ return ret;
+}
struct btrfs_ioctl_space_info spaces[0];
};
+struct btrfs_data_container {
+ __u32 bytes_left; /* out -- bytes not needed to deliver output */
+ __u32 bytes_missing; /* out -- additional bytes needed for result */
+ __u32 elem_cnt; /* out */
+ __u32 elem_missed; /* out */
+ __u64 val[0]; /* out */
+};
+
+struct btrfs_ioctl_ino_path_args {
+ __u64 inum; /* in */
+ __u64 size; /* in */
+ __u64 reserved[4];
+ /* struct btrfs_data_container *fspath; out */
+ __u64 fspath; /* out */
+};
+
+struct btrfs_ioctl_logical_ino_args {
+ __u64 logical; /* in */
+ __u64 size; /* in */
+ __u64 reserved[4];
+ /* struct btrfs_data_container *inodes; out */
+ __u64 inodes;
+};
+
/* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \
struct btrfs_ioctl_dev_info_args)
#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
- struct btrfs_ioctl_fs_info_args)
+ struct btrfs_ioctl_fs_info_args)
+#define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, \
+ struct btrfs_ioctl_ino_path_args)
+#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
+ struct btrfs_ioctl_ino_path_args)
+
#endif