summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2006-09-26 04:15:59 +0000
committertegge <tegge@FreeBSD.org>2006-09-26 04:15:59 +0000
commitf42473d76b149849661d41c1f44a36dd01096d40 (patch)
tree3bc9361221d5a734023278052dddd20fb2025bee /sys
parentb500b0ae92746b6a7309c0f88afadb7c588fd859 (diff)
downloadFreeBSD-src-f42473d76b149849661d41c1f44a36dd01096d40.zip
FreeBSD-src-f42473d76b149849661d41c1f44a36dd01096d40.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/boot/pc98/boot2/inode.h2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_inode.c2
-rw-r--r--sys/kern/vfs_cluster.c2
-rw-r--r--sys/kern/vfs_extattr.c10
-rw-r--r--sys/kern/vfs_mount.c15
-rw-r--r--sys/kern/vfs_subr.c11
-rw-r--r--sys/kern/vfs_syscalls.c10
-rw-r--r--sys/nfsclient/nfs_vnops.c2
-rw-r--r--sys/sys/mount.h2
-rw-r--r--sys/ufs/ufs/inode.h2
10 files changed, 40 insertions, 18 deletions
diff --git a/sys/boot/pc98/boot2/inode.h b/sys/boot/pc98/boot2/inode.h
index 9a59f99..add9bb9 100644
--- a/sys/boot/pc98/boot2/inode.h
+++ b/sys/boot/pc98/boot2/inode.h
@@ -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 {
diff --git a/sys/gnu/fs/ext2fs/ext2_inode.c b/sys/gnu/fs/ext2fs/ext2_inode.c
index 9f84fd4..04a9d46 100644
--- a/sys/gnu/fs/ext2fs/ext2_inode.c
+++ b/sys/gnu/fs/ext2fs/ext2_inode.c
@@ -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);
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index b749f56..4c2cfaf 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -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;
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 147b31e..d23f19b 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -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);
}
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index f99b083..db40943 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -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);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 72c4b5c..c5189ed 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -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);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 147b31e..d23f19b 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -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);
}
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index e073de9..c284b1a 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -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)
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index c7e0db3..70e5097 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -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 */
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index 0417f9c..38e2c30 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -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 {
OpenPOWER on IntegriCloud