summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2017-02-02 13:39:11 +0000
committerkib <kib@FreeBSD.org>2017-02-02 13:39:11 +0000
commit00bac917f4c58a8b7de153b2a3ba29dd7df53b7d (patch)
tree30dcb75021f5a8dc37e0482aec6ad1750751014a /sys/fs
parent4460d36584dac605d2195bc715403db3c10ab758 (diff)
downloadFreeBSD-src-00bac917f4c58a8b7de153b2a3ba29dd7df53b7d.zip
FreeBSD-src-00bac917f4c58a8b7de153b2a3ba29dd7df53b7d.tar.gz
MFC r312432:
Add a mount option for tmpfs(5) to not use namecache.
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/tmpfs/tmpfs.h11
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c3
-rw-r--r--sys/fs/tmpfs/tmpfs_vfsops.c5
-rw-r--r--sys/fs/tmpfs/tmpfs_vnops.c51
-rw-r--r--sys/fs/tmpfs/tmpfs_vnops.h1
5 files changed, 54 insertions, 17 deletions
diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h
index 8661f42..37e5bbb 100644
--- a/sys/fs/tmpfs/tmpfs.h
+++ b/sys/fs/tmpfs/tmpfs.h
@@ -383,7 +383,9 @@ struct tmpfs_mount {
uma_zone_t tm_node_pool;
/* Read-only status. */
- int tm_ronly;
+ bool tm_ronly;
+ /* Do not use namecache. */
+ bool tm_nonc;
};
#define TMPFS_LOCK(tm) mtx_lock(&(tm)->tm_allnode_lock)
#define TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->tm_allnode_lock)
@@ -528,4 +530,11 @@ VP_TO_TMPFS_DIR(struct vnode *vp)
return (node);
}
+static inline bool
+tmpfs_use_nc(struct vnode *vp)
+{
+
+ return (!(VFS_TO_TMPFS(vp->v_mount)->tm_nonc));
+}
+
#endif /* _FS_TMPFS_TMPFS_H_ */
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 9cefba3..816b3cc 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -591,7 +591,8 @@ loop:
TMPFS_NODE_UNLOCK(node);
/* Get a new vnode and associate it with our node. */
- error = getnewvnode("tmpfs", mp, &tmpfs_vnodeop_entries, &vp);
+ error = getnewvnode("tmpfs", mp, VFS_TO_TMPFS(mp)->tm_nonc ?
+ &tmpfs_vnodeop_nonc_entries : &tmpfs_vnodeop_entries, &vp);
if (error != 0)
goto unlock;
MPASS(vp != NULL);
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c
index 037d3fc..65a2a12 100644
--- a/sys/fs/tmpfs/tmpfs_vfsops.c
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -78,7 +78,7 @@ static int tmpfs_statfs(struct mount *, struct statfs *);
static const char *tmpfs_opts[] = {
"from", "size", "maxfilesize", "inodes", "uid", "gid", "mode", "export",
- "union", NULL
+ "union", "nonc", NULL
};
static const char *tmpfs_updateopts[] = {
@@ -137,6 +137,7 @@ tmpfs_mount(struct mount *mp)
struct tmpfs_node *root;
struct thread *td = curthread;
int error;
+ bool nonc;
/* Size counters. */
u_quad_t pages;
off_t nodes_max, size_max, maxfilesize;
@@ -185,6 +186,7 @@ tmpfs_mount(struct mount *mp)
size_max = 0;
if (vfs_getopt_size(mp->mnt_optnew, "maxfilesize", &maxfilesize) != 0)
maxfilesize = 0;
+ nonc = vfs_getopt(mp->mnt_optnew, "nonc", NULL, NULL) == 0;
/* Do not allow mounts if we do not have enough memory to preserve
* the minimum reserved pages. */
@@ -235,6 +237,7 @@ tmpfs_mount(struct mount *mp)
sizeof(struct tmpfs_node), 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;
+ tmp->tm_nonc = nonc;
/* Allocate the root node. */
error = tmpfs_alloc_node(mp, tmp, VDIR, root_uid, root_gid,
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index 9b8c460..6d6982f 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -76,11 +76,8 @@ tmpfs_vn_get_ino_alloc(struct mount *mp, void *arg, int lkflags,
}
static int
-tmpfs_lookup(struct vop_cachedlookup_args *v)
+tmpfs_lookup1(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
{
- struct vnode *dvp = v->a_dvp;
- struct vnode **vpp = v->a_vpp;
- struct componentname *cnp = v->a_cnp;
struct tmpfs_dirent *de;
struct tmpfs_node *dnode, *pnode;
struct tmpfs_mount *tm;
@@ -213,7 +210,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
* request was for creation, as it does not improve timings on
* emprical tests.
*/
- if ((cnp->cn_flags & MAKEENTRY) != 0)
+ if ((cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
cache_enter(dvp, *vpp, cnp);
out:
@@ -227,6 +224,20 @@ out:
}
static int
+tmpfs_cached_lookup(struct vop_cachedlookup_args *v)
+{
+
+ return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
+}
+
+static int
+tmpfs_lookup(struct vop_lookup_args *v)
+{
+
+ return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
+}
+
+static int
tmpfs_create(struct vop_create_args *v)
{
struct vnode *dvp = v->a_dvp;
@@ -238,7 +249,7 @@ tmpfs_create(struct vop_create_args *v)
MPASS(vap->va_type == VREG || vap->va_type == VSOCK);
error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
- if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0)
+ if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
cache_enter(dvp, *vpp, cnp);
return (error);
}
@@ -1009,10 +1020,12 @@ tmpfs_rename(struct vop_rename_args *v)
tmpfs_dir_attach(tdvp, de);
- cache_purge(fvp);
- if (tvp != NULL)
- cache_purge(tvp);
- cache_purge_negative(tdvp);
+ if (tmpfs_use_nc(fvp)) {
+ cache_purge(fvp);
+ if (tvp != NULL)
+ cache_purge(tvp);
+ cache_purge_negative(tdvp);
+ }
error = 0;
@@ -1125,8 +1138,10 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
TMPFS_NODE_MODIFIED;
TMPFS_NODE_UNLOCK(dnode);
- cache_purge(dvp);
- cache_purge(vp);
+ if (tmpfs_use_nc(dvp)) {
+ cache_purge(dvp);
+ cache_purge(vp);
+ }
/* Free the directory entry we just deleted. Note that the node
* referred by it will not be removed until the vnode is really
@@ -1270,7 +1285,8 @@ tmpfs_reclaim(struct vop_reclaim_args *v)
else
vnode_destroy_vobject(vp);
vp->v_object = NULL;
- cache_purge(vp);
+ if (tmpfs_use_nc(vp))
+ cache_purge(vp);
TMPFS_NODE_LOCK(node);
tmpfs_free_vp(vp);
@@ -1534,7 +1550,7 @@ restart:
struct vop_vector tmpfs_vnodeop_entries = {
.vop_default = &default_vnodeops,
.vop_lookup = vfs_cache_lookup,
- .vop_cachedlookup = tmpfs_lookup,
+ .vop_cachedlookup = tmpfs_cached_lookup,
.vop_create = tmpfs_create,
.vop_mknod = tmpfs_mknod,
.vop_open = tmpfs_open,
@@ -1563,3 +1579,10 @@ struct vop_vector tmpfs_vnodeop_entries = {
.vop_vptocnp = tmpfs_vptocnp,
};
+/*
+ * Same vector for mounts which do not use namecache.
+ */
+struct vop_vector tmpfs_vnodeop_nonc_entries = {
+ .vop_default = &tmpfs_vnodeop_entries,
+ .vop_lookup = tmpfs_lookup,
+};
diff --git a/sys/fs/tmpfs/tmpfs_vnops.h b/sys/fs/tmpfs/tmpfs_vnops.h
index 1e06c13..db614a05 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.h
+++ b/sys/fs/tmpfs/tmpfs_vnops.h
@@ -44,6 +44,7 @@
*/
extern struct vop_vector tmpfs_vnodeop_entries;
+extern struct vop_vector tmpfs_vnodeop_nonc_entries;
vop_access_t tmpfs_access;
vop_getattr_t tmpfs_getattr;
OpenPOWER on IntegriCloud