parse_size(): add new suffixes
[platform/upstream/btrfs-progs.git] / utils.c
diff --git a/utils.c b/utils.c
index 5833030..b487be6 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -31,6 +31,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <mntent.h>
+#include <ctype.h>
 #include <linux/loop.h>
 #include <linux/major.h>
 #include <linux/kdev_t.h>
@@ -537,7 +538,7 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
 }
 
 int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
-                        int *mixed)
+                          u64 max_block_count, int *mixed, int nodiscard)
 {
        u64 block_count;
        u64 bytenr;
@@ -555,8 +556,8 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
                fprintf(stderr, "unable to find %s size\n", file);
                exit(1);
        }
-       if (*block_count_ret)
-               block_count = min(block_count, *block_count_ret);
+       if (max_block_count)
+               block_count = min(block_count, max_block_count);
        zero_end = 1;
 
        if (block_count < 1024 * 1024 * 1024 && !(*mixed)) {
@@ -564,11 +565,13 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
                *mixed = 1;
        }
 
-       /*
-        * We intentionally ignore errors from the discard ioctl.  It is
-        * not necessary for the mkfs functionality but just an optimization.
-        */
-       discard_blocks(fd, 0, block_count);
+       if (!nodiscard) {
+               /*
+                * We intentionally ignore errors from the discard ioctl.  It is
+                * not necessary for the mkfs functionality but just an optimization.
+                */
+               discard_blocks(fd, 0, block_count);
+       }
 
        ret = zero_dev_start(fd);
        if (ret) {
@@ -606,7 +609,7 @@ int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
        btrfs_set_stack_inode_size(&inode_item, 0);
        btrfs_set_stack_inode_nlink(&inode_item, 1);
        btrfs_set_stack_inode_nbytes(&inode_item, root->leafsize);
-       btrfs_set_stack_inode_mode(&inode_item, S_IFDIR | 0555);
+       btrfs_set_stack_inode_mode(&inode_item, S_IFDIR | 0755);
        btrfs_set_stack_timespec_sec(&inode_item.atime, now);
        btrfs_set_stack_timespec_nsec(&inode_item.atime, 0);
        btrfs_set_stack_timespec_sec(&inode_item.ctime, now);
@@ -1089,25 +1092,27 @@ char *pretty_sizes(u64 size)
 {
        int num_divs = 0;
         int pretty_len = 16;
-       u64 last_size = size;
-       u64 fract_size = size;
        float fraction;
        char *pretty;
 
-       while(size > 0) {
-               fract_size = last_size;
-               last_size = size;
-               size /= 1024;
-               num_divs++;
-       }
-       if (num_divs == 0)
-               num_divs = 1;
-       if (num_divs > ARRAY_SIZE(size_strs))
-               return NULL;
+       if( size < 1024 ){
+               fraction = size;
+               num_divs = 0;
+       } else {
+               u64 last_size = size;
+               num_divs = 0;
+               while(size >= 1024){
+                       last_size = size;
+                       size /= 1024;
+                       num_divs ++;
+               }
 
-       fraction = (float)fract_size / 1024;
+               if (num_divs > ARRAY_SIZE(size_strs))
+                       return NULL;
+               fraction = (float)last_size / 1024;
+       }
        pretty = malloc(pretty_len);
-       snprintf(pretty, pretty_len, "%.2f%s", fraction, size_strs[num_divs-1]);
+       snprintf(pretty, pretty_len, "%.2f%s", fraction, size_strs[num_divs]);
        return pretty;
 }
 
@@ -1216,3 +1221,47 @@ scan_again:
        return 0;
 }
 
+u64 parse_size(char *s)
+{
+       int i;
+       char c;
+       u64 mult = 1;
+
+       for (i=0 ; s[i] && isdigit(s[i]) ; i++) ;
+       if (!i) {
+               fprintf(stderr, "ERROR: size value is empty\n");
+               exit(50);
+       }
+
+       if (s[i]) {
+               c = tolower(s[i]);
+               switch (c) {
+               case 'e':
+                       mult *= 1024;
+               case 'p':
+                       mult *= 1024;
+               case 't':
+                       mult *= 1024;
+               case 'g':
+                       mult *= 1024;
+               case 'm':
+                       mult *= 1024;
+               case 'k':
+                       mult *= 1024;
+               case 'b':
+                       break;
+               default:
+                       fprintf(stderr, "ERROR: Unknown size descriptor "
+                               "'%c'\n", c);
+                       exit(1);
+               }
+       }
+       if (s[i] && s[i+1]) {
+               fprintf(stderr, "ERROR: Illegal suffix contains "
+                       "character '%c' in wrong position\n",
+                       s[i+1]);
+               exit(51);
+       }
+       return strtoull(s, NULL, 10) * mult;
+}
+