Skip site navigation (1)Skip section navigation (2)
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>