Add mnt_noasync counter to better handle interleaved calls to nmount(),

sync() and sync_fsync() without losing MNT_ASYNC.  Add MNTK_ASYNC flag
which is set only when MNT_ASYNC is set and mnt_noasync is zero, and
check that flag instead of MNT_ASYNC before initiating async io.
This commit is contained in:
Tor Egge 2006-09-26 04:15:59 +00:00
parent cea9d840d8
commit a1e363f256
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=162649
10 changed files with 40 additions and 18 deletions

View File

@ -147,7 +147,7 @@ struct indir {
/* Determine if soft dependencies are being done */
#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_flag & MNT_ASYNC)
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
/* This overlays the fid structure (see mount.h). */
struct ufid {

View File

@ -92,7 +92,7 @@ ext2_update(vp, waitfor)
}
ext2_i2ei(ip, (struct ext2_inode *)((char *)bp->b_data +
EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)));
if (waitfor && (vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
if (waitfor && (vp->v_mount->mnt_kern_flag & MNTK_ASYNC) == 0)
return (bwrite(bp));
else {
bdwrite(bp);

View File

@ -595,7 +595,7 @@ cluster_write(struct vnode *vp, struct buf *bp, u_quad_t filesize, int seqcount)
int async;
if (vp->v_type == VREG) {
async = vp->v_mount->mnt_flag & MNT_ASYNC;
async = vp->v_mount->mnt_kern_flag & MNTK_ASYNC;
lblocksize = vp->v_mount->mnt_stat.f_iosize;
} else {
async = 0;

View File

@ -122,7 +122,6 @@ sync(td, uap)
{
struct mount *mp, *nmp;
int vfslocked;
int asyncflag;
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
@ -134,13 +133,16 @@ sync(td, uap)
if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
MNT_ILOCK(mp);
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
mp->mnt_noasync++;
mp->mnt_kern_flag &= ~MNTK_ASYNC;
MNT_IUNLOCK(mp);
vfs_msync(mp, MNT_NOWAIT);
VFS_SYNC(mp, MNT_NOWAIT, td);
MNT_ILOCK(mp);
mp->mnt_flag |= asyncflag;
mp->mnt_noasync--;
if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
mp->mnt_noasync == 0)
mp->mnt_kern_flag |= MNTK_ASYNC;
MNT_IUNLOCK(mp);
vn_finished_write(mp);
}

View File

@ -946,6 +946,8 @@ vfs_domount(
mp->mnt_flag |= MNT_RDONLY;
mp->mnt_flag &=~ MNT_UPDATEMASK;
mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS);
if ((mp->mnt_flag & MNT_ASYNC) == 0)
mp->mnt_kern_flag &= ~MNTK_ASYNC;
MNT_IUNLOCK(mp);
/*
* Mount the filesystem.
@ -981,6 +983,10 @@ vfs_domount(
~(MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
if (error)
mp->mnt_flag = flag;
if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
mp->mnt_kern_flag |= MNTK_ASYNC;
else
mp->mnt_kern_flag &= ~MNTK_ASYNC;
MNT_IUNLOCK(mp);
if ((mp->mnt_flag & MNT_RDONLY) == 0) {
if (mp->mnt_syncer == NULL)
@ -997,6 +1003,12 @@ vfs_domount(
vrele(vp);
return (error);
}
MNT_ILOCK(mp);
if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
mp->mnt_kern_flag |= MNTK_ASYNC;
else
mp->mnt_kern_flag &= ~MNTK_ASYNC;
MNT_IUNLOCK(mp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
/*
* Put the new filesystem on the mount list after root.
@ -1196,6 +1208,7 @@ dounmount(mp, flags, td)
MNT_ILOCK(mp);
async_flag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
mp->mnt_kern_flag &= ~MNTK_ASYNC;
MNT_IUNLOCK(mp);
cache_purgevfs(mp); /* remove cache entries for this file sys */
if (mp->mnt_syncer != NULL)
@ -1238,6 +1251,8 @@ dounmount(mp, flags, td)
MNT_ILOCK(mp);
mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF);
mp->mnt_flag |= async_flag;
if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
mp->mnt_kern_flag |= MNTK_ASYNC;
lockmgr(&mp->mnt_lock, LK_RELEASE, NULL, td);
if (mp->mnt_kern_flag & MNTK_MWAIT)
wakeup(mp);

View File

@ -3051,7 +3051,7 @@ sync_fsync(struct vop_fsync_args *ap)
struct vnode *syncvp = ap->a_vp;
struct mount *mp = syncvp->v_mount;
struct thread *td = ap->a_td;
int error, asyncflag;
int error;
struct bufobj *bo;
/*
@ -3082,14 +3082,15 @@ sync_fsync(struct vop_fsync_args *ap)
return (0);
}
MNT_ILOCK(mp);
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
mp->mnt_noasync++;
mp->mnt_kern_flag &= ~MNTK_ASYNC;
MNT_IUNLOCK(mp);
vfs_msync(mp, MNT_NOWAIT);
error = VFS_SYNC(mp, MNT_LAZY, td);
MNT_ILOCK(mp);
if (asyncflag)
mp->mnt_flag |= MNT_ASYNC;
mp->mnt_noasync--;
if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
mp->mnt_kern_flag |= MNTK_ASYNC;
MNT_IUNLOCK(mp);
vn_finished_write(mp);
vfs_unbusy(mp, td);

View File

@ -122,7 +122,6 @@ sync(td, uap)
{
struct mount *mp, *nmp;
int vfslocked;
int asyncflag;
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
@ -134,13 +133,16 @@ sync(td, uap)
if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
MNT_ILOCK(mp);
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
mp->mnt_noasync++;
mp->mnt_kern_flag &= ~MNTK_ASYNC;
MNT_IUNLOCK(mp);
vfs_msync(mp, MNT_NOWAIT);
VFS_SYNC(mp, MNT_NOWAIT, td);
MNT_ILOCK(mp);
mp->mnt_flag |= asyncflag;
mp->mnt_noasync--;
if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
mp->mnt_noasync == 0)
mp->mnt_kern_flag |= MNTK_ASYNC;
MNT_IUNLOCK(mp);
vn_finished_write(mp);
}

View File

@ -1223,7 +1223,7 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
tsiz -= len;
}
nfsmout:
if (vp->v_mount->mnt_flag & MNT_ASYNC)
if (vp->v_mount->mnt_kern_flag & MNTK_ASYNC)
committed = NFSV3WRITE_FILESYNC;
*iomode = committed;
if (error)

View File

@ -157,6 +157,7 @@ struct mount {
int mnt_writeopcount; /* (i) write syscalls pending */
int mnt_kern_flag; /* (i) kernel only flags */
u_int mnt_flag; /* (i) flags shared with user */
u_int mnt_noasync; /* (i) # noasync overrides */
struct vfsoptlist *mnt_opt; /* current mount options */
struct vfsoptlist *mnt_optnew; /* new options passed to fs */
int mnt_maxsymlinklen; /* max size of short symlink */
@ -303,6 +304,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
* with the unmount attempt (used by NFS).
*/
#define MNTK_UNMOUNTF 0x00000001 /* forced unmount in progress */
#define MNTK_ASYNC 0x00000002 /* filtered async flag */
#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
#define MNTK_SUSPEND 0x08000000 /* request write suspension */

View File

@ -166,7 +166,7 @@ struct indir {
/* Determine if soft dependencies are being done */
#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_flag & MNT_ASYNC)
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
/* This overlays the fid structure (see mount.h). */
struct ufid {