Current implementations of sync(2) and syncer vnode fsync() VOP uses
mnt_noasync counter to temporary remove MNTK_ASYNC mount option, which is needed to guarantee a synchronous completion of the initiated i/o before syscall or VOP return. Global removal of MNTK_ASYNC option is harmful because not only i/o started from corresponding thread becomes synchronous, but all i/o is synchronous on the filesystem which is initiated during sync(2) or syncer activity. Instead of removing MNTK_ASYNC from mnt_kern_flag, provide a local thread flag to disable async i/o for current thread only. Use the opportunity to move DOINGASYNC() macro into sys/vnode.h and consistently use it through places which tested for MNTK_ASYNC. Some testing demonstrated 60-70% improvements in run time for the metadata-intensive operations on async-mounted UFS volumes, but still with great deviation due to other reasons. Reviewed by: mckusick Tested by: scottl MFC after: 2 weeks
This commit is contained in:
parent
f1cf024599
commit
c480f781ea
@ -158,9 +158,6 @@ struct indir {
|
||||
#define VTOI(vp) ((struct inode *)(vp)->v_data)
|
||||
#define ITOV(ip) ((ip)->i_vnode)
|
||||
|
||||
/* Check whether the MNTK_ASYNC flag has been set for a mount point */
|
||||
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
|
||||
|
||||
/* This overlays the fid structure (see mount.h). */
|
||||
struct ufid {
|
||||
uint16_t ufid_len; /* Length of structure. */
|
||||
|
@ -1376,7 +1376,7 @@ ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
|
||||
if (ret && !error)
|
||||
error = ret;
|
||||
}
|
||||
if (vp->v_mount->mnt_kern_flag & MNTK_ASYNC)
|
||||
if (DOINGASYNC(vp))
|
||||
*iomode = NFSWRITE_FILESYNC;
|
||||
if (error && NFS_ISV4(vp))
|
||||
error = nfscl_maperr(uiop->uio_td, error, (uid_t)0, (gid_t)0);
|
||||
|
@ -2870,7 +2870,7 @@ g_journal_do_switch(struct g_class *classp)
|
||||
struct mount *mp;
|
||||
struct bintime bt;
|
||||
char *mountpoint;
|
||||
int error, vfslocked;
|
||||
int error, save, vfslocked;
|
||||
|
||||
DROP_GIANT();
|
||||
g_topology_lock();
|
||||
@ -2932,10 +2932,7 @@ g_journal_do_switch(struct g_class *classp)
|
||||
goto next;
|
||||
}
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_noasync++;
|
||||
mp->mnt_kern_flag &= ~MNTK_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
save = curthread_pflags_set(TDP_SYNCIO);
|
||||
|
||||
GJ_TIMER_START(1, &bt);
|
||||
vfs_msync(mp, MNT_NOWAIT);
|
||||
@ -2950,11 +2947,7 @@ g_journal_do_switch(struct g_class *classp)
|
||||
mountpoint, error);
|
||||
}
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_noasync--;
|
||||
if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
|
||||
mp->mnt_kern_flag |= MNTK_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
curthread_pflags_restore(save);
|
||||
|
||||
vn_finished_write(mp);
|
||||
|
||||
|
@ -3521,7 +3521,7 @@ sync_fsync(struct vop_fsync_args *ap)
|
||||
{
|
||||
struct vnode *syncvp = ap->a_vp;
|
||||
struct mount *mp = syncvp->v_mount;
|
||||
int error;
|
||||
int error, save;
|
||||
struct bufobj *bo;
|
||||
|
||||
/*
|
||||
@ -3551,17 +3551,10 @@ sync_fsync(struct vop_fsync_args *ap)
|
||||
vfs_unbusy(mp);
|
||||
return (0);
|
||||
}
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_noasync++;
|
||||
mp->mnt_kern_flag &= ~MNTK_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
save = curthread_pflags_set(TDP_SYNCIO);
|
||||
vfs_msync(mp, MNT_NOWAIT);
|
||||
error = VFS_SYNC(mp, MNT_LAZY);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_noasync--;
|
||||
if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
|
||||
mp->mnt_kern_flag |= MNTK_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
curthread_pflags_restore(save);
|
||||
vn_finished_write(mp);
|
||||
vfs_unbusy(mp);
|
||||
return (error);
|
||||
|
@ -134,7 +134,7 @@ sys_sync(td, uap)
|
||||
struct sync_args *uap;
|
||||
{
|
||||
struct mount *mp, *nmp;
|
||||
int vfslocked;
|
||||
int save, vfslocked;
|
||||
|
||||
mtx_lock(&mountlist_mtx);
|
||||
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
|
||||
@ -145,18 +145,10 @@ sys_sync(td, uap)
|
||||
vfslocked = VFS_LOCK_GIANT(mp);
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
|
||||
vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_noasync++;
|
||||
mp->mnt_kern_flag &= ~MNTK_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
save = curthread_pflags_set(TDP_SYNCIO);
|
||||
vfs_msync(mp, MNT_NOWAIT);
|
||||
VFS_SYNC(mp, MNT_NOWAIT);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_noasync--;
|
||||
if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
|
||||
mp->mnt_noasync == 0)
|
||||
mp->mnt_kern_flag |= MNTK_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
curthread_pflags_restore(save);
|
||||
vn_finished_write(mp);
|
||||
}
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
|
@ -1448,7 +1448,7 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
|
||||
tsiz -= len;
|
||||
}
|
||||
nfsmout:
|
||||
if (vp->v_mount->mnt_kern_flag & MNTK_ASYNC)
|
||||
if (DOINGASYNC(vp))
|
||||
committed = NFSV3WRITE_FILESYNC;
|
||||
*iomode = committed;
|
||||
if (error)
|
||||
|
@ -400,7 +400,7 @@ do { \
|
||||
#define TDP_NOSLEEPING 0x00000100 /* Thread is not allowed to sleep on a sq. */
|
||||
#define TDP_OWEUPC 0x00000200 /* Call addupc() at next AST. */
|
||||
#define TDP_ITHREAD 0x00000400 /* Thread is an interrupt thread. */
|
||||
#define TDP_UNUSED800 0x00000800 /* available. */
|
||||
#define TDP_SYNCIO 0x00000800 /* Local override, disable async i/o. */
|
||||
#define TDP_SCHED1 0x00001000 /* Reserved for scheduler private use */
|
||||
#define TDP_SCHED2 0x00002000 /* Reserved for scheduler private use */
|
||||
#define TDP_SCHED3 0x00004000 /* Reserved for scheduler private use */
|
||||
|
@ -538,6 +538,10 @@ void assert_vop_unlocked(struct vnode *vp, const char *str);
|
||||
*/
|
||||
#define VCALL(c) ((c)->a_desc->vdesc_call(c))
|
||||
|
||||
#define DOINGASYNC(vp) \
|
||||
(((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC) != 0 && \
|
||||
((curthread->td_pflags & TDP_SYNCIO) == 0))
|
||||
|
||||
/*
|
||||
* VMIO support inline
|
||||
*/
|
||||
|
@ -176,7 +176,6 @@ struct indir {
|
||||
/* Determine if soft dependencies are being done */
|
||||
#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & (MNT_SOFTDEP | MNT_SUJ))
|
||||
#define MOUNTEDSOFTDEP(mp) ((mp)->mnt_flag & (MNT_SOFTDEP | MNT_SUJ))
|
||||
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
|
||||
#define DOINGSUJ(vp) ((vp)->v_mount->mnt_flag & MNT_SUJ)
|
||||
#define MOUNTEDSUJ(mp) ((mp)->mnt_flag & MNT_SUJ)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user