]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - c_src/cmd_fsck.c
Disable pristine-tar option in gbp.conf, since there is no pristine-tar branch.
[bcachefs-tools-debian] / c_src / cmd_fsck.c
index 79f520076bb204703e4bfa1e7908bad98709fbe4..0d4070a3a1afadbd66b15a393d0e527c74916826 100644 (file)
@@ -70,15 +70,17 @@ static int splice_fd_to_stdinout(int fd)
                select(fd + 1, &fds, NULL, NULL, NULL);
 
                int r = do_splice(fd, STDOUT_FILENO);
+               if (r < 0)
+                       return r;
                if (r)
-                       return r < 0 ? r : 0;
+                       break;
 
                r = do_splice(STDIN_FILENO, fd);
                if (r < 0)
                        return r;
        }
 
-       return 0;
+       return close(fd);
 }
 
 static int fsck_online(const char *dev_path)
@@ -215,11 +217,34 @@ int cmd_fsck(int argc, char *argv[])
 
        darray_str devs = get_or_split_cmdline_devs(argc, argv);
 
-       if (kernel < 0)
-               kernel = should_use_kernel_fsck(devs);
+       int kernel_probed = kernel;
+       if (kernel_probed < 0)
+               kernel_probed = should_use_kernel_fsck(devs);
+
+       struct bch_opts opts = bch2_opts_empty();
 
-       if (!kernel) {
-               struct bch_opts opts = bch2_opts_empty();
+       if (kernel_probed) {
+               struct bch_ioctl_fsck_offline *fsck = calloc(sizeof(*fsck) +
+                                                            sizeof(u64) * devs.nr, 1);
+
+               fsck->opts = (unsigned long)opts_str.buf;
+               darray_for_each(devs, i)
+                       fsck->devs[i - devs.data] = (unsigned long) *i;
+               fsck->nr_devs = devs.nr;
+
+               int ctl_fd = bcachectl_open();
+               int fsck_fd = ioctl(ctl_fd, BCH_IOCTL_FSCK_OFFLINE, fsck);
+               free(fsck);
+
+               if (fsck_fd < 0 && kernel < 0)
+                       goto userland_fsck;
+
+               if (fsck_fd < 0)
+                       die("BCH_IOCTL_FSCK_OFFLINE error: %s", bch2_err_str(fsck_fd));
+
+               ret = splice_fd_to_stdinout(fsck_fd);
+       } else {
+userland_fsck:
                ret = bch2_parse_mount_opts(NULL, &opts, opts_str.buf);
                if (ret)
                        return ret;
@@ -242,23 +267,6 @@ int cmd_fsck(int argc, char *argv[])
                }
 
                bch2_fs_stop(c);
-       } else {
-               struct bch_ioctl_fsck_offline *fsck = calloc(sizeof(*fsck) +
-                                                            sizeof(u64) * devs.nr, 1);
-
-               fsck->opts = (unsigned long)opts_str.buf;
-               darray_for_each(devs, i)
-                       fsck->devs[i - devs.data] = (unsigned long) *i;
-               fsck->nr_devs = devs.nr;
-
-               int ctl_fd = bcachectl_open();
-
-               int fsck_fd = ioctl(ctl_fd, BCH_IOCTL_FSCK_OFFLINE, fsck);
-               if (fsck_fd < 0)
-                       die("BCH_IOCTL_FSCK_OFFLINE error: %s", bch2_err_str(fsck_fd));
-
-               ret = splice_fd_to_stdinout(fsck_fd);
-               free(fsck);
        }
 
        printbuf_exit(&opts_str);