diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-01-09 20:38:06 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-01-09 20:38:06 +0000 |
commit | 38226a2929159aed5ae343513ff593dc5130de71 (patch) | |
tree | d42122000b4384e16247344ccf754c8812e89689 /sys/ufs | |
parent | 0fd4ac00db99ae2c7af812efa8c458f4e6b5f40c (diff) |
Prevent double insertions into the inode hash queue
Silently allow removal of inodes that aren't on the hash queues
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ufs/ufs_extern.h | 4 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_ihash.c | 27 |
2 files changed, 25 insertions, 6 deletions
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index 8a20bbbac48..0eeb1cfb608 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ufs_extern.h,v 1.6 1997/12/02 17:11:10 csapuntz Exp $ */ +/* $OpenBSD: ufs_extern.h,v 1.7 1998/01/09 20:38:03 csapuntz Exp $ */ /* $NetBSD: ufs_extern.h,v 1.5 1996/02/09 22:36:03 christos Exp $ */ /*- @@ -115,7 +115,7 @@ int ufs_getlbns __P((struct vnode *, daddr_t, struct indir *, int *)); void ufs_ihashinit __P((void)); struct vnode *ufs_ihashlookup __P((dev_t, ino_t)); struct vnode *ufs_ihashget __P((dev_t, ino_t)); -void ufs_ihashins __P((struct inode *)); +int ufs_ihashins __P((struct inode *)); void ufs_ihashrem __P((struct inode *)); /* ufs_inode.c */ diff --git a/sys/ufs/ufs/ufs_ihash.c b/sys/ufs/ufs/ufs_ihash.c index 24e217fef99..73abce20529 100644 --- a/sys/ufs/ufs/ufs_ihash.c +++ b/sys/ufs/ufs/ufs_ihash.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufs_ihash.c,v 1.5 1997/11/06 05:59:26 csapuntz Exp $ */ +/* $OpenBSD: ufs_ihash.c,v 1.6 1998/01/09 20:38:05 csapuntz Exp $ */ /* $NetBSD: ufs_ihash.c,v 1.3 1996/02/09 22:36:04 christos Exp $ */ /* @@ -119,20 +119,35 @@ loop: /* * Insert the inode into the hash table, and return it locked. */ -void +int ufs_ihashins(ip) struct inode *ip; { + struct inode *curip; struct proc *p = curproc; /* XXX */ struct ihashhead *ipp; + dev_t dev = ip->i_dev; + ino_t inum = ip->i_number; /* lock the inode, then put it on the appropriate hash list */ lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p); - + simple_lock(&ufs_ihash_slock); - ipp = INOHASH(ip->i_dev, ip->i_number); + + for (curip = INOHASH(dev, inum)->lh_first; curip; + curip = curip->i_hash.le_next) { + if (inum == curip->i_number && dev == curip->i_dev) { + simple_unlock(&ufs_ihash_slock); + lockmgr(&ip->i_lock, LK_RELEASE, (struct simplelock *)0, p); + return (EEXIST); + } + } + + ipp = INOHASH(dev, inum); LIST_INSERT_HEAD(ipp, ip, i_hash); simple_unlock(&ufs_ihash_slock); + + return (0); } /* @@ -143,6 +158,10 @@ ufs_ihashrem(ip) struct inode *ip; { simple_lock(&ufs_ihash_slock); + + if (ip->i_hash.le_prev == NULL) + return; + LIST_REMOVE(ip, i_hash); #ifdef DIAGNOSTIC ip->i_hash.le_next = NULL; |