summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/adosfs/adosfs.h4
-rw-r--r--sys/adosfs/adutil.c25
-rw-r--r--sys/adosfs/advfsops.c14
-rw-r--r--sys/adosfs/advnops.c6
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 = &amp->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(&amp->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);