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>