Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/tmpfs Change tmpfs to vcache.
details: https://anonhg.NetBSD.org/src/rev/53f293d20b22
branches: trunk
changeset: 339232:53f293d20b22
user: hannken <hannken%NetBSD.org@localhost>
date: Mon Jul 06 10:07:12 2015 +0000
description:
Change tmpfs to vcache.
- Use tmpfs node address as key.
- Remove tn_vlock, field tn_vnode now protected by vcache.
- Add a hold count to tmpfs node to prevent nodes from disappearing
while tmpfs_fhtovp() trys to vcache_get() them. Last holder
destroys reclaimed nodes.
- Remove the now unneeded parent unlock/lock for lookup of '..'.
diffstat:
sys/fs/tmpfs/tmpfs.h | 26 +-
sys/fs/tmpfs/tmpfs_rename.c | 39 +--
sys/fs/tmpfs/tmpfs_subr.c | 385 ++++++++++++++++++++++---------------------
sys/fs/tmpfs/tmpfs_vfsops.c | 57 +++++-
sys/fs/tmpfs/tmpfs_vnops.c | 40 +---
5 files changed, 278 insertions(+), 269 deletions(-)
diffs (truncated from 907 to 300 lines):
diff -r ba1102415645 -r 53f293d20b22 sys/fs/tmpfs/tmpfs.h
--- a/sys/fs/tmpfs/tmpfs.h Mon Jul 06 10:05:50 2015 +0000
+++ b/sys/fs/tmpfs/tmpfs.h Mon Jul 06 10:07:12 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs.h,v 1.51 2015/07/06 10:05:50 hannken Exp $ */
+/* $NetBSD: tmpfs.h,v 1.52 2015/07/06 10:07:12 hannken Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
* a particular type.
*
* All fields are protected by vnode lock. The vnode association itself
- * is protected by tmpfs_node_t::tn_vlock.
+ * is protected by vcache.
*/
typedef struct tmpfs_node {
LIST_ENTRY(tmpfs_node) tn_entries;
@@ -88,9 +88,11 @@
* tn_vnode. It may be NULL when the node is unused (that is,
* no vnode has been allocated or it has been reclaimed).
*/
- kmutex_t tn_vlock;
vnode_t * tn_vnode;
+ /* Prevent node from being reclaimed. */
+ uint32_t tn_holdcount;
+
/* Directory entry. Only a hint, since hard link can have multiple. */
tmpfs_dirent_t * tn_dirent_hint;
@@ -188,16 +190,12 @@
#define TMPFS_UPDATE_CTIME 0x04
/*
- * Bits indicating vnode reclamation and whiteout use for the directory.
+ * Bits indicating whiteout use for the directory.
* We abuse tmpfs_node_t::tn_gen for that.
*/
-#define TMPFS_RECLAIMING_BIT (1U << 31)
-#define TMPFS_WHITEOUT_BIT (1U << 30)
+#define TMPFS_WHITEOUT_BIT (1U << 31)
#define TMPFS_NODE_GEN_MASK (TMPFS_WHITEOUT_BIT - 1)
-#define TMPFS_NODE_RECLAIMING(node) \
- (((node)->tn_gen & TMPFS_RECLAIMING_BIT) != 0)
-
#define TMPFS_NODE_GEN(node) \
((node)->tn_gen & TMPFS_NODE_GEN_MASK)
@@ -205,6 +203,12 @@
#define TMPFS_NODE_WHITEOUT ((tmpfs_node_t *)-1)
/*
+ * Bit indicating this node must be reclaimed when holdcount reaches zero.
+ * Ored into tmpfs_node_t::tn_holdcount.
+ */
+#define TMPFS_NODE_RECLAIMED (1U << 30)
+
+/*
* Internal representation of a tmpfs mount point.
*/
typedef struct tmpfs_mount {
@@ -242,15 +246,11 @@
* Prototypes for tmpfs_subr.c.
*/
-int tmpfs_alloc_node(tmpfs_mount_t *, enum vtype, uid_t, gid_t,
- mode_t, char *, dev_t, tmpfs_node_t **);
void tmpfs_free_node(tmpfs_mount_t *, tmpfs_node_t *);
int tmpfs_construct_node(vnode_t *, vnode_t **, struct vattr *,
struct componentname *, char *);
-int tmpfs_vnode_get(struct mount *, tmpfs_node_t *, vnode_t **);
-
int tmpfs_alloc_dirent(tmpfs_mount_t *, const char *, uint16_t,
tmpfs_dirent_t **);
void tmpfs_free_dirent(tmpfs_mount_t *, tmpfs_dirent_t *);
diff -r ba1102415645 -r 53f293d20b22 sys/fs/tmpfs/tmpfs_rename.c
--- a/sys/fs/tmpfs/tmpfs_rename.c Mon Jul 06 10:05:50 2015 +0000
+++ b/sys/fs/tmpfs/tmpfs_rename.c Mon Jul 06 10:07:12 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_rename.c,v 1.6 2013/11/23 16:35:32 rmind Exp $ */
+/* $NetBSD: tmpfs_rename.c,v 1.7 2015/07/06 10:07:12 hannken Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_rename.c,v 1.6 2013/11/23 16:35:32 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_rename.c,v 1.7 2015/07/06 10:07:12 hannken Exp $");
#include <sys/param.h>
#include <sys/errno.h>
@@ -425,7 +425,7 @@
{
struct tmpfs_dirent *dirent, **dep_ret = de_ret;
struct vnode *vp;
- int error;
+ int error __diagused;
(void)mp;
KASSERT(mp != NULL);
@@ -439,27 +439,15 @@
if (dirent == NULL)
return ENOENT;
- mutex_enter(&dirent->td_node->tn_vlock);
- error = tmpfs_vnode_get(mp, dirent->td_node, &vp);
- /* Note: tmpfs_vnode_get always releases dirent->td_node->tn_vlock. */
+ error = vcache_get(mp, &dirent->td_node, sizeof(dirent->td_node), &vp);
if (error)
return error;
-
KASSERT(vp != NULL);
- KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
/*
- * tmpfs_vnode_get returns this locked for us, which would be
- * convenient but for lossage in other file systems. So, for
- * hysterical raisins, we have to unlock it here. The caller
- * will lock it again, and we don't rely on any interesting
- * invariants in the interim, beyond that it won't vanish from
- * under us, which it won't because it's referenced.
- *
* XXX Once namei is fixed, we can change the genfs_rename
- * protocol so that this unlock is not necessary.
+ * protocol so that we have to lock vp her.
*/
- VOP_UNLOCK(vp);
*dep_ret = dirent;
*vp_ret = vp;
@@ -491,7 +479,7 @@
struct vnode *fdvp, struct vnode *tdvp,
struct vnode **intermediate_node_ret)
{
- struct vnode *vp;
+ struct vnode *vp, *ovp;
struct tmpfs_node *dnode;
int error;
@@ -549,15 +537,20 @@
}
/* Neither -- keep ascending the family tree. */
- mutex_enter(&dnode->tn_vlock);
- vput(vp);
- vp = NULL; /* Just in case, for the kassert above... */
- error = tmpfs_vnode_get(mp, dnode, &vp);
+ ovp = vp;
+ vp = NULL;
+ error = vcache_get(mp, &dnode, sizeof(dnode), &vp);
+ vput(ovp);
if (error)
return error;
+ error = vn_lock(vp, LK_EXCLUSIVE);
+ if (error) {
+ vrele(vp);
+ return error;
+ }
/*
- * tmpfs_vnode_get only guarantees that dnode will not
+ * vcache_get only guarantees that dnode will not
* be freed while we get a vnode for it. It does not
* preserve any other invariants, so we must check
* whether the parent has been removed in the meantime.
diff -r ba1102415645 -r 53f293d20b22 sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c Mon Jul 06 10:05:50 2015 +0000
+++ b/sys/fs/tmpfs/tmpfs_subr.c Mon Jul 06 10:07:12 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_subr.c,v 1.98 2015/04/20 13:44:16 riastradh Exp $ */
+/* $NetBSD: tmpfs_subr.c,v 1.99 2015/07/06 10:07:12 hannken Exp $ */
/*
* Copyright (c) 2005-2013 The NetBSD Foundation, Inc.
@@ -64,17 +64,16 @@
* If an inode has references within the file system (tn_links > 0) and
* its inactive vnode gets reclaimed/recycled - then the association is
* broken in tmpfs_reclaim(). In such case, an inode will always pass
- * tmpfs_lookup() and thus tmpfs_vnode_get() to associate a new vnode.
+ * tmpfs_lookup() and thus vcache_get() to associate a new vnode.
*
* Lock order
*
- * tmpfs_node_t::tn_vlock ->
- * vnode_t::v_vlock ->
- * vnode_t::v_interlock
+ * vnode_t::v_vlock ->
+ * vnode_t::v_interlock
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.98 2015/04/20 13:44:16 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.99 2015/07/06 10:07:12 hannken Exp $");
#include <sys/param.h>
#include <sys/cprng.h>
@@ -102,115 +101,197 @@
static void tmpfs_dir_putseq(tmpfs_node_t *, tmpfs_dirent_t *);
/*
- * tmpfs_alloc_node: allocate a new inode of a specified type and
- * insert it into the list of specified mount point.
+ * Initialize vnode with tmpfs node.
+ */
+static void
+tmpfs_init_vnode(struct vnode *vp, tmpfs_node_t *node)
+{
+ kmutex_t *slock;
+
+ KASSERT(node->tn_vnode == NULL);
+
+ /* Share the interlock with the node. */
+ if (node->tn_type == VREG) {
+ slock = node->tn_spec.tn_reg.tn_aobj->vmobjlock;
+ mutex_obj_hold(slock);
+ uvm_obj_setlock(&vp->v_uobj, slock);
+ }
+
+ vp->v_tag = VT_TMPFS;
+ vp->v_type = node->tn_type;
+
+ /* Type-specific initialization. */
+ switch (vp->v_type) {
+ case VBLK:
+ case VCHR:
+ vp->v_op = tmpfs_specop_p;
+ spec_node_init(vp, node->tn_spec.tn_dev.tn_rdev);
+ break;
+ case VFIFO:
+ vp->v_op = tmpfs_fifoop_p;
+ break;
+ case VDIR:
+ if (node->tn_spec.tn_dir.tn_parent == node)
+ vp->v_vflag |= VV_ROOT;
+ /* FALLTHROUGH */
+ case VLNK:
+ case VREG:
+ case VSOCK:
+ vp->v_op = tmpfs_vnodeop_p;
+ break;
+ default:
+ panic("bad node type %d", vp->v_type);
+ break;
+ }
+
+ vp->v_data = node;
+ node->tn_vnode = vp;
+ uvm_vnp_setsize(vp, node->tn_size);
+}
+
+/*
+ * tmpfs_loadvnode: initialise a vnode for a specified inode.
*/
int
-tmpfs_alloc_node(tmpfs_mount_t *tmp, enum vtype type, uid_t uid, gid_t gid,
- mode_t mode, char *target, dev_t rdev, tmpfs_node_t **node)
+tmpfs_loadvnode(struct mount *mp, struct vnode *vp,
+ const void *key, size_t key_len, const void **new_key)
{
- tmpfs_node_t *nnode;
+ tmpfs_node_t *node;
+
+ KASSERT(key_len == sizeof(node));
+ memcpy(&node, key, key_len);
+
+ if (node->tn_links == 0)
+ return ENOENT;
+
+ tmpfs_init_vnode(vp, node);
+
+ *new_key = &vp->v_data;
+
+ return 0;
+}
- nnode = tmpfs_node_get(tmp);
- if (nnode == NULL) {
+/*
+ * tmpfs_newvnode: allocate a new inode of a specified type and
+ * attach the vonode.
+ */
+int
+tmpfs_newvnode(struct mount *mp, struct vnode *dvp, struct vnode *vp,
+ struct vattr *vap, kauth_cred_t cred,
+ size_t *key_len, const void **new_key)
+{
+ tmpfs_mount_t *tmp = VFS_TO_TMPFS(mp);
+ tmpfs_node_t *node, *dnode;
+
+ if (dvp != NULL) {
+ KASSERT(VOP_ISLOCKED(dvp));
+ dnode = VP_TO_TMPFS_DIR(dvp);
+ if (dnode->tn_links == 0)
+ return ENOENT;
Home |
Main Index |
Thread Index |
Old Index