Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Dec 2015 11:50:32 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r292541 - head/sys/ufs/ffs
Message-ID:  <201512211150.tBLBoW6D029258@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Dec 21 11:50:32 2015
New Revision: 292541
URL: https://svnweb.freebsd.org/changeset/base/292541

Log:
  Recheck curthread->td_su after the VFS_SYNC() call, and re-sync if the
  ast was rescheduled during VFS_SYNC().  It is possible that enough
  parallel writes or slow/hung volume result in VFS_SYNC() deferring to
  the ast flushing of workqueue.
  
  Reported and tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/ufs/ffs/ffs_softdep.c

Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c	Mon Dec 21 11:44:54 2015	(r292540)
+++ head/sys/ufs/ffs/ffs_softdep.c	Mon Dec 21 11:50:32 2015	(r292541)
@@ -13301,43 +13301,43 @@ softdep_ast_cleanup_proc(void)
 	bool req;
 
 	td = curthread;
-	mp = td->td_su;
-	if (mp == NULL)
-		return;
-	td->td_su = NULL;
-	error = vfs_busy(mp, MBF_NOWAIT);
-	vfs_rel(mp);
-	if (error != 0)
-		return;
-	if (ffs_own_mount(mp) && MOUNTEDSOFTDEP(mp)) {
-		ump = VFSTOUFS(mp);
-		for (;;) {
-			req = false;
-			ACQUIRE_LOCK(ump);
-			if (softdep_excess_items(ump, D_INODEDEP)) {
-				req = true;
-				request_cleanup(mp, FLUSH_INODES);
-			}
-			if (softdep_excess_items(ump, D_DIRREM)) {
-				req = true;
-				request_cleanup(mp, FLUSH_BLOCKS);
-			}
-			FREE_LOCK(ump);
-			if (softdep_excess_items(ump, D_NEWBLK) ||
-			    softdep_excess_items(ump, D_ALLOCDIRECT) ||
-			    softdep_excess_items(ump, D_ALLOCINDIR)) {
-				error = vn_start_write(NULL, &mp, V_WAIT);
-				if (error == 0) {
+	while ((mp = td->td_su) != NULL) {
+		td->td_su = NULL;
+		error = vfs_busy(mp, MBF_NOWAIT);
+		vfs_rel(mp);
+		if (error != 0)
+			return;
+		if (ffs_own_mount(mp) && MOUNTEDSOFTDEP(mp)) {
+			ump = VFSTOUFS(mp);
+			for (;;) {
+				req = false;
+				ACQUIRE_LOCK(ump);
+				if (softdep_excess_items(ump, D_INODEDEP)) {
 					req = true;
-					VFS_SYNC(mp, MNT_WAIT);
-					vn_finished_write(mp);
+					request_cleanup(mp, FLUSH_INODES);
 				}
+				if (softdep_excess_items(ump, D_DIRREM)) {
+					req = true;
+					request_cleanup(mp, FLUSH_BLOCKS);
+				}
+				FREE_LOCK(ump);
+				if (softdep_excess_items(ump, D_NEWBLK) ||
+				    softdep_excess_items(ump, D_ALLOCDIRECT) ||
+				    softdep_excess_items(ump, D_ALLOCINDIR)) {
+					error = vn_start_write(NULL, &mp,
+					    V_WAIT);
+					if (error == 0) {
+						req = true;
+						VFS_SYNC(mp, MNT_WAIT);
+						vn_finished_write(mp);
+					}
+				}
+				if ((td->td_pflags & TDP_KTHREAD) != 0 || !req)
+					break;
 			}
-			if ((td->td_pflags & TDP_KTHREAD) != 0 || !req)
-				break;
 		}
+		vfs_unbusy(mp);
 	}
-	vfs_unbusy(mp);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512211150.tBLBoW6D029258>