summaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2014-04-14 22:25:41 +0000
committerBob Beck <beck@cvs.openbsd.org>2014-04-14 22:25:41 +0000
commit2d157b40fc69b0196c17decc3493b9dcb0932d4f (patch)
treea175485d1a9fac91c7e733efb3065bfc839ae16a /sys/ufs
parent29ded3cbe5323bf9c410d949e6a4432e09cc767e (diff)
fix potential race where an allocated inode could fail to get added,
noticed by pedro@ in bitrig. ok philip@ millert@
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/inode.h3
-rw-r--r--sys/ufs/ufs/ufs_ihash.c9
2 files changed, 8 insertions, 4 deletions
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index ae721caad4d..8acfa30893e 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: inode.h,v 1.43 2014/03/19 04:17:33 guenther Exp $ */
+/* $OpenBSD: inode.h,v 1.44 2014/04/14 22:25:40 beck Exp $ */
/* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */
/*
@@ -251,6 +251,7 @@ struct inode_vtbl {
#define IN_SHLOCK 0x0020 /* File has shared lock. */
#define IN_EXLOCK 0x0040 /* File has exclusive lock. */
#define IN_LAZYMOD 0x0080 /* Modified, but don't write yet. */
+#define IN_HASHED 0x0100 /* Inode is on the hash chain */
#define i_devvp i_ump->um_devvp
diff --git a/sys/ufs/ufs/ufs_ihash.c b/sys/ufs/ufs/ufs_ihash.c
index 460fb9f5aa3..29396abeb52 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.17 2013/05/30 19:19:09 guenther Exp $ */
+/* $OpenBSD: ufs_ihash.c,v 1.18 2014/04/14 22:25:40 beck Exp $ */
/* $NetBSD: ufs_ihash.c,v 1.3 1996/02/09 22:36:04 christos Exp $ */
/*
@@ -129,6 +129,7 @@ ufs_ihashins(struct inode *ip)
}
ipp = INOHASH(dev, inum);
+ SET(ip->i_flag, IN_HASHED);
LIST_INSERT_HEAD(ipp, ip, i_hash);
/* XXXLOCKING unlock hash list? */
@@ -145,8 +146,10 @@ ufs_ihashrem(struct inode *ip)
if (ip->i_hash.le_prev == NULL)
return;
-
- LIST_REMOVE(ip, i_hash);
+ if (ISSET(ip->i_flag, IN_HASHED)) {
+ LIST_REMOVE(ip, i_hash);
+ CLR(ip->i_flag, IN_HASHED);
+ }
#ifdef DIAGNOSTIC
ip->i_hash.le_next = NULL;
ip->i_hash.le_prev = NULL;