Syncronize filesystems to disk when suspending. Each mountpoint's vnodes

are pushed to disk.  Dangling vnodes (unlinked files still in use) and
vnodes undergoing change by long-running syscalls are identified -- and
such filesystems are marked dirty on-disk while we are suspended (in case
power is lost, a fsck will be required).  Filesystems without dangling or
busy vnodes are marked clean, resulting in faster boots following
"battery died" circumstances.
Tested by numerous developers, thanks for the feedback.
This commit is contained in:
deraadt 2018-02-10 05:24:23 +00:00
parent 50b6cc81a0
commit 976e983900
22 changed files with 310 additions and 95 deletions

View File

@ -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);

View File

@ -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 *);

View File

@ -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;
{

View File

@ -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 **);

View File

@ -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);
}

View File

@ -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
}
/*

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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 *);

View File

@ -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;

View File

@ -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);

View File

@ -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 { \

View File

@ -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 */

View File

@ -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 */

View File

@ -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 *);

View File

@ -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;
if (vp->v_type == VNON)
return (0);
if (vp->v_inflight)
esa->inflight = MIN(esa->inflight+1, 65536);
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) {
return (0);
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);
}

View File

@ -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 *);

View File

@ -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);

View File

@ -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);
}