diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2021-10-24 15:33:13 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2021-10-24 15:33:13 +0000 |
commit | 84050e1b340e3e305a45cb6e2275146315f4567b (patch) | |
tree | 4c6cd3fa2978a0b951d6e5b719409aefbd258c49 /sys/tmpfs/tmpfs_vfsops.c | |
parent | d617215f58543b2efac8e550a7e2d7d3d73f87a1 (diff) |
Add mount -ur/uw support to tmpfs.
From Pedro Martelletto
Diffstat (limited to 'sys/tmpfs/tmpfs_vfsops.c')
-rw-r--r-- | sys/tmpfs/tmpfs_vfsops.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/sys/tmpfs/tmpfs_vfsops.c b/sys/tmpfs/tmpfs_vfsops.c index 4f553fd8766..55f73124a37 100644 --- a/sys/tmpfs/tmpfs_vfsops.c +++ b/sys/tmpfs/tmpfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmpfs_vfsops.c,v 1.17 2019/12/26 13:28:49 bluhm Exp $ */ +/* $OpenBSD: tmpfs_vfsops.c,v 1.18 2021/10/24 15:33:12 patrick Exp $ */ /* $NetBSD: tmpfs_vfsops.c,v 1.52 2011/09/27 01:10:43 christos Exp $ */ /* @@ -67,6 +67,7 @@ int tmpfs_vptofh(struct vnode *, struct fid *); int tmpfs_statfs(struct mount *, struct statfs *, struct proc *); int tmpfs_sync(struct mount *, int, int, struct ucred *, struct proc *); int tmpfs_init(struct vfsconf *); +int tmpfs_mount_update(struct mount *); int tmpfs_init(struct vfsconf *vfsp) @@ -81,6 +82,40 @@ tmpfs_init(struct vfsconf *vfsp) } int +tmpfs_mount_update(struct mount *mp) +{ + tmpfs_mount_t *tmp; + struct vnode *rootvp; + int error; + + if ((mp->mnt_flag & MNT_RDONLY) == 0) + return EOPNOTSUPP; + + /* ro->rw transition: nothing to do? */ + if (mp->mnt_flag & MNT_WANTRDWR) + return 0; + + tmp = mp->mnt_data; + rootvp = tmp->tm_root->tn_vnode; + + /* Lock root to prevent lookups. */ + error = vn_lock(rootvp, LK_EXCLUSIVE | LK_RETRY); + if (error) + return error; + + /* Lock mount point to prevent nodes from being added/removed. */ + rw_enter_write(&tmp->tm_lock); + + /* Flush files opened for writing; skip rootvp. */ + error = vflush(mp, rootvp, WRITECLOSE); + + rw_exit_write(&tmp->tm_lock); + VOP_UNLOCK(rootvp); + + return error; +} + +int tmpfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { @@ -112,10 +147,8 @@ tmpfs_mount(struct mount *mp, const char *path, void *data, } #endif - if (mp->mnt_flag & MNT_UPDATE) { - /* TODO */ - return EOPNOTSUPP; - } + if (mp->mnt_flag & MNT_UPDATE) + return (tmpfs_mount_update(mp)); /* Prohibit mounts if there is not enough memory. */ if (tmpfs_mem_info(1) < TMPFS_PAGES_RESERVED) |