Date: Sun, 24 May 2026 16:15:10 +0000 From: Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav <des@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 0f4fd69ee282 - stable/15 - tmpfs: Overhaul option handling on remount Message-ID: <6a13240e.30e37.687e8170@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch stable/15 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=0f4fd69ee282b7ab5f23d0a4d3e57ab1ef6ec26c commit 0f4fd69ee282b7ab5f23d0a4d3e57ab1ef6ec26c Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-05-19 06:54:28 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2026-05-24 16:14:39 +0000 tmpfs: Overhaul option handling on remount On remount, we must accept all the same options as on initial mount. For parameters which we're unable to modify on the fly, fail only if the new value is different from the existing one. PR: 295096 MFC after: 1 week Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D57044 (cherry picked from commit 1cfc208a07b64a64377a4f8fe51c28f588a929cf) --- sys/fs/tmpfs/tmpfs_vfsops.c | 100 +++++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 38 deletions(-) diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 431893b77bb9..5a9b9782b9da 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -93,10 +93,6 @@ static const char *tmpfs_opts[] = { "export", "union", "nonc", "nomtime", "nosymfollow", "pgread", NULL }; -static const char *tmpfs_updateopts[] = { - "from", "easize", "export", "nomtime", "size", "nosymfollow", NULL -}; - static int tmpfs_update_mtime_lazy_filter(struct vnode *vp, void *arg) { @@ -325,6 +321,7 @@ tmpfs_mount(struct mount *mp) sizeof(struct tmpfs_dirent) + sizeof(struct tmpfs_node)); struct tmpfs_mount *tmp; struct tmpfs_node *root; + struct vfsoptlist *opts; int error; bool nomtime, nonc, pgread; /* Size counters. */ @@ -338,44 +335,71 @@ tmpfs_mount(struct mount *mp) struct vattr va; - if (vfs_filteropt(mp->mnt_optnew, tmpfs_opts)) + opts = mp->mnt_optnew; + if (vfs_filteropt(opts, tmpfs_opts)) return (EINVAL); if (mp->mnt_flag & MNT_UPDATE) { - /* Only support update mounts for certain options. */ - if (vfs_filteropt(mp->mnt_optnew, tmpfs_updateopts) != 0) - return (EOPNOTSUPP); tmp = VFS_TO_TMPFS(mp); - if (vfs_getopt_size(mp->mnt_optnew, "size", &size_max) == 0) { - /* - * On-the-fly resizing is not supported (yet). We still - * need to have "size" listed as "supported", otherwise - * trying to update fs that is listed in fstab with size - * parameter, say trying to change rw to ro or vice - * versa, would cause vfs_filteropt() to bail. - */ - if (size_max != tmp->tm_size_max) - return (EOPNOTSUPP); - } - if (vfs_getopt_size(mp->mnt_optnew, "easize", &ea_max_size) == 0) { + + /* + * These options cannot (yet) be modified on the fly, but + * mount(8) will still pass them when remounting, so we + * will silently ignore them as long as the value is + * unchanged. + */ + if (vfs_scanopt(opts, "gid", "%d", &root_gid) == 1 && + root_gid != tmp->tm_root->tn_gid) + return (EOPNOTSUPP); + if (vfs_scanopt(opts, "uid", "%d", &root_uid) == 1 && + root_uid != tmp->tm_root->tn_uid) + return (EOPNOTSUPP); + if (vfs_scanopt(opts, "mode", "%ho", &root_mode) == 1 && + (root_mode & S_IFMT) != (tmp->tm_root->tn_mode & S_IFMT)) + return (EOPNOTSUPP); + if (vfs_getopt_size(opts, "inodes", &nodes_max) == 0 && + nodes_max != 0 && nodes_max != tmp->tm_nodes_max) + return (EOPNOTSUPP); + if (vfs_getopt_size(opts, "size", &size_max) == 0 && + size_max != 0 && size_max != tmp->tm_size_max) + return (EOPNOTSUPP); + if (vfs_getopt_size(opts, "maxfilesize", &maxfilesize) == 0 && + maxfilesize != 0 && maxfilesize != tmp->tm_maxfilesize) + return (EOPNOTSUPP); + if (tmp->tm_nonc != + (vfs_getopt(opts, "nonc", NULL, NULL) == 0)) + return (EOPNOTSUPP); + if (tmp->tm_pgread != + (vfs_getopt(opts, "pgread", NULL, NULL) == 0)) + return (EOPNOTSUPP); + + /* + * These options can be modified. + */ + if (vfs_getopt_size(opts, "easize", &ea_max_size) != 0) tmp->tm_ea_memory_max = ea_max_size; - } - if (vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) && - !tmp->tm_ronly) { + tmp->tm_nomtime = (vfs_getopt(opts, "nomtime", NULL, 0) == 0); + + /* + * Handle read-write to read-only or vice versa. + */ + if (vfs_flagopt(opts, "ro", NULL, 0) && !tmp->tm_ronly) { /* RW -> RO */ return (tmpfs_rw_to_ro(mp)); - } else if (!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) && - tmp->tm_ronly) { + } + if (!vfs_flagopt(opts, "ro", NULL, 0) && tmp->tm_ronly) { /* RO -> RW */ tmp->tm_ronly = 0; MNT_ILOCK(mp); mp->mnt_flag &= ~MNT_RDONLY; MNT_IUNLOCK(mp); } - tmp->tm_nomtime = vfs_getopt(mp->mnt_optnew, "nomtime", NULL, - 0) == 0; + + /* + * Check if fast path lookup is still supported. + */ MNT_ILOCK(mp); - if ((mp->mnt_flag & MNT_UNION) == 0) { + if (!tmp->tm_nonc && (mp->mnt_flag & MNT_UNION) == 0) { mp->mnt_kern_flag |= MNTK_FPLOOKUP; } else { mp->mnt_kern_flag &= ~MNTK_FPLOOKUP; @@ -391,25 +415,25 @@ tmpfs_mount(struct mount *mp) return (error); if (mp->mnt_cred->cr_ruid != 0 || - vfs_scanopt(mp->mnt_optnew, "gid", "%d", &root_gid) != 1) + vfs_scanopt(opts, "gid", "%d", &root_gid) != 1) root_gid = va.va_gid; if (mp->mnt_cred->cr_ruid != 0 || - vfs_scanopt(mp->mnt_optnew, "uid", "%d", &root_uid) != 1) + vfs_scanopt(opts, "uid", "%d", &root_uid) != 1) root_uid = va.va_uid; if (mp->mnt_cred->cr_ruid != 0 || - vfs_scanopt(mp->mnt_optnew, "mode", "%ho", &root_mode) != 1) + vfs_scanopt(opts, "mode", "%ho", &root_mode) != 1) root_mode = va.va_mode; - if (vfs_getopt_size(mp->mnt_optnew, "inodes", &nodes_max) != 0) + if (vfs_getopt_size(opts, "inodes", &nodes_max) != 0) nodes_max = 0; - if (vfs_getopt_size(mp->mnt_optnew, "size", &size_max) != 0) + if (vfs_getopt_size(opts, "size", &size_max) != 0) size_max = 0; - if (vfs_getopt_size(mp->mnt_optnew, "maxfilesize", &maxfilesize) != 0) + if (vfs_getopt_size(opts, "maxfilesize", &maxfilesize) != 0) maxfilesize = 0; - if (vfs_getopt_size(mp->mnt_optnew, "easize", &ea_max_size) != 0) + if (vfs_getopt_size(opts, "easize", &ea_max_size) != 0) ea_max_size = 0; - nonc = vfs_getopt(mp->mnt_optnew, "nonc", NULL, NULL) == 0; - nomtime = vfs_getopt(mp->mnt_optnew, "nomtime", NULL, NULL) == 0; - pgread = vfs_getopt(mp->mnt_optnew, "pgread", NULL, NULL) == 0; + nonc = vfs_getopt(opts, "nonc", NULL, NULL) == 0; + nomtime = vfs_getopt(opts, "nomtime", NULL, NULL) == 0; + pgread = vfs_getopt(opts, "pgread", NULL, NULL) == 0; /* Do not allow mounts if we do not have enough memory to preserve * the minimum reserved pages. */home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a13240e.30e37.687e8170>
