]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - tools-util.c
New upstream release
[bcachefs-tools-debian] / tools-util.c
index f29d202618db4623e73284eafa8ec47eadae5ced..624656a1fa50d16f322414e6f0aa30c5938075a0 100644 (file)
@@ -330,21 +330,21 @@ struct fiemap_extent fiemap_iter_next(struct fiemap_iter *iter)
 {
        struct fiemap_extent e;
 
-       BUG_ON(iter->idx > iter->f.fm_mapped_extents);
+       BUG_ON(iter->idx > iter->f->fm_mapped_extents);
 
-       if (iter->idx == iter->f.fm_mapped_extents) {
-               xioctl(iter->fd, FS_IOC_FIEMAP, &iter->f);
+       if (iter->idx == iter->f->fm_mapped_extents) {
+               xioctl(iter->fd, FS_IOC_FIEMAP, iter->f);
 
-               if (!iter->f.fm_mapped_extents)
+               if (!iter->f->fm_mapped_extents)
                        return (struct fiemap_extent) { .fe_length = 0 };
 
                iter->idx = 0;
        }
 
-       e = iter->f.fm_extents[iter->idx++];
+       e = iter->f->fm_extents[iter->idx++];
        BUG_ON(!e.fe_length);
 
-       iter->f.fm_start = e.fe_logical + e.fe_length;
+       iter->f->fm_start = e.fe_logical + e.fe_length;
 
        return e;
 }
@@ -605,21 +605,72 @@ int dev_mounted(char *dev)
        return 2;
 }
 
+static int kstrtoull_symbolic(const char *s, unsigned int base, unsigned long long *res)
+{
+       if (!strcmp(s, "U64_MAX")) {
+               *res = U64_MAX;
+               return 0;
+       }
+
+       if (!strcmp(s, "U32_MAX")) {
+               *res = U32_MAX;
+               return 0;
+       }
+
+       return kstrtoull(s, base, res);
+}
+
+static int kstrtouint_symbolic(const char *s, unsigned int base, unsigned *res)
+{
+       unsigned long long tmp;
+       int rv;
+
+       rv = kstrtoull_symbolic(s, base, &tmp);
+       if (rv < 0)
+               return rv;
+       if (tmp != (unsigned long long)(unsigned int)tmp)
+               return -ERANGE;
+       *res = tmp;
+       return 0;
+}
+
 struct bpos bpos_parse(char *buf)
 {
-       char *s = buf, *field;
+       char *orig = strdup(buf);
+       char *s = buf;
+
+       char *inode_s   = strsep(&s, ":");
+       char *offset_s  = strsep(&s, ":");
+       char *snapshot_s = strsep(&s, ":");
+
+       if (!inode_s || !offset_s || s)
+               die("invalid bpos %s", orig);
+       free(orig);
+
        u64 inode_v = 0, offset_v = 0;
+       u32 snapshot_v = 0;
+       if (kstrtoull_symbolic(inode_s, 10, &inode_v))
+               die("invalid bpos.inode %s", inode_s);
 
-       if (!(field = strsep(&s, ":")) ||
-           kstrtoull(field, 10, &inode_v))
-               die("invalid bpos %s", buf);
+       if (kstrtoull_symbolic(offset_s, 10, &offset_v))
+               die("invalid bpos.offset %s", offset_s);
 
-       if ((field = strsep(&s, ":")) &&
-           kstrtoull(field, 10, &offset_v))
-               die("invalid bpos %s", buf);
+       if (snapshot_s &&
+           kstrtouint_symbolic(snapshot_s, 10, &snapshot_v))
+               die("invalid bpos.snapshot %s", snapshot_s);
 
-       if (s)
-               die("invalid bpos %s", buf);
+       return (struct bpos) { .inode = inode_v, .offset = offset_v, .snapshot = snapshot_v };
+}
+
+struct bbpos bbpos_parse(char *buf)
+{
+       char *s = buf, *field;
+       struct bbpos ret;
+
+       if (!(field = strsep(&s, ":")))
+               die("invalid bbpos %s", buf);
 
-       return (struct bpos) { .inode = inode_v, .offset = offset_v };
+       ret.btree = read_string_list_or_die(field, bch2_btree_ids, "btree id");
+       ret.pos = bpos_parse(s);
+       return ret;
 }