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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to