X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=tools-util.c;h=a1e67dd51ad12fc38f64c1fc5254ac3640bdb85a;hb=e3e7f67b3ed89f5b3158142c29e66bb98f868ce2;hp=65835edfae5af3b5fafad2b3229a98114e36e94c;hpb=4697efb7a01affe650dbc9a4e81a8203d0316d96;p=bcachefs-tools-debian diff --git a/tools-util.c b/tools-util.c index 65835ed..a1e67dd 100644 --- a/tools-util.c +++ b/tools-util.c @@ -17,6 +17,7 @@ #include #include +#include "libbcachefs.h" #include "libbcachefs/bcachefs_ioctl.h" #include "linux/sort.h" #include "tools-util.h" @@ -186,7 +187,7 @@ ssize_t read_string_list_or_die(const char *opt, const char * const list[], } /* Returns size of file or block device: */ -u64 get_size(const char *path, int fd) +u64 get_size(int fd) { struct stat statbuf = xfstat(fd); @@ -199,7 +200,7 @@ u64 get_size(const char *path, int fd) } /* Returns blocksize, in bytes: */ -unsigned get_blocksize(const char *path, int fd) +unsigned get_blocksize(int fd) { struct stat statbuf = xfstat(fd); @@ -212,24 +213,26 @@ unsigned get_blocksize(const char *path, int fd) } /* Open a block device, do magic blkid stuff to probe for existing filesystems: */ -int open_for_format(const char *dev, bool force) +int open_for_format(struct dev_opts *dev, bool force) { blkid_probe pr; const char *fs_type = NULL, *fs_label = NULL; size_t fs_type_len, fs_label_len; - int fd = open(dev, O_RDWR|O_EXCL); - if (fd < 0) - die("Error opening device to format %s: %m", dev); - - if (force) - return fd; + dev->bdev = blkdev_get_by_path(dev->path, BLK_OPEN_READ|BLK_OPEN_WRITE|BLK_OPEN_EXCL, + dev, NULL); + int ret = PTR_ERR_OR_ZERO(dev->bdev); + if (ret < 0) + die("Error opening device to format %s: %s", dev->path, strerror(-ret)); if (!(pr = blkid_new_probe())) die("blkid error 1"); - if (blkid_probe_set_device(pr, fd, 0, 0)) + if (blkid_probe_set_device(pr, dev->bdev->bd_buffered_fd, 0, 0)) die("blkid error 2"); - if (blkid_probe_enable_partitions(pr, true)) + if (blkid_probe_enable_partitions(pr, true) || + blkid_probe_enable_superblocks(pr, true) || + blkid_probe_set_superblocks_flags(pr, + BLKID_SUBLKS_LABEL|BLKID_SUBLKS_TYPE|BLKID_SUBLKS_MAGIC)) die("blkid error 3"); if (blkid_do_fullprobe(pr) < 0) die("blkid error 4"); @@ -240,19 +243,23 @@ int open_for_format(const char *dev, bool force) if (fs_type) { if (fs_label) printf("%s contains a %s filesystem labelled '%s'\n", - dev, fs_type, fs_label); + dev->path, fs_type, fs_label); else printf("%s contains a %s filesystem\n", - dev, fs_type); - fputs("Proceed anyway?", stdout); - if (!ask_yn()) - exit(EXIT_FAILURE); - while (blkid_do_probe(pr) == 0) - blkid_do_wipe(pr, 0); + dev->path, fs_type); + if (!force) { + fputs("Proceed anyway?", stdout); + if (!ask_yn()) + exit(EXIT_FAILURE); + } + while (blkid_do_probe(pr) == 0) { + if (blkid_do_wipe(pr, 0)) + die("Failed to wipe preexisting metadata."); + } } blkid_free_probe(pr); - return fd; + return ret; } bool ask_yn(void) @@ -330,21 +337,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,6 +612,35 @@ 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 *orig = strdup(buf); @@ -620,14 +656,14 @@ struct bpos bpos_parse(char *buf) u64 inode_v = 0, offset_v = 0; u32 snapshot_v = 0; - if (kstrtoull(inode_s, 10, &inode_v)) + if (kstrtoull_symbolic(inode_s, 10, &inode_v)) die("invalid bpos.inode %s", inode_s); - if (kstrtoull(offset_s, 10, &offset_v)) + if (kstrtoull_symbolic(offset_s, 10, &offset_v)) die("invalid bpos.offset %s", offset_s); if (snapshot_s && - kstrtouint(snapshot_s, 10, &snapshot_v)) + kstrtouint_symbolic(snapshot_s, 10, &snapshot_v)) die("invalid bpos.snapshot %s", snapshot_s); return (struct bpos) { .inode = inode_v, .offset = offset_v, .snapshot = snapshot_v }; @@ -641,7 +677,11 @@ struct bbpos bbpos_parse(char *buf) if (!(field = strsep(&s, ":"))) die("invalid bbpos %s", buf); - ret.btree = read_string_list_or_die(field, bch2_btree_ids, "btree id"); + ret.btree = read_string_list_or_die(field, __bch2_btree_ids, "btree id"); + + if (!s) + die("invalid bbpos %s", buf); + ret.pos = bpos_parse(s); return ret; }