From: Darrick J. Wong <djwong@xxxxxxxxxx> Add a mount option to control iomap usage so that we can test before and after scenarios. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- misc/fuse2fs.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index e688772ddd8b60..d4912dee08d43f 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -219,6 +219,12 @@ enum fuse2fs_opstate { F2OP_SHUTDOWN, }; +enum fuse2fs_feature_toggle { + FT_DISABLE, + FT_ENABLE, + FT_DEFAULT, +}; + #ifdef HAVE_FUSE_IOMAP enum fuse2fs_iomap_state { IOMAP_DISABLED, @@ -253,6 +259,7 @@ struct fuse2fs { enum fuse2fs_opstate opstate; int blocklog; #ifdef HAVE_FUSE_IOMAP + enum fuse2fs_feature_toggle iomap_want; enum fuse2fs_iomap_state iomap_state; #endif unsigned int blockmask; @@ -1235,6 +1242,13 @@ static void *op_init(struct fuse_conn_info *conn fuse2fs_iomap_confirm(conn, ff); } +#if defined(HAVE_FUSE_IOMAP) + if (ff->iomap_want == FT_ENABLE && !fuse2fs_iomap_enabled(ff)) { + err_printf(ff, "%s\n", _("could not enable iomap.")); + goto mount_fail; + } +#endif + /* * If we're mounting in iomap mode, we need to unmount in op_destroy * so that the block device will be released before umount(2) returns. @@ -5307,6 +5321,9 @@ enum { FUSE2FS_CACHE_SIZE, FUSE2FS_DIRSYNC, FUSE2FS_ERRORS_BEHAVIOR, +#ifdef HAVE_FUSE_IOMAP + FUSE2FS_IOMAP, +#endif }; #define FUSE2FS_OPT(t, p, v) { t, offsetof(struct fuse2fs, p), v } @@ -5335,6 +5352,10 @@ static struct fuse_opt fuse2fs_opts[] = { FUSE_OPT_KEY("cache_size=%s", FUSE2FS_CACHE_SIZE), FUSE_OPT_KEY("dirsync", FUSE2FS_DIRSYNC), FUSE_OPT_KEY("errors=%s", FUSE2FS_ERRORS_BEHAVIOR), +#ifdef HAVE_FUSE_IOMAP + FUSE_OPT_KEY("iomap=%s", FUSE2FS_IOMAP), + FUSE_OPT_KEY("iomap", FUSE2FS_IOMAP), +#endif FUSE_OPT_KEY("-V", FUSE2FS_VERSION), FUSE_OPT_KEY("--version", FUSE2FS_VERSION), @@ -5386,6 +5407,23 @@ static int fuse2fs_opt_proc(void *data, const char *arg, /* do not pass through to libfuse */ return 0; +#ifdef HAVE_FUSE_IOMAP + case FUSE2FS_IOMAP: + if (strcmp(arg, "iomap") == 0 || strcmp(arg + 6, "1") == 0) + ff->iomap_want = FT_ENABLE; + else if (strcmp(arg + 6, "0") == 0) + ff->iomap_want = FT_DISABLE; + else if (strcmp(arg + 6, "default") == 0) + ff->iomap_want = FT_DEFAULT; + else { + fprintf(stderr, "%s: %s\n", arg, + _("unknown iomap= behavior.")); + return -1; + } + + /* do not pass through to libfuse */ + return 0; +#endif case FUSE2FS_IGNORED: return 0; case FUSE2FS_HELP: @@ -5413,6 +5451,9 @@ static int fuse2fs_opt_proc(void *data, const char *arg, " -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" +#ifdef HAVE_FUSE_IOMAP + " -o iomap= 0 to disable iomap, 1 to enable iomap\n" +#endif "\n", outargs->argv[0]); if (key == FUSE2FS_HELPFULL) { @@ -5500,6 +5541,7 @@ int main(int argc, char *argv[]) .magic = FUSE2FS_MAGIC, .opstate = F2OP_WRITABLE, #ifdef HAVE_FUSE_IOMAP + .iomap_want = FT_DEFAULT, .iomap_state = IOMAP_UNKNOWN, #endif }; @@ -5518,6 +5560,11 @@ int main(int argc, char *argv[]) exit(1); } +#ifdef HAVE_FUSE_IOMAP + if (fctx.iomap_want == FT_DISABLE) + fctx.iomap_state = IOMAP_DISABLED; +#endif + /* /dev/sda -> sda for reporting */ fctx.shortdev = strrchr(fctx.device, '/'); if (fctx.shortdev)