summaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1998-01-09 20:38:06 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1998-01-09 20:38:06 +0000
commit38226a2929159aed5ae343513ff593dc5130de71 (patch)
treed42122000b4384e16247344ccf754c8812e89689 /sys/ufs
parent0fd4ac00db99ae2c7af812efa8c458f4e6b5f40c (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.h4
-rw-r--r--sys/ufs/ufs/ufs_ihash.c27
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;