[RFC PATCH 2/6] shmem: add tmpfs_create_mount() to create tmpfs mounts internally
From: Pratyush Yadav
Date: Wed Sep 23 2026 - 18:44:38 EST
From: "Pratyush Yadav (Google)" <pratyush@xxxxxxxxxx>
Upcoming commits will add support for preserving a tmpfs mount via LUO.
While the retrieve logic can create the mount by constructing an options
string from its preserved data, it is simpler to let it directly pass
the parameters.
tmpfs_create_mount() allows creating a mount with the specified
max_blocks and mode. The function only takes max_blocks and mode for now
because that is all the tmpfs preservation will use. All other values
are left to their defaults.
Signed-off-by: Pratyush Yadav (Google) <pratyush@xxxxxxxxxx>
---
mm/internal.h | 1 +
mm/shmem.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/mm/internal.h b/mm/internal.h
index 38b1165212c9..d82c92c8fddd 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1436,6 +1436,7 @@ int shmem_add_to_page_cache(struct folio *folio,
pgoff_t index, void *expected, gfp_t gfp);
int shmem_inode_acct_blocks(struct inode *inode, long pages);
bool shmem_recalc_inode(struct inode *inode, long alloced, long swapped);
+struct vfsmount *tmpfs_create_mount(unsigned long max_blocks, umode_t mode);
#ifdef CONFIG_SHRINKER_DEBUG
static inline __printf(2, 0) int shrinker_debugfs_name_alloc(
diff --git a/mm/shmem.c b/mm/shmem.c
index 897fa2b61346..8660405b6ab8 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -5313,6 +5313,44 @@ static struct file_system_type shmem_fs_type = {
.fs_flags = FS_USERNS_MOUNT | FS_ALLOW_IDMAP | FS_MGTIME,
};
+/**
+ * tmpfs_create_mount - Create a new tmpfs instance from explicit parameters.
+ * @max_blocks: Block limit of the filesystem, in PAGE_SIZE units, as held by
+ * shmem_sb_info::max_blocks.
+ * @mode: Mode of the root directory.
+ *
+ * Creates a new tmpfs superblock and returns a mount for it. Everything not
+ * named above is left at its default.
+ *
+ * The returned mount belongs to no mount namespace and is owned by the caller,
+ * who must either mntput() it or hand it to something that takes it over.
+ *
+ * Return: the new mount, or an ERR_PTR.
+ */
+struct vfsmount *tmpfs_create_mount(unsigned long max_blocks, umode_t mode)
+{
+ struct shmem_options *ctx;
+ struct fs_context *fc;
+ struct vfsmount *mnt;
+
+ if (!IS_ENABLED(CONFIG_TMPFS))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ fc = fs_context_for_mount(&shmem_fs_type, 0);
+ if (IS_ERR(fc))
+ return ERR_CAST(fc);
+
+ ctx = fc->fs_private;
+ ctx->blocks = max_blocks;
+ ctx->seen |= SHMEM_SEEN_BLOCKS;
+ ctx->mode = mode;
+
+ mnt = fc_mount(fc);
+ put_fs_context(fc);
+
+ return mnt;
+}
+
#if defined(CONFIG_SYSFS) && defined(CONFIG_TMPFS)
#define __INIT_KOBJ_ATTR(_name, _mode, _show, _store) \
--
2.56.0.rc1.310.g51773c2048-goog