btrfs-progs: rename __strncpy__null to __strncpy_null
[platform/upstream/btrfs-progs.git] / utils.c
diff --git a/utils.c b/utils.c
index cd3234e..e057cf3 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -856,8 +856,8 @@ out:
        return ret;
 }
 
-int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
-                          u64 max_block_count, int discard)
+int btrfs_prepare_device(int fd, const char *file, int zero_end,
+               u64 *block_count_ret, u64 max_block_count, int discard)
 {
        u64 block_count;
        struct stat st;
@@ -1683,7 +1683,7 @@ int pretty_size_snprintf(u64 size, char *str, size_t str_size, unsigned unit_mod
 }
 
 /*
- * __strncpy__null - strncpy with null termination
+ * __strncpy_null - strncpy with null termination
  * @dest:      the target array
  * @src:       the source string
  * @n:         maximum bytes to copy (size of *dest)
@@ -1694,7 +1694,7 @@ int pretty_size_snprintf(u64 size, char *str, size_t str_size, unsigned unit_mod
  * byte ('\0'), to the buffer pointed to by dest, up to a maximum
  * of n bytes.  Then ensure that dest is null-terminated.
  */
-char *__strncpy__null(char *dest, const char *src, size_t n)
+char *__strncpy_null(char *dest, const char *src, size_t n)
 {
        strncpy(dest, src, n);
        if (n > 0)
@@ -2350,9 +2350,7 @@ out:
  *      0 for nothing found
  *     -1 for internal error
  */
-static int
-check_overwrite(
-       char            *device)
+static int check_overwrite(const char *device)
 {
        const char      *type;
        blkid_probe     pr = NULL;
@@ -2463,9 +2461,7 @@ int test_num_disk_vs_raid(u64 metadata_profile, u64 data_profile,
 
        if (dev_cnt > 1 &&
            ((metadata_profile | data_profile) & BTRFS_BLOCK_GROUP_DUP)) {
-               fprintf(stderr,
-                   "ERROR: DUP is not allowed when FS has multiple devices\n");
-               return 1;
+               warning("DUP is not recommended on filesystem with multiple devices");
        }
        if (metadata_profile & ~allowed) {
                fprintf(stderr,
@@ -2514,7 +2510,7 @@ int group_profile_max_safe_loss(u64 flags)
  *  1: something is wrong, an error is printed
  *  0: all is fine
  */
-int test_dev_for_mkfs(char *file, int force_overwrite)
+int test_dev_for_mkfs(const char *file, int force_overwrite)
 {
        int ret, fd;
        struct stat st;
@@ -2618,7 +2614,7 @@ int btrfs_scan_lblkid(void)
        return 0;
 }
 
-int is_vol_small(char *file)
+int is_vol_small(const char *file)
 {
        int fd = -1;
        int e;
@@ -2652,7 +2648,7 @@ int is_vol_small(char *file)
  * first whitespace delimited token is a case insensitive match with yes
  * or y.
  */
-int ask_user(char *question)
+int ask_user(const char *question)
 {
        char buf[30] = {0,};
        char *saveptr = NULL;
@@ -2823,7 +2819,7 @@ int find_next_key(struct btrfs_path *path, struct btrfs_key *key)
        return 1;
 }
 
-char* btrfs_group_type_str(u64 flag)
+const char* btrfs_group_type_str(u64 flag)
 {
        u64 mask = BTRFS_BLOCK_GROUP_TYPE_MASK |
                BTRFS_SPACE_INFO_GLOBAL_RSV;
@@ -2844,7 +2840,7 @@ char* btrfs_group_type_str(u64 flag)
        }
 }
 
-char* btrfs_group_profile_str(u64 flag)
+const char* btrfs_group_profile_str(u64 flag)
 {
        switch (flag & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
        case 0:
@@ -2866,7 +2862,7 @@ char* btrfs_group_profile_str(u64 flag)
        }
 }
 
-u64 disk_size(char *path)
+u64 disk_size(const char *path)
 {
        struct statfs sfs;
 
@@ -2876,7 +2872,7 @@ u64 disk_size(char *path)
                return sfs.f_bsize * sfs.f_blocks;
 }
 
-u64 get_partition_size(char *dev)
+u64 get_partition_size(const char *dev)
 {
        u64 result;
        int fd = open(dev, O_RDONLY);
@@ -2973,7 +2969,7 @@ int arg_copy_path(char *dest, const char *src, int destlen)
        if (len >= PATH_MAX || len >= destlen)
                return -ENAMETOOLONG;
 
-       __strncpy__null(dest, src, destlen);
+       __strncpy_null(dest, src, destlen);
 
        return 0;
 }
@@ -3160,7 +3156,7 @@ int test_issubvolume(const char *path)
        return (int)stfs.f_type == BTRFS_SUPER_MAGIC;
 }
 
-char *get_subvol_name(char *mnt, char *full_path)
+const char *subvol_strip_mountpoint(const char *mnt, const char *full_path)
 {
        int len = strlen(mnt);
        if (!len)
@@ -3171,3 +3167,76 @@ char *get_subvol_name(char *mnt, char *full_path)
 
        return full_path + len;
 }
+
+/*
+ * Returns
+ * <0: Std error
+ * 0: All fine
+ * 1: Error; and error info printed to the terminal. Fixme.
+ * 2: If the fullpath is root tree instead of subvol tree
+ */
+int get_subvol_info(const char *fullpath, struct root_info *get_ri)
+{
+       u64 sv_id;
+       int ret = 1;
+       int fd = -1;
+       int mntfd = -1;
+       char *mnt = NULL;
+       const char *svpath = NULL;
+       DIR *dirstream1 = NULL;
+       DIR *dirstream2 = NULL;
+
+       ret = test_issubvolume(fullpath);
+       if (ret < 0)
+               return ret;
+       if (!ret) {
+               error("not a subvolume: %s", fullpath);
+               return 1;
+       }
+
+       ret = find_mount_root(fullpath, &mnt);
+       if (ret < 0)
+               return ret;
+       if (ret > 0) {
+               error("%s doesn't belong to btrfs mount point", fullpath);
+               return 1;
+       }
+       ret = 1;
+       svpath = subvol_strip_mountpoint(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 = 2;
+               /*
+                * So that caller may decide if thats an error or just fine.
+                */
+               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': %d", svpath, ret);
+
+out:
+       close_file_or_dir(mntfd, dirstream2);
+       close_file_or_dir(mntfd, dirstream1);
+       free(mnt);
+
+       return ret;
+}