Change filecore to vcache.
Compile-tested only, was not able to get my hands on a readable fs image.
This commit is contained in:
parent
1c5fb5d101
commit
e716e7d8d6
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue