Module Name: src Committed By: hannken Date: Tue Aug 5 08:50:54 UTC 2014
Modified Files: src/sys/fs/adosfs: adosfs.h adutil.c advfsops.c advnops.c Log Message: Change adosfs from hashlist to vcache. - point ap->block to real file header block for hard links. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/fs/adosfs/adosfs.h cvs rdiff -u -r1.16 -r1.17 src/sys/fs/adosfs/adutil.c cvs rdiff -u -r1.70 -r1.71 src/sys/fs/adosfs/advfsops.c cvs rdiff -u -r1.44 -r1.45 src/sys/fs/adosfs/advnops.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/adosfs/adosfs.h diff -u src/sys/fs/adosfs/adosfs.h:1.12 src/sys/fs/adosfs/adosfs.h:1.13 --- src/sys/fs/adosfs/adosfs.h:1.12 Wed Oct 3 07:20:50 2012 +++ src/sys/fs/adosfs/adosfs.h Tue Aug 5 08:50:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: adosfs.h,v 1.12 2012/10/03 07:20:50 mlelstv Exp $ */ +/* $NetBSD: adosfs.h,v 1.13 2014/08/05 08:50:54 hannken Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -73,7 +73,6 @@ enum anode_type { AROOT, ADIR, AFILE, AL */ struct anode { struct genfs_node gnode; - LIST_ENTRY(anode) link; enum anode_type type; char name[ADMAXNAMELEN+1]; /* (r/d/f) name for object */ struct datestamp mtimev; /* (r) volume modified */ @@ -112,7 +111,6 @@ struct anode { #define ANODEHASHSZ (512) struct adosfsmount { - LIST_HEAD(anodechain, anode) anodetab[ANODEHASHSZ]; struct mount *mp; /* owner mount */ u_int32_t dostype; /* type of volume */ u_long rootb; /* root block number */ @@ -169,10 +167,6 @@ int adoshash(const u_char *, int, int, i int adunixprot(int); int adosfs_getblktype(struct adosfsmount *, struct buf *); -struct vnode *adosfs_ahashget(struct mount *, ino_t); -void adosfs_ainshash(struct adosfsmount *, struct anode *); -void adosfs_aremhash(struct anode *); - int adosfs_lookup(void *); extern int (**adosfs_vnodeop_p)(void *); Index: src/sys/fs/adosfs/adutil.c diff -u src/sys/fs/adosfs/adutil.c:1.16 src/sys/fs/adosfs/adutil.c:1.17 --- src/sys/fs/adosfs/adutil.c:1.16 Thu Feb 27 16:51:37 2014 +++ src/sys/fs/adosfs/adutil.c Tue Aug 5 08:50:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $ */ +/* $NetBSD: adutil.c,v 1.17 2014/08/05 08:50:54 hannken Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.17 2014/08/05 08:50:54 hannken Exp $"); #include <sys/param.h> #include <sys/vnode.h> @@ -47,62 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1 /* * look for anode in the mount's hash table, return locked. */ -#define AHASH(an) ((an) & (ANODEHASHSZ - 1)) static int CapitalChar(int, int); -extern kmutex_t adosfs_hashlock; - -struct vnode * -adosfs_ahashget(struct mount *mp, ino_t an) -{ - struct anodechain *hp; - struct anode *ap; - struct vnode *vp; - - hp = &VFSTOADOSFS(mp)->anodetab[AHASH(an)]; - -start_over: - mutex_enter(&adosfs_hashlock); - for (ap = hp->lh_first; ap != NULL; ap = ap->link.le_next) { - if (ap->block == an) { - vp = ATOV(ap); - mutex_enter(vp->v_interlock); - mutex_exit(&adosfs_hashlock); - if (vget(vp, LK_EXCLUSIVE)) - goto start_over; - return (ATOV(ap)); - } - } - mutex_exit(&adosfs_hashlock); - return (NULL); -} - -/* - * insert in hash table and lock - * - * ap->vp must have been initialized before this call. - */ -void -adosfs_ainshash(struct adosfsmount *amp, struct anode *ap) -{ - int error __diagused; - - error = VOP_LOCK(ATOV(ap), LK_EXCLUSIVE); - KASSERT(error == 0); - - mutex_enter(&adosfs_hashlock); - LIST_INSERT_HEAD(&->anodetab[AHASH(ap->block)], ap, link); - mutex_exit(&adosfs_hashlock); -} - -void -adosfs_aremhash(struct anode *ap) -{ - mutex_enter(&adosfs_hashlock); - LIST_REMOVE(ap, link); - mutex_exit(&adosfs_hashlock); -} - int adosfs_getblktype(struct adosfsmount *amp, struct buf *bp) { Index: src/sys/fs/adosfs/advfsops.c diff -u src/sys/fs/adosfs/advfsops.c:1.70 src/sys/fs/adosfs/advfsops.c:1.71 --- src/sys/fs/adosfs/advfsops.c:1.70 Wed Apr 16 18:55:18 2014 +++ src/sys/fs/adosfs/advfsops.c Tue Aug 5 08:50:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: advfsops.c,v 1.70 2014/04/16 18:55:18 maxv Exp $ */ +/* $NetBSD: advfsops.c,v 1.71 2014/08/05 08:50:54 hannken Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.70 2014/04/16 18:55:18 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.71 2014/08/05 08:50:54 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -70,8 +70,6 @@ static struct sysctllog *adosfs_sysctl_l int adosfs_mountfs(struct vnode *, struct mount *, struct lwp *); int adosfs_loadbitmap(struct adosfsmount *); -kmutex_t adosfs_hashlock; - struct pool adosfs_node_pool; MALLOC_JUSTDEFINE(M_ANODE, "adosfs anode","adosfs anode structures and tables"); @@ -169,7 +167,7 @@ adosfs_mountfs(struct vnode *devvp, stru struct buf *bp; struct vnode *rvp; size_t bitmap_sz = 0; - int error, i; + int error; uint64_t numsecs; unsigned secsize; unsigned long secsperblk, blksperdisk, resvblks; @@ -264,12 +262,6 @@ adosfs_mountfs(struct vnode *devvp, stru mp->mnt_flag |= MNT_LOCAL; /* - * init anode table. - */ - for (i = 0; i < ANODEHASHSZ; i++) - LIST_INIT(&->anodetab[i]); - - /* * get the root anode, if not a valid fs this will fail. */ if ((error = VFS_ROOT(mp, &rvp)) != 0) @@ -371,50 +363,55 @@ adosfs_statvfs(struct mount *mp, struct } /* - * lookup an anode, check mount's hash table if not found, create - * return locked and referenced al la vget(vp, 1); + * lookup an anode, if not found, create + * return locked and referenced al la vget(vp, LK_EXCLUSIVE); */ int adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp) { + int error; + + error = vcache_get(mp, &an, sizeof(an), vpp); + if (error) + return error; + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error) { + vrele(*vpp); + *vpp = NULL; + return error; + } + return 0; +} + +/* + * Initialize this vnode / anode pair. + * Caller assures no other thread will try to load this inode. + */ +int +adosfs_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) +{ struct adosfsmount *amp; - struct vnode *vp; struct anode *ap; struct buf *bp; + ino_t an; char *nam, *tmp; int namlen, error; - error = 0; + KASSERT(key_len == sizeof(an)); + memcpy(&an, key, key_len); amp = VFSTOADOSFS(mp); - bp = NULL; - /* - * check hash table. we are done if found - */ - if ((*vpp = adosfs_ahashget(mp, an)) != NULL) - return (0); - - error = getnewvnode(VT_ADOSFS, mp, adosfs_vnodeop_p, NULL, &vp); - if (error) - return (error); + if ((error = bread(amp->devvp, an * amp->bsize / DEV_BSIZE, + amp->bsize, NOCRED, 0, &bp)) != 0) + return error; - /* - * setup, insert in hash, and lock before io. - */ - vp->v_data = ap = pool_get(&adosfs_node_pool, PR_WAITOK); + ap = pool_get(&adosfs_node_pool, PR_WAITOK); memset(ap, 0, sizeof(struct anode)); ap->vp = vp; ap->amp = amp; ap->block = an; ap->nwords = amp->nwords; - genfs_node_init(vp, &adosfs_genfsops); - adosfs_ainshash(amp, ap); - - if ((error = bread(amp->devvp, an * amp->bsize / DEV_BSIZE, - amp->bsize, NOCRED, 0, &bp)) != 0) { - vput(vp); - return (error); - } /* * get type and fill rest in based on that. @@ -468,9 +465,8 @@ adosfs_vget(struct mount *mp, ino_t an, ap->fsize = namlen; break; default: - brelse(bp, 0); - vput(vp); - return (EINVAL); + error = EINVAL; + goto bad; } /* @@ -488,9 +484,8 @@ adosfs_vget(struct mount *mp, ino_t an, printf("adosfs: aget: name length too long blk %llu\n", (unsigned long long)an); #endif - brelse(bp, 0); - vput(vp); - return (EINVAL); + error = EINVAL; + goto bad; } memcpy(ap->name, nam, namlen); ap->name[namlen] = 0; @@ -531,15 +526,9 @@ adosfs_vget(struct mount *mp, ino_t an, bp = NULL; error = bread(amp->devvp, ap->linkto * amp->bsize / DEV_BSIZE, amp->bsize, NOCRED, 0, &bp); - if (error) { - vput(vp); - return (error); - } + if (error) + goto bad; ap->fsize = adoswordn(bp, ap->nwords - 47); - /* - * Should ap->block be set to the real file header block? - */ - ap->block = ap->linkto; } if (ap->type == AROOT) { @@ -586,10 +575,20 @@ adosfs_vget(struct mount *mp, ino_t an, ap->mtime.mins = adoswordn(bp, ap->nwords - 22); ap->mtime.ticks = adoswordn(bp, ap->nwords - 21); - *vpp = vp; brelse(bp, 0); + vp->v_tag = VT_ADOSFS; + vp->v_op = adosfs_vnodeop_p; + vp->v_data = ap; + genfs_node_init(vp, &adosfs_genfsops); uvm_vnp_setsize(vp, ap->fsize); - return (0); + *new_key = &ap->block; + return 0; + +bad: + if (bp) + brelse(bp, 0); + pool_put(&adosfs_node_pool, ap); + return error; } /* @@ -761,7 +760,6 @@ adosfs_init(void) { malloc_type_attach(M_ANODE); - mutex_init(&adosfs_hashlock, MUTEX_DEFAULT, IPL_NONE); pool_init(&adosfs_node_pool, sizeof(struct anode), 0, 0, 0, "adosndpl", &pool_allocator_nointr, IPL_NONE); } @@ -771,7 +769,6 @@ adosfs_done(void) { pool_destroy(&adosfs_node_pool); - mutex_destroy(&adosfs_hashlock); malloc_type_detach(M_ANODE); } @@ -797,6 +794,7 @@ struct vfsops adosfs_vfsops = { .vfs_statvfs = adosfs_statvfs, .vfs_sync = adosfs_sync, .vfs_vget = adosfs_vget, + .vfs_loadvnode = adosfs_loadvnode, .vfs_fhtovp = adosfs_fhtovp, .vfs_vptofh = adosfs_vptofh, .vfs_init = adosfs_init, Index: src/sys/fs/adosfs/advnops.c diff -u src/sys/fs/adosfs/advnops.c:1.44 src/sys/fs/adosfs/advnops.c:1.45 --- src/sys/fs/adosfs/advnops.c:1.44 Fri Jul 25 08:20:51 2014 +++ src/sys/fs/adosfs/advnops.c Tue Aug 5 08:50:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: advnops.c,v 1.44 2014/07/25 08:20:51 dholland Exp $ */ +/* $NetBSD: advnops.c,v 1.45 2014/08/05 08:50:54 hannken Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.44 2014/07/25 08:20:51 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.45 2014/08/05 08:50:54 hannken Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -880,7 +880,7 @@ adosfs_reclaim(void *v) #endif vp = sp->a_vp; ap = VTOA(vp); - LIST_REMOVE(ap, link); + vcache_remove(vp->v_mount, &ap->block, sizeof(ap->block)); if (vp->v_type == VDIR && ap->tab) free(ap->tab, M_ANODE); else if (vp->v_type == VLNK && ap->slinkto)