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