[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <174786678835.1385354.17591732684085988440.stgit@frogsfrogsfrogs>
Date: Wed, 21 May 2025 15:47:12 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: tytso@....edu
Cc: linux-ext4@...r.kernel.org
Subject: [PATCH 08/10] fuse2fs: improve error handling behaviors
From: Darrick J. Wong <djwong@...nel.org>
Make the behavior of fuse2fs on filesystem errors consistent with what
the kernel driver does. Sort of. We can't panic the kernel, but we can
abort the server, which leaves a dead mount.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
misc/fuse2fs.c | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index 2d4b9c8f51264e..7f9f230f37ed2b 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -152,7 +152,7 @@ struct fuse2fs {
uint8_t ro;
uint8_t debug;
uint8_t no_default_opts;
- uint8_t panic_on_error;
+ uint8_t errors_behavior; /* actually an enum */
uint8_t minixdf;
uint8_t fakeroot;
uint8_t alloc_all_blocks;
@@ -841,6 +841,9 @@ _("Mounting read-only without recovering journal."));
err_printf(ff, "%s\n",
_("Orphans detected; running e2fsck is recommended."));
+ if (!ff->errors_behavior)
+ ff->errors_behavior = fs->super->s_errors;
+
return 0;
}
@@ -4488,6 +4491,7 @@ enum {
FUSE2FS_HELPFULL,
FUSE2FS_CACHE_SIZE,
FUSE2FS_DIRSYNC,
+ FUSE2FS_ERRORS_BEHAVIOR,
};
#define FUSE2FS_OPT(t, p, v) { t, offsetof(struct fuse2fs, p), v }
@@ -4495,7 +4499,6 @@ enum {
static struct fuse_opt fuse2fs_opts[] = {
FUSE2FS_OPT("ro", ro, 1),
FUSE2FS_OPT("rw", ro, 0),
- FUSE2FS_OPT("errors=panic", panic_on_error, 1),
FUSE2FS_OPT("minixdf", minixdf, 1),
FUSE2FS_OPT("bsddf", minixdf, 0),
FUSE2FS_OPT("fakeroot", fakeroot, 1),
@@ -4514,6 +4517,7 @@ static struct fuse_opt fuse2fs_opts[] = {
FUSE_OPT_KEY("nodelalloc", FUSE2FS_IGNORED),
FUSE_OPT_KEY("cache_size=%s", FUSE2FS_CACHE_SIZE),
FUSE_OPT_KEY("dirsync", FUSE2FS_DIRSYNC),
+ FUSE_OPT_KEY("errors=%s", FUSE2FS_ERRORS_BEHAVIOR),
FUSE_OPT_KEY("-V", FUSE2FS_VERSION),
FUSE_OPT_KEY("--version", FUSE2FS_VERSION),
@@ -4548,6 +4552,21 @@ static int fuse2fs_opt_proc(void *data, const char *arg,
return -1;
}
+ /* do not pass through to libfuse */
+ return 0;
+ case FUSE2FS_ERRORS_BEHAVIOR:
+ if (strcmp(arg + 7, "continue") == 0)
+ ff->errors_behavior = EXT2_ERRORS_CONTINUE;
+ else if (strcmp(arg + 7, "remount-ro") == 0)
+ ff->errors_behavior = EXT2_ERRORS_RO;
+ else if (strcmp(arg + 7, "panic") == 0)
+ ff->errors_behavior = EXT2_ERRORS_PANIC;
+ else {
+ fprintf(stderr, "%s: %s\n", arg,
+ _("unknown errors behavior."));
+ return -1;
+ }
+
/* do not pass through to libfuse */
return 0;
case FUSE2FS_IGNORED:
@@ -4574,6 +4593,8 @@ static int fuse2fs_opt_proc(void *data, const char *arg,
" allow_others,default_permissions,suid,dev\n"
" -o directio use O_DIRECT to read and write the disk\n"
" -o cache_size=N[KMG] use a disk cache of this size\n"
+ " -o errors= behavior when an error is encountered:\n"
+ " continue|remount-ro|panic\n"
"\n",
outargs->argv[0]);
if (key == FUSE2FS_HELPFULL) {
@@ -4962,8 +4983,22 @@ static int __translate_error(ext2_filsys fs, ext2_ino_t ino, errcode_t err,
fs->super->s_error_count++;
ext2fs_mark_super_dirty(fs);
ext2fs_flush(fs);
- if (ff->panic_on_error)
+ switch (ff->errors_behavior) {
+ case EXT2_ERRORS_CONTINUE:
+ err_printf(ff, "%s\n",
+ _("Continuing after errors; is this a good idea?."));
+ break;
+ case EXT2_ERRORS_RO:
+ err_printf(ff, "%s\n",
+ _("Remounting read-only due to errors."));
+ fs->flags &= ~EXT2_FLAG_RW;
+ break;
+ case EXT2_ERRORS_PANIC:
+ err_printf(ff, "%s\n",
+ _("Aborting filesystem mount due to errors."));
abort();
+ break;
+ }
return ret;
}
Powered by blists - more mailing lists