btrfs-progs: add getopt stubs where needed
[platform/upstream/btrfs-progs.git] / cmds-subvolume.c
index 424b00b..02e1dec 100644 (file)
 #include <sys/ioctl.h>
 #include <errno.h>
 #include <sys/stat.h>
+#include <sys/vfs.h>
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
 #include <uuid/uuid.h>
+#include <linux/magic.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -158,6 +160,10 @@ static int cmd_subvol_create(int argc, char **argv)
 
        retval = 1;     /* failure */
        res = test_isdir(dst);
+       if (res < 0 && res != -ENOENT) {
+               error("cannot access %s: %s", dst, strerror(-res));
+               goto out;
+       }
        if (res >= 0) {
                error("target path already exists: %s", dst);
                goto out;
@@ -219,22 +225,30 @@ out:
 }
 
 /*
- * test if path is a subvolume:
- * this function return
- * 0-> path exists but it is not a subvolume
- * 1-> path exists and it is  a subvolume
- * -1 -> path is unaccessible
+ * 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(char *path)
+int test_issubvolume(const char *path)
 {
        struct stat     st;
+       struct statfs stfs;
        int             res;
 
        res = stat(path, &st);
-       if(res < 0 )
-               return -1;
+       if (res < 0)
+               return -errno;
+
+       if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode))
+               return 0;
 
-       return (st.st_ino == 256) && S_ISDIR(st.st_mode);
+       res = statfs(path, &stfs);
+       if (res < 0)
+               return -errno;
+
+       return (int)stfs.f_type == BTRFS_SUPER_MAGIC;
 }
 
 static int wait_for_commit(int fd)
@@ -320,7 +334,7 @@ again:
 
        res = test_issubvolume(path);
        if (res < 0) {
-               error("cannot access subvolume %s", path);
+               error("cannot access subvolume %s: %s", path, strerror(-res));
                ret = 1;
                goto out;
        }
@@ -675,7 +689,7 @@ static int cmd_subvol_snapshot(int argc, char **argv)
        retval = 1;     /* failure */
        res = test_issubvolume(subvol);
        if (res < 0) {
-               error("cannot access subvolume %s", subvol);
+               error("cannot access subvolume %s: %s", subvol, strerror(-res));
                goto out;
        }
        if (!res) {
@@ -684,6 +698,10 @@ static int cmd_subvol_snapshot(int argc, char **argv)
        }
 
        res = test_isdir(dst);
+       if (res < 0 && res != -ENOENT) {
+               error("cannot access %s: %s", dst, strerror(-res));
+               goto out;
+       }
        if (res == 0) {
                error("'%s' exists and it is not a directory", dst);
                goto out;
@@ -770,7 +788,9 @@ static int cmd_subvol_get_default(int argc, char **argv)
        u64 default_id;
        DIR *dirstream = NULL;
 
-       if (check_argc_exact(argc, 2))
+       clean_args_no_options(argc, argv, cmd_subvol_get_default_usage);
+
+       if (check_argc_exact(argc - optind, 2))
                usage(cmd_subvol_get_default_usage);
 
        subvol = argv[1];
@@ -832,11 +852,13 @@ static int cmd_subvol_set_default(int argc, char **argv)
        char    *subvolid;
        DIR     *dirstream = NULL;
 
-       if (check_argc_exact(argc, 3))
+       clean_args_no_options(argc, argv, cmd_subvol_set_default_usage);
+
+       if (check_argc_exact(argc - optind, 2))
                usage(cmd_subvol_set_default_usage);
 
-       subvolid = argv[1];
-       path = argv[2];
+       subvolid = argv[optind];
+       path = argv[optind + 1];
 
        objectid = arg_strtou64(subvolid);
 
@@ -869,15 +891,17 @@ static int cmd_subvol_find_new(int argc, char **argv)
        u64 last_gen;
        DIR *dirstream = NULL;
 
-       if (check_argc_exact(argc, 3))
+       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[1];
-       last_gen = arg_strtou64(argv[2]);
+       subvol = argv[optind];
+       last_gen = arg_strtou64(argv[optind + 1]);
 
        ret = test_issubvolume(subvol);
        if (ret < 0) {
-               error("cannot access subvolume %s", subvol);
+               error("cannot access subvolume %s: %s", subvol, strerror(-ret));
                return 1;
        }
        if (!ret) {
@@ -921,19 +945,22 @@ static int cmd_subvol_show(int argc, char **argv)
        int ret = 1;
        DIR *dirstream1 = NULL, *dirstream2 = NULL;
 
-       if (check_argc_exact(argc, 2))
+       clean_args_no_options(argc, argv, cmd_subvol_show_usage);
+
+       if (check_argc_exact(argc - optind, 1))
                usage(cmd_subvol_show_usage);
 
-       fullpath = realpath(argv[1], NULL);
+       fullpath = realpath(argv[optind], NULL);
        if (!fullpath) {
                error("cannot find real path for '%s': %s",
-                       argv[1], strerror(errno));
+                       argv[optind], strerror(errno));
                goto out;
        }
 
        ret = test_issubvolume(fullpath);
        if (ret < 0) {
-               error("cannot access subvolume %s", fullpath);
+               error("cannot access subvolume %s: %s", fullpath,
+                       strerror(-ret));
                goto out;
        }
        if (!ret) {