Module Name:    src
Committed By:   hannken
Date:           Sat Oct  4 13:27:24 UTC 2014

Modified Files:
        src/sys/fs/filecorefs: filecore_lookup.c filecore_node.c
            filecore_node.h filecore_vfsops.c

Log Message:
Change filecore to vcache.

Compile-tested only, was not able to get my hands on a readable fs image.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/fs/filecorefs/filecore_lookup.c
cvs rdiff -u -r1.26 -r1.27 src/sys/fs/filecorefs/filecore_node.c
cvs rdiff -u -r1.5 -r1.6 src/sys/fs/filecorefs/filecore_node.h
cvs rdiff -u -r1.76 -r1.77 src/sys/fs/filecorefs/filecore_vfsops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/filecorefs/filecore_lookup.c
diff -u src/sys/fs/filecorefs/filecore_lookup.c:1.20 src/sys/fs/filecorefs/filecore_lookup.c:1.21
--- src/sys/fs/filecorefs/filecore_lookup.c:1.20	Tue Jun  3 19:30:30 2014
+++ src/sys/fs/filecorefs/filecore_lookup.c	Sat Oct  4 13:27:24 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecore_lookup.c,v 1.20 2014/06/03 19:30:30 joerg Exp $	*/
+/*	$NetBSD: filecore_lookup.c,v 1.21 2014/10/04 13:27:24 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1989, 1993, 1994 The Regents of the University of California.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filecore_lookup.c,v 1.20 2014/06/03 19:30:30 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filecore_lookup.c,v 1.21 2014/10/04 13:27:24 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/namei.h>
@@ -128,8 +128,6 @@ filecore_lookup(void *v)
 	struct buf *bp;			/* a buffer of directory entries */
 	struct filecore_direntry *de;
 	int numdirpasses;		/* strategy for directory search */
-	struct vnode *pdp;		/* saved dp during symlink work */
-	struct vnode *tdp;		/* returned by filecore_vget_internal */
 	int error;
 	u_short namelen;
 	int res;
@@ -259,54 +257,24 @@ found:
 	if ((flags & ISLASTCN) && nameiop == LOOKUP)
 		dp->i_diroff = i;
 
-	/*
-	 * Step through the translation in the name.  We do not `iput' the
-	 * directory because we may need it again if a symbolic link
-	 * is relative to the current directory.  Instead we save it
-	 * unlocked as "pdp".  We must get the target inode before unlocking
-	 * the directory to insure that the inode will not be removed
-	 * before we get it.  We prevent deadlock by always fetching
-	 * inodes from the root, moving down the directory tree. Thus
-	 * when following backward pointers ".." we must unlock the
-	 * parent directory before getting the requested directory.
-	 * There is a potential race condition here if both the current
-	 * and parent directories are removed before the `iget' for the
-	 * inode associated with ".." returns.  We hope that this occurs
-	 * infrequently since we cannot avoid this race condition without
-	 * implementing a sophisticated deadlock detection algorithm.
-	 * Note also that this simple deadlock detection scheme will not
-	 * work if the file system has any hard links other than ".."
-	 * that point backwards in the directory structure.
-	 */
-	pdp = vdp;
-
-	/*
-	 * If ino is different from dp->i_ino,
-	 * it's a relocated directory.
-	 */
-	if (flags & ISDOTDOT) {
-		ino_t pin = filecore_getparent(dp);
-
-		VOP_UNLOCK(pdp);	/* race to get the inode */
-		error = VFS_VGET(vdp->v_mount, pin, &tdp);
-		vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
-		if (error) {
-			return error;
-		}
-		*vpp = tdp;
-	} else if (name[0] == '.' && namelen == 1) {
+	if (name[0] == '.' && namelen == 1) {
 		vref(vdp);	/* we want ourself, ie "." */
 		*vpp = vdp;
 	} else {
+		ino_t ino;
+
+		if (flags & ISDOTDOT) {
+			ino = filecore_getparent(dp);
+		} else {
+			ino = dp->i_dirent.addr | (i << FILECORE_INO_INDEX);
 #ifdef FILECORE_DEBUG_BR
 			printf("brelse(%p) lo4\n", bp);
 #endif
-		brelse(bp, 0);
-		error = VFS_VGET(vdp->v_mount, dp->i_dirent.addr |
-		    (i << FILECORE_INO_INDEX), &tdp);
+			brelse(bp, 0);
+		}
+		error = vcache_get(vdp->v_mount, &ino, sizeof(ino), vpp);
 		if (error)
-			return (error);
-		*vpp = tdp;
+			return error;
 	}
 
 	/*
@@ -314,7 +282,5 @@ found:
 	 */
 	cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
 		    cnp->cn_flags);
-	if (*vpp != vdp)
-		VOP_UNLOCK(*vpp);
 	return 0;
 }

Index: src/sys/fs/filecorefs/filecore_node.c
diff -u src/sys/fs/filecorefs/filecore_node.c:1.26 src/sys/fs/filecorefs/filecore_node.c:1.27
--- src/sys/fs/filecorefs/filecore_node.c:1.26	Thu Feb 27 16:51:38 2014
+++ src/sys/fs/filecorefs/filecore_node.c	Sat Oct  4 13:27:24 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecore_node.c,v 1.26 2014/02/27 16:51:38 hannken Exp $	*/
+/*	$NetBSD: filecore_node.c,v 1.27 2014/10/04 13:27:24 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1994
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filecore_node.c,v 1.26 2014/02/27 16:51:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filecore_node.c,v 1.27 2014/10/04 13:27:24 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -87,19 +87,14 @@ __KERNEL_RCSID(0, "$NetBSD: filecore_nod
 #include <fs/filecorefs/filecore_node.h>
 #include <fs/filecorefs/filecore_mount.h>
 
-/*
- * Structures associated with filecore_node caching.
- */
-static LIST_HEAD(ihashhead, filecore_node) *filecorehashtbl;
-static u_long		filecorehash;
-
-#define	INOHASH(device, inum)	(((device) + ((inum)>>12)) & filecorehash)
-
-static kmutex_t		filecore_ihash_lock;
 struct pool		filecore_node_pool;
 
 extern int prtactive;	/* 1 => print out reclaim of active vnodes */
 
+static const struct genfs_ops filecore_genfsops = {
+        .gop_size = genfs_size,
+};
+
 /*
  * Initialize hash links for inodes and dnodes.
  */
@@ -107,11 +102,8 @@ void
 filecore_init(void)
 {
 
-	mutex_init(&filecore_ihash_lock, MUTEX_DEFAULT, IPL_NONE);
 	pool_init(&filecore_node_pool, sizeof(struct filecore_node), 0, 0, 0,
 	    "filecrnopl", &pool_allocator_nointr, IPL_NONE);
-	filecorehashtbl = hashinit(desiredvnodes, HASH_LIST, true,
-	    &filecorehash);
 }
 
 /*
@@ -120,27 +112,7 @@ filecore_init(void)
 void
 filecore_reinit(void)
 {
-	struct filecore_node *ip;
-	struct ihashhead *oldhash, *hash;
-	u_long oldmask, mask, val;
-	int i;
-
-	hash = hashinit(desiredvnodes, HASH_LIST, true, &mask);
-
-	mutex_enter(&filecore_ihash_lock);
-	oldhash = filecorehashtbl;
-	oldmask = filecorehash;
-	filecorehashtbl = hash;
-	filecorehash = mask;
-	for (i = 0; i <= oldmask; i++) {
-		while ((ip = LIST_FIRST(&oldhash[i])) != NULL) {
-			LIST_REMOVE(ip, i_hash);
-			val = INOHASH(ip->i_dev, ip->i_number);
-			LIST_INSERT_HEAD(&hash[val], ip, i_hash);
-		}
-	}
-	mutex_exit(&filecore_ihash_lock);
-	hashdone(oldhash, HASH_LIST, oldmask);
+
 }
 
 /*
@@ -150,64 +122,88 @@ void
 filecore_done(void)
 {
 
-	hashdone(filecorehashtbl, HASH_LIST, filecorehash);
 	pool_destroy(&filecore_node_pool);
-	mutex_destroy(&filecore_ihash_lock);
 }
 
 /*
- * Use the device/inum pair to find the incore inode, and return a pointer
- * to it. If it is in core, but locked, wait for it.
+ * Initialize this vnode / filecore node pair.
+ * Caller assures no other thread will try to load this node.
  */
-struct vnode *
-filecore_ihashget(dev_t dev, ino_t inum)
+int
+filecore_loadvnode(struct mount *mp, struct vnode *vp,
+    const void *key, size_t key_len, const void **new_key)
 {
+	ino_t ino;
+	struct filecore_mnt *fcmp;
 	struct filecore_node *ip;
-	struct vnode *vp;
+	struct buf *bp;
+	int error;
 
-loop:
-	mutex_enter(&filecore_ihash_lock);
-	LIST_FOREACH(ip, &filecorehashtbl[INOHASH(dev, inum)], i_hash) {
-		if (inum == ip->i_number && dev == ip->i_dev) {
-			vp = ITOV(ip);
-			mutex_enter(vp->v_interlock);
-			mutex_exit(&filecore_ihash_lock);
-			if (vget(vp, LK_EXCLUSIVE))
-				goto loop;
-			return (vp);
+	KASSERT(key_len == sizeof(ino));
+	memcpy(&ino, key, key_len);
+	fcmp = VFSTOFILECORE(mp);
+
+	ip = pool_get(&filecore_node_pool, PR_WAITOK);
+	memset(ip, 0, sizeof(struct filecore_node));
+	ip->i_vnode = vp;
+	ip->i_dev = fcmp->fc_dev;
+	ip->i_number = ino;
+	ip->i_block = -1;
+	ip->i_parent = -2;
+
+	if (ino == FILECORE_ROOTINO) {
+		/* Here we need to construct a root directory inode */
+		memcpy(ip->i_dirent.name, "root", 4);
+		ip->i_dirent.load = 0;
+		ip->i_dirent.exec = 0;
+		ip->i_dirent.len = FILECORE_DIR_SIZE;
+		ip->i_dirent.addr = fcmp->drec.root;
+		ip->i_dirent.attr = FILECORE_ATTR_DIR | FILECORE_ATTR_READ;
+
+	} else {
+		/* Read in Data from Directory Entry */
+		if ((error = filecore_bread(fcmp, ino & FILECORE_INO_MASK,
+		    FILECORE_DIR_SIZE, NOCRED, &bp)) != 0) {
+			pool_put(&filecore_node_pool, ip);
+			return error;
 		}
+
+		memcpy(&ip->i_dirent,
+		    fcdirentry(bp->b_data, ino >> FILECORE_INO_INDEX),
+		    sizeof(struct filecore_direntry));
+#ifdef FILECORE_DEBUG_BR
+		printf("brelse(%p) vf5\n", bp);
+#endif
+		brelse(bp, 0);
 	}
-	mutex_exit(&filecore_ihash_lock);
-	return (NULL);
-}
 
-/*
- * Insert the inode into the hash table, and return it locked.
- */
-void
-filecore_ihashins(struct filecore_node *ip)
-{
-	struct ihashhead *ipp;
-	int error __diagused;
+	ip->i_mnt = fcmp;
+	ip->i_devvp = fcmp->fc_devvp;
+	ip->i_diroff = 0;
+	vref(ip->i_devvp);
 
-	mutex_enter(&filecore_ihash_lock);
-	ipp = &filecorehashtbl[INOHASH(ip->i_dev, ip->i_number)];
-	LIST_INSERT_HEAD(ipp, ip, i_hash);
-	mutex_exit(&filecore_ihash_lock);
+	/*
+	 * Initialize the associated vnode
+	 */
 
-	error = VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
-	KASSERT(error == 0);
-}
+	vp->v_tag = VT_FILECORE;
+	vp->v_op = filecore_vnodeop_p;
+	vp->v_data = ip;
+	if (ip->i_dirent.attr & FILECORE_ATTR_DIR)
+		vp->v_type = VDIR;
+	else
+		vp->v_type = VREG;
+	if (ino == FILECORE_ROOTINO)
+		vp->v_vflag |= VV_ROOT;
+	genfs_node_init(vp, &filecore_genfsops);
 
-/*
- * Remove the inode from the hash table.
- */
-void
-filecore_ihashrem(struct filecore_node *ip)
-{
-	mutex_enter(&filecore_ihash_lock);
-	LIST_REMOVE(ip, i_hash);
-	mutex_exit(&filecore_ihash_lock);
+	/*
+	 * XXX need generation number?
+	 */
+
+	uvm_vnp_setsize(vp, ip->i_size);
+	*new_key = &ip->i_number;
+	return 0;
 }
 
 /*
@@ -251,9 +247,10 @@ filecore_reclaim(void *v)
 	if (prtactive && vp->v_usecount > 1)
 		vprint("filecore_reclaim: pushing active", vp);
 	/*
-	 * Remove the inode from its hash chain.
+	 * Remove the inode from the vnode cache.
 	 */
-	filecore_ihashrem(ip);
+	vcache_remove(vp->v_mount, &ip->i_number, sizeof(ip->i_number));
+
 	/*
 	 * Purge old data structures associated with the inode.
 	 */

Index: src/sys/fs/filecorefs/filecore_node.h
diff -u src/sys/fs/filecorefs/filecore_node.h:1.5 src/sys/fs/filecorefs/filecore_node.h:1.6
--- src/sys/fs/filecorefs/filecore_node.h:1.5	Sat Mar 14 14:46:09 2009
+++ src/sys/fs/filecorefs/filecore_node.h	Sat Oct  4 13:27:24 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecore_node.h,v 1.5 2009/03/14 14:46:09 dsl Exp $	*/
+/*	$NetBSD: filecore_node.h,v 1.6 2014/10/04 13:27:24 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1994 The Regents of the University of California.
@@ -98,8 +98,6 @@ struct filecore_node {
 	struct	filecore_direntry i_dirent; /* directory entry */
 };
 
-#define	i_forw		i_chain[0]
-#define	i_back		i_chain[1]
 #define i_size		i_dirent.len
 
 /* flags */
@@ -135,10 +133,6 @@ int	filecore_print(void *);
 int	filecore_pathconf(void *);
 int	filecore_blkatoff(void *);
 
-struct	vnode *filecore_ihashget(dev_t, ino_t);
-void	filecore_ihashins(struct filecore_node *);
-void	filecore_ihashrem(struct filecore_node *);
-
 mode_t	filecore_mode(struct filecore_node *);
 struct timespec	filecore_time(struct filecore_node *);
 ino_t	filecore_getparent(struct filecore_node *);

Index: src/sys/fs/filecorefs/filecore_vfsops.c
diff -u src/sys/fs/filecorefs/filecore_vfsops.c:1.76 src/sys/fs/filecorefs/filecore_vfsops.c:1.77
--- src/sys/fs/filecorefs/filecore_vfsops.c:1.76	Wed Apr 16 18:55:18 2014
+++ src/sys/fs/filecorefs/filecore_vfsops.c	Sat Oct  4 13:27:24 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecore_vfsops.c,v 1.76 2014/04/16 18:55:18 maxv Exp $	*/
+/*	$NetBSD: filecore_vfsops.c,v 1.77 2014/10/04 13:27:24 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1994 The Regents of the University of California.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filecore_vfsops.c,v 1.76 2014/04/16 18:55:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filecore_vfsops.c,v 1.77 2014/10/04 13:27:24 hannken Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -117,6 +117,7 @@ struct vfsops filecore_vfsops = {
 	.vfs_statvfs = filecore_statvfs,
 	.vfs_sync = filecore_sync,
 	.vfs_vget = filecore_vget,
+	.vfs_loadvnode = filecore_loadvnode,
 	.vfs_fhtovp = filecore_fhtovp,
 	.vfs_vptofh = filecore_vptofh,
 	.vfs_init = filecore_init,
@@ -131,10 +132,6 @@ struct vfsops filecore_vfsops = {
 	.vfs_opv_descs = filecore_vnodeopv_descs
 };
 
-static const struct genfs_ops filecore_genfsops = {
-	.gop_size = genfs_size,
-};
-
 static int
 filecore_modcmd(modcmd_t cmd, void *arg)
 {
@@ -558,112 +555,18 @@ filecore_fhtovp(struct mount *mp, struct
 int
 filecore_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
 {
-	struct filecore_mnt *fcmp;
-	struct filecore_node *ip;
-	struct buf *bp;
-	struct vnode *vp;
-	dev_t dev;
 	int error;
 
-	fcmp = VFSTOFILECORE(mp);
-	dev = fcmp->fc_dev;
-	if ((*vpp = filecore_ihashget(dev, ino)) != NULLVP)
-		return (0);
-
-	/* Allocate a new vnode/filecore_node. */
-	error = getnewvnode(VT_FILECORE, mp, filecore_vnodeop_p, NULL, &vp);
+	error = vcache_get(mp, &ino, sizeof(ino), vpp);
+	if (error)
+		return error;
+	error = vn_lock(*vpp, LK_EXCLUSIVE);
 	if (error) {
-		*vpp = NULLVP;
-		return (error);
-	}
-	ip = pool_get(&filecore_node_pool, PR_WAITOK);
-	memset(ip, 0, sizeof(struct filecore_node));
-	vp->v_data = ip;
-	ip->i_vnode = vp;
-	ip->i_dev = dev;
-	ip->i_number = ino;
-	ip->i_block = -1;
-	ip->i_parent = -2;
-	genfs_node_init(vp, &filecore_genfsops);
-
-	/*
-	 * Put it onto its hash chain and lock it so that other requests for
-	 * this inode will block if they arrive while we are sleeping waiting
-	 * for old data structures to be purged or for the contents of the
-	 * disk portion of this inode to be read.
-	 */
-	filecore_ihashins(ip);
-
-	if (ino == FILECORE_ROOTINO) {
-		/* Here we need to construct a root directory inode */
-		memcpy(ip->i_dirent.name, "root", 4);
-		ip->i_dirent.load = 0;
-		ip->i_dirent.exec = 0;
-		ip->i_dirent.len = FILECORE_DIR_SIZE;
-		ip->i_dirent.addr = fcmp->drec.root;
-		ip->i_dirent.attr = FILECORE_ATTR_DIR | FILECORE_ATTR_READ;
-
-	} else {
-		/* Read in Data from Directory Entry */
-		if ((error = filecore_bread(fcmp, ino & FILECORE_INO_MASK,
-		    FILECORE_DIR_SIZE, NOCRED, &bp)) != 0) {
-			vput(vp);
-			*vpp = NULL;
-			return (error);
-		}
-
-		memcpy(&ip->i_dirent,
-		    fcdirentry(bp->b_data, ino >> FILECORE_INO_INDEX),
-		    sizeof(struct filecore_direntry));
-#ifdef FILECORE_DEBUG_BR
-		printf("brelse(%p) vf5\n", bp);
-#endif
-		brelse(bp, 0);
-	}
-
-	ip->i_mnt = fcmp;
-	ip->i_devvp = fcmp->fc_devvp;
-	ip->i_diroff = 0;
-	vref(ip->i_devvp);
-
-	/*
-	 * Setup type
-	 */
-	vp->v_type = VREG;
-	if (ip->i_dirent.attr & FILECORE_ATTR_DIR)
-		vp->v_type = VDIR;
-
-	/*
-	 * Initialize the associated vnode
-	 */
-	switch (vp->v_type) {
-	case VFIFO:
-	case VCHR:
-	case VBLK:
-		/*
-		 * Devices not supported.
-		 */
-		vput(vp);
-		return (EOPNOTSUPP);
-	case VLNK:
-	case VNON:
-	case VSOCK:
-	case VDIR:
-	case VBAD:
-	case VREG:
-		break;
+		vrele(*vpp);
+		*vpp = NULL;
+		return error;
 	}
-
-	if (ino == FILECORE_ROOTINO)
-		vp->v_vflag |= VV_ROOT;
-
-	/*
-	 * XXX need generation number?
-	 */
-
-	uvm_vnp_setsize(vp, ip->i_size);
-	*vpp = vp;
-	return (0);
+	return 0;
 }
 
 /*

Reply via email to