btrfs-progs: look up the containing tree root id

Find the tree id of the containing subvolume for a given file or
directory. For subvolume return it's own id.

$ btrfs inspect-internal rootid <path>

Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
master
David Sterba 2013-09-18 18:19:30 +02:00 committed by Chris Mason
parent 8e937074a4
commit 7fbcc39c30
4 changed files with 79 additions and 0 deletions

View File

@ -301,6 +301,43 @@ out:
return ret ? 1 : 0;
}
static const char* const cmd_rootid_usage[] = {
"btrfs inspect-internal rootid <path>",
"Get tree ID of the containing subvolume of path.",
NULL
};
static int cmd_rootid(int argc, char **argv)
{
int ret;
int fd = -1;
u64 rootid;
DIR *dirstream = NULL;
if (check_argc_exact(argc, 2))
usage(cmd_rootid_usage);
fd = open_file_or_dir(argv[1], &dirstream);
if (fd < 0) {
fprintf(stderr, "ERROR: can't access '%s'\n", argv[1]);
ret = -ENOENT;
goto out;
}
ret = lookup_ino_rootid(fd, &rootid);
if (ret) {
fprintf(stderr, "%s: rootid failed with ret=%d\n",
argv[0], ret);
goto out;
}
printf("%llu\n", (unsigned long long)rootid);
out:
close_file_or_dir(fd, dirstream);
return !!ret;
}
const struct cmd_group inspect_cmd_group = {
inspect_cmd_group_usage, NULL, {
{ "inode-resolve", cmd_inode_resolve, cmd_inode_resolve_usage,
@ -309,6 +346,7 @@ const struct cmd_group inspect_cmd_group = {
cmd_logical_resolve_usage, NULL, 0 },
{ "subvolid-resolve", cmd_subvolid_resolve,
cmd_subvolid_resolve_usage, NULL, 0 },
{ "rootid", cmd_rootid, cmd_rootid_usage, NULL, 0 },
NULL_CMD_STRUCT
}
};

View File

@ -80,6 +80,8 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBinspect-internal subvolid-resolve\fP \fI<subvolid>\fP \fI<path>\fP
.PP
\fBbtrfs\fP \fBinspect-internal rootid\fP \fI<path>\fP
.PP
.PP
\fBbtrfs\fP \fBsend\fP [-v] [-p \fI<parent>\fP] [-c \fI<clone-src>\fP] [-f \fI<outfile>\fP] \fI<subvol>\fP
.PP
@ -577,6 +579,13 @@ not enough to read all the resolved results. The max value one can set is 64k.
Get file system paths for the given subvolume ID.
.TP
\fBinspect-internal rootid\fP \fI<path>\fP
For a given file or directory, return the containing tree root id. For a
subvolume return it's own tree id.
The result is undefined for the so-called empty subvolumes (identified by inode number 2).
.TP
\fBsend\fP [-v] [-p \fI<parent>\fP] [-c \fI<clone-src>\fP] [-f \fI<outfile>\fP] \fI<subvol>\fP
Send the subvolume to stdout.
Sends the subvolume specified by \fI<subvol>\fR to stdout.

30
utils.c
View File

@ -1975,3 +1975,33 @@ int ask_user(char *question)
(answer = strtok_r(buf, " \t\n\r", &saveptr)) &&
(!strcasecmp(answer, "yes") || !strcasecmp(answer, "y"));
}
/*
* For a given:
* - file or directory return the containing tree root id
* - subvolume return it's own tree id
* - BTRFS_EMPTY_SUBVOL_DIR_OBJECTID (directory with ino == 2) the result is
* undefined and function returns -1
*/
int lookup_ino_rootid(int fd, u64 *rootid)
{
struct btrfs_ioctl_ino_lookup_args args;
int ret;
int e;
memset(&args, 0, sizeof(args));
args.treeid = 0;
args.objectid = BTRFS_FIRST_FREE_OBJECTID;
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
e = errno;
if (ret) {
fprintf(stderr, "ERROR: Failed to lookup root id - %s\n",
strerror(e));
return ret;
}
*rootid = args.treeid;
return 0;
}

View File

@ -81,4 +81,6 @@ int is_vol_small(char *file);
int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
int verify);
int ask_user(char *question);
int lookup_ino_rootid(int fd, u64 *rootid);
#endif