Page MenuHomeFreeBSD

D21575.id62130.diff
No OneTemporary

D21575.id62130.diff

Index: sys/kern/vfs_vnops.c
===================================================================
--- sys/kern/vfs_vnops.c
+++ sys/kern/vfs_vnops.c
@@ -1621,11 +1621,23 @@
* suspension is over, and then proceed.
*/
static int
-vn_start_write_locked(struct mount *mp, int flags)
+vn_start_write_refed(struct mount *mp, int flags, bool mplocked)
{
int error, mflags;
- mtx_assert(MNT_MTX(mp), MA_OWNED);
+ if (__predict_true(!mplocked) && (flags & V_XSLEEP) == 0 &&
+ vfs_op_thread_enter(mp)) {
+ MPASS((mp->mnt_kern_flag & MNTK_SUSPEND) == 0);
+ atomic_add_int(&mp->mnt_writeopcount, 1);
+ vfs_op_thread_exit(mp);
+ return (0);
+ }
+
+ if (mplocked)
+ mtx_assert(MNT_MTX(mp), MA_OWNED);
+ else
+ MNT_ILOCK(mp);
+
error = 0;
/*
@@ -1648,7 +1660,7 @@
}
if (flags & V_XSLEEP)
goto unlock;
- mp->mnt_writeopcount++;
+ atomic_add_int(&mp->mnt_writeopcount, 1);
unlock:
if (error != 0 || (flags & V_XSLEEP) != 0)
MNT_REL(mp);
@@ -1694,11 +1706,10 @@
* refcount for the provided mountpoint too, in order to
* emulate a vfs_ref().
*/
- MNT_ILOCK(mp);
if (vp == NULL && (flags & V_MNTREF) == 0)
- MNT_REF(mp);
+ vfs_ref(mp);
- return (vn_start_write_locked(mp, flags));
+ return (vn_start_write_refed(mp, flags, false));
}
/*
@@ -1780,15 +1791,26 @@
void
vn_finished_write(struct mount *mp)
{
+ int c;
+
if (mp == NULL || !vn_suspendable(mp))
return;
+
+ if (vfs_op_thread_enter(mp)) {
+ c = atomic_fetchadd_int(&mp->mnt_writeopcount, -1) - 1;
+ if (c < 0)
+ panic("vn_finished_write: invalid writeopcount %d", c);
+ MNT_REL_UNLOCKED(mp);
+ vfs_op_thread_exit(mp);
+ return;
+ }
+
MNT_ILOCK(mp);
MNT_REL(mp);
- mp->mnt_writeopcount--;
- if (mp->mnt_writeopcount < 0)
- panic("vn_finished_write: neg cnt");
- if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0 &&
- mp->mnt_writeopcount <= 0)
+ c = atomic_fetchadd_int(&mp->mnt_writeopcount, -1) - 1;
+ if (c < 0)
+ panic("vn_finished_write: invalid writeopcount %d", c);
+ if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0 && c == 0)
wakeup(&mp->mnt_writeopcount);
MNT_IUNLOCK(mp);
}
@@ -1827,8 +1849,11 @@
MPASS(vn_suspendable(mp));
+ vfs_op_enter(mp);
+
MNT_ILOCK(mp);
if (mp->mnt_susp_owner == curthread) {
+ vfs_op_exit_locked(mp);
MNT_IUNLOCK(mp);
return (EALREADY);
}
@@ -1845,6 +1870,7 @@
*/
if ((flags & VS_SKIP_UNMOUNT) != 0 &&
(mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) {
+ vfs_op_exit_locked(mp);
MNT_IUNLOCK(mp);
return (EBUSY);
}
@@ -1856,8 +1882,10 @@
MNT_MTX(mp), (PUSER - 1)|PDROP, "suspwt", 0);
else
MNT_IUNLOCK(mp);
- if ((error = VFS_SYNC(mp, MNT_SUSPEND)) != 0)
+ if ((error = VFS_SYNC(mp, MNT_SUSPEND)) != 0) {
vfs_write_resume(mp, 0);
+ vfs_op_exit(mp);
+ }
return (error);
}
@@ -1881,14 +1909,15 @@
curthread->td_pflags &= ~TDP_IGNSUSP;
if ((flags & VR_START_WRITE) != 0) {
MNT_REF(mp);
- mp->mnt_writeopcount++;
+ atomic_add_int(&mp->mnt_writeopcount, 1);
}
MNT_IUNLOCK(mp);
if ((flags & VR_NO_SUSPCLR) == 0)
VFS_SUSP_CLEAN(mp);
+ vfs_op_exit(mp);
} else if ((flags & VR_START_WRITE) != 0) {
MNT_REF(mp);
- vn_start_write_locked(mp, 0);
+ vn_start_write_refed(mp, 0, true);
} else {
MNT_IUNLOCK(mp);
}
Index: sys/ufs/ffs/ffs_softdep.c
===================================================================
--- sys/ufs/ffs/ffs_softdep.c
+++ sys/ufs/ffs/ffs_softdep.c
@@ -2954,17 +2954,26 @@
{
struct jblocks *jblocks;
struct mount *mp;
+ bool set;
mp = UFSTOVFS(ump);
+ if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0)
+ return;
+
jblocks = ump->softdep_jblocks;
+ vfs_op_enter(mp);
+ set = false;
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_SUSPEND) == 0) {
stat_journal_min++;
mp->mnt_kern_flag |= MNTK_SUSPEND;
mp->mnt_susp_owner = ump->softdep_flushtd;
+ set = true;
}
jblocks->jb_suspended = 1;
MNT_IUNLOCK(mp);
+ if (!set)
+ vfs_op_exit(mp);
}
static int

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 28, 2:36 AM (9 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26271813
Default Alt Text
D21575.id62130.diff (3 KB)

Event Timeline