Change filecore to vcache.

Compile-tested only, was not able to get my hands on a readable fs image.
This commit is contained in:
hannken 2014-10-04 13:27:24 +00:00
parent 1c5fb5d101
commit e716e7d8d6
4 changed files with 102 additions and 242 deletions

View File

@ -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;
}

View File

@ -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_node.c,v 1.26 2014/02/27 16:51:38 hannken E
#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.
*/

View File

@ -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 *);

View File

@ -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 fid *fhp, struct vnode **vpp)
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);
vrele(*vpp);
*vpp = NULL;
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;
}
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;
}
/*