]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 3704d0779c bcachefs: Improved human readable integer parsing
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 11 Jun 2022 22:13:40 +0000 (18:13 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Sat, 11 Jun 2022 22:14:06 +0000 (18:14 -0400)
.bcachefs_revision
include/linux/printbuf.h
libbcachefs/alloc_background.c
libbcachefs/util.c
libbcachefs/util.h

index 5b9e7323a4a707f643c3f3558eae996a668954ba..8e176a6f2f1ef56dcfe8683e459e09b6df717a21 100644 (file)
@@ -1 +1 @@
-24f7e08cd8a8b62fc467f1b359bd934ad943f0b7
+3704d0779c7885dd74ab345aa7017a4430231e1a
index c898faac742c4a0aa6dfb1a1817d74c1d0e6944b..fa8e73d5766aa23bb1acf1f428ecf3c7a847b949 100644 (file)
@@ -225,6 +225,8 @@ static inline void printbuf_reset(struct printbuf *buf)
 {
        buf->pos                = 0;
        buf->allocation_failure = 0;
+       buf->indent             = 0;
+       buf->tabstop            = 0;
 }
 
 /**
index d114ba0949a8aff1823dae597b126bedbbadd4e0..86df10e67ce7a3953281ef25af804fc9c9484107 100644 (file)
@@ -1190,12 +1190,26 @@ void bch2_do_invalidates(struct bch_fs *c)
                queue_work(system_long_wq, &c->invalidate_work);
 }
 
+static int bucket_freespace_init(struct btree_trans *trans, struct btree_iter *iter)
+{
+       struct bch_alloc_v4 a;
+       struct bkey_s_c k;
+       int ret;
+
+       k = bch2_btree_iter_peek_slot(iter);
+       ret = bkey_err(k);
+       if (ret)
+               return ret;
+
+       bch2_alloc_to_v4(k, &a);
+       return bch2_bucket_do_index(trans, k, &a, true);
+}
+
 static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca)
 {
        struct btree_trans trans;
        struct btree_iter iter;
        struct bkey_s_c k;
-       struct bch_alloc_v4 a;
        struct bch_member *m;
        int ret;
 
@@ -1208,10 +1222,9 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca)
                if (iter.pos.offset >= ca->mi.nbuckets)
                        break;
 
-               bch2_alloc_to_v4(k, &a);
                ret = __bch2_trans_do(&trans, NULL, NULL,
                                      BTREE_INSERT_LAZY_RW,
-                                bch2_bucket_do_index(&trans, k, &a, true));
+                                bucket_freespace_init(&trans, &iter));
                if (ret)
                        break;
        }
index 37ef7094da65d1f7604b58243b010816c80ae87f..85b8f3df22e0b7ad1ac2df76f9cfc049c38f1158 100644 (file)
 
 static const char si_units[] = "?kMGTPEZY";
 
-static int __bch2_strtoh(const char *cp, u64 *res,
-                        u64 t_max, bool t_signed)
+/* string_get_size units: */
+static const char *const units_2[] = {
+       "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
+};
+static const char *const units_10[] = {
+       "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
+};
+
+static int parse_u64(const char *cp, u64 *res)
 {
-       bool positive = *cp != '-';
-       unsigned u;
+       const char *start = cp;
        u64 v = 0;
 
-       if (*cp == '+' || *cp == '-')
-               cp++;
-
        if (!isdigit(*cp))
                return -EINVAL;
 
@@ -50,22 +53,121 @@ static int __bch2_strtoh(const char *cp, u64 *res,
                cp++;
        } while (isdigit(*cp));
 
+       *res = v;
+       return cp - start;
+}
+
+static int bch2_pow(u64 n, u64 p, u64 *res)
+{
+       *res = 1;
+
+       while (p--) {
+               if (*res > div_u64(U64_MAX, n))
+                       return -ERANGE;
+               *res *= n;
+       }
+       return 0;
+}
+
+static int parse_unit_suffix(const char *cp, u64 *res)
+{
+       const char *start = cp;
+       u64 base = 1024;
+       unsigned u;
+       int ret;
+
+       if (*cp == ' ')
+               cp++;
+
        for (u = 1; u < strlen(si_units); u++)
                if (*cp == si_units[u]) {
                        cp++;
                        goto got_unit;
                }
-       u = 0;
+
+       for (u = 0; u < ARRAY_SIZE(units_2); u++)
+               if (!strncmp(cp, units_2[u], strlen(units_2[u]))) {
+                       cp += strlen(units_2[u]);
+                       goto got_unit;
+               }
+
+       for (u = 0; u < ARRAY_SIZE(units_10); u++)
+               if (!strncmp(cp, units_10[u], strlen(units_10[u]))) {
+                       cp += strlen(units_10[u]);
+                       base = 1000;
+                       goto got_unit;
+               }
+
+       *res = 1;
+       return 0;
 got_unit:
-       if (*cp == '\n')
+       ret = bch2_pow(base, u, res);
+       if (ret)
+               return ret;
+
+       return cp - start;
+}
+
+#define parse_or_ret(cp, _f)                   \
+do {                                           \
+       int ret = _f;                           \
+       if (ret < 0)                            \
+               return ret;                     \
+       cp += ret;                              \
+} while (0)
+
+static int __bch2_strtou64_h(const char *cp, u64 *res)
+{
+       const char *start = cp;
+       u64 v = 0, b, f_n = 0, f_d = 1;
+       int ret;
+
+       parse_or_ret(cp, parse_u64(cp, &v));
+
+       if (*cp == '.') {
                cp++;
-       if (*cp)
-               return -EINVAL;
+               ret = parse_u64(cp, &f_n);
+               if (ret < 0)
+                       return ret;
+               cp += ret;
+
+               ret = bch2_pow(10, ret, &f_d);
+               if (ret)
+                       return ret;
+       }
+
+       parse_or_ret(cp, parse_unit_suffix(cp, &b));
+
+       if (v > div_u64(U64_MAX, b))
+               return -ERANGE;
+       v *= b;
+
+       if (f_n > div_u64(U64_MAX, b))
+               return -ERANGE;
 
-       if (fls64(v) + u * 10 > 64)
+       if (v + (f_n * b) / f_d < v)
                return -ERANGE;
+       v += (f_n * b) / f_d;
 
-       v <<= u * 10;
+       *res = v;
+       return cp - start;
+}
+
+static int __bch2_strtoh(const char *cp, u64 *res,
+                        u64 t_max, bool t_signed)
+{
+       bool positive = *cp != '-';
+       u64 v = 0;
+
+       if (*cp == '+' || *cp == '-')
+               cp++;
+
+       parse_or_ret(cp, __bch2_strtou64_h(cp, &v));
+
+       if (*cp == '\n')
+               cp++;
+       if (*cp)
+               return -EINVAL;
 
        if (positive) {
                if (v > t_max)
@@ -86,7 +188,7 @@ got_unit:
 #define STRTO_H(name, type)                                    \
 int bch2_ ## name ## _h(const char *cp, type *res)             \
 {                                                              \
-       u64 v;                                                  \
+       u64 v = 0;                                              \
        int ret = __bch2_strtoh(cp, &v, ANYSINT_MAX(type),      \
                        ANYSINT_MAX(type) != ((type) ~0ULL));   \
        *res = v;                                               \
index bbef4745f5ce8e7f3356d085cb539449e99de7a5..1fe66fd91ccc724203d29b83d6787c94f9e1b5b6 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 u*/
+/* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _BCACHEFS_UTIL_H
 #define _BCACHEFS_UTIL_H