+ DIR *dirstream = NULL;
+ enum btrfs_util_error err;
+
+ clean_args_no_options(argc, argv, cmd_subvol_find_new_usage);
+
+ if (check_argc_exact(argc - optind, 2))
+ usage(cmd_subvol_find_new_usage);
+
+ subvol = argv[optind];
+ last_gen = arg_strtou64(argv[optind + 1]);
+
+ err = btrfs_util_is_subvolume(subvol);
+ if (err) {
+ error_btrfs_util(err);
+ return 1;
+ }
+
+ fd = btrfs_open_dir(subvol, &dirstream, 1);
+ if (fd < 0)
+ return 1;
+
+ err = btrfs_util_sync_fd(fd);
+ if (err) {
+ error_btrfs_util(err);
+ close_file_or_dir(fd, dirstream);
+ return 1;
+ }
+
+ ret = btrfs_list_find_updated_files(fd, 0, last_gen);
+ close_file_or_dir(fd, dirstream);
+ return !!ret;
+}
+
+static const char * const cmd_subvol_show_usage[] = {
+ "btrfs subvolume show [options] <subvol-path>|<mnt>",
+ "Show more information about the subvolume",
+ "-r|--rootid rootid of the subvolume",
+ "-u|--uuid uuid of the subvolume",
+ "",
+ "If no option is specified, <subvol-path> will be shown, otherwise",
+ "the rootid or uuid are resolved relative to the <mnt> path.",
+ NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+ char tstr[256];
+ char uuidparse[BTRFS_UUID_UNPARSED_SIZE];
+ char *fullpath = NULL;
+ int fd = -1;
+ int ret = 1;
+ DIR *dirstream1 = NULL;
+ int by_rootid = 0;
+ int by_uuid = 0;
+ u64 rootid_arg = 0;
+ u8 uuid_arg[BTRFS_UUID_SIZE];
+ struct btrfs_util_subvolume_iterator *iter;
+ struct btrfs_util_subvolume_info subvol;
+ char *subvol_path = NULL;
+ enum btrfs_util_error err;
+
+ while (1) {
+ int c;
+ static const struct option long_options[] = {
+ { "rootid", required_argument, NULL, 'r'},
+ { "uuid", required_argument, NULL, 'u'},
+ { NULL, 0, NULL, 0 }
+ };
+
+ c = getopt_long(argc, argv, "r:u:", long_options, NULL);
+ if (c < 0)
+ break;
+
+ switch (c) {
+ case 'r':
+ rootid_arg = arg_strtou64(optarg);
+ by_rootid = 1;
+ break;
+ case 'u':
+ uuid_parse(optarg, uuid_arg);
+ by_uuid = 1;
+ break;
+ default:
+ usage(cmd_subvol_show_usage);
+ }
+ }
+
+ if (check_argc_exact(argc - optind, 1))
+ usage(cmd_subvol_show_usage);
+
+ if (by_rootid && by_uuid) {
+ error(
+ "options --rootid and --uuid cannot be used at the same time");
+ usage(cmd_subvol_show_usage);
+ }
+
+ fullpath = realpath(argv[optind], NULL);
+ if (!fullpath) {
+ error("cannot find real path for '%s': %m", argv[optind]);
+ goto out;
+ }
+
+ fd = open_file_or_dir(fullpath, &dirstream1);
+ if (fd < 0) {
+ error("can't access '%s'", fullpath);
+ goto out;
+ }
+
+ if (by_uuid) {
+ err = btrfs_util_create_subvolume_iterator_fd(fd,
+ BTRFS_FS_TREE_OBJECTID,
+ 0, &iter);
+ if (err) {
+ error_btrfs_util(err);
+ goto out;
+ }
+
+ for (;;) {
+ err = btrfs_util_subvolume_iterator_next_info(iter,
+ &subvol_path,
+ &subvol);
+ if (err == BTRFS_UTIL_ERROR_STOP_ITERATION) {
+ uuid_unparse(uuid_arg, uuidparse);
+ error("can't find uuid '%s' on '%s'", uuidparse,
+ fullpath);
+ btrfs_util_destroy_subvolume_iterator(iter);
+ goto out;
+ } else if (err) {
+ error_btrfs_util(err);
+ btrfs_util_destroy_subvolume_iterator(iter);
+ goto out;
+ }
+
+ if (uuid_compare(subvol.uuid, uuid_arg) == 0)
+ break;
+
+ free(subvol_path);
+ }
+ btrfs_util_destroy_subvolume_iterator(iter);
+ } else {
+ /*
+ * If !by_rootid, rootid_arg = 0, which means find the
+ * subvolume ID of the fd and use that.
+ */
+ err = btrfs_util_subvolume_info_fd(fd, rootid_arg, &subvol);
+ if (err) {
+ error_btrfs_util(err);
+ goto out;
+ }
+
+ err = btrfs_util_subvolume_path_fd(fd, subvol.id, &subvol_path);
+ if (err) {
+ error_btrfs_util(err);
+ goto out;
+ }