]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - tools-util.c
Update bcachefs sources to 4a4139a563 bcachefs: Fix extent_sort_fix_overlapping()
[bcachefs-tools-debian] / tools-util.c
index f2ff97d2c90cba76392acadd938c5baf6a32cdc6..1a656ed1911c815a71f6ccbe76515bf86a9bed04 100644 (file)
@@ -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, ...)
@@ -122,7 +122,7 @@ struct stat xstat(const char *path)
 {
        struct stat statbuf;
        if (stat(path, &statbuf))
-               die("stat error: %m");
+               die("stat error statting %s: %m", path);
        return statbuf;
 }
 
@@ -197,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);
 
@@ -218,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);
 
@@ -386,7 +390,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++;
@@ -530,10 +534,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;
@@ -546,8 +550,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
 
@@ -603,34 +614,48 @@ char *dev_to_path(dev_t dev)
        return path;
 }
 
-char *dev_to_mount(char *dev)
+struct mntent *dev_to_mount(char *dev)
 {
-       char *line = NULL, *ret = NULL;
-       size_t n = 0;
-
-       FILE *f = fopen("/proc/mounts", "r");
+       struct mntent *mnt, *ret = NULL;
+       FILE *f = setmntent("/proc/mounts", "r");
        if (!f)
                die("error opening /proc/mounts: %m");
 
-       while (getline(&line, &n, f) != -1) {
-               char *d, *p = line;
-               char *devs = strsep(&p, " ");
-               char *mount = strsep(&p, " ");
-
-               if (!devs || !mount)
-                       continue;
-
-               p = devs;
-               while ((d = strsep(&p, ":")))
-                       if (!strcmp(d, dev)) {
-                               ret = strdup(mount);
-                               goto found;
+       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);
-       free(line);
        return ret;
 }
 
-#endif
+bool dev_mounted_rw(char *dev)
+{
+       struct mntent *mnt = dev_to_mount(dev);
+
+       return mnt && !hasmntopt(mnt, "ro");
+}