Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Mar 2019 21:31:22 +0000 (UTC)
From:      Maxim Sobolev <sobomax@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r345425 - head/sys/fs/tmpfs
Message-ID:  <201903222131.x2MLVM46080847@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903222131.x2MLVM46080847>