X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=tools-util.c;h=3cc0de444cf95b32d2def2e16c476c6bd726bcb6;hb=3f7b0b0832a61ccaf590f3503521eb7cf8f14f64;hp=70f5558b2dfa1e5342eaa16d06fa9f436cbba8d4;hpb=30caf69540dfb3913e8b5c0359f7714dd52a08cb;p=bcachefs-tools-debian diff --git a/tools-util.c b/tools-util.c index 70f5558..3cc0de4 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, ...) @@ -82,10 +82,16 @@ void *xrealloc(void *p, size_t size) void xpread(int fd, void *buf, size_t count, off_t offset) { - ssize_t r = pread(fd, buf, count, offset); + while (count) { + ssize_t r = pread(fd, buf, count, offset); - if (r != count) - die("read error (ret %zi)", r); + if (r < 0) + die("read error: %m"); + if (!r) + die("pread error: unexpected eof"); + count -= r; + offset += r; + } } void xpwrite(int fd, const void *buf, size_t count, off_t offset) @@ -112,7 +118,30 @@ struct stat xfstat(int fd) return stat; } -/* Integer stuff: */ +struct stat xstat(const char *path) +{ + struct stat statbuf; + if (stat(path, &statbuf)) + die("stat error statting %s: %m", 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; +} struct units_buf __pr_units(s64 _v, enum units units) { @@ -168,6 +197,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); @@ -189,7 +222,7 @@ u64 read_file_u64(int dirfd, const char *path) ssize_t read_string_list_or_die(const char *opt, const char * const list[], const char *msg) { - ssize_t v = bch2_read_string_list(opt, list); + ssize_t v = match_string(list, -1, opt); if (v < 0) die("Bad %s %s", msg, opt); @@ -256,64 +289,14 @@ 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); return fd; } -/* Global control device: */ -int bcachectl_open(void) -{ - return xopen("/dev/bcachefs-ctl", O_RDWR); -} - -/* Filesystem handles (ioctl, sysfs dir): */ - -#define SYSFS_BASE "/sys/fs/bcachefs/" - -void bcache_fs_close(struct bcache_handle fs) -{ - close(fs.ioctl_fd); - close(fs.sysfs_fd); -} - -struct bcache_handle bcache_fs_open(const char *path) -{ - struct bcache_handle ret; - - if (!uuid_parse(path, ret.uuid.b)) { - /* It's a UUID, look it up in sysfs: */ - char *sysfs = mprintf("%s%s", SYSFS_BASE, path); - ret.sysfs_fd = xopen(sysfs, O_RDONLY); - - char *minor = read_file_str(ret.sysfs_fd, "minor"); - char *ctl = mprintf("/dev/bcachefs%s-ctl", minor); - ret.ioctl_fd = xopen(ctl, O_RDWR); - - free(sysfs); - free(minor); - free(ctl); - } else { - /* It's a path: */ - ret.ioctl_fd = xopen(path, O_RDONLY); - - struct bch_ioctl_query_uuid uuid; - xioctl(ret.ioctl_fd, BCH_IOCTL_QUERY_UUID, &uuid); - - ret.uuid = uuid.uuid; - - char uuid_str[40]; - uuid_unparse(uuid.uuid.b, uuid_str); - - char *sysfs = mprintf("%s%s", SYSFS_BASE, uuid_str); - ret.sysfs_fd = xopen(sysfs, O_RDONLY); - free(sysfs); - } - - return ret; -} - bool ask_yn(void) { const char *short_yes = "yY"; @@ -409,7 +392,7 @@ struct fiemap_extent fiemap_iter_next(struct fiemap_iter *iter) return e; } -const char *strcmp_prefix(const char *a, const char *a_prefix) +char *strcmp_prefix(char *a, const char *a_prefix) { while (*a_prefix && *a == *a_prefix) { a++; @@ -553,10 +536,10 @@ static u32 crc32c_sse42(u32 crc, const void *buf, size_t size) return crc; } +#endif + static void *resolve_crc32c(void) { - __builtin_cpu_init(); - #ifdef __x86_64__ if (__builtin_cpu_supports("sse4.2")) return crc32c_sse42; @@ -569,8 +552,15 @@ static void *resolve_crc32c(void) */ #ifdef HAVE_WORKING_IFUNC +static void *ifunc_resolve_crc32c(void) +{ + __builtin_cpu_init(); + + return resolve_crc32c +} + u32 crc32c(u32, const void *, size_t) - __attribute__((ifunc("resolve_crc32c"))); + __attribute__((ifunc("ifunc_resolve_crc32c"))); #else @@ -586,9 +576,9 @@ u32 crc32c(u32 crc, const void *buf, size_t size) #endif /* HAVE_WORKING_IFUNC */ -char *dev_to_path(dev_t dev) +char *dev_to_name(dev_t dev) { - char *line = NULL, *name = NULL, *path = NULL; + char *line = NULL, *name = NULL; size_t n = 0; FILE *f = fopen("/proc/partitions", "r"); @@ -602,17 +592,95 @@ char *dev_to_path(dev_t dev) name = realloc(name, n + 1); if (sscanf(line, " %u %u %llu %s", &ma, &mi, §ors, name) == 4 && - ma == major(dev) && mi == minor(dev)) { - path = mprintf("/dev/%s", name); - break; - } - + ma == major(dev) && mi == minor(dev)) + goto found; } + free(name); + name = NULL; +found: fclose(f); free(line); + return name; +} + +char *dev_to_path(dev_t dev) +{ + char *name = dev_to_name(dev); + if (!name) + return NULL; + + char *path = mprintf("/dev/%s", name); + free(name); return path; } -#endif +struct mntent *dev_to_mount(char *dev) +{ + struct mntent *mnt, *ret = NULL; + FILE *f = setmntent("/proc/mounts", "r"); + if (!f) + die("error opening /proc/mounts: %m"); + + struct stat d1 = xstat(dev); + + while ((mnt = getmntent(f))) { + char *d, *p = mnt->mnt_fsname; + + while ((d = strsep(&p, ":"))) { + struct stat d2; + + if (stat(d, &d2)) + continue; + + if (S_ISBLK(d1.st_mode) != S_ISBLK(d2.st_mode)) + continue; + + if (S_ISBLK(d1.st_mode)) { + if (d1.st_rdev != d2.st_rdev) + continue; + } else { + if (d1.st_dev != d2.st_dev || + d1.st_ino != d2.st_ino) + continue; + } + + ret = mnt; + goto found; + } + } +found: + fclose(f); + return ret; +} + +int dev_mounted(char *dev) +{ + struct mntent *mnt = dev_to_mount(dev); + + 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 }; +}