Module Name: src Committed By: chs Date: Sun Mar 8 00:23:59 UTC 2020
Modified Files: src/sys/ufs/ufs: ufs_dirhash.c Log Message: in ufsdirhash_free(), only examine dh->dh_onlist after taking the dirhashlist lock. if we skip the lock then we might see that dh_onlist is zero while ufsdirhash_recycle() is still working on the dirhash. the symptom I saw was that ufsdirhash_free() would try to destroy the dh_lock mutex while it was still held. To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/sys/ufs/ufs/ufs_dirhash.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/ufs/ufs_dirhash.c diff -u src/sys/ufs/ufs/ufs_dirhash.c:1.37 src/sys/ufs/ufs/ufs_dirhash.c:1.38 --- src/sys/ufs/ufs/ufs_dirhash.c:1.37 Sat Dec 20 00:28:05 2014 +++ src/sys/ufs/ufs/ufs_dirhash.c Sun Mar 8 00:23:59 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_dirhash.c,v 1.37 2014/12/20 00:28:05 christos Exp $ */ +/* $NetBSD: ufs_dirhash.c,v 1.38 2020/03/08 00:23:59 chs Exp $ */ /* * Copyright (c) 2001, 2002 Ian Dowse. All rights reserved. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_dirhash.c,v 1.37 2014/12/20 00:28:05 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_dirhash.c,v 1.38 2020/03/08 00:23:59 chs Exp $"); /* * This implements a hash-based lookup scheme for UFS directories. @@ -285,12 +285,10 @@ ufsdirhash_free(struct inode *ip) ip->i_dirhash = NULL; - if (dh->dh_onlist) { - DIRHASHLIST_LOCK(); - if (dh->dh_onlist) - TAILQ_REMOVE(&ufsdirhash_list, dh, dh_list); - DIRHASHLIST_UNLOCK(); - } + DIRHASHLIST_LOCK(); + if (dh->dh_onlist) + TAILQ_REMOVE(&ufsdirhash_list, dh, dh_list); + DIRHASHLIST_UNLOCK(); /* The dirhash pointed to by 'dh' is exclusively ours now. */ mem = sizeof(*dh);