Remove miscfs/syncfs and

- move the syncer into kern/vfs_subr.c.

- change the syncer to process the mountlist and VFS_SYNC as appropriate.

- use an API for mount points similiar to the API for vnodes:
  - vfs_syncer_add_to_worklist(struct mount *mp) to add
  - vfs_syncer_remove_from_worklist(struct mount *mp) to remove a mount.

No objections on tech-kern@
This commit is contained in:
hannken 2015-05-06 15:57:07 +00:00
parent 85e6157fe0
commit e10a32f7f7
23 changed files with 431 additions and 737 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1102 2015/04/26 21:37:22 mrg Exp $
# $NetBSD: mi,v 1.1103 2015/05/06 15:57:07 hannken Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -1135,7 +1135,7 @@
./usr/include/miscfs/procfs base-c-usr
./usr/include/miscfs/ptyfs base-obsolete obsolete
./usr/include/miscfs/specfs base-c-usr
./usr/include/miscfs/syncfs base-c-usr
./usr/include/miscfs/syncfs base-obsolete obsolete
./usr/include/miscfs/umapfs base-c-usr
./usr/include/miscfs/union base-c-usr
./usr/include/msdosfs base-c-usr

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1956 2015/04/27 07:03:57 knakahara Exp $
# $NetBSD: mi,v 1.1957 2015/05/06 15:57:07 hannken Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -2529,7 +2529,7 @@
./usr/include/miscfs/portal/portal.h comp-obsolete obsolete
./usr/include/miscfs/procfs/procfs.h comp-c-include
./usr/include/miscfs/specfs/specdev.h comp-c-include
./usr/include/miscfs/syncfs/syncfs.h comp-c-include
./usr/include/miscfs/syncfs/syncfs.h comp-obsolete obsolete
./usr/include/miscfs/umapfs/umap.h comp-c-include
./usr/include/miscfs/union/union.h comp-c-include
./usr/include/mj.h comp-c-include crypto

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs.c,v 1.5 2013/11/25 22:48:05 christos Exp $ */
/* $NetBSD: vfs.c,v 1.6 2015/05/06 15:57:07 hannken Exp $ */
/*-
* Copyright (c) 2006-2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
@ -332,12 +332,9 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
vput(mvp);
VOP_UNLOCK(vp);
if ((mp->mnt_flag & MNT_RDONLY) == 0)
error = vfs_allocate_syncvnode(mp);
vfs_syncer_add_to_worklist(mp);
vfs_unbusy(mp, td);
if (error)
vrele(vp);
else
vfs_mountedfrom(mp, fspec);
vfs_mountedfrom(mp, fspec);
} else {
simple_lock(&vp->v_interlock);
vp->v_iflag &= ~VI_MOUNT;

View File

@ -1,4 +1,4 @@
/* $NetBSD: coda_psdev.c,v 1.54 2014/12/13 15:58:39 hannken Exp $ */
/* $NetBSD: coda_psdev.c,v 1.55 2015/05/06 15:57:08 hannken Exp $ */
/*
*
@ -54,7 +54,7 @@
/* These routines are the device entry points for Venus. */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: coda_psdev.c,v 1.54 2014/12/13 15:58:39 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: coda_psdev.c,v 1.55 2015/05/06 15:57:08 hannken Exp $");
extern int coda_nc_initialized; /* Set if cache has been initialized */
@ -72,8 +72,6 @@ extern int coda_nc_initialized; /* Set if cache has been initialized */
#include <sys/atomic.h>
#include <sys/module.h>
#include <miscfs/syncfs/syncfs.h>
#include <coda/coda.h>
#include <coda/cnode.h>
#include <coda/coda_namecache.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: puffs_msgif.c,v 1.97 2014/11/10 18:46:33 maxv Exp $ */
/* $NetBSD: puffs_msgif.c,v 1.98 2015/05/06 15:57:08 hannken Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.97 2014/11/10 18:46:33 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.98 2015/05/06 15:57:08 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -51,8 +51,6 @@ __KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.97 2014/11/10 18:46:33 maxv Exp $"
#include <fs/puffs/puffs_msgif.h>
#include <fs/puffs/puffs_sys.h>
#include <miscfs/syncfs/syncfs.h> /* XXX: for syncer_mutex reference */
/*
* waitq data structures
*/

View File

@ -1,4 +1,4 @@
# $NetBSD: files.kern,v 1.4 2015/05/02 12:57:19 mlelstv Exp $
# $NetBSD: files.kern,v 1.5 2015/05/06 15:57:08 hannken Exp $
#
# kernel sources
@ -226,5 +226,3 @@ file miscfs/genfs/layer_vfsops.c layerfs
file miscfs/genfs/layer_vnops.c layerfs
file miscfs/specfs/spec_vnops.c vfs
file miscfs/syncfs/sync_subr.c vfs
file miscfs/syncfs/sync_vnops.c vfs

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_main.c,v 1.466 2015/04/30 15:22:32 nat Exp $ */
/* $NetBSD: init_main.c,v 1.467 2015/05/06 15:57:08 hannken Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.466 2015/04/30 15:22:32 nat Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.467 2015/05/06 15:57:08 hannken Exp $");
#include "opt_ddb.h"
#include "opt_ipsec.h"
@ -216,7 +216,6 @@ extern void *_binary_splash_image_end;
#include <ufs/ufs/quota.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/syncfs/syncfs.h>
#include <miscfs/specfs/specdev.h>
#include <sys/cpu.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_init.c,v 1.47 2014/02/25 18:30:11 pooka Exp $ */
/* $NetBSD: vfs_init.c,v 1.48 2015/05/06 15:57:08 hannken Exp $ */
/*-
* Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_init.c,v 1.47 2014/02/25 18:30:11 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_init.c,v 1.48 2015/05/06 15:57:08 hannken Exp $");
#include <sys/param.h>
#include <sys/mount.h>
@ -107,13 +107,11 @@ extern const struct vnodeop_desc * const vfs_op_descs[];
extern const struct vnodeopv_desc dead_vnodeop_opv_desc;
extern const struct vnodeopv_desc fifo_vnodeop_opv_desc;
extern const struct vnodeopv_desc spec_vnodeop_opv_desc;
extern const struct vnodeopv_desc sync_vnodeop_opv_desc;
const struct vnodeopv_desc * const vfs_special_vnodeopv_descs[] = {
&dead_vnodeop_opv_desc,
&fifo_vnodeop_opv_desc,
&spec_vnodeop_opv_desc,
&sync_vnodeop_opv_desc,
NULL,
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_mount.c,v 1.34 2015/04/20 13:44:16 riastradh Exp $ */
/* $NetBSD: vfs_mount.c,v 1.35 2015/05/06 15:57:08 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.34 2015/04/20 13:44:16 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.35 2015/05/06 15:57:08 hannken Exp $");
#define _VFS_VNODE_PRIVATE
@ -93,7 +93,6 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.34 2015/04/20 13:44:16 riastradh Exp
#include <sys/vnode.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/syncfs/syncfs.h>
#include <miscfs/specfs/specdev.h>
/* Root filesystem. */
@ -722,12 +721,9 @@ mount_domount(struct lwp *l, vnode_t **vpp, struct vfsops *vfsops,
TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
mutex_exit(&mountlist_lock);
if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0)
error = vfs_allocate_syncvnode(mp);
if (error == 0)
vp->v_mountedhere = mp;
vfs_syncer_add_to_worklist(mp);
vp->v_mountedhere = mp;
vput(nd.ni_vp);
if (error != 0)
goto err_onmountlist;
mount_checkdirs(vp);
mutex_exit(&mp->mnt_updating);
@ -746,12 +742,6 @@ mount_domount(struct lwp *l, vnode_t **vpp, struct vfsops *vfsops,
*vpp = NULL;
return error;
err_onmountlist:
mutex_enter(&mountlist_lock);
TAILQ_REMOVE(&mountlist, mp, mnt_list);
mp->mnt_iflag |= IMNT_GONE;
mutex_exit(&mountlist_lock);
err_mounted:
if (VFS_UNMOUNT(mp, MNT_FORCE) != 0)
panic("Unmounting fresh file system failed");
@ -808,7 +798,7 @@ dounmount(struct mount *mp, int flags, struct lwp *l)
return ENOENT;
}
used_syncer = (mp->mnt_syncer != NULL);
used_syncer = (mp->mnt_iflag & IMNT_ONWORKLIST) != 0;
used_extattr = mp->mnt_flag & MNT_EXTATTR;
/*
@ -831,8 +821,8 @@ dounmount(struct mount *mp, int flags, struct lwp *l)
async = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
cache_purgevfs(mp); /* remove cache entries for this file sys */
if (mp->mnt_syncer != NULL)
vfs_deallocate_syncvnode(mp);
if (used_syncer)
vfs_syncer_remove_from_worklist(mp);
error = 0;
if ((mp->mnt_flag & MNT_RDONLY) == 0) {
error = VFS_SYNC(mp, MNT_WAIT, l->l_cred);
@ -844,7 +834,7 @@ dounmount(struct mount *mp, int flags, struct lwp *l)
mp->mnt_iflag &= ~IMNT_UNMOUNT;
mutex_exit(&mp->mnt_unmounting);
if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0)
(void) vfs_allocate_syncvnode(mp);
vfs_syncer_add_to_worklist(mp);
mp->mnt_flag |= async;
mutex_exit(&mp->mnt_updating);
if (used_syncer)

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_subr.c,v 1.445 2014/09/05 05:57:21 matt Exp $ */
/* $NetBSD: vfs_subr.c,v 1.446 2015/05/06 15:57:08 hannken Exp $ */
/*-
* Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@ -6,7 +6,8 @@
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran.
* NASA Ames Research Center, by Charles M. Hannum, by Andrew Doran,
* by Marshall Kirk McKusick and Greg Ganger at the University of Michigan.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -67,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.445 2014/09/05 05:57:21 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.446 2015/05/06 15:57:08 hannken Exp $");
#include "opt_ddb.h"
#include "opt_compat_netbsd.h"
@ -92,7 +93,6 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.445 2014/09/05 05:57:21 matt Exp $");
#include <sys/module.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/syncfs/syncfs.h>
#include <miscfs/specfs/specdev.h>
#include <uvm/uvm_ddb.h>
@ -122,6 +122,7 @@ int prtactive = 0; /* 1 => print out reclaim of active vnodes */
*/
static int getdevvp(dev_t, vnode_t **, enum vtype);
static void vn_initialize_syncerd(void);
/*
* Initialize the vnode management data structures.
@ -537,6 +538,373 @@ vdevgone(int maj, int minl, int minh, enum vtype type)
}
}
/*
* The filesystem synchronizer mechanism - syncer.
*
* It is useful to delay writes of file data and filesystem metadata for
* a certain amount of time so that quickly created and deleted files need
* not waste disk bandwidth being created and removed. To implement this,
* vnodes are appended to a "workitem" queue.
*
* Most pending metadata should not wait for more than ten seconds. Thus,
* mounted on block devices are delayed only about a half the time that file
* data is delayed. Similarly, directory updates are more critical, so are
* only delayed about a third the time that file data is delayed.
*
* There are SYNCER_MAXDELAY queues that are processed in a round-robin
* manner at a rate of one each second (driven off the filesystem syner
* thread). The syncer_delayno variable indicates the next queue that is
* to be processed. Items that need to be processed soon are placed in
* this queue:
*
* syncer_workitem_pending[syncer_delayno]
*
* A delay of e.g. fifteen seconds is done by placing the request fifteen
* entries later in the queue:
*
* syncer_workitem_pending[(syncer_delayno + 15) & syncer_mask]
*
* Flag VI_ONWORKLST indicates that vnode is added into the queue.
*/
#define SYNCER_MAXDELAY 32
typedef TAILQ_HEAD(synclist, vnode) synclist_t;
static void vn_syncer_add1(struct vnode *, int);
static void sysctl_vfs_syncfs_setup(struct sysctllog **);
/*
* Defines and variables for the syncer process.
*/
int syncer_maxdelay = SYNCER_MAXDELAY; /* maximum delay time */
time_t syncdelay = 30; /* max time to delay syncing data */
time_t filedelay = 30; /* time to delay syncing files */
time_t dirdelay = 15; /* time to delay syncing directories */
time_t metadelay = 10; /* time to delay syncing metadata */
time_t lockdelay = 1; /* time to delay if locking fails */
kmutex_t syncer_mutex; /* used to freeze syncer, long term */
static kmutex_t syncer_data_lock; /* short term lock on data structs */
static int syncer_delayno = 0;
static long syncer_last;
static synclist_t * syncer_workitem_pending;
static void
vn_initialize_syncerd(void)
{
int i;
syncer_last = SYNCER_MAXDELAY + 2;
sysctl_vfs_syncfs_setup(NULL);
syncer_workitem_pending =
kmem_alloc(syncer_last * sizeof (struct synclist), KM_SLEEP);
for (i = 0; i < syncer_last; i++)
TAILQ_INIT(&syncer_workitem_pending[i]);
mutex_init(&syncer_mutex, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&syncer_data_lock, MUTEX_DEFAULT, IPL_NONE);
}
/*
* Return delay factor appropriate for the given file system. For
* WAPBL we use the sync vnode to burst out metadata updates: sync
* those file systems more frequently.
*/
static inline int
sync_delay(struct mount *mp)
{
return mp->mnt_wapbl != NULL ? metadelay : syncdelay;
}
/*
* Compute the next slot index from delay.
*/
static inline int
sync_delay_slot(int delayx)
{
if (delayx > syncer_maxdelay - 2)
delayx = syncer_maxdelay - 2;
return (syncer_delayno + delayx) % syncer_last;
}
/*
* Add an item to the syncer work queue.
*/
static void
vn_syncer_add1(struct vnode *vp, int delayx)
{
synclist_t *slp;
KASSERT(mutex_owned(&syncer_data_lock));
if (vp->v_iflag & VI_ONWORKLST) {
/*
* Remove in order to adjust the position of the vnode.
* Note: called from sched_sync(), which will not hold
* interlock, therefore we cannot modify v_iflag here.
*/
slp = &syncer_workitem_pending[vp->v_synclist_slot];
TAILQ_REMOVE(slp, vp, v_synclist);
} else {
KASSERT(mutex_owned(vp->v_interlock));
vp->v_iflag |= VI_ONWORKLST;
}
vp->v_synclist_slot = sync_delay_slot(delayx);
slp = &syncer_workitem_pending[vp->v_synclist_slot];
TAILQ_INSERT_TAIL(slp, vp, v_synclist);
}
void
vn_syncer_add_to_worklist(struct vnode *vp, int delayx)
{
KASSERT(mutex_owned(vp->v_interlock));
mutex_enter(&syncer_data_lock);
vn_syncer_add1(vp, delayx);
mutex_exit(&syncer_data_lock);
}
/*
* Remove an item from the syncer work queue.
*/
void
vn_syncer_remove_from_worklist(struct vnode *vp)
{
synclist_t *slp;
KASSERT(mutex_owned(vp->v_interlock));
mutex_enter(&syncer_data_lock);
if (vp->v_iflag & VI_ONWORKLST) {
vp->v_iflag &= ~VI_ONWORKLST;
slp = &syncer_workitem_pending[vp->v_synclist_slot];
TAILQ_REMOVE(slp, vp, v_synclist);
}
mutex_exit(&syncer_data_lock);
}
/*
* Add this mount point to the syncer.
*/
void
vfs_syncer_add_to_worklist(struct mount *mp)
{
static int start, incr, next;
int vdelay;
KASSERT(mutex_owned(&mp->mnt_updating));
KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) == 0);
/*
* We attempt to scatter the mount points on the list
* so that they will go off at evenly distributed times
* even if all the filesystems are mounted at once.
*/
next += incr;
if (next == 0 || next > syncer_maxdelay) {
start /= 2;
incr /= 2;
if (start == 0) {
start = syncer_maxdelay / 2;
incr = syncer_maxdelay;
}
next = start;
}
mp->mnt_iflag |= IMNT_ONWORKLIST;
vdelay = sync_delay(mp);
mp->mnt_synclist_slot = vdelay > 0 ? next % vdelay : 0;
}
/*
* Remove the mount point from the syncer.
*/
void
vfs_syncer_remove_from_worklist(struct mount *mp)
{
KASSERT(mutex_owned(&mp->mnt_updating));
KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) != 0);
mp->mnt_iflag &= ~IMNT_ONWORKLIST;
}
/*
* Try lazy sync, return true on success.
*/
static bool
lazy_sync_vnode(struct vnode *vp)
{
bool synced;
KASSERT(mutex_owned(&syncer_data_lock));
synced = false;
/* We are locking in the wrong direction. */
if (mutex_tryenter(vp->v_interlock)) {
mutex_exit(&syncer_data_lock);
if (vget(vp, LK_NOWAIT, false /* !wait */) == 0) {
if (vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT) == 0) {
synced = true;
(void) VOP_FSYNC(vp, curlwp->l_cred,
FSYNC_LAZY, 0, 0);
vput(vp);
} else
vrele(vp);
}
mutex_enter(&syncer_data_lock);
}
return synced;
}
/*
* System filesystem synchronizer daemon.
*/
void
sched_sync(void *arg)
{
synclist_t *slp;
struct vnode *vp;
struct mount *mp, *nmp;
time_t starttime;
bool synced;
for (;;) {
mutex_enter(&syncer_mutex);
starttime = time_second;
/*
* Sync mounts whose dirty time has expired.
*/
mutex_enter(&mountlist_lock);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if ((mp->mnt_iflag & IMNT_ONWORKLIST) == 0 ||
mp->mnt_synclist_slot != syncer_delayno) {
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
mp->mnt_synclist_slot = sync_delay_slot(sync_delay(mp));
if (vfs_busy(mp, &nmp))
continue;
VFS_SYNC(mp, MNT_LAZY, curlwp->l_cred);
vfs_unbusy(mp, false, &nmp);
}
mutex_exit(&mountlist_lock);
mutex_enter(&syncer_data_lock);
/*
* Push files whose dirty time has expired.
*/
slp = &syncer_workitem_pending[syncer_delayno];
syncer_delayno += 1;
if (syncer_delayno >= syncer_last)
syncer_delayno = 0;
while ((vp = TAILQ_FIRST(slp)) != NULL) {
synced = lazy_sync_vnode(vp);
/*
* XXX The vnode may have been recycled, in which
* case it may have a new identity.
*/
if (TAILQ_FIRST(slp) == vp) {
/*
* Put us back on the worklist. The worklist
* routine will remove us from our current
* position and then add us back in at a later
* position.
*
* Try again sooner rather than later if
* we were unable to lock the vnode. Lock
* failure should not prevent us from doing
* the sync "soon".
*
* If we locked it yet arrive here, it's
* likely that lazy sync is in progress and
* so the vnode still has dirty metadata.
* syncdelay is mainly to get this vnode out
* of the way so we do not consider it again
* "soon" in this loop, so the delay time is
* not critical as long as it is not "soon".
* While write-back strategy is the file
* system's domain, we expect write-back to
* occur no later than syncdelay seconds
* into the future.
*/
vn_syncer_add1(vp,
synced ? syncdelay : lockdelay);
}
}
mutex_exit(&syncer_mutex);
/*
* If it has taken us less than a second to process the
* current work, then wait. Otherwise start right over
* again. We can still lose time if any single round
* takes more than two seconds, but it does not really
* matter as we are just trying to generally pace the
* filesystem activity.
*/
if (time_second == starttime) {
kpause("syncer", false, hz, &syncer_data_lock);
}
mutex_exit(&syncer_data_lock);
}
}
static void
sysctl_vfs_syncfs_setup(struct sysctllog **clog)
{
const struct sysctlnode *rnode, *cnode;
sysctl_createv(clog, 0, NULL, &rnode,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "sync",
SYSCTL_DESCR("syncer options"),
NULL, 0, NULL, 0,
CTL_VFS, CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "delay",
SYSCTL_DESCR("max time to delay syncing data"),
NULL, 0, &syncdelay, 0,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "filedelay",
SYSCTL_DESCR("time to delay syncing files"),
NULL, 0, &filedelay, 0,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "dirdelay",
SYSCTL_DESCR("time to delay syncing directories"),
NULL, 0, &dirdelay, 0,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "metadelay",
SYSCTL_DESCR("time to delay syncing metadata"),
NULL, 0, &metadelay, 0,
CTL_CREATE, CTL_EOL);
}
/*
* sysctl helper routine to return list of supported fstypes
*/
@ -1152,8 +1520,8 @@ vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...))
{
char sbuf[256];
(*pr)("vnodecovered = %p syncer = %p data = %p\n",
mp->mnt_vnodecovered,mp->mnt_syncer,mp->mnt_data);
(*pr)("vnodecovered = %p data = %p\n",
mp->mnt_vnodecovered,mp->mnt_data);
(*pr)("fs_bshift %d dev_bshift = %d\n",
mp->mnt_fs_bshift,mp->mnt_dev_bshift);

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_syscalls.c,v 1.497 2015/04/21 03:19:03 riastradh Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.498 2015/05/06 15:57:08 hannken Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.497 2015/04/21 03:19:03 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.498 2015/05/06 15:57:08 hannken Exp $");
#ifdef _KERNEL_OPT
#include "opt_fileassoc.h"
@ -108,7 +108,6 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.497 2015/04/21 03:19:03 riastradh
#include <sys/buf.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/syncfs/syncfs.h>
#include <miscfs/specfs/specdev.h>
#include <nfs/rpcv2.h>
@ -328,11 +327,11 @@ mount_update(struct lwp *l, struct vnode *vp, const char *path, int flags,
mp->mnt_flag &= ~MNT_OP_FLAGS;
mp->mnt_iflag &= ~IMNT_WANTRDWR;
if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0) {
if (mp->mnt_syncer == NULL)
error = vfs_allocate_syncvnode(mp);
if ((mp->mnt_iflag & IMNT_ONWORKLIST) == 0)
vfs_syncer_add_to_worklist(mp);
} else {
if (mp->mnt_syncer != NULL)
vfs_deallocate_syncvnode(mp);
if ((mp->mnt_iflag & IMNT_ONWORKLIST) != 0)
vfs_syncer_remove_from_worklist(mp);
}
mutex_exit(&mp->mnt_updating);
vfs_unbusy(mp, false, NULL);

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_trans.c,v 1.32 2015/04/21 10:54:52 pooka Exp $ */
/* $NetBSD: vfs_trans.c,v 1.33 2015/05/06 15:57:08 hannken Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.32 2015/04/21 10:54:52 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.33 2015/05/06 15:57:08 hannken Exp $");
/*
* File system transaction operations.
@ -51,7 +51,6 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.32 2015/04/21 10:54:52 pooka Exp $")
#include <sys/proc.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/syncfs/syncfs.h>
struct fscow_handler {
LIST_ENTRY(fscow_handler) ch_list;

View File

@ -1,7 +1,6 @@
# $NetBSD: Makefile,v 1.9 2009/12/05 20:11:17 pooka Exp $
# $NetBSD: Makefile,v 1.10 2015/05/06 15:57:08 hannken Exp $
SUBDIR= fdesc fifofs genfs kernfs nullfs overlay
SUBDIR+= procfs specfs syncfs umapfs
SUBDIR= fdesc fifofs genfs kernfs nullfs overlay procfs specfs umapfs
INCSDIR= /usr/include/miscfs

View File

@ -1,4 +1,4 @@
/* $NetBSD: genfs_io.c,v 1.60 2015/04/12 14:44:06 skrll Exp $ */
/* $NetBSD: genfs_io.c,v 1.61 2015/05/06 15:57:08 hannken Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.60 2015/04/12 14:44:06 skrll Exp $");
__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.61 2015/05/06 15:57:08 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -47,7 +47,6 @@ __KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.60 2015/04/12 14:44:06 skrll Exp $");
#include <miscfs/genfs/genfs.h>
#include <miscfs/genfs/genfs_node.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/syncfs/syncfs.h>
#include <uvm/uvm.h>
#include <uvm/uvm_pager.h>

View File

@ -1,7 +0,0 @@
# $NetBSD: Makefile,v 1.1 2001/09/09 17:42:46 assar Exp $
INCSDIR= /usr/include/miscfs/syncfs
INCS= syncfs.h
.include <bsd.kinc.mk>

View File

@ -1,345 +0,0 @@
/* $NetBSD: sync_subr.c,v 1.50 2015/04/20 13:44:16 riastradh Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright 1997 Marshall Kirk McKusick. All Rights Reserved.
*
* This code is derived from work done by Greg Ganger at the
* University of Michigan.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. None of the names of McKusick, Ganger, or the University of Michigan
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* The filesystem synchronizer mechanism - syncer.
*
* It is useful to delay writes of file data and filesystem metadata for
* a certain amount of time so that quickly created and deleted files need
* not waste disk bandwidth being created and removed. To implement this,
* vnodes are appended to a "workitem" queue.
*
* Most pending metadata should not wait for more than ten seconds. Thus,
* mounted on block devices are delayed only about a half the time that file
* data is delayed. Similarly, directory updates are more critical, so are
* only delayed about a third the time that file data is delayed.
*
* There are SYNCER_MAXDELAY queues that are processed in a round-robin
* manner at a rate of one each second (driven off the filesystem syner
* thread). The syncer_delayno variable indicates the next queue that is
* to be processed. Items that need to be processed soon are placed in
* this queue:
*
* syncer_workitem_pending[syncer_delayno]
*
* A delay of e.g. fifteen seconds is done by placing the request fifteen
* entries later in the queue:
*
* syncer_workitem_pending[(syncer_delayno + 15) & syncer_mask]
*
* Flag VI_ONWORKLST indicates that vnode is added into the queue.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sync_subr.c,v 1.50 2015/04/20 13:44:16 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/vnode.h>
#include <sys/buf.h>
#include <sys/errno.h>
#include <sys/kmem.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/syncfs/syncfs.h>
typedef TAILQ_HEAD(synclist, vnode) synclist_t;
static void vn_syncer_add1(struct vnode *, int);
static void sysctl_vfs_syncfs_setup(struct sysctllog **);
/*
* Defines and variables for the syncer process.
*/
int syncer_maxdelay = SYNCER_MAXDELAY; /* maximum delay time */
time_t syncdelay = 30; /* max time to delay syncing data */
time_t filedelay = 30; /* time to delay syncing files */
time_t dirdelay = 15; /* time to delay syncing directories */
time_t metadelay = 10; /* time to delay syncing metadata */
time_t lockdelay = 1; /* time to delay if locking fails */
kmutex_t syncer_mutex; /* used to freeze syncer, long term */
static kmutex_t syncer_data_lock; /* short term lock on data structs */
static int syncer_delayno = 0;
static long syncer_last;
static synclist_t * syncer_workitem_pending;
void
vn_initialize_syncerd(void)
{
int i;
syncer_last = SYNCER_MAXDELAY + 2;
sysctl_vfs_syncfs_setup(NULL);
syncer_workitem_pending =
kmem_alloc(syncer_last * sizeof (struct synclist), KM_SLEEP);
for (i = 0; i < syncer_last; i++)
TAILQ_INIT(&syncer_workitem_pending[i]);
mutex_init(&syncer_mutex, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&syncer_data_lock, MUTEX_DEFAULT, IPL_NONE);
}
/*
* Add an item to the syncer work queue.
*/
static void
vn_syncer_add1(struct vnode *vp, int delayx)
{
synclist_t *slp;
KASSERT(mutex_owned(&syncer_data_lock));
if (vp->v_iflag & VI_ONWORKLST) {
/*
* Remove in order to adjust the position of the vnode.
* Note: called from sched_sync(), which will not hold
* interlock, therefore we cannot modify v_iflag here.
*/
slp = &syncer_workitem_pending[vp->v_synclist_slot];
TAILQ_REMOVE(slp, vp, v_synclist);
} else {
KASSERT(mutex_owned(vp->v_interlock));
vp->v_iflag |= VI_ONWORKLST;
}
if (delayx > syncer_maxdelay - 2)
delayx = syncer_maxdelay - 2;
vp->v_synclist_slot = (syncer_delayno + delayx) % syncer_last;
slp = &syncer_workitem_pending[vp->v_synclist_slot];
TAILQ_INSERT_TAIL(slp, vp, v_synclist);
}
void
vn_syncer_add_to_worklist(struct vnode *vp, int delayx)
{
KASSERT(mutex_owned(vp->v_interlock));
mutex_enter(&syncer_data_lock);
vn_syncer_add1(vp, delayx);
mutex_exit(&syncer_data_lock);
}
/*
* Remove an item from the syncer work queue.
*/
void
vn_syncer_remove_from_worklist(struct vnode *vp)
{
synclist_t *slp;
KASSERT(mutex_owned(vp->v_interlock));
mutex_enter(&syncer_data_lock);
if (vp->v_iflag & VI_ONWORKLST) {
vp->v_iflag &= ~VI_ONWORKLST;
slp = &syncer_workitem_pending[vp->v_synclist_slot];
TAILQ_REMOVE(slp, vp, v_synclist);
}
mutex_exit(&syncer_data_lock);
}
/*
* System filesystem synchronizer daemon.
*/
void
sched_sync(void *arg)
{
synclist_t *slp;
struct vnode *vp;
time_t starttime;
bool synced;
for (;;) {
mutex_enter(&syncer_mutex);
mutex_enter(&syncer_data_lock);
starttime = time_second;
/*
* Push files whose dirty time has expired.
*/
slp = &syncer_workitem_pending[syncer_delayno];
syncer_delayno += 1;
if (syncer_delayno >= syncer_last)
syncer_delayno = 0;
while ((vp = TAILQ_FIRST(slp)) != NULL) {
/* We are locking in the wrong direction. */
synced = false;
if (mutex_tryenter(vp->v_interlock)) {
mutex_exit(&syncer_data_lock);
if (vget(vp, LK_NOWAIT, false /* !wait */)
== 0) {
if (vn_lock(vp, LK_EXCLUSIVE|LK_NOWAIT)
== 0) {
synced = true;
(void) VOP_FSYNC(vp,
curlwp->l_cred, FSYNC_LAZY,
0, 0);
VOP_UNLOCK(vp);
}
vrele(vp);
}
mutex_enter(&syncer_data_lock);
}
/*
* XXX The vnode may have been recycled, in which
* case it may have a new identity.
*/
if (TAILQ_FIRST(slp) == vp) {
/*
* Put us back on the worklist. The worklist
* routine will remove us from our current
* position and then add us back in at a later
* position.
*
* Try again sooner rather than later if
* we were unable to lock the vnode. Lock
* failure should not prevent us from doing
* the sync "soon".
*
* If we locked it yet arrive here, it's
* likely that lazy sync is in progress and
* so the vnode still has dirty metadata.
* syncdelay is mainly to get this vnode out
* of the way so we do not consider it again
* "soon" in this loop, so the delay time is
* not critical as long as it is not "soon".
* While write-back strategy is the file
* system's domain, we expect write-back to
* occur no later than syncdelay seconds
* into the future.
*/
vn_syncer_add1(vp,
synced ? syncdelay : lockdelay);
}
}
mutex_exit(&syncer_mutex);
/*
* If it has taken us less than a second to process the
* current work, then wait. Otherwise start right over
* again. We can still lose time if any single round
* takes more than two seconds, but it does not really
* matter as we are just trying to generally pace the
* filesystem activity.
*/
if (time_second == starttime) {
kpause("syncer", false, hz, &syncer_data_lock);
}
mutex_exit(&syncer_data_lock);
}
}
static void
sysctl_vfs_syncfs_setup(struct sysctllog **clog)
{
const struct sysctlnode *rnode, *cnode;
sysctl_createv(clog, 0, NULL, &rnode,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "sync",
SYSCTL_DESCR("syncer options"),
NULL, 0, NULL, 0,
CTL_VFS, CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "delay",
SYSCTL_DESCR("max time to delay syncing data"),
NULL, 0, &syncdelay, 0,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "filedelay",
SYSCTL_DESCR("time to delay syncing files"),
NULL, 0, &filedelay, 0,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "dirdelay",
SYSCTL_DESCR("time to delay syncing directories"),
NULL, 0, &dirdelay, 0,
CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_QUAD, "metadelay",
SYSCTL_DESCR("time to delay syncing metadata"),
NULL, 0, &metadelay, 0,
CTL_CREATE, CTL_EOL);
}

View File

@ -1,238 +0,0 @@
/* $NetBSD: sync_vnops.c,v 1.29 2011/06/12 03:35:58 rmind Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright 1997 Marshall Kirk McKusick. All Rights Reserved.
*
* This code is derived from work done by Greg Ganger at the
* University of Michigan.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. None of the names of McKusick, Ganger, or the University of Michigan
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sync_vnops.c,v 1.29 2011/06/12 03:35:58 rmind Exp $");
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/errno.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/syncfs/syncfs.h>
int (**sync_vnodeop_p)(void *);
const struct vnodeopv_entry_desc sync_vnodeop_entries[] = {
{ &vop_default_desc, vn_default_error },
{ &vop_close_desc, sync_close }, /* close */
{ &vop_fsync_desc, sync_fsync }, /* fsync */
{ &vop_inactive_desc, sync_inactive }, /* inactive */
{ &vop_reclaim_desc, sync_reclaim }, /* reclaim */
{ &vop_lock_desc, sync_lock }, /* lock */
{ &vop_unlock_desc, sync_unlock }, /* unlock */
{ &vop_print_desc, sync_print }, /* print */
{ &vop_islocked_desc, sync_islocked }, /* islocked */
{ &vop_putpages_desc, sync_putpages }, /* islocked */
{ NULL, NULL }
};
const struct vnodeopv_desc sync_vnodeop_opv_desc =
{ &sync_vnodeop_p, sync_vnodeop_entries };
/*
* Return delay factor appropriate for the given file system. For
* WAPBL we use the sync vnode to burst out metadata updates: sync
* those file systems more frequently.
*/
static inline int
sync_delay(struct mount *mp)
{
return mp->mnt_wapbl != NULL ? metadelay : syncdelay;
}
/*
* Create a new filesystem syncer vnode for the specified mount point.
*/
int
vfs_allocate_syncvnode(struct mount *mp)
{
struct vnode *vp;
static int start, incr, next;
int error, vdelay;
/* Allocate a new vnode */
error = getnewvnode(VT_VFS, mp, sync_vnodeop_p, NULL, &vp);
if (error) {
return error;
}
vp->v_writecount = 1;
vp->v_type = VNON;
/*
* Place the vnode onto the syncer worklist. We attempt to
* scatter them about on the list so that they will go off
* at evenly distributed times even if all the filesystems
* are mounted at once.
*/
next += incr;
if (next == 0 || next > syncer_maxdelay) {
start /= 2;
incr /= 2;
if (start == 0) {
start = syncer_maxdelay / 2;
incr = syncer_maxdelay;
}
next = start;
}
mutex_enter(vp->v_interlock);
vdelay = sync_delay(mp);
vn_syncer_add_to_worklist(vp, vdelay > 0 ? next % vdelay : 0);
mutex_exit(vp->v_interlock);
mp->mnt_syncer = vp;
return (0);
}
/*
* Destroy the filesystem syncer vnode for the specified mount point.
*/
void
vfs_deallocate_syncvnode(struct mount *mp)
{
struct vnode *vp;
vp = mp->mnt_syncer;
mp->mnt_syncer = NULL;
mutex_enter(vp->v_interlock);
vn_syncer_remove_from_worklist(vp);
vp->v_writecount = 0;
mutex_exit(vp->v_interlock);
vgone(vp);
}
/*
* Do a lazy sync of the filesystem.
*/
int
sync_fsync(void *v)
{
struct vop_fsync_args /* {
struct vnode *a_vp;
kauth_cred_t a_cred;
int a_flags;
off_t offlo;
off_t offhi;
} */ *ap = v;
struct vnode *syncvp = ap->a_vp;
struct mount *mp = syncvp->v_mount;
/*
* We only need to do something if this is a lazy evaluation.
*/
if (!(ap->a_flags & FSYNC_LAZY))
return (0);
/*
* Move ourselves to the back of the sync list.
*/
mutex_enter(syncvp->v_interlock);
vn_syncer_add_to_worklist(syncvp, sync_delay(mp));
mutex_exit(syncvp->v_interlock);
/*
* Walk the list of vnodes pushing all that are dirty and
* not already on the sync list.
*/
if (vfs_busy(mp, NULL) == 0) {
VFS_SYNC(mp, MNT_LAZY, ap->a_cred);
vfs_unbusy(mp, false, NULL);
}
return (0);
}
/*
* The syncer vnode is no longer needed and is being decommissioned.
*/
int
sync_inactive(void *v)
{
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
VOP_UNLOCK(vp);
return (0);
}
int
sync_reclaim(void *v)
{
return (0);
}
/*
* Print out a syncer vnode.
*/
int
sync_print(void *v)
{
printf("syncer vnode\n");
return (0);
}

View File

@ -1,67 +0,0 @@
/* $NetBSD: syncfs.h,v 1.12 2011/04/18 15:53:04 rmind Exp $ */
/*
* Copyright 1997 Marshall Kirk McKusick. All Rights Reserved.
*
* This code is derived from work done by Greg Ganger at the
* University of Michigan.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. None of the names of McKusick, Ganger, or the University of Michigan
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _MISCFS_SYNCFS_SYNCFS_H_
#define _MISCFS_SYNCFS_SYNCFS_H_
/*
* Routines to create and manage a filesystem syncer vnode.
*/
#define sync_close genfs_nullop
int sync_fsync(void *);
int sync_inactive(void *);
int sync_reclaim(void *);
#define sync_lock genfs_nolock
#define sync_unlock genfs_nounlock
int sync_print(void *);
#define sync_islocked genfs_noislocked
#define sync_putpages genfs_null_putpages
void sched_sync(void *);
void vn_initialize_syncerd(void);
int vfs_allocate_syncvnode(struct mount *);
void vfs_deallocate_syncvnode(struct mount *);
extern int (**sync_vnodeop_p)(void *);
#define SYNCER_MAXDELAY 32
extern int syncer_maxdelay;
extern kmutex_t syncer_mutex;
extern time_t syncdelay;
extern time_t filedelay;
extern time_t dirdelay;
extern time_t metadelay;
#endif /* _MISCFS_SYNCFS_SYNCFS_H_ */

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.rumpvfs,v 1.46 2015/04/23 14:49:26 pooka Exp $
# $NetBSD: Makefile.rumpvfs,v 1.47 2015/05/06 15:57:08 hannken Exp $
#
.include "${RUMPTOP}/Makefile.rump"
@ -11,7 +11,7 @@ MAN= rump_etfs.3 rumpfs.4
.PATH: ${RUMPTOP}/librump/rumpvfs ${RUMPTOP}/librump \
${RUMPTOP}/../kern \
${RUMPTOP}/../miscfs/genfs ${RUMPTOP}/../miscfs/syncfs \
${RUMPTOP}/../miscfs/genfs \
${RUMPTOP}/../miscfs/specfs ${RUMPTOP}/../miscfs/deadfs \
${RUMPTOP}/../compat/common ${RUMPTOP}/../uvm \
${RUMPTOP}/../dev ${RUMPTOP}/../ufs/mfs \
@ -41,9 +41,6 @@ SRCS+= kern_module_vfs.c subr_kobj_vfs.c
# sys/uvm
SRCS+= uvm_vnode.c
# sys/miscfs/syncfs
SRCS+= sync_subr.c sync_vnops.c
# sys/miscfs/deadfs
SRCS+= dead_vfsops.c dead_vnops.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: rump_vfs.c,v 1.81 2014/11/17 14:30:31 pooka Exp $ */
/* $NetBSD: rump_vfs.c,v 1.82 2015/05/06 15:57:08 hannken Exp $ */
/*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.81 2014/11/17 14:30:31 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.82 2015/05/06 15:57:08 hannken Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@ -49,7 +49,6 @@ __KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.81 2014/11/17 14:30:31 pooka Exp $");
#include <sys/wapbl.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/syncfs/syncfs.h>
#include <rump/rump.h>
#include <rump/rumpuser.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: fstypes.h,v 1.32 2012/11/26 16:22:21 drochner Exp $ */
/* $NetBSD: fstypes.h,v 1.33 2015/05/06 15:57:08 hannken Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
@ -220,6 +220,7 @@ typedef struct fhandle fhandle_t;
#define IMNT_HAS_TRANS 0x00000080 /* supports transactions */
#define IMNT_MPSAFE 0x00000100 /* file system code MP safe */
#define IMNT_CAN_RWTORO 0x00000200 /* can downgrade fs to from rw to r/o */
#define IMNT_ONWORKLIST 0x00000400 /* on syncer worklist */
#define __MNT_FLAGS \
__MNT_BASIC_FLAGS \
@ -264,6 +265,7 @@ typedef struct fhandle fhandle_t;
#define __IMNT_FLAG_BITS \
"\20" \
"\13IMNT_ONWORKLIST" \
"\12IMNT_CAN_RWTORO" \
"\11IMNT_MPSAFE" \
"\10IMNT_HAS_TRANS" \

View File

@ -1,4 +1,4 @@
/* $NetBSD: mount.h,v 1.216 2015/03/17 09:38:21 hannken Exp $ */
/* $NetBSD: mount.h,v 1.217 2015/05/06 15:57:08 hannken Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
@ -112,7 +112,7 @@ struct mount {
TAILQ_HEAD(, vnode) mnt_vnodelist; /* list of vnodes this mount */
struct vfsops *mnt_op; /* operations on fs */
struct vnode *mnt_vnodecovered; /* vnode we mounted on */
struct vnode *mnt_syncer; /* syncer vnode */
int mnt_synclist_slot; /* synclist slot index */
void *mnt_transinfo; /* for FS-internal use */
void *mnt_data; /* private data */
kmutex_t mnt_unmounting; /* to prevent new activity */
@ -454,6 +454,16 @@ void vfs_vnode_iterator_destroy(struct vnode_iterator *);
struct vnode *vfs_vnode_iterator_next(struct vnode_iterator *,
bool (*)(void *, struct vnode *), void *);
/* Syncer */
extern int syncer_maxdelay;
extern kmutex_t syncer_mutex;
extern time_t syncdelay;
extern time_t filedelay;
extern time_t dirdelay;
extern time_t metadelay;
void vfs_syncer_add_to_worklist(struct mount *);
void vfs_syncer_remove_from_worklist(struct mount *);
extern TAILQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */
extern struct vfsops *vfssw[]; /* filesystem type table */
extern int nvfssw;

View File

@ -1,4 +1,4 @@
/* $NetBSD: vnode.h,v 1.254 2015/04/20 19:36:56 riastradh Exp $ */
/* $NetBSD: vnode.h,v 1.255 2015/05/06 15:57:08 hannken Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -585,6 +585,7 @@ int vn_fifo_bypass(void *);
void vntblinit(void);
/* misc stuff */
void sched_sync(void *);
void vn_syncer_add_to_worklist(struct vnode *, int);
void vn_syncer_remove_from_worklist(struct vnode *);
int dorevoke(struct vnode *, kauth_cred_t);