Date: Thu, 14 Dec 2017 11:41:12 +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-11@freebsd.org Subject: svn commit: r326845 - stable/11/sys/ufs/ufs Message-ID: <201712141141.vBEBfCJN038815@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Dec 14 11:41:12 2017 New Revision: 326845 URL: https://svnweb.freebsd.org/changeset/base/326845 Log: MFC r326657: Fix livelock in ufsdirhash_create(). Modified: stable/11/sys/ufs/ufs/ufs_dirhash.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/ufs/ufs/ufs_dirhash.c ============================================================================== --- stable/11/sys/ufs/ufs/ufs_dirhash.c Thu Dec 14 08:57:37 2017 (r326844) +++ stable/11/sys/ufs/ufs/ufs_dirhash.c Thu Dec 14 11:41:12 2017 (r326845) @@ -190,9 +190,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) { @@ -229,8 +231,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); @@ -251,9 +256,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?201712141141.vBEBfCJN038815>