svn commit: r196888 - head/sys/ufs/ffs
Konstantin Belousov
kib at FreeBSD.org
Sun Sep 6 11:46:52 UTC 2009
Author: kib
Date: Sun Sep 6 11:46:51 2009
New Revision: 196888
URL: http://svn.freebsd.org/changeset/base/196888
Log:
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.
Noted and reviewed by: tegge
Tested by: pho
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 Sun Sep 6 11:44:46 2009 (r196887)
+++ head/sys/ufs/ffs/ffs_softdep.c Sun Sep 6 11:46:51 2009 (r196888)
@@ -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-head
mailing list