summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-02-17 20:49:11 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2024-02-27 13:59:06 -0500
commite913944e1fa77dfce7f35c07020cf98a6666adf4 (patch)
tree1547ab4093b3d5d336e886ea7fc0d22f0353e856
parent1e43327115dddff2a4b77fcde3738c45bcdea769 (diff)
thread_with_file: add f_ops.flush
Add a flush op, to return the exit code via close(). Also update bcachefs usage to use this to return fsck exit codes. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/chardev.c25
-rw-r--r--include/linux/thread_with_file.h2
-rw-r--r--lib/thread_with_file.c12
3 files changed, 32 insertions, 7 deletions
diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c
index a2f30f45f93f..992939152f01 100644
--- a/fs/bcachefs/chardev.c
+++ b/fs/bcachefs/chardev.c
@@ -155,14 +155,28 @@ static void bch2_fsck_thread_exit(struct thread_with_stdio *_thr)
kfree(thr);
}
-static void bch2_fsck_offline_thread_fn(struct thread_with_stdio *stdio)
+static int bch2_fsck_offline_thread_fn(struct thread_with_stdio *stdio)
{
struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
struct bch_fs *c = bch2_fs_open(thr->devs, thr->nr_devs, thr->opts);
- thr->thr.thr.ret = PTR_ERR_OR_ZERO(c);
- if (!thr->thr.thr.ret)
- bch2_fs_stop(c);
+ if (IS_ERR(c))
+ return PTR_ERR(c);
+
+ int ret = 0;
+ if (test_bit(BCH_FS_errors_fixed, &c->flags))
+ ret |= 1;
+ if (test_bit(BCH_FS_error, &c->flags))
+ ret |= 4;
+
+ bch2_fs_stop(c);
+
+ if (ret & 1)
+ stdio_redirect_printf(&stdio->stdio, false, "%s: errors fixed\n", c->name);
+ if (ret & 4)
+ stdio_redirect_printf(&stdio->stdio, false, "%s: still has errors\n", c->name);
+
+ return ret;
}
static const struct thread_with_stdio_ops bch2_offline_fsck_ops = {
@@ -763,7 +777,7 @@ static long bch2_ioctl_disk_resize_journal(struct bch_fs *c,
return ret;
}
-static void bch2_fsck_online_thread_fn(struct thread_with_stdio *stdio)
+static int bch2_fsck_online_thread_fn(struct thread_with_stdio *stdio)
{
struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
struct bch_fs *c = thr->c;
@@ -795,6 +809,7 @@ static void bch2_fsck_online_thread_fn(struct thread_with_stdio *stdio)
up(&c->online_fsck_mutex);
bch2_ro_ref_put(c);
+ return ret;
}
static const struct thread_with_stdio_ops bch2_online_fsck_ops = {
diff --git a/include/linux/thread_with_file.h b/include/linux/thread_with_file.h
index 33770938d5d9..cf44337af3e9 100644
--- a/include/linux/thread_with_file.h
+++ b/include/linux/thread_with_file.h
@@ -56,7 +56,7 @@ struct thread_with_stdio;
struct thread_with_stdio_ops {
void (*exit)(struct thread_with_stdio *);
- void (*fn)(struct thread_with_stdio *);
+ int (*fn)(struct thread_with_stdio *);
long (*unlocked_ioctl)(struct thread_with_stdio *, unsigned int, unsigned long);
};
diff --git a/lib/thread_with_file.c b/lib/thread_with_file.c
index 37a1ea22823c..4f60ce7287cc 100644
--- a/lib/thread_with_file.c
+++ b/lib/thread_with_file.c
@@ -381,6 +381,14 @@ static __poll_t thread_with_stdout_poll(struct file *file, struct poll_table_str
return mask;
}
+static int thread_with_stdio_flush(struct file *file, fl_owner_t id)
+{
+ struct thread_with_stdio *thr =
+ container_of(file->private_data, struct thread_with_stdio, thr);
+
+ return thr->thr.ret;
+}
+
static long thread_with_stdio_ioctl(struct file *file, unsigned int cmd, unsigned long p)
{
struct thread_with_stdio *thr =
@@ -396,6 +404,7 @@ static const struct file_operations thread_with_stdio_fops = {
.read = thread_with_stdio_read,
.write = thread_with_stdio_write,
.poll = thread_with_stdio_poll,
+ .flush = thread_with_stdio_flush,
.release = thread_with_stdio_release,
.unlocked_ioctl = thread_with_stdio_ioctl,
};
@@ -404,6 +413,7 @@ static const struct file_operations thread_with_stdout_fops = {
.llseek = no_llseek,
.read = thread_with_stdio_read,
.poll = thread_with_stdout_poll,
+ .flush = thread_with_stdio_flush,
.release = thread_with_stdio_release,
.unlocked_ioctl = thread_with_stdio_ioctl,
};
@@ -412,7 +422,7 @@ static int thread_with_stdio_fn(void *arg)
{
struct thread_with_stdio *thr = arg;
- thr->ops->fn(thr);
+ thr->thr.ret = thr->ops->fn(thr);
thread_with_stdio_done(thr);
return 0;