X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=tools-util.c;h=f29d202618db4623e73284eafa8ec47eadae5ced;hb=99caca2c70f312c4a2504a7e7a9c92a91426d885;hp=e4d2beae232f53d5418b146521f54275b0a45d15;hpb=9b08492bc733f3b1b1eefc87a4c52d9673432e42;p=bcachefs-tools-debian diff --git a/tools-util.c b/tools-util.c index e4d2bea..f29d202 100644 --- a/tools-util.c +++ b/tools-util.c @@ -31,7 +31,7 @@ void die(const char *fmt, ...) va_end(args); fputc('\n', stderr); - exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } char *mprintf(const char *fmt, ...) @@ -94,12 +94,12 @@ void xpread(int fd, void *buf, size_t count, off_t offset) } } -void xpwrite(int fd, const void *buf, size_t count, off_t offset) +void xpwrite(int fd, const void *buf, size_t count, off_t offset, const char *msg) { ssize_t r = pwrite(fd, buf, count, offset); if (r != count) - die("write error (ret %zi err %m)", r); + die("error writing %s (ret %zi err %m)", msg, r); } struct stat xfstatat(int dirfd, const char *path, int flags) @@ -126,63 +126,19 @@ struct stat xstat(const char *path) return statbuf; } -/* Formatting: */ - -int printf_pad(unsigned pad, const char * fmt, ...) -{ - va_list args; - int ret; - - va_start(args, fmt); - ret = vprintf(fmt, args); - va_end(args); - - while (ret++ < pad) - putchar(' '); - - return ret; -} +/* File parsing (i.e. sysfs) */ -struct units_buf __pr_units(s64 _v, enum units units) +void write_file_str(int dirfd, const char *path, const char *str) { - struct units_buf ret; - char *out = ret.b, *end = out + sizeof(ret.b); - u64 v = _v; + int fd = xopenat(dirfd, path, O_WRONLY); + ssize_t wrote, len = strlen(str); - if (_v < 0) { - out += scnprintf(out, end - out, "-"); - v = -_v; - } - - switch (units) { - case BYTES: - snprintf(out, end - out, "%llu", v << 9); - break; - case SECTORS: - snprintf(out, end - out, "%llu", v); - break; - case HUMAN_READABLE: - v <<= 9; - - if (v >= 1024) { - int exp = log(v) / log(1024); - snprintf(out, end - out, "%.1f%c", - v / pow(1024, exp), - "KMGTPE"[exp-1]); - } else { - snprintf(out, end - out, "%llu", v); - } - - break; - } - - return ret; + wrote = write(fd, str, len); + if (wrote != len) + die("read error: %m"); + close(fd); } -/* Argument parsing stuff: */ - -/* File parsing (i.e. sysfs) */ - char *read_file_str(int dirfd, const char *path) { int fd = xopenat(dirfd, path, O_RDONLY); @@ -197,6 +153,10 @@ char *read_file_str(int dirfd, const char *path) buf[len] = '\0'; if (len && buf[len - 1] == '\n') buf[len - 1] = '\0'; + if (!strlen(buf)) { + free(buf); + buf = NULL; + } close(fd); @@ -207,7 +167,7 @@ u64 read_file_u64(int dirfd, const char *path) { char *buf = read_file_str(dirfd, path); u64 v; - if (kstrtou64(buf, 10, &v)) + if (bch2_strtou64_h(buf, &v)) die("read_file_u64: error parsing %s (got %s)", path, buf); free(buf); return v; @@ -238,17 +198,17 @@ u64 get_size(const char *path, int fd) return ret; } -/* Returns blocksize in units of 512 byte sectors: */ +/* Returns blocksize, in bytes: */ unsigned get_blocksize(const char *path, int fd) { struct stat statbuf = xfstat(fd); if (!S_ISBLK(statbuf.st_mode)) - return statbuf.st_blksize >> 9; + return statbuf.st_blksize; unsigned ret; xioctl(fd, BLKPBSZGET, &ret); - return ret >> 9; + return ret; } /* Open a block device, do magic blkid stuff to probe for existing filesystems: */ @@ -258,7 +218,9 @@ int open_for_format(const char *dev, bool force) const char *fs_type = NULL, *fs_label = NULL; size_t fs_type_len, fs_label_len; - int fd = xopen(dev, O_RDWR|O_EXCL); + int fd = open(dev, O_RDWR|O_EXCL); + if (fd < 0) + die("Error opening device to format %s: %m", dev); if (force) return fd; @@ -285,6 +247,8 @@ int open_for_format(const char *dev, bool force) fputs("Proceed anyway?", stdout); if (!ask_yn()) exit(EXIT_FAILURE); + while (blkid_do_probe(pr) == 0) + blkid_do_wipe(pr, 0); } blkid_free_probe(pr); @@ -323,22 +287,21 @@ static int range_cmp(const void *_l, const void *_r) void ranges_sort_merge(ranges *r) { struct range *t, *i; - ranges tmp = { NULL }; + ranges tmp = { 0 }; - sort(&darray_item(*r, 0), darray_size(*r), - sizeof(darray_item(*r, 0)), range_cmp, NULL); + sort(r->data, r->nr, sizeof(r->data[0]), range_cmp, NULL); /* Merge contiguous ranges: */ - darray_foreach(i, *r) { - t = tmp.size ? &tmp.item[tmp.size - 1] : NULL; + darray_for_each(*r, i) { + t = tmp.nr ? &tmp.data[tmp.nr - 1] : NULL; if (t && t->end >= i->start) t->end = max(t->end, i->end); else - darray_append(tmp, *i); + darray_push(&tmp, *i); } - darray_free(*r); + darray_exit(r); *r = tmp; } @@ -346,7 +309,7 @@ void ranges_roundup(ranges *r, unsigned block_size) { struct range *i; - darray_foreach(i, *r) { + darray_for_each(*r, i) { i->start = round_down(i->start, block_size); i->end = round_up(i->end, block_size); } @@ -356,7 +319,7 @@ void ranges_rounddown(ranges *r, unsigned block_size) { struct range *i; - darray_foreach(i, *r) { + darray_for_each(*r, i) { i->start = round_up(i->start, block_size); i->end = round_down(i->end, block_size); i->end = max(i->end, i->start); @@ -395,24 +358,6 @@ char *strcmp_prefix(char *a, const char *a_prefix) return *a_prefix ? NULL : a; } -unsigned hatoi_validate(const char *s, const char *msg) -{ - u64 v; - - if (bch2_strtoull_h(s, &v)) - die("bad %s %s", msg, s); - - v /= 512; - - if (v > USHRT_MAX) - die("%s too large\n", msg); - - if (!v) - die("%s too small\n", msg); - - return v; -} - /* crc32c */ static u32 crc32c_default(u32 crc, const void *buf, size_t size) @@ -649,9 +594,32 @@ found: return ret; } -bool dev_mounted_rw(char *dev) +int dev_mounted(char *dev) { struct mntent *mnt = dev_to_mount(dev); - return mnt && !hasmntopt(mnt, "ro"); + if (!mnt) + return 0; + if (hasmntopt(mnt, "ro")) + return 1; + return 2; +} + +struct bpos bpos_parse(char *buf) +{ + char *s = buf, *field; + u64 inode_v = 0, offset_v = 0; + + if (!(field = strsep(&s, ":")) || + kstrtoull(field, 10, &inode_v)) + die("invalid bpos %s", buf); + + if ((field = strsep(&s, ":")) && + kstrtoull(field, 10, &offset_v)) + die("invalid bpos %s", buf); + + if (s) + die("invalid bpos %s", buf); + + return (struct bpos) { .inode = inode_v, .offset = offset_v }; }