svn commit: r345425 - head/sys/fs/tmpfs
Maxim Sobolev
sobomax at FreeBSD.org
Fri Mar 22 21:31:23 UTC 2019
Author: sobomax
Date: Fri Mar 22 21:31:21 2019
New Revision: 345425
URL: https://svnweb.freebsd.org/changeset/base/345425
Log:
Make it possible to update TMPFS mount point from read-only to read-write
and vice versa.
Reviewed by: delphij
Approved by: delphij
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D19682
Modified:
head/sys/fs/tmpfs/tmpfs.h
head/sys/fs/tmpfs/tmpfs_vfsops.c
Modified: head/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- head/sys/fs/tmpfs/tmpfs.h Fri Mar 22 19:43:50 2019 (r345424)
+++ head/sys/fs/tmpfs/tmpfs.h Fri Mar 22 21:31:21 2019 (r345425)
@@ -325,6 +325,11 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node);
*/
struct tmpfs_mount {
/*
+ * Original value of the "size" parameter, for reference purposes,
+ * mostly.
+ */
+ off_t tm_size_max;
+ /*
* Maximum number of memory pages available for use by the file
* system, set during mount time. This variable must never be
* used directly as it may be bigger than the current amount of
Modified: head/sys/fs/tmpfs/tmpfs_vfsops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vfsops.c Fri Mar 22 19:43:50 2019 (r345424)
+++ head/sys/fs/tmpfs/tmpfs_vfsops.c Fri Mar 22 21:31:21 2019 (r345425)
@@ -88,7 +88,7 @@ static const char *tmpfs_opts[] = {
};
static const char *tmpfs_updateopts[] = {
- "from", "export", NULL
+ "from", "export", "size", NULL
};
static int
@@ -134,6 +134,8 @@ tmpfs_node_fini(void *mem, int size)
mtx_destroy(&node->tn_interlock);
}
+#define TMPFS_SC(mp) ((struct tmpfs_mount *)(mp)->mnt_data)
+
static int
tmpfs_mount(struct mount *mp)
{
@@ -141,7 +143,7 @@ tmpfs_mount(struct mount *mp)
sizeof(struct tmpfs_dirent) + sizeof(struct tmpfs_node));
struct tmpfs_mount *tmp;
struct tmpfs_node *root;
- int error;
+ int error, flags;
bool nonc;
/* Size counters. */
u_quad_t pages;
@@ -161,9 +163,41 @@ tmpfs_mount(struct mount *mp)
/* Only support update mounts for certain options. */
if (vfs_filteropt(mp->mnt_optnew, tmpfs_updateopts) != 0)
return (EOPNOTSUPP);
- if (vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) !=
- ((struct tmpfs_mount *)mp->mnt_data)->tm_ronly)
- return (EOPNOTSUPP);
+ 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 != TMPFS_SC(mp)->tm_size_max)
+ return (EOPNOTSUPP);
+ }
+ if (vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) &&
+ !(TMPFS_SC(mp)->tm_ronly)) {
+ /* RW -> RO */
+ error = VFS_SYNC(mp, MNT_WAIT);
+ if (error)
+ return (error);
+ flags = WRITECLOSE;
+ if (mp->mnt_flag & MNT_FORCE)
+ flags |= FORCECLOSE;
+ error = vflush(mp, 0, flags, curthread);
+ if (error)
+ return (error);
+ TMPFS_SC(mp)->tm_ronly = 1;
+ MNT_ILOCK(mp);
+ mp->mnt_flag |= MNT_RDONLY;
+ MNT_IUNLOCK(mp);
+ } else if (!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0) &&
+ TMPFS_SC(mp)->tm_ronly) {
+ /* RO -> RW */
+ TMPFS_SC(mp)->tm_ronly = 0;
+ MNT_ILOCK(mp);
+ mp->mnt_flag &= ~MNT_RDONLY;
+ MNT_IUNLOCK(mp);
+ }
return (0);
}
@@ -229,6 +263,7 @@ tmpfs_mount(struct mount *mp)
tmp->tm_maxfilesize = maxfilesize > 0 ? maxfilesize : OFF_MAX;
LIST_INIT(&tmp->tm_nodes_used);
+ tmp->tm_size_max = size_max;
tmp->tm_pages_max = pages;
tmp->tm_pages_used = 0;
new_unrhdr64(&tmp->tm_ino_unr, 2);
More information about the svn-src-all
mailing list