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;
}
/*