summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-06-30 10:07:00 +0000
committerkib <kib@FreeBSD.org>2009-06-30 10:07:00 +0000
commitc424611d793944a4fe03022da72a5ecc34649c72 (patch)
treed14f883c5b9a0d85635c462dd9fd2f1f1a9cefdc /sys/ufs
parent905d9397a05effde536c6c52c272bcd0bd3ccfd5 (diff)
downloadFreeBSD-src-c424611d793944a4fe03022da72a5ecc34649c72.zip
FreeBSD-src-c424611d793944a4fe03022da72a5ecc34649c72.tar.gz
Softdep_fsync() may need to lock parent directory of the synced vnode.
Use inlined (due to FFSV_FORCEINSMQ) version of vn_vget_ino() to prevent mountpoint from being unmounted and freed while no vnodes are locked. Tested by: pho Approved by: re (kensmith) MFC after: 1 month
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 195df44..d7b8818 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -5102,10 +5102,28 @@ softdep_fsync(vp)
FREE_LOCK(&lk);
if (ffs_vgetf(mp, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp,
FFSV_FORCEINSMQ)) {
+ error = vfs_busy(mp, MBF_NOWAIT);
+ if (error != 0) {
+ VOP_UNLOCK(vp, 0);
+ error = vfs_busy(mp, 0);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if (error != 0)
+ return (ENOENT);
+ if (vp->v_iflag & VI_DOOMED) {
+ vfs_unbusy(mp);
+ return (ENOENT);
+ }
+ }
VOP_UNLOCK(vp, 0);
error = ffs_vgetf(mp, parentino, LK_EXCLUSIVE,
&pvp, FFSV_FORCEINSMQ);
+ vfs_unbusy(mp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if (vp->v_iflag & VI_DOOMED) {
+ if (error == 0)
+ vput(pvp);
+ error = ENOENT;
+ }
if (error != 0)
return (error);
}
OpenPOWER on IntegriCloud