diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h index fad97acac069..1c6d7146d758 100644 --- a/sys/fs/tmpfs/tmpfs.h +++ b/sys/fs/tmpfs/tmpfs.h @@ -387,6 +387,9 @@ struct tmpfs_mount { * tmpfs_pool.c. */ uma_zone_t tm_dirent_pool; uma_zone_t tm_node_pool; + + /* Read-only status. */ + int tm_ronly; }; #define TMPFS_LOCK(tm) mtx_lock(&(tm)->allnode_lock) #define TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->allnode_lock) diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 96d7321e6b49..a08dafa5739d 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -82,6 +82,10 @@ static const char *tmpfs_opts[] = { NULL }; +static const char *tmpfs_updateopts[] = { + "from", "export", NULL +}; + /* --------------------------------------------------------------------- */ static int @@ -150,12 +154,13 @@ tmpfs_mount(struct mount *mp) return (EINVAL); if (mp->mnt_flag & MNT_UPDATE) { - /* - * Only support update mounts for NFS export. - */ - if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) - return (0); - return (EOPNOTSUPP); + /* 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); + return (0); } vn_lock(mp->mnt_vnodecovered, LK_SHARED | LK_RETRY); @@ -228,6 +233,7 @@ tmpfs_mount(struct mount *mp) tmpfs_node_ctor, tmpfs_node_dtor, tmpfs_node_init, tmpfs_node_fini, UMA_ALIGN_PTR, 0); + tmp->tm_ronly = (mp->mnt_flag & MNT_RDONLY) != 0; /* Allocate the root node. */ error = tmpfs_alloc_node(tmp, VDIR, root_uid,