summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpi.c8
-rw-r--r--sys/isofs/cd9660/cd9660_extern.h4
-rw-r--r--sys/isofs/cd9660/cd9660_vfsops.c5
-rw-r--r--sys/isofs/udf/udf_extern.h4
-rw-r--r--sys/isofs/udf/udf_vfsops.c4
-rw-r--r--sys/kern/vfs_subr.c57
-rw-r--r--sys/kern/vfs_sync.c4
-rw-r--r--sys/kern/vfs_syscalls.c6
-rw-r--r--sys/kern/vfs_vops.c135
-rw-r--r--sys/miscfs/fuse/fuse_vfsops.c6
-rw-r--r--sys/msdosfs/msdosfs_vfsops.c9
-rw-r--r--sys/msdosfs/msdosfsmount.h4
-rw-r--r--sys/nfs/nfs_vfsops.c6
-rw-r--r--sys/ntfs/ntfs_vfsops.c6
-rw-r--r--sys/sys/file.h10
-rw-r--r--sys/sys/mount.h8
-rw-r--r--sys/sys/vnode.h3
-rw-r--r--sys/ufs/ext2fs/ext2fs_extern.h4
-rw-r--r--sys/ufs/ext2fs/ext2fs_vfsops.c58
-rw-r--r--sys/ufs/ffs/ffs_extern.h4
-rw-r--r--sys/ufs/ffs/ffs_softdep.c4
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c56
22 files changed, 310 insertions, 95 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index ea23d66040a..4e5fc3f7aa8 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.338 2018/02/08 09:42:48 deraadt Exp $ */
+/* $OpenBSD: acpi.c,v 1.339 2018/02/10 05:24:23 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -30,6 +30,8 @@
#include <sys/sched.h>
#include <sys/reboot.h>
#include <sys/sysctl.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
#ifdef HIBERNATE
#include <sys/hibernate.h>
@@ -2503,6 +2505,7 @@ acpi_sleep_state(struct acpi_softc *sc, int sleepmode)
if (config_suspend_all(DVACT_QUIESCE))
goto fail_quiesce;
+ vfs_stall(curproc, 1);
#if NSOFTRAID > 0
sr_quiesce();
#endif
@@ -2590,6 +2593,7 @@ fail_suspend:
acpi_resume_mp();
#endif
+ vfs_stall(curproc, 0);
bufq_restart();
fail_quiesce:
@@ -2612,6 +2616,8 @@ fail_alloc:
rw_enter_write(&sc->sc_lck);
#endif /* NWSDISPLAY > 0 */
+ sys_sync(curproc, NULL, NULL);
+
/* Restore hw.setperf */
if (cpu_setperf != NULL)
cpu_setperf(perflevel);
diff --git a/sys/isofs/cd9660/cd9660_extern.h b/sys/isofs/cd9660/cd9660_extern.h
index 48b842adce1..8c4bebfa8dd 100644
--- a/sys/isofs/cd9660/cd9660_extern.h
+++ b/sys/isofs/cd9660/cd9660_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd9660_extern.h,v 1.13 2013/06/02 01:07:39 deraadt Exp $ */
+/* $OpenBSD: cd9660_extern.h,v 1.14 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: cd9660_extern.h,v 1.1 1997/01/24 00:24:53 cgd Exp $ */
/*-
@@ -87,7 +87,7 @@ int cd9660_unmount(struct mount *, int, struct proc *);
int cd9660_root(struct mount *, struct vnode **);
int cd9660_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *);
int cd9660_statfs(struct mount *, struct statfs *, struct proc *);
-int cd9660_sync(struct mount *, int, struct ucred *, struct proc *);
+int cd9660_sync(struct mount *, int, int, struct ucred *, struct proc *);
int cd9660_vget(struct mount *, ino_t, struct vnode **);
int cd9660_fhtovp(struct mount *, struct fid *, struct vnode **);
int cd9660_vptofh(struct vnode *, struct fid *);
diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c
index efe2e4abdb5..ac3df59ad1b 100644
--- a/sys/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/isofs/cd9660/cd9660_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd9660_vfsops.c,v 1.86 2017/12/30 23:08:29 guenther Exp $ */
+/* $OpenBSD: cd9660_vfsops.c,v 1.87 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: cd9660_vfsops.c,v 1.26 1997/06/13 15:38:58 pk Exp $ */
/*-
@@ -644,9 +644,10 @@ cd9660_statfs(mp, sbp, p)
/* ARGSUSED */
int
-cd9660_sync(mp, waitfor, cred, p)
+cd9660_sync(mp, waitfor, stall, cred, p)
struct mount *mp;
int waitfor;
+ int stall;
struct ucred *cred;
struct proc *p;
{
diff --git a/sys/isofs/udf/udf_extern.h b/sys/isofs/udf/udf_extern.h
index 07859f3fc4b..c48782c820c 100644
--- a/sys/isofs/udf/udf_extern.h
+++ b/sys/isofs/udf/udf_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: udf_extern.h,v 1.13 2013/06/02 15:35:18 deraadt Exp $ */
+/* $OpenBSD: udf_extern.h,v 1.14 2018/02/10 05:24:23 deraadt Exp $ */
/*
* Written by Pedro Martelletto <pedro@ambientworks.net> in February 2005.
@@ -26,7 +26,7 @@ int udf_root(struct mount *, struct vnode **);
int udf_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *);
int udf_statfs(struct mount *, struct statfs *, struct proc *);
int udf_vget(struct mount *, ino_t, struct vnode **);
-int udf_sync(struct mount *, int, struct ucred *, struct proc *);
+int udf_sync(struct mount *, int, int, struct ucred *, struct proc *);
int udf_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *);
int udf_checkexp(struct mount *, struct mbuf *, int *, struct ucred **);
int udf_fhtovp(struct mount *, struct fid *, struct vnode **);
diff --git a/sys/isofs/udf/udf_vfsops.c b/sys/isofs/udf/udf_vfsops.c
index 56ef21fa34f..8a0173db611 100644
--- a/sys/isofs/udf/udf_vfsops.c
+++ b/sys/isofs/udf/udf_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udf_vfsops.c,v 1.61 2017/12/11 05:27:40 deraadt Exp $ */
+/* $OpenBSD: udf_vfsops.c,v 1.62 2018/02/10 05:24:23 deraadt Exp $ */
/*
* Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
@@ -537,7 +537,7 @@ udf_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
}
int
-udf_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
+udf_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred, struct proc *p)
{
return (0);
}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 7311916fbf5..1e325fa3eca 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.265 2017/12/14 20:23:15 deraadt Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.266 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -72,7 +72,7 @@
#include "softraid.h"
-void sr_shutdown(int);
+void sr_quiesce(void);
enum vtype iftovt_tab[16] = {
VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
@@ -1583,6 +1583,48 @@ vaccess(enum vtype type, mode_t file_mode, uid_t uid, gid_t gid,
return (file_mode & mask) == mask ? 0 : EACCES;
}
+struct rwlock vfs_stall_lock = RWLOCK_INITIALIZER("vfs_stall");
+
+int
+vfs_stall(struct proc *p, int stall)
+{
+ struct mount *mp, *nmp;
+ int allerror = 0, error;
+
+ if (stall)
+ rw_enter_write(&vfs_stall_lock);
+
+ TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) {
+ if (stall) {
+ error = vfs_busy(mp, VB_WRITE|VB_WAIT);
+ if (error) {
+ printf("%s: busy\n", mp->mnt_stat.f_mntonname);
+ allerror = error;
+ continue;
+ }
+ uvm_vnp_sync(mp);
+ error = VFS_SYNC(mp, MNT_WAIT, stall, p->p_ucred, p);
+ if (error) {
+ printf("%s: failed to sync\n", mp->mnt_stat.f_mntonname);
+ vfs_unbusy(mp);
+ allerror = error;
+ continue;
+ }
+ mp->mnt_flag |= MNT_STALLED;
+ } else {
+ if (mp->mnt_flag & MNT_STALLED) {
+ vfs_unbusy(mp);
+ mp->mnt_flag &= ~MNT_STALLED;
+ }
+ }
+ }
+
+ if (!stall)
+ rw_exit_write(&vfs_stall_lock);
+
+ return (allerror);
+}
+
int
vfs_readonly(struct mount *mp, struct proc *p)
{
@@ -1594,7 +1636,7 @@ vfs_readonly(struct mount *mp, struct proc *p)
return (error);
}
uvm_vnp_sync(mp);
- error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p);
+ error = VFS_SYNC(mp, MNT_WAIT, 0, p->p_ucred, p);
if (error) {
printf("%s: failed to sync\n", mp->mnt_stat.f_mntonname);
vfs_unbusy(mp);
@@ -1628,7 +1670,6 @@ vfs_rofs(struct proc *p)
struct mount *mp, *nmp;
TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) {
- /* XXX Here is a race, the next pointer is not locked. */
(void) vfs_readonly(mp, p);
}
}
@@ -1651,14 +1692,14 @@ vfs_shutdown(struct proc *p)
vfs_rofs(p);
}
+#if NSOFTRAID > 0
+ sr_quiesce();
+#endif
+
if (vfs_syncwait(p, 1))
printf("giving up\n");
else
printf("done\n");
-
-#if NSOFTRAID > 0
- sr_shutdown(1);
-#endif
}
/*
diff --git a/sys/kern/vfs_sync.c b/sys/kern/vfs_sync.c
index 86fda887951..bb8ee505e81 100644
--- a/sys/kern/vfs_sync.c
+++ b/sys/kern/vfs_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_sync.c,v 1.56 2017/02/14 10:31:15 mpi Exp $ */
+/* $OpenBSD: vfs_sync.c,v 1.57 2018/02/10 05:24:23 deraadt Exp $ */
/*
* Portions of this code are:
@@ -339,7 +339,7 @@ sync_fsync(void *v)
if (vfs_busy(mp, VB_READ|VB_NOWAIT) == 0) {
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
- VFS_SYNC(mp, MNT_LAZY, ap->a_cred, ap->a_p);
+ VFS_SYNC(mp, MNT_LAZY, 0, ap->a_cred, ap->a_p);
if (asyncflag)
mp->mnt_flag |= MNT_ASYNC;
vfs_unbusy(mp);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 675a4d64d50..1edad2495cd 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.274 2018/01/02 06:38:45 guenther Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.275 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -494,7 +494,7 @@ dounmount_leaf(struct mount *mp, int flags, struct proc *p)
mp->mnt_syncer = NULL;
}
if (((mp->mnt_flag & MNT_RDONLY) ||
- (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) ||
+ (error = VFS_SYNC(mp, MNT_WAIT, 0, p->p_ucred, p)) == 0) ||
(flags & MNT_FORCE))
error = VFS_UNMOUNT(mp, flags, p);
@@ -543,7 +543,7 @@ sys_sync(struct proc *p, void *v, register_t *retval)
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
uvm_vnp_sync(mp);
- VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);
+ VFS_SYNC(mp, MNT_NOWAIT, 0, p->p_ucred, p);
if (asyncflag)
mp->mnt_flag |= MNT_ASYNC;
}
diff --git a/sys/kern/vfs_vops.c b/sys/kern/vfs_vops.c
index f579134aeed..42ba4eecf00 100644
--- a/sys/kern/vfs_vops.c
+++ b/sys/kern/vfs_vops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_vops.c,v 1.16 2016/05/23 09:31:28 natano Exp $ */
+/* $OpenBSD: vfs_vops.c,v 1.17 2018/02/10 05:24:23 deraadt Exp $ */
/*
* Copyright (c) 2010 Thordur I. Bjornsson <thib@openbsd.org>
*
@@ -76,6 +76,7 @@ int
VOP_LOOKUP(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp)
{
+ int r;
struct vop_lookup_args a;
a.a_dvp = dvp;
a.a_vpp = vpp;
@@ -84,13 +85,17 @@ VOP_LOOKUP(struct vnode *dvp, struct vnode **vpp,
if (dvp->v_op->vop_lookup == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_lookup)(&a));
+ dvp->v_inflight++;
+ r = (dvp->v_op->vop_lookup)(&a);
+ dvp->v_inflight--;
+ return r;
}
int
VOP_CREATE(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp, struct vattr *vap)
{
+ int r;
struct vop_create_args a;
a.a_dvp = dvp;
a.a_vpp = vpp;
@@ -102,13 +107,17 @@ VOP_CREATE(struct vnode *dvp, struct vnode **vpp,
if (dvp->v_op->vop_create == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_create)(&a));
+ dvp->v_inflight++;
+ r = (dvp->v_op->vop_create)(&a);
+ dvp->v_inflight--;
+ return r;
}
int
VOP_MKNOD(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp, struct vattr *vap)
{
+ int r;
struct vop_mknod_args a;
a.a_dvp = dvp;
a.a_vpp = vpp;
@@ -120,12 +129,16 @@ VOP_MKNOD(struct vnode *dvp, struct vnode **vpp,
if (dvp->v_op->vop_mknod == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_mknod)(&a));
+ dvp->v_inflight++;
+ r = (dvp->v_op->vop_mknod)(&a);
+ dvp->v_inflight--;
+ return r;
}
int
VOP_OPEN(struct vnode *vp, int mode, struct ucred *cred, struct proc *p)
{
+ int r;
struct vop_open_args a;
a.a_vp = vp;
a.a_mode = mode;
@@ -135,12 +148,16 @@ VOP_OPEN(struct vnode *vp, int mode, struct ucred *cred, struct proc *p)
if (vp->v_op->vop_open == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_open)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_open)(&a);
+ vp->v_inflight--;
+ return r;
}
int
VOP_CLOSE(struct vnode *vp, int fflag, struct ucred *cred, struct proc *p)
{
+ int r;
struct vop_close_args a;
a.a_vp = vp;
a.a_fflag = fflag;
@@ -152,7 +169,10 @@ VOP_CLOSE(struct vnode *vp, int fflag, struct ucred *cred, struct proc *p)
if (vp->v_op->vop_close == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_close)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_close)(&a);
+ vp->v_inflight--;
+ return r;
}
int
@@ -192,6 +212,7 @@ int
VOP_SETATTR(struct vnode *vp, struct vattr *vap, struct ucred *cred,
struct proc *p)
{
+ int r;
struct vop_setattr_args a;
a.a_vp = vp;
a.a_vap = vap;
@@ -203,7 +224,10 @@ VOP_SETATTR(struct vnode *vp, struct vattr *vap, struct ucred *cred,
if (vp->v_op->vop_setattr == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_setattr)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_setattr)(&a);
+ vp->v_inflight--;
+ return r;
}
int
@@ -227,6 +251,7 @@ int
VOP_WRITE(struct vnode *vp, struct uio *uio, int ioflag,
struct ucred *cred)
{
+ int r;
struct vop_write_args a;
a.a_vp = vp;
a.a_uio = uio;
@@ -238,13 +263,17 @@ VOP_WRITE(struct vnode *vp, struct uio *uio, int ioflag,
if (vp->v_op->vop_write == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_write)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_write)(&a);
+ vp->v_inflight--;
+ return r;
}
int
VOP_IOCTL(struct vnode *vp, u_long command, void *data, int fflag,
struct ucred *cred, struct proc *p)
{
+ int r;
struct vop_ioctl_args a;
a.a_vp = vp;
a.a_command = command;
@@ -256,8 +285,10 @@ VOP_IOCTL(struct vnode *vp, u_long command, void *data, int fflag,
if (vp->v_op->vop_ioctl == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_ioctl)(&a));
-
+ vp->v_inflight++;
+ r = (vp->v_op->vop_ioctl)(&a);
+ vp->v_inflight--;
+ return r;
}
int
@@ -305,6 +336,7 @@ int
VOP_FSYNC(struct vnode *vp, struct ucred *cred, int waitfor,
struct proc *p)
{
+ int r;
struct vop_fsync_args a;
a.a_vp = vp;
a.a_cred = cred;
@@ -316,12 +348,16 @@ VOP_FSYNC(struct vnode *vp, struct ucred *cred, int waitfor,
if (vp->v_op->vop_fsync == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_fsync)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_fsync)(&a);
+ vp->v_inflight--;
+ return r;
}
int
VOP_REMOVE(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
+ int r;
struct vop_remove_args a;
a.a_dvp = dvp;
a.a_vp = vp;
@@ -333,12 +369,16 @@ VOP_REMOVE(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
if (dvp->v_op->vop_remove == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_remove)(&a));
+ dvp->v_inflight++;
+ r = (dvp->v_op->vop_remove)(&a);
+ dvp->v_inflight--;
+ return r;
}
int
VOP_LINK(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
+ int r;
struct vop_link_args a;
a.a_dvp = dvp;
a.a_vp = vp;
@@ -349,7 +389,12 @@ VOP_LINK(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
if (dvp->v_op->vop_link == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_link)(&a));
+ dvp->v_inflight++;
+ vp->v_inflight++;
+ r = (dvp->v_op->vop_link)(&a);
+ dvp->v_inflight--;
+ vp->v_inflight--;
+ return r;
}
int
@@ -357,6 +402,7 @@ VOP_RENAME(struct vnode *fdvp, struct vnode *fvp,
struct componentname *fcnp, struct vnode *tdvp, struct vnode *tvp,
struct componentname *tcnp)
{
+ int r;
struct vop_rename_args a;
a.a_fdvp = fdvp;
a.a_fvp = fvp;
@@ -370,13 +416,19 @@ VOP_RENAME(struct vnode *fdvp, struct vnode *fvp,
if (fdvp->v_op->vop_rename == NULL)
return (EOPNOTSUPP);
- return ((fdvp->v_op->vop_rename)(&a));
+ fdvp->v_inflight++;
+ tdvp->v_inflight++;
+ r = (fdvp->v_op->vop_rename)(&a);
+ fdvp->v_inflight--;
+ tdvp->v_inflight--;
+ return r;
}
int
VOP_MKDIR(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp, struct vattr *vap)
{
+ int r;
struct vop_mkdir_args a;
a.a_dvp = dvp;
a.a_vpp = vpp;
@@ -388,12 +440,16 @@ VOP_MKDIR(struct vnode *dvp, struct vnode **vpp,
if (dvp->v_op->vop_mkdir == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_mkdir)(&a));
+ dvp->v_inflight++;
+ r = (dvp->v_op->vop_mkdir)(&a);
+ dvp->v_inflight--;
+ return r;
}
int
VOP_RMDIR(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
+ int r;
struct vop_rmdir_args a;
a.a_dvp = dvp;
a.a_vp = vp;
@@ -405,13 +461,19 @@ VOP_RMDIR(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
if (dvp->v_op->vop_rmdir == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_rmdir)(&a));
+ dvp->v_inflight++;
+ vp->v_inflight++;
+ r = (dvp->v_op->vop_rmdir)(&a);
+ dvp->v_inflight--;
+ vp->v_inflight--;
+ return r;
}
int
VOP_SYMLINK(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp, struct vattr *vap, char *target)
{
+ int r;
struct vop_symlink_args a;
a.a_dvp = dvp;
a.a_vpp = vpp;
@@ -424,13 +486,17 @@ VOP_SYMLINK(struct vnode *dvp, struct vnode **vpp,
if (dvp->v_op->vop_symlink == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_symlink)(&a));
+ dvp->v_inflight++;
+ r = (dvp->v_op->vop_symlink)(&a);
+ dvp->v_inflight--;
+ return r;
}
int
VOP_READDIR(struct vnode *vp, struct uio *uio, struct ucred *cred,
int *eofflag)
{
+ int r;
struct vop_readdir_args a;
a.a_vp = vp;
a.a_uio = uio;
@@ -442,12 +508,16 @@ VOP_READDIR(struct vnode *vp, struct uio *uio, struct ucred *cred,
if (vp->v_op->vop_readdir == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_readdir)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_readdir)(&a);
+ vp->v_inflight--;
+ return r;
}
int
VOP_READLINK(struct vnode *vp, struct uio *uio, struct ucred *cred)
{
+ int r;
struct vop_readlink_args a;
a.a_vp = vp;
a.a_uio = uio;
@@ -458,12 +528,16 @@ VOP_READLINK(struct vnode *vp, struct uio *uio, struct ucred *cred)
if (vp->v_op->vop_readlink == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_readlink)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_readlink)(&a);
+ vp->v_inflight--;
+ return r;
}
int
VOP_ABORTOP(struct vnode *dvp, struct componentname *cnp)
{
+ int r;
struct vop_abortop_args a;
a.a_dvp = dvp;
a.a_cnp = cnp;
@@ -471,7 +545,10 @@ VOP_ABORTOP(struct vnode *dvp, struct componentname *cnp)
if (dvp->v_op->vop_abortop == NULL)
return (EOPNOTSUPP);
- return ((dvp->v_op->vop_abortop)(&a));
+ dvp->v_inflight++;
+ r = (dvp->v_op->vop_abortop)(&a);
+ dvp->v_inflight--;
+ return r;
}
int
@@ -492,6 +569,7 @@ VOP_INACTIVE(struct vnode *vp, struct proc *p)
int
VOP_RECLAIM(struct vnode *vp, struct proc *p)
{
+ int r;
struct vop_reclaim_args a;
a.a_vp = vp;
a.a_p = p;
@@ -499,7 +577,10 @@ VOP_RECLAIM(struct vnode *vp, struct proc *p)
if (vp->v_op->vop_reclaim == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_reclaim)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_reclaim)(&a);
+ vp->v_inflight--;
+ return r;
}
int
@@ -519,6 +600,7 @@ VOP_LOCK(struct vnode *vp, int flags, struct proc *p)
int
VOP_UNLOCK(struct vnode *vp, struct proc *p)
{
+ int r;
struct vop_unlock_args a;
a.a_vp = vp;
a.a_p = p;
@@ -526,7 +608,10 @@ VOP_UNLOCK(struct vnode *vp, struct proc *p)
if (vp->v_op->vop_unlock == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_unlock)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_unlock)(&a);
+ vp->v_inflight--;
+ return r;
}
int
@@ -598,6 +683,7 @@ VOP_PATHCONF(struct vnode *vp, int name, register_t *retval)
int
VOP_ADVLOCK(struct vnode *vp, void *id, int op, struct flock *fl, int flags)
{
+ int r;
struct vop_advlock_args a;
a.a_vp = vp;
a.a_id = id;
@@ -608,7 +694,10 @@ VOP_ADVLOCK(struct vnode *vp, void *id, int op, struct flock *fl, int flags)
if (vp->v_op->vop_advlock == NULL)
return (EOPNOTSUPP);
- return ((vp->v_op->vop_advlock)(&a));
+ vp->v_inflight++;
+ r = (vp->v_op->vop_advlock)(&a);
+ vp->v_inflight--;
+ return r;
}
int
diff --git a/sys/miscfs/fuse/fuse_vfsops.c b/sys/miscfs/fuse/fuse_vfsops.c
index 7867ff60579..7f7b044f458 100644
--- a/sys/miscfs/fuse/fuse_vfsops.c
+++ b/sys/miscfs/fuse/fuse_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vfsops.c,v 1.31 2018/01/04 10:51:11 mpi Exp $ */
+/* $OpenBSD: fuse_vfsops.c,v 1.32 2018/02/10 05:24:23 deraadt Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -40,7 +40,7 @@ int fusefs_unmount(struct mount *, int, struct proc *);
int fusefs_root(struct mount *, struct vnode **);
int fusefs_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *);
int fusefs_statfs(struct mount *, struct statfs *, struct proc *);
-int fusefs_sync(struct mount *, int, struct ucred *, struct proc *);
+int fusefs_sync(struct mount *, int, int, struct ucred *, struct proc *);
int fusefs_vget(struct mount *, ino_t, struct vnode **);
int fusefs_fhtovp(struct mount *, struct fid *, struct vnode **);
int fusefs_vptofh(struct vnode *, struct fid *);
@@ -239,7 +239,7 @@ fusefs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
}
int
-fusefs_sync(struct mount *mp, int waitfor, struct ucred *cred,
+fusefs_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred,
struct proc *p)
{
return (0);
diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c
index 67af60dcbf9..f2a7a5de845 100644
--- a/sys/msdosfs/msdosfs_vfsops.c
+++ b/sys/msdosfs/msdosfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfs_vfsops.c,v 1.86 2017/12/30 23:08:29 guenther Exp $ */
+/* $OpenBSD: msdosfs_vfsops.c,v 1.87 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: msdosfs_vfsops.c,v 1.48 1997/10/18 02:54:57 briggs Exp $ */
/*-
@@ -80,7 +80,7 @@ int msdosfs_start(struct mount *, int, struct proc *);
int msdosfs_unmount(struct mount *, int, struct proc *);
int msdosfs_root(struct mount *, struct vnode **);
int msdosfs_statfs(struct mount *, struct statfs *, struct proc *);
-int msdosfs_sync(struct mount *, int, struct ucred *, struct proc *);
+int msdosfs_sync(struct mount *, int, int, struct ucred *, struct proc *);
int msdosfs_fhtovp(struct mount *, struct fid *, struct vnode **);
int msdosfs_vptofh(struct vnode *, struct fid *);
int msdosfs_check_export(struct mount *mp, struct mbuf *nam,
@@ -118,7 +118,7 @@ msdosfs_mount(struct mount *mp, const char *path, void *data,
if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) &&
(mp->mnt_flag & MNT_RDONLY)) {
mp->mnt_flag &= ~MNT_RDONLY;
- VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p);
+ VFS_SYNC(mp, MNT_WAIT, 0, p->p_ucred, p);
mp->mnt_flag |= MNT_RDONLY;
flags = WRITECLOSE;
@@ -689,7 +689,8 @@ msdosfs_sync_vnode(struct vnode *vp, void *arg)
int
-msdosfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
+msdosfs_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred,
+ struct proc *p)
{
struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
struct msdosfs_sync_arg msa;
diff --git a/sys/msdosfs/msdosfsmount.h b/sys/msdosfs/msdosfsmount.h
index dc892feab1f..23b5a65d208 100644
--- a/sys/msdosfs/msdosfsmount.h
+++ b/sys/msdosfs/msdosfsmount.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfsmount.h,v 1.21 2016/05/21 18:11:36 natano Exp $ */
+/* $OpenBSD: msdosfsmount.h,v 1.22 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: msdosfsmount.h,v 1.16 1997/10/17 11:24:24 ws Exp $ */
/*-
@@ -206,7 +206,7 @@ int msdosfs_unmount(struct mount *, int, struct proc *);
int msdosfs_root(struct mount *, struct vnode **);
int msdosfs_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *);
int msdosfs_statfs(struct mount *, struct statfs *, struct proc *);
-int msdosfs_sync(struct mount *, int, struct ucred *, struct proc *);
+int msdosfs_sync(struct mount *, int, int, struct ucred *, struct proc *);
int msdosfs_fhtovp(struct mount *, struct fid *, struct vnode **);
int msdosfs_vptofh(struct vnode *, struct fid *);
int msdosfs_init(struct vfsconf *);
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c
index 65874a1e2b1..259b2f7f0d6 100644
--- a/sys/nfs/nfs_vfsops.c
+++ b/sys/nfs/nfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vfsops.c,v 1.115 2017/12/11 05:27:40 deraadt Exp $ */
+/* $OpenBSD: nfs_vfsops.c,v 1.116 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.46.4.1 1996/05/25 22:40:35 fvdl Exp $ */
/*
@@ -80,7 +80,7 @@ int nfs_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *);
int nfs_root(struct mount *, struct vnode **);
int nfs_start(struct mount *, int, struct proc *);
int nfs_statfs(struct mount *, struct statfs *, struct proc *);
-int nfs_sync(struct mount *, int, struct ucred *, struct proc *);
+int nfs_sync(struct mount *, int, int, struct ucred *, struct proc *);
int nfs_unmount(struct mount *, int, struct proc *);
int nfs_vget(struct mount *, ino_t, struct vnode **);
int nfs_vptofh(struct vnode *, struct fid *);
@@ -729,7 +729,7 @@ nfs_root(struct mount *mp, struct vnode **vpp)
* Flush out the buffer cache
*/
int
-nfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
+nfs_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred, struct proc *p)
{
struct vnode *vp;
int error, allerror = 0;
diff --git a/sys/ntfs/ntfs_vfsops.c b/sys/ntfs/ntfs_vfsops.c
index 6ceac5b3288..9ad5ac1e01d 100644
--- a/sys/ntfs/ntfs_vfsops.c
+++ b/sys/ntfs/ntfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntfs_vfsops.c,v 1.57 2017/12/11 05:27:40 deraadt Exp $ */
+/* $OpenBSD: ntfs_vfsops.c,v 1.58 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: ntfs_vfsops.c,v 1.7 2003/04/24 07:50:19 christos Exp $ */
/*-
@@ -60,7 +60,7 @@ int ntfs_root(struct mount *, struct vnode **);
int ntfs_start(struct mount *, int, struct proc *);
int ntfs_statfs(struct mount *, struct statfs *,
struct proc *);
-int ntfs_sync(struct mount *, int, struct ucred *,
+int ntfs_sync(struct mount *, int, int, struct ucred *,
struct proc *);
int ntfs_unmount(struct mount *, int, struct proc *);
int ntfs_vget(struct mount *mp, ino_t ino,
@@ -612,7 +612,7 @@ ntfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
}
int
-ntfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
+ntfs_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred, struct proc *p)
{
/*DPRINTF("ntfs_sync():\n");*/
return (0);
diff --git a/sys/sys/file.h b/sys/sys/file.h
index 23c2b868531..ef27cd5cc15 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.h,v 1.39 2018/01/02 06:40:55 guenther Exp $ */
+/* $OpenBSD: file.h,v 1.40 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: file.h,v 1.11 1995/03/26 20:24:13 jtc Exp $ */
/*
@@ -89,7 +89,13 @@ struct file {
#define FILE_IS_USABLE(fp) \
(((fp)->f_iflags & FIF_LARVAL) == 0)
-#define FREF(fp) do { (fp)->f_count++; } while (0)
+#define FREF(fp) \
+ do { \
+ extern struct rwlock vfs_stall_lock; \
+ rw_enter_read(&vfs_stall_lock); \
+ rw_exit_read(&vfs_stall_lock); \
+ (fp)->f_count++; \
+ } while (0)
#define FRELE(fp,p) (--(fp)->f_count == 0 ? fdrop(fp, p) : 0)
#define FILE_SET_MATURE(fp,p) do { \
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index fbed4bc6fe9..9ec04f6e729 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount.h,v 1.134 2018/01/05 05:54:36 deraadt Exp $ */
+/* $OpenBSD: mount.h,v 1.135 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: mount.h,v 1.48 1996/02/18 11:55:47 fvdl Exp $ */
/*
@@ -389,6 +389,7 @@ struct mount {
#define MNT_DELEXPORT 0x00020000 /* delete export host lists */
#define MNT_RELOAD 0x00040000 /* reload filesystem data */
#define MNT_FORCE 0x00080000 /* force unmount or readonly change */
+#define MNT_STALLED 0x00100000 /* filesystem stalled */
#define MNT_WANTRDWR 0x02000000 /* want upgrade to read/write */
#define MNT_SOFTDEP 0x04000000 /* soft dependencies being done */
#define MNT_DOOMED 0x08000000 /* device behind filesystem is gone */
@@ -505,7 +506,7 @@ struct vfsops {
caddr_t arg, struct proc *p);
int (*vfs_statfs)(struct mount *mp, struct statfs *sbp,
struct proc *p);
- int (*vfs_sync)(struct mount *mp, int waitfor,
+ int (*vfs_sync)(struct mount *mp, int waitfor, int stall,
struct ucred *cred, struct proc *p);
int (*vfs_vget)(struct mount *mp, ino_t ino,
struct vnode **vpp);
@@ -526,7 +527,7 @@ struct vfsops {
#define VFS_ROOT(MP, VPP) (*(MP)->mnt_op->vfs_root)(MP, VPP)
#define VFS_QUOTACTL(MP,C,U,A,P) (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A, P)
#define VFS_STATFS(MP, SBP, P) (*(MP)->mnt_op->vfs_statfs)(MP, SBP, P)
-#define VFS_SYNC(MP, WAIT, C, P) (*(MP)->mnt_op->vfs_sync)(MP, WAIT, C, P)
+#define VFS_SYNC(MP, W, S, C, P) (*(MP)->mnt_op->vfs_sync)(MP, W, S, C, P)
#define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP)
#define VFS_FHTOVP(MP, FIDP, VPP) \
(*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP)
@@ -573,6 +574,7 @@ int vfs_mountedon(struct vnode *);
int vfs_rootmountalloc(char *, char *, struct mount **);
void vfs_unbusy(struct mount *);
extern TAILQ_HEAD(mntlist, mount) mountlist;
+int vfs_stall(struct proc *, int);
struct mount *getvfs(fsid_t *); /* return vfs given fsid */
/* process mount export info */
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 32a2d96f71c..f113739395e 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnode.h,v 1.142 2017/12/14 20:20:38 deraadt Exp $ */
+/* $OpenBSD: vnode.h,v 1.143 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
@@ -99,6 +99,7 @@ struct vnode {
u_int v_bioflag;
u_int v_holdcnt; /* buffer references */
u_int v_id; /* capability identifier */
+ u_int v_inflight;
struct mount *v_mount; /* ptr to vfs we are in */
TAILQ_ENTRY(vnode) v_freelist; /* vnode freelist */
LIST_ENTRY(vnode) v_mntvnodes; /* vnodes for mount point */
diff --git a/sys/ufs/ext2fs/ext2fs_extern.h b/sys/ufs/ext2fs/ext2fs_extern.h
index a0253a1470e..68c71ca1e9e 100644
--- a/sys/ufs/ext2fs/ext2fs_extern.h
+++ b/sys/ufs/ext2fs/ext2fs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_extern.h,v 1.36 2016/08/10 07:53:02 natano Exp $ */
+/* $OpenBSD: ext2fs_extern.h,v 1.37 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: ext2fs_extern.h,v 1.1 1997/06/11 09:33:55 bouyer Exp $ */
/*-
@@ -105,7 +105,7 @@ int ext2fs_mountfs(struct vnode *, struct mount *, struct proc *);
int ext2fs_unmount(struct mount *, int, struct proc *);
int ext2fs_flushfiles(struct mount *, int, struct proc *);
int ext2fs_statfs(struct mount *, struct statfs *, struct proc *);
-int ext2fs_sync(struct mount *, int, struct ucred *, struct proc *);
+int ext2fs_sync(struct mount *, int, int, struct ucred *, struct proc *);
int ext2fs_vget(struct mount *, ino_t, struct vnode **);
int ext2fs_fhtovp(struct mount *, struct fid *, struct vnode **);
int ext2fs_vptofh(struct vnode *, struct fid *);
diff --git a/sys/ufs/ext2fs/ext2fs_vfsops.c b/sys/ufs/ext2fs/ext2fs_vfsops.c
index 114285d423c..55cfacddb2e 100644
--- a/sys/ufs/ext2fs/ext2fs_vfsops.c
+++ b/sys/ufs/ext2fs/ext2fs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_vfsops.c,v 1.101 2017/12/30 23:08:29 guenther Exp $ */
+/* $OpenBSD: ext2fs_vfsops.c,v 1.102 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */
/*
@@ -696,6 +696,8 @@ int ext2fs_sync_vnode(struct vnode *vp, void *);
struct ext2fs_sync_args {
int allerror;
int waitfor;
+ int nlink0;
+ int inflight;
struct proc *p;
struct ucred *cred;
};
@@ -705,22 +707,34 @@ ext2fs_sync_vnode(struct vnode *vp, void *args)
{
struct ext2fs_sync_args *esa = args;
struct inode *ip;
- int error;
+ int error, nlink0 = 0;
- ip = VTOI(vp);
- if (vp->v_type == VNON ||
- ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
- LIST_EMPTY(&vp->v_dirtyblkhd)) ||
- esa->waitfor == MNT_LAZY) {
+ if (vp->v_type == VNON)
return (0);
+
+ if (vp->v_inflight)
+ esa->inflight = MIN(esa->inflight+1, 65536);
+
+ ip = VTOI(vp);
+
+ if (ip->i_e2fs_nlink == 0)
+ nlink0 = 1;
+
+ if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
+ LIST_EMPTY(&vp->v_dirtyblkhd)) {
+ goto end;
}
- if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT, esa->p))
- return (0);
+ if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT, esa->p)) {
+ nlink0 = 1; /* potentially */
+ goto end;
+ }
if ((error = VOP_FSYNC(vp, esa->cred, esa->waitfor, esa->p)) != 0)
esa->allerror = error;
vput(vp);
+end:
+ esa->nlink0 = MIN(esa->nlink0 + nlink0, 65536);
return (0);
}
/*
@@ -731,11 +745,12 @@ ext2fs_sync_vnode(struct vnode *vp, void *args)
* Should always be called with the mount point locked.
*/
int
-ext2fs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
+ext2fs_sync(struct mount *mp, int waitfor, int stall,
+ struct ucred *cred, struct proc *p)
{
struct ufsmount *ump = VFSTOUFS(mp);
struct m_ext2fs *fs;
- int error, allerror = 0;
+ int error, allerror = 0, state, fmod;
struct ext2fs_sync_args esa;
fs = ump->um_e2fs;
@@ -751,6 +766,8 @@ ext2fs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
esa.cred = cred;
esa.allerror = 0;
esa.waitfor = waitfor;
+ esa.nlink0 = 0;
+ esa.inflight = 0;
vfs_mount_foreach_vnode(mp, ext2fs_sync_vnode, &esa);
if (esa.allerror != 0)
@@ -768,12 +785,31 @@ ext2fs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
/*
* Write back modified superblock.
*/
+ state = fs->e2fs.e2fs_state;
+ fmod = fs->e2fs_fmod;
+ if (stall && fs->e2fs_ronly == 0) {
+ fs->e2fs_fmod = 1;
+ if (allerror == 0 && esa.nlink0 == 0 && esa.inflight == 0) {
+ if ((fs->e2fs.e2fs_state & E2FS_ERRORS) == 0)
+ fs->e2fs.e2fs_state = E2FS_ISCLEAN;
+#if 0
+ printf("%s force clean (dangling %d inflight %d)\n",
+ mp->mnt_stat.f_mntonname, esa.nlink0, esa.inflight);
+#endif
+ } else {
+ fs->e2fs.e2fs_state = 0;
+ printf("%s force dirty (dangling %d inflight %d)\n",
+ mp->mnt_stat.f_mntonname, esa.nlink0, esa.inflight);
+ }
+ }
if (fs->e2fs_fmod != 0) {
fs->e2fs_fmod = 0;
fs->e2fs.e2fs_wtime = time_second;
if ((error = ext2fs_cgupdate(ump, waitfor)))
allerror = error;
}
+ fs->e2fs.e2fs_state = state;
+ fs->e2fs_fmod = fmod;
return (allerror);
}
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 45de5724f2f..0abe9d73b59 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_extern.h,v 1.43 2016/08/10 08:04:57 natano Exp $ */
+/* $OpenBSD: ffs_extern.h,v 1.44 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: ffs_extern.h,v 1.4 1996/02/09 22:22:22 christos Exp $ */
/*
@@ -144,7 +144,7 @@ int ffs_oldfscompat(struct fs *);
int ffs_unmount(struct mount *, int, struct proc *);
int ffs_flushfiles(struct mount *, int, struct proc *);
int ffs_statfs(struct mount *, struct statfs *, struct proc *);
-int ffs_sync(struct mount *, int, struct ucred *, struct proc *);
+int ffs_sync(struct mount *, int, int, struct ucred *, struct proc *);
int ffs_vget(struct mount *, ino_t, struct vnode **);
int ffs_fhtovp(struct mount *, struct fid *, struct vnode **);
int ffs_vptofh(struct vnode *, struct fid *);
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index f98dcd25286..97b3d244025 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_softdep.c,v 1.137 2017/12/13 16:38:34 beck Exp $ */
+/* $OpenBSD: ffs_softdep.c,v 1.138 2018/02/10 05:24:23 deraadt Exp $ */
/*
* Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
@@ -4945,7 +4945,7 @@ loop:
*/
if (vn_isdisk(vp, NULL) &&
vp->v_specmountpoint && !VOP_ISLOCKED(vp) &&
- (error = VFS_SYNC(vp->v_specmountpoint, MNT_WAIT, ap->a_cred,
+ (error = VFS_SYNC(vp->v_specmountpoint, MNT_WAIT, 0, ap->a_cred,
ap->a_p)) != 0)
return (error);
return (0);
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 9492e50d6fd..874551b3ea3 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_vfsops.c,v 1.171 2017/12/30 23:08:29 guenther Exp $ */
+/* $OpenBSD: ffs_vfsops.c,v 1.172 2018/02/10 05:24:23 deraadt Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */
/*
@@ -243,7 +243,7 @@ ffs_mount(struct mount *mp, const char *path, void *data,
if (ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
/* Flush any dirty data */
- VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p);
+ VFS_SYNC(mp, MNT_WAIT, 0, p->p_ucred, p);
/*
* Get rid of files open for writing.
@@ -1141,20 +1141,26 @@ struct ffs_sync_args {
int allerror;
struct proc *p;
int waitfor;
+ int nlink0;
+ int inflight;
struct ucred *cred;
};
int
-ffs_sync_vnode(struct vnode *vp, void *arg) {
+ffs_sync_vnode(struct vnode *vp, void *arg)
+{
struct ffs_sync_args *fsa = arg;
struct inode *ip;
- int error;
+ int error, nlink0 = 0;
if (vp->v_type == VNON)
return (0);
ip = VTOI(vp);
+ if (vp->v_inflight && !(vp->v_type == VCHR || vp->v_type == VBLK))
+ fsa->inflight = MIN(fsa->inflight+1, 65536);
+
/*
* If unmounting or converting rw to ro, then stop deferring
* timestamp writes.
@@ -1164,20 +1170,27 @@ ffs_sync_vnode(struct vnode *vp, void *arg) {
UFS_UPDATE(ip, 1);
}
+ if (ip->i_effnlink == 0)
+ nlink0 = 1;
+
if ((ip->i_flag &
- (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
- LIST_EMPTY(&vp->v_dirtyblkhd)) {
- return (0);
+ (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
+ LIST_EMPTY(&vp->v_dirtyblkhd)) {
+ goto end;
}
- if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT, fsa->p))
- return (0);
+ if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT, fsa->p)) {
+ nlink0 = 1; /* potentially.. */
+ goto end;
+ }
if ((error = VOP_FSYNC(vp, fsa->cred, fsa->waitfor, fsa->p)))
fsa->allerror = error;
VOP_UNLOCK(vp, fsa->p);
vrele(vp);
+end:
+ fsa->nlink0 = MIN(fsa->nlink0 + nlink0, 65536);
return (0);
}
@@ -1189,11 +1202,11 @@ ffs_sync_vnode(struct vnode *vp, void *arg) {
* Should always be called with the mount point locked.
*/
int
-ffs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
+ffs_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred, struct proc *p)
{
struct ufsmount *ump = VFSTOUFS(mp);
struct fs *fs;
- int error, allerror = 0, count;
+ int error, allerror = 0, count, clean, fmod;
struct ffs_sync_args fsa;
fs = ump->um_fs;
@@ -1214,6 +1227,8 @@ ffs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
fsa.p = p;
fsa.cred = cred;
fsa.waitfor = waitfor;
+ fsa.nlink0 = 0;
+ fsa.inflight = 0;
/*
* Don't traverse the vnode list if we want to skip all of them.
@@ -1243,9 +1258,26 @@ ffs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
/*
* Write back modified superblock.
*/
-
+ clean = fs->fs_clean;
+ fmod = fs->fs_fmod;
+ if (stall && fs->fs_ronly == 0) {
+ fs->fs_fmod = 1;
+ if (allerror == 0 && fsa.nlink0 == 0 && fsa.inflight == 0) {
+ fs->fs_clean = (fs->fs_flags & FS_UNCLEAN) ? 0 : 1;
+#if 0
+ printf("%s force clean (dangling %d inflight %d)\n",
+ mp->mnt_stat.f_mntonname, fsa.nlink0, fsa.inflight);
+#endif
+ } else {
+ fs->fs_clean = 0;
+ printf("%s force dirty (dangling %d inflight %d)\n",
+ mp->mnt_stat.f_mntonname, fsa.nlink0, fsa.inflight);
+ }
+ }
if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0)
allerror = error;
+ fs->fs_clean = clean;
+ fs->fs_fmod = fmod;
return (allerror);
}