Date: Thu, 14 Dec 2017 11:45:02 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r326846 - stable/10/sys/ufs/ufs Message-ID: <201712141145.vBEBj27T040569@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712141145.vBEBj27T040569>