]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
fuse2fs: allow setting of the cache size
authorDarrick J. Wong <djwong@kernel.org>
Thu, 24 Apr 2025 21:46:49 +0000 (14:46 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 21 May 2025 14:29:30 +0000 (10:29 -0400)
Create a CLI option so that we can adjust the disk cache size, and set
it to 32MB by default.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/174553065600.1161238.586822649522740605.stgit@frogsfrogsfrogs
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
misc/Makefile.in
misc/fuse2fs.1.in
misc/fuse2fs.c

index 2d5be8c627c5e179bc1c163b697f5137214d33cd..ce4a24d5151c817199f80ef6ec245312cf5f100b 100644 (file)
@@ -422,11 +422,11 @@ filefrag.profiled: $(FILEFRAG_OBJS)
                $(PROFILED_FILEFRAG_OBJS) 
 
 fuse2fs: $(FUSE2FS_OBJS) $(DEPLIBS) $(DEPLIBBLKID) $(DEPLIBUUID) \
-               $(LIBEXT2FS)
+               $(LIBEXT2FS) $(DEPLIBS_E2P)
        $(E) "  LD $@"
        $(Q) $(CC) $(ALL_LDFLAGS) -o fuse2fs $(FUSE2FS_OBJS) $(LIBS) \
                $(LIBFUSE) $(LIBBLKID) $(LIBUUID) $(LIBEXT2FS) $(LIBINTL) \
-               $(CLOCK_GETTIME_LIB) $(SYSLIBS)
+               $(CLOCK_GETTIME_LIB) $(SYSLIBS) $(LIBS_E2P)
 
 journal.o: $(srcdir)/../debugfs/journal.c
        $(E) "  CC $<"
@@ -875,7 +875,8 @@ fuse2fs.o: $(srcdir)/fuse2fs.c $(top_builddir)/lib/config.h \
  $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
- $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/version.h
+ $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/version.h \
+ $(top_srcdir)/lib/e2p/e2p.h
 e2fuzz.o: $(srcdir)/e2fuzz.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
index 43678a1c1971c53353efd312384b03fd40d017c2..d485ccbdc02f34de60e14b7fce8fc8b0295c076a 100644 (file)
@@ -65,6 +65,12 @@ Note that these options can still be overridden (e.g.
 .TP
 .BR -o direct
 Use O_DIRECT to access the block device.
+.TP
+.BR -o cache_size
+Set the disk cache size to this quantity.
+The quantity may contain the suffixes k, m, or g.
+By default, the size is 32MB.
+The size may not be larger than 2GB.
 .SS "FUSE options:"
 .TP
 \fB-d -o\fR debug
index 96f30ac240e6b6f88a548216190b69301953d7c4..99ef573cac39228bd746c9737f4f1511a9785eed 100644 (file)
@@ -53,6 +53,7 @@
 
 #include "../version.h"
 #include "uuid/uuid.h"
+#include "e2p/e2p.h"
 
 #ifdef ENABLE_NLS
 #include <libintl.h>
@@ -161,6 +162,7 @@ struct fuse2fs {
        int directio;
        unsigned long offset;
        unsigned int next_generation;
+       unsigned long long cache_size;
 };
 
 #define FUSE2FS_CHECK_MAGIC(fs, ptr, num) do {if ((ptr)->magic != (num)) \
@@ -3760,6 +3762,7 @@ enum {
        FUSE2FS_VERSION,
        FUSE2FS_HELP,
        FUSE2FS_HELPFULL,
+       FUSE2FS_CACHE_SIZE,
 };
 
 #define FUSE2FS_OPT(t, p, v) { t, offsetof(struct fuse2fs, p), v }
@@ -3782,6 +3785,7 @@ static struct fuse_opt fuse2fs_opts[] = {
        FUSE_OPT_KEY("acl",             FUSE2FS_IGNORED),
        FUSE_OPT_KEY("user_xattr",      FUSE2FS_IGNORED),
        FUSE_OPT_KEY("noblock_validity", FUSE2FS_IGNORED),
+       FUSE_OPT_KEY("cache_size=%s",   FUSE2FS_CACHE_SIZE),
 
        FUSE_OPT_KEY("-V",             FUSE2FS_VERSION),
        FUSE_OPT_KEY("--version",      FUSE2FS_VERSION),
@@ -3804,6 +3808,16 @@ static int fuse2fs_opt_proc(void *data, const char *arg,
                        return 0;
                }
                return 1;
+       case FUSE2FS_CACHE_SIZE:
+               ff->cache_size = parse_num_blocks2(arg + 12, -1);
+               if (ff->cache_size < 1 || ff->cache_size > INT32_MAX) {
+                       fprintf(stderr, "%s: %s\n", arg,
+ _("cache size must be between 1 block and 2GB."));
+                       return -1;
+               }
+
+               /* do not pass through to libfuse */
+               return 0;
        case FUSE2FS_IGNORED:
                return 0;
        case FUSE2FS_HELP:
@@ -3827,6 +3841,7 @@ static int fuse2fs_opt_proc(void *data, const char *arg,
        "    -o kernel              run this as if it were the kernel, which sets:\n"
        "                           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"
        "\n",
                        outargs->argv[0]);
                if (key == FUSE2FS_HELPFULL) {
@@ -3865,6 +3880,25 @@ out_default:
        return "ext4";
 }
 
+/* Figure out a reasonable default size for the disk cache */
+static unsigned long long default_cache_size(void)
+{
+       long pages = 0, pagesize = 0;
+
+#ifdef _SC_PHYS_PAGES
+       pages = sysconf(_SC_PHYS_PAGES);
+#endif
+#ifdef _SC_PAGESIZE
+       pagesize = sysconf(_SC_PAGESIZE);
+#endif
+       long long max_cache = (long long)pagesize * pages / 20;
+       unsigned long long ret = 32ULL << 20; /* 32 MB */
+
+       if (max_cache > 0 && ret > max_cache)
+               return max_cache;
+       return ret;
+}
+
 int main(int argc, char *argv[])
 {
        struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
@@ -3944,6 +3978,23 @@ int main(int argc, char *argv[])
        fctx.fs = global_fs;
        global_fs->priv_data = &fctx;
 
+       if (!fctx.cache_size)
+               fctx.cache_size = default_cache_size();
+       if (fctx.cache_size) {
+               char buf[55];
+
+               snprintf(buf, sizeof(buf), "cache_blocks=%llu",
+                               fctx.cache_size / global_fs->blocksize);
+               err = io_channel_set_options(global_fs->io, buf);
+               if (err) {
+                       err_printf(&fctx, "%s %lluk: %s\n",
+                                  _("cannot set disk cache size to"),
+                                  fctx.cache_size >> 10,
+                                  error_message(err));
+                       goto out;
+               }
+       }
+
        ret = 3;
 
        if (ext2fs_has_feature_quota(global_fs->super)) {