diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/adosfs/adosfs.h | 4 | ||||
-rw-r--r-- | sys/adosfs/adutil.c | 25 | ||||
-rw-r--r-- | sys/adosfs/advfsops.c | 14 | ||||
-rw-r--r-- | sys/adosfs/advnops.c | 6 |
4 files changed, 38 insertions, 11 deletions
diff --git a/sys/adosfs/adosfs.h b/sys/adosfs/adosfs.h index b8017d38b16..d890747b09b 100644 --- a/sys/adosfs/adosfs.h +++ b/sys/adosfs/adosfs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: adosfs.h,v 1.7 1997/11/10 23:57:04 niklas Exp $ */ +/* $OpenBSD: adosfs.h,v 1.8 1998/08/21 23:03:13 csapuntz Exp $ */ /* $NetBSD: adosfs.h,v 1.12 1996/10/08 22:18:02 thorpej Exp $ */ /* @@ -144,7 +144,7 @@ int adunixprot __P((int)); int adosfs_getblktype __P((struct adosfsmount *, struct buf *)); struct vnode *adosfs_ahashget __P((struct mount *, ino_t)); -void adosfs_ainshash __P((struct adosfsmount *, struct anode *)); +int adosfs_ainshash __P((struct adosfsmount *, struct anode *)); void adosfs_aremhash __P((struct anode *)); int adosfs_lookup __P((void *)); diff --git a/sys/adosfs/adutil.c b/sys/adosfs/adutil.c index cec01c08d17..6449f0af4fa 100644 --- a/sys/adosfs/adutil.c +++ b/sys/adosfs/adutil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: adutil.c,v 1.10 1997/11/10 23:57:05 niklas Exp $ */ +/* $OpenBSD: adutil.c,v 1.11 1998/08/21 23:03:14 csapuntz Exp $ */ /* $NetBSD: adutil.c,v 1.15 1996/10/13 02:52:07 christos Exp $ */ /* @@ -83,25 +83,40 @@ adosfs_ahashget(mp, an) /* * insert in hash table and lock */ -void +int adosfs_ainshash(amp, ap) struct adosfsmount *amp; struct anode *ap; { struct proc *p = curproc; /* XXX */ + struct anodechain *hp; + struct anode *aq; /* lock the inode, then put it on the appropriate hash list */ lockmgr(&ap->a_lock, LK_EXCLUSIVE, (struct simplelock *)0, p); + + hp = &->anodetab[AHASH(ap->block)]; + + for (aq = hp->lh_first; ; aq = aq->link.le_next) { + if (aq->block == ap->block) { + lockmgr(&ap->a_lock, LK_RELEASE, + (struct simplelock *)0, p); + + return (EEXIST); + } + } - LIST_INSERT_HEAD(&->anodetab[AHASH(ABLKTOINO(ap->block))], ap, - link); + LIST_INSERT_HEAD(hp, ap, link); + return (0); } void adosfs_aremhash(ap) struct anode *ap; { - LIST_REMOVE(ap, link); + + if (ap->link.le_prev != NULL) + LIST_REMOVE(ap, link); } int diff --git a/sys/adosfs/advfsops.c b/sys/adosfs/advfsops.c index 7aef686aa4f..5d92af575d5 100644 --- a/sys/adosfs/advfsops.c +++ b/sys/adosfs/advfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: advfsops.c,v 1.13 1998/02/08 22:41:31 tholo Exp $ */ +/* $OpenBSD: advfsops.c,v 1.14 1998/08/21 23:03:15 csapuntz Exp $ */ /* $NetBSD: advfsops.c,v 1.24 1996/12/22 10:10:12 cgd Exp $ */ /* @@ -366,6 +366,7 @@ adosfs_vget(mp, an, vpp) /* * check hash table. we are done if found */ + retry: if ((*vpp = adosfs_ahashget(mp, an)) != NULL) return (0); @@ -383,7 +384,16 @@ adosfs_vget(mp, an, vpp) ap->amp = amp; ap->block = AINOTOBLK(an); ap->nwords = amp->nwords; - adosfs_ainshash(amp, ap); + error = adosfs_ainshash(amp, ap); + + if (error) { + vrele (vp); + + if (error == EEXIST) + goto retry; + + return (error); + } if ((error = bread(amp->devvp, an * amp->secsperblk, amp->bsize, NOCRED, &bp)) != 0) { diff --git a/sys/adosfs/advnops.c b/sys/adosfs/advnops.c index 683742b82c4..9c900a82d90 100644 --- a/sys/adosfs/advnops.c +++ b/sys/adosfs/advnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: advnops.c,v 1.14 1998/08/21 22:04:42 deraadt Exp $ */ +/* $OpenBSD: advnops.c,v 1.15 1998/08/21 23:03:16 csapuntz Exp $ */ /* $NetBSD: advnops.c,v 1.32 1996/10/13 02:52:09 christos Exp $ */ /* @@ -1011,7 +1011,9 @@ adosfs_reclaim(v) #endif vp = sp->a_vp; ap = VTOA(vp); - LIST_REMOVE(ap, link); + + adosfs_aremhash(ap); + cache_purge(vp); if (vp->v_type == VDIR && ap->tab) free(ap->tab, M_ANODE); |