Close a race between concurrent calls to ufsdirhash_recycle() and

ufsdirhash_free() introduced in my last commit by removing the dirhash
about to be free'd in ufsdirhash_free() from the global dirhash list
before dropping the sx lock.

Tested by:	kris
This commit is contained in:
jhb 2008-09-22 20:53:22 +00:00
parent 849a6bf2d2
commit 82d0acb613

View File

@ -460,6 +460,16 @@ ufsdirhash_free_locked(struct inode *ip)
ip->i_dirhash = NULL;
VI_UNLOCK(vp);
/*
* Remove the hash from the list since we are going to free its
* memory.
*/
DIRHASHLIST_LOCK();
if (dh->dh_onlist)
TAILQ_REMOVE(&ufsdirhash_list, dh, dh_list);
ufs_dirhashmem -= dh->dh_memreq;
DIRHASHLIST_UNLOCK();
/*
* At this point, any waiters for the lock should hold their
* own reference on the dirhash structure. They will drop
@ -479,11 +489,6 @@ ufsdirhash_free_locked(struct inode *ip)
if (dh->dh_blkfree != NULL)
FREE(dh->dh_blkfree, M_DIRHASH);
}
DIRHASHLIST_LOCK();
if (dh->dh_onlist)
TAILQ_REMOVE(&ufsdirhash_list, dh, dh_list);
ufs_dirhashmem -= dh->dh_memreq;
DIRHASHLIST_UNLOCK();
/*
* Drop the inode's reference to the data structure.