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