-/* $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>
#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>
if (config_suspend_all(DVACT_QUIESCE))
goto fail_quiesce;
+ vfs_stall(curproc, 1);
#if NSOFTRAID > 0
sr_quiesce();
#endif
acpi_resume_mp();
#endif
+ vfs_stall(curproc, 0);
bufq_restart();
fail_quiesce:
rw_enter_write(&sc->sc_lck);
#endif /* NWSDISPLAY > 0 */
+ sys_sync(curproc, NULL, NULL);
+
/* Restore hw.setperf */
if (cpu_setperf != NULL)
cpu_setperf(perflevel);
-/* $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 $ */
/*-
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 *);
-/* $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 $ */
/*-
/* 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;
{
-/* $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.
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 **);
-/* $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>
}
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);
}
-/* $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 $ */
/*
#include "softraid.h"
-void sr_shutdown(int);
+void sr_quiesce(void);
enum vtype iftovt_tab[16] = {
VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
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)
{
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);
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);
}
}
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
}
/*
-/* $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:
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);
-/* $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 $ */
/*
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);
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;
}
-/* $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>
*
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;
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;
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;
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;
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;
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
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;
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
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;
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;
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
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;
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;
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;
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
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;
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;
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;
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;
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;
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;
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;
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
int
VOP_RECLAIM(struct vnode *vp, struct proc *p)
{
+ int r;
struct vop_reclaim_args a;
a.a_vp = vp;
a.a_p = 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
int
VOP_UNLOCK(struct vnode *vp, struct proc *p)
{
+ int r;
struct vop_unlock_args a;
a.a_vp = vp;
a.a_p = 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
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;
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
-/* $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>
*
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 *);
}
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);
-/* $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 $ */
/*-
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,
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;
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;
-/* $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 $ */
/*-
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 *);
-/* $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 $ */
/*
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 *);
* 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;
-/* $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 $ */
/*-
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,
}
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);
-/* $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 $ */
/*
#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 { \
-/* $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 $ */
/*
#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 */
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);
#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)
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 */
-/* $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 $ */
/*
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 */
-/* $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 $ */
/*-
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 *);
-/* $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 $ */
/*
struct ext2fs_sync_args {
int allerror;
int waitfor;
+ int nlink0;
+ int inflight;
struct proc *p;
struct ucred *cred;
};
{
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);
}
/*
* 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;
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)
/*
* 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);
}
-/* $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 $ */
/*
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 *);
-/* $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.
*/
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);
-/* $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 $ */
/*
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.
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.
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);
}
* 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;
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.
/*
* 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);
}