svn commit: r326846 - stable/10/sys/ufs/ufs
Konstantin Belousov
kib at FreeBSD.org
Thu Dec 14 11:45:03 UTC 2017
Author: kib
Date: Thu Dec 14 11:45:02 2017
New Revision: 326846
URL: https://svnweb.freebsd.org/changeset/base/326846
Log:
MFC r326657:
Fix livelock in ufsdirhash_create().
Modified:
stable/10/sys/ufs/ufs/ufs_dirhash.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/ufs/ufs/ufs_dirhash.c
==============================================================================
--- stable/10/sys/ufs/ufs/ufs_dirhash.c Thu Dec 14 11:41:12 2017 (r326845)
+++ stable/10/sys/ufs/ufs/ufs_dirhash.c Thu Dec 14 11:45:02 2017 (r326846)
@@ -189,9 +189,11 @@ ufsdirhash_create(struct inode *ip)
struct dirhash *ndh;
struct dirhash *dh;
struct vnode *vp;
+ bool excl;
ndh = dh = NULL;
vp = ip->i_vnode;
+ excl = false;
for (;;) {
/* Racy check for i_dirhash to prefetch a dirhash structure. */
if (ip->i_dirhash == NULL && ndh == NULL) {
@@ -228,8 +230,11 @@ ufsdirhash_create(struct inode *ip)
ufsdirhash_hold(dh);
VI_UNLOCK(vp);
- /* Acquire a shared lock on existing hashes. */
- sx_slock(&dh->dh_lock);
+ /* Acquire a lock on existing hashes. */
+ if (excl)
+ sx_xlock(&dh->dh_lock);
+ else
+ sx_slock(&dh->dh_lock);
/* The hash could've been recycled while we were waiting. */
VI_LOCK(vp);
@@ -250,9 +255,10 @@ ufsdirhash_create(struct inode *ip)
* so we can recreate it. If we fail the upgrade, drop our
* lock and try again.
*/
- if (sx_try_upgrade(&dh->dh_lock))
+ if (excl || sx_try_upgrade(&dh->dh_lock))
break;
sx_sunlock(&dh->dh_lock);
+ excl = true;
}
/* Free the preallocated structure if it was not necessary. */
if (ndh) {
More information about the svn-src-stable-10
mailing list