svn commit: r197222 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/xen/xenpci ufs/ffs

Konstantin Belousov kib at FreeBSD.org
Tue Sep 15 12:51:22 UTC 2009


Author: kib
Date: Tue Sep 15 12:51:22 2009
New Revision: 197222
URL: http://svn.freebsd.org/changeset/base/197222

Log:
  MFC r196888:
  The clear_remove() and clear_inodedeps() call vn_start_write(NULL, &mp,
  V_NOWAIT) on the non-busied mount point. Unmount might free ufs-specific
  mp data, causing ffs_vgetf() to access freed memory.
  
  Busy mountpoint before dropping softdep lk.
  
  Approved by:	re (kensmith)

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/ufs/ffs/ffs_softdep.c

Modified: stable/8/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- stable/8/sys/ufs/ffs/ffs_softdep.c	Tue Sep 15 12:21:06 2009	(r197221)
+++ stable/8/sys/ufs/ffs/ffs_softdep.c	Tue Sep 15 12:51:22 2009	(r197222)
@@ -5977,12 +5977,19 @@ clear_remove(td)
 			if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
 				continue;
 			FREE_LOCK(&lk);
-			if ((error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp,
-			     FFSV_FORCEINSMQ))) {
+
+			/*
+			 * Let unmount clear deps
+			 */
+			error = vfs_busy(mp, MBF_NOWAIT);
+			if (error != 0)
+				goto finish_write;
+			error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp,
+			     FFSV_FORCEINSMQ);
+			vfs_unbusy(mp);
+			if (error != 0) {
 				softdep_error("clear_remove: vget", error);
-				vn_finished_write(mp);
-				ACQUIRE_LOCK(&lk);
-				return;
+				goto finish_write;
 			}
 			if ((error = ffs_syncvnode(vp, MNT_NOWAIT)))
 				softdep_error("clear_remove: fsync", error);
@@ -5991,6 +5998,7 @@ clear_remove(td)
 			drain_output(vp);
 			BO_UNLOCK(bo);
 			vput(vp);
+		finish_write:
 			vn_finished_write(mp);
 			ACQUIRE_LOCK(&lk);
 			return;
@@ -6050,13 +6058,21 @@ clear_inodedeps(td)
 		if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
 			continue;
 		FREE_LOCK(&lk);
+		error = vfs_busy(mp, MBF_NOWAIT); /* Let unmount clear deps */
+		if (error != 0) {
+			vn_finished_write(mp);
+			ACQUIRE_LOCK(&lk);
+			return;
+		}
 		if ((error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp,
 		    FFSV_FORCEINSMQ)) != 0) {
 			softdep_error("clear_inodedeps: vget", error);
+			vfs_unbusy(mp);
 			vn_finished_write(mp);
 			ACQUIRE_LOCK(&lk);
 			return;
 		}
+		vfs_unbusy(mp);
 		if (ino == lastino) {
 			if ((error = ffs_syncvnode(vp, MNT_WAIT)))
 				softdep_error("clear_inodedeps: fsync1", error);


More information about the svn-src-stable mailing list