btrfs-progs: convert: Fix a bug which fails to insert hole file extent
[platform/upstream/btrfs-progs.git] / cmds-subvolume.c
index 32caaa5..e3d2cbc 100644 (file)
@@ -224,33 +224,6 @@ out:
        return retval;
 }
 
-/*
- * Test if path is a subvolume
- * Returns:
- *   0 - path exists but it is not a subvolume
- *   1 - path exists and it is  a subvolume
- * < 0 - error
- */
-int test_issubvolume(const char *path)
-{
-       struct stat     st;
-       struct statfs stfs;
-       int             res;
-
-       res = stat(path, &st);
-       if (res < 0)
-               return -errno;
-
-       if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode))
-               return 0;
-
-       res = statfs(path, &stfs);
-       if (res < 0)
-               return -errno;
-
-       return (int)stfs.f_type == BTRFS_SUPER_MAGIC;
-}
-
 static int wait_for_commit(int fd)
 {
        int ret;
@@ -790,7 +763,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 
        clean_args_no_options(argc, argv, cmd_subvol_get_default_usage);
 
-       if (check_argc_exact(argc - optind, 2))
+       if (check_argc_exact(argc - optind, 1))
                usage(cmd_subvol_get_default_usage);
 
        subvol = argv[1];
@@ -935,21 +908,21 @@ static const char * const cmd_subvol_show_usage[] = {
 static int cmd_subvol_show(int argc, char **argv)
 {
        struct root_info get_ri;
-       struct btrfs_list_filter_set *filter_set;
+       struct btrfs_list_filter_set *filter_set = NULL;
        char tstr[256];
        char uuidparse[BTRFS_UUID_UNPARSED_SIZE];
-       char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
+       char *fullpath = NULL;
        char raw_prefix[] = "\t\t\t\t";
-       u64 sv_id;
-       int fd = -1, mntfd = -1;
+       int fd = -1;
        int ret = 1;
-       DIR *dirstream1 = NULL, *dirstream2 = NULL;
+       DIR *dirstream1 = NULL;
 
        clean_args_no_options(argc, argv, cmd_subvol_show_usage);
 
        if (check_argc_exact(argc - optind, 1))
                usage(cmd_subvol_show_usage);
 
+       memset(&get_ri, 0, sizeof(get_ri));
        fullpath = realpath(argv[optind], NULL);
        if (!fullpath) {
                error("cannot find real path for '%s': %s",
@@ -957,57 +930,23 @@ static int cmd_subvol_show(int argc, char **argv)
                goto out;
        }
 
-       ret = test_issubvolume(fullpath);
-       if (ret < 0) {
-               error("cannot access subvolume %s: %s", fullpath,
-                       strerror(-ret));
-               goto out;
-       }
-       if (!ret) {
-               error("not a subvolume: %s", fullpath);
-               ret = 1;
-               goto out;
-       }
-
-       ret = find_mount_root(fullpath, &mnt);
-       if (ret < 0) {
-               error("find_mount_root failed on '%s': %s",
-                       fullpath, strerror(-ret));
-               goto out;
-       }
-       if (ret > 0) {
-               error("%s doesn't belong to btrfs mount point", fullpath);
-               goto out;
-       }
-       ret = 1;
-       svpath = get_subvol_name(mnt, fullpath);
-
-       fd = btrfs_open_dir(fullpath, &dirstream1, 1);
-       if (fd < 0)
-               goto out;
-
-       ret = btrfs_list_get_path_rootid(fd, &sv_id);
-       if (ret) {
-               error("can't get rootid for '%s'", fullpath);
-               goto out;
-       }
-
-       mntfd = btrfs_open_dir(mnt, &dirstream2, 1);
-       if (mntfd < 0)
-               goto out;
-
-       if (sv_id == BTRFS_FS_TREE_OBJECTID) {
+       ret = get_subvol_info(fullpath, &get_ri);
+       if (ret == 2) {
+               /*
+                * Since the top level btrfs was given don't
+                * take that as error
+                */
                printf("%s is toplevel subvolume\n", fullpath);
+               ret = 0;
                goto out;
        }
-
-       memset(&get_ri, 0, sizeof(get_ri));
-       get_ri.root_id = sv_id;
-
-       ret = btrfs_get_subvol(mntfd, &get_ri);
        if (ret) {
-               error("can't find '%s'", svpath);
-               goto out;
+               ret < 0 ?
+                       error("Failed to get subvol info %s: %s\n",
+                                                       fullpath, strerror(-ret)):
+                       error("Failed to get subvol info %s: %d\n",
+                                                       fullpath, ret);
+               return ret;
        }
 
        /* print the info */
@@ -1058,19 +997,23 @@ static int cmd_subvol_show(int argc, char **argv)
        btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
                                (u64)(unsigned long)get_ri.uuid);
        btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+       fd = open_file_or_dir(fullpath, &dirstream1);
+       if (fd < 0) {
+               fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+               goto out;
+       }
        btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
                        1, raw_prefix);
 
+out:
        /* clean up */
        free(get_ri.path);
        free(get_ri.name);
        free(get_ri.full_path);
        btrfs_list_free_filter_set(filter_set);
 
-out:
        close_file_or_dir(fd, dirstream1);
-       close_file_or_dir(mntfd, dirstream2);
-       free(mnt);
        free(fullpath);
        return !!ret;
 }
@@ -1199,7 +1142,8 @@ static int enumerate_dead_subvols(int fd, u64 **ids)
                        sh = (struct btrfs_ioctl_search_header*)(args.buf + off);
                        off += sizeof(*sh);
 
-                       if (sh->type == BTRFS_ORPHAN_ITEM_KEY) {
+                       if (btrfs_search_header_type(sh)
+                           == BTRFS_ORPHAN_ITEM_KEY) {
                                if (idx >= count) {
                                        u64 *newids;
 
@@ -1210,14 +1154,14 @@ static int enumerate_dead_subvols(int fd, u64 **ids)
                                                return -ENOMEM;
                                        *ids = newids;
                                }
-                               (*ids)[idx] = sh->offset;
+                               (*ids)[idx] = btrfs_search_header_offset(sh);
                                idx++;
                        }
-                       off += sh->len;
+                       off += btrfs_search_header_len(sh);
 
-                       sk->min_objectid = sh->objectid;
-                       sk->min_type = sh->type;
-                       sk->min_offset = sh->offset;
+                       sk->min_objectid = btrfs_search_header_objectid(sh);
+                       sk->min_type = btrfs_search_header_type(sh);
+                       sk->min_offset = btrfs_search_header_offset(sh);
                }
                if (sk->min_offset < (u64)-1)
                        sk->min_offset++;
@@ -1251,10 +1195,9 @@ static int cmd_subvol_sync(int argc, char **argv)
 
                switch (c) {
                case 's':
-                       sleep_interval = atoi(argv[optind]);
+                       sleep_interval = atoi(optarg);
                        if (sleep_interval < 1) {
-                               error("invalid sleep interval %s",
-                                       argv[optind]);
+                               error("invalid sleep interval %s", optarg);
                                ret = 1;
                                goto out;
                        }