diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2014-04-14 22:25:41 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2014-04-14 22:25:41 +0000 |
commit | 2d157b40fc69b0196c17decc3493b9dcb0932d4f (patch) | |
tree | a175485d1a9fac91c7e733efb3065bfc839ae16a /sys/ufs | |
parent | 29ded3cbe5323bf9c410d949e6a4432e09cc767e (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.h | 3 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_ihash.c | 9 |
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; |