Module Name: src Committed By: hannken Date: Wed May 6 15:57:08 UTC 2015
Modified Files: src/distrib/sets/lists/base: mi src/distrib/sets/lists/comp: mi src/external/cddl/osnet/sys/kern: vfs.c src/sys/coda: coda_psdev.c src/sys/fs/puffs: puffs_msgif.c src/sys/kern: files.kern init_main.c vfs_init.c vfs_mount.c vfs_subr.c vfs_syscalls.c vfs_trans.c src/sys/miscfs: Makefile src/sys/miscfs/genfs: genfs_io.c src/sys/rump/librump/rumpvfs: Makefile.rumpvfs rump_vfs.c src/sys/sys: fstypes.h mount.h vnode.h Removed Files: src/sys/miscfs/syncfs: Makefile sync_subr.c sync_vnops.c syncfs.h Log Message: 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@ To generate a diff of this commit: cvs rdiff -u -r1.1102 -r1.1103 src/distrib/sets/lists/base/mi cvs rdiff -u -r1.1956 -r1.1957 src/distrib/sets/lists/comp/mi cvs rdiff -u -r1.5 -r1.6 src/external/cddl/osnet/sys/kern/vfs.c cvs rdiff -u -r1.54 -r1.55 src/sys/coda/coda_psdev.c cvs rdiff -u -r1.97 -r1.98 src/sys/fs/puffs/puffs_msgif.c cvs rdiff -u -r1.4 -r1.5 src/sys/kern/files.kern cvs rdiff -u -r1.466 -r1.467 src/sys/kern/init_main.c cvs rdiff -u -r1.47 -r1.48 src/sys/kern/vfs_init.c cvs rdiff -u -r1.34 -r1.35 src/sys/kern/vfs_mount.c cvs rdiff -u -r1.445 -r1.446 src/sys/kern/vfs_subr.c cvs rdiff -u -r1.497 -r1.498 src/sys/kern/vfs_syscalls.c cvs rdiff -u -r1.32 -r1.33 src/sys/kern/vfs_trans.c cvs rdiff -u -r1.9 -r1.10 src/sys/miscfs/Makefile cvs rdiff -u -r1.60 -r1.61 src/sys/miscfs/genfs/genfs_io.c cvs rdiff -u -r1.1 -r0 src/sys/miscfs/syncfs/Makefile cvs rdiff -u -r1.50 -r0 src/sys/miscfs/syncfs/sync_subr.c cvs rdiff -u -r1.29 -r0 src/sys/miscfs/syncfs/sync_vnops.c cvs rdiff -u -r1.12 -r0 src/sys/miscfs/syncfs/syncfs.h cvs rdiff -u -r1.46 -r1.47 src/sys/rump/librump/rumpvfs/Makefile.rumpvfs cvs rdiff -u -r1.81 -r1.82 src/sys/rump/librump/rumpvfs/rump_vfs.c cvs rdiff -u -r1.32 -r1.33 src/sys/sys/fstypes.h cvs rdiff -u -r1.216 -r1.217 src/sys/sys/mount.h cvs rdiff -u -r1.254 -r1.255 src/sys/sys/vnode.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/base/mi diff -u src/distrib/sets/lists/base/mi:1.1102 src/distrib/sets/lists/base/mi:1.1103 --- src/distrib/sets/lists/base/mi:1.1102 Sun Apr 26 21:37:22 2015 +++ src/distrib/sets/lists/base/mi Wed May 6 15:57:07 2015 @@ -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 Index: src/distrib/sets/lists/comp/mi diff -u src/distrib/sets/lists/comp/mi:1.1956 src/distrib/sets/lists/comp/mi:1.1957 --- src/distrib/sets/lists/comp/mi:1.1956 Mon Apr 27 07:03:57 2015 +++ src/distrib/sets/lists/comp/mi Wed May 6 15:57:07 2015 @@ -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 Index: src/external/cddl/osnet/sys/kern/vfs.c diff -u src/external/cddl/osnet/sys/kern/vfs.c:1.5 src/external/cddl/osnet/sys/kern/vfs.c:1.6 --- src/external/cddl/osnet/sys/kern/vfs.c:1.5 Mon Nov 25 22:48:05 2013 +++ src/external/cddl/osnet/sys/kern/vfs.c Wed May 6 15:57:07 2015 @@ -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 <p...@freebsd.org> @@ -332,12 +332,9 @@ domount(kthread_t *td, vnode_t *vp, cons 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; Index: src/sys/coda/coda_psdev.c diff -u src/sys/coda/coda_psdev.c:1.54 src/sys/coda/coda_psdev.c:1.55 --- src/sys/coda/coda_psdev.c:1.54 Sat Dec 13 15:58:39 2014 +++ src/sys/coda/coda_psdev.c Wed May 6 15:57:08 2015 @@ -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; /* Se #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> Index: src/sys/fs/puffs/puffs_msgif.c diff -u src/sys/fs/puffs/puffs_msgif.c:1.97 src/sys/fs/puffs/puffs_msgif.c:1.98 --- src/sys/fs/puffs/puffs_msgif.c:1.97 Mon Nov 10 18:46:33 2014 +++ src/sys/fs/puffs/puffs_msgif.c Wed May 6 15:57:08 2015 @@ -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. #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 */ Index: src/sys/kern/files.kern diff -u src/sys/kern/files.kern:1.4 src/sys/kern/files.kern:1.5 --- src/sys/kern/files.kern:1.4 Sat May 2 12:57:19 2015 +++ src/sys/kern/files.kern Wed May 6 15:57:08 2015 @@ -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 Index: src/sys/kern/init_main.c diff -u src/sys/kern/init_main.c:1.466 src/sys/kern/init_main.c:1.467 --- src/sys/kern/init_main.c:1.466 Thu Apr 30 15:22:32 2015 +++ src/sys/kern/init_main.c Wed May 6 15:57:08 2015 @@ -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> Index: src/sys/kern/vfs_init.c diff -u src/sys/kern/vfs_init.c:1.47 src/sys/kern/vfs_init.c:1.48 --- src/sys/kern/vfs_init.c:1.47 Tue Feb 25 18:30:11 2014 +++ src/sys/kern/vfs_init.c Wed May 6 15:57:08 2015 @@ -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 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, }; Index: src/sys/kern/vfs_mount.c diff -u src/sys/kern/vfs_mount.c:1.34 src/sys/kern/vfs_mount.c:1.35 --- src/sys/kern/vfs_mount.c:1.34 Mon Apr 20 13:44:16 2015 +++ src/sys/kern/vfs_mount.c Wed May 6 15:57:08 2015 @@ -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, #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 **v 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 **v *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, s 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, s 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, s 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) Index: src/sys/kern/vfs_subr.c diff -u src/sys/kern/vfs_subr.c:1.445 src/sys/kern/vfs_subr.c:1.446 --- src/sys/kern/vfs_subr.c:1.445 Fri Sep 5 05:57:21 2014 +++ src/sys/kern/vfs_subr.c Wed May 6 15:57:08 2015 @@ -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 #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 re */ static int getdevvp(dev_t, vnode_t **, enum vtype); +static void vn_initialize_syncerd(void); /* * Initialize the vnode management data structures. @@ -538,6 +539,373 @@ vdevgone(int maj, int minl, int minh, en } /* + * 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 */ int @@ -1152,8 +1520,8 @@ vfs_mount_print(struct mount *mp, int fu { 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); Index: src/sys/kern/vfs_syscalls.c diff -u src/sys/kern/vfs_syscalls.c:1.497 src/sys/kern/vfs_syscalls.c:1.498 --- src/sys/kern/vfs_syscalls.c:1.497 Tue Apr 21 03:19:03 2015 +++ src/sys/kern/vfs_syscalls.c Wed May 6 15:57:08 2015 @@ -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 #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 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); Index: src/sys/kern/vfs_trans.c diff -u src/sys/kern/vfs_trans.c:1.32 src/sys/kern/vfs_trans.c:1.33 --- src/sys/kern/vfs_trans.c:1.32 Tue Apr 21 10:54:52 2015 +++ src/sys/kern/vfs_trans.c Wed May 6 15:57:08 2015 @@ -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, #include <sys/proc.h> #include <miscfs/specfs/specdev.h> -#include <miscfs/syncfs/syncfs.h> struct fscow_handler { LIST_ENTRY(fscow_handler) ch_list; Index: src/sys/miscfs/Makefile diff -u src/sys/miscfs/Makefile:1.9 src/sys/miscfs/Makefile:1.10 --- src/sys/miscfs/Makefile:1.9 Sat Dec 5 20:11:17 2009 +++ src/sys/miscfs/Makefile Wed May 6 15:57:08 2015 @@ -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 Index: src/sys/miscfs/genfs/genfs_io.c diff -u src/sys/miscfs/genfs/genfs_io.c:1.60 src/sys/miscfs/genfs/genfs_io.c:1.61 --- src/sys/miscfs/genfs/genfs_io.c:1.60 Sun Apr 12 14:44:06 2015 +++ src/sys/miscfs/genfs/genfs_io.c Wed May 6 15:57:08 2015 @@ -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 #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> Index: src/sys/rump/librump/rumpvfs/Makefile.rumpvfs diff -u src/sys/rump/librump/rumpvfs/Makefile.rumpvfs:1.46 src/sys/rump/librump/rumpvfs/Makefile.rumpvfs:1.47 --- src/sys/rump/librump/rumpvfs/Makefile.rumpvfs:1.46 Thu Apr 23 14:49:26 2015 +++ src/sys/rump/librump/rumpvfs/Makefile.rumpvfs Wed May 6 15:57:08 2015 @@ -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 Index: src/sys/rump/librump/rumpvfs/rump_vfs.c diff -u src/sys/rump/librump/rumpvfs/rump_vfs.c:1.81 src/sys/rump/librump/rumpvfs/rump_vfs.c:1.82 --- src/sys/rump/librump/rumpvfs/rump_vfs.c:1.81 Mon Nov 17 14:30:31 2014 +++ src/sys/rump/librump/rumpvfs/rump_vfs.c Wed May 6 15:57:08 2015 @@ -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 #include <sys/wapbl.h> #include <miscfs/specfs/specdev.h> -#include <miscfs/syncfs/syncfs.h> #include <rump/rump.h> #include <rump/rumpuser.h> Index: src/sys/sys/fstypes.h diff -u src/sys/sys/fstypes.h:1.32 src/sys/sys/fstypes.h:1.33 --- src/sys/sys/fstypes.h:1.32 Mon Nov 26 16:22:21 2012 +++ src/sys/sys/fstypes.h Wed May 6 15:57:08 2015 @@ -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" \ Index: src/sys/sys/mount.h diff -u src/sys/sys/mount.h:1.216 src/sys/sys/mount.h:1.217 --- src/sys/sys/mount.h:1.216 Tue Mar 17 09:38:21 2015 +++ src/sys/sys/mount.h Wed May 6 15:57:08 2015 @@ -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 v 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; Index: src/sys/sys/vnode.h diff -u src/sys/sys/vnode.h:1.254 src/sys/sys/vnode.h:1.255 --- src/sys/sys/vnode.h:1.254 Mon Apr 20 19:36:56 2015 +++ src/sys/sys/vnode.h Wed May 6 15:57:08 2015 @@ -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);