1 /* $NetBSD: sync_vnops.c,v 1.26 2009/02/22 20:10:25 ad Exp $ */
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright 1997 Marshall Kirk McKusick. All Rights Reserved.
35 * This code is derived from work done by Greg Ganger at the
36 * University of Michigan.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. None of the names of McKusick, Ganger, or the University of Michigan
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
50 * THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 #include <sys/cdefs.h>
64 __KERNEL_RCSID(0, "$NetBSD: sync_vnops.c,v 1.26 2009/02/22 20:10:25 ad Exp $");
66 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/vnode.h>
70 #include <sys/mount.h>
71 #include <sys/errno.h>
73 #include <miscfs/genfs/genfs.h>
74 #include <miscfs/syncfs/syncfs.h>
76 int (**sync_vnodeop_p
)(void *);
77 const struct vnodeopv_entry_desc sync_vnodeop_entries
[] = {
78 { &vop_default_desc
, vn_default_error
},
79 { &vop_close_desc
, sync_close
}, /* close */
80 { &vop_fsync_desc
, sync_fsync
}, /* fsync */
81 { &vop_inactive_desc
, sync_inactive
}, /* inactive */
82 { &vop_reclaim_desc
, sync_reclaim
}, /* reclaim */
83 { &vop_lock_desc
, sync_lock
}, /* lock */
84 { &vop_unlock_desc
, sync_unlock
}, /* unlock */
85 { &vop_print_desc
, sync_print
}, /* print */
86 { &vop_islocked_desc
, sync_islocked
}, /* islocked */
87 { &vop_putpages_desc
, sync_putpages
}, /* islocked */
91 const struct vnodeopv_desc sync_vnodeop_opv_desc
=
92 { &sync_vnodeop_p
, sync_vnodeop_entries
};
95 * Return delay factor appropriate for the given file system. For
96 * WAPBL we use the sync vnode to burst out metadata updates: sync
97 * those file systems more frequently.
100 sync_delay(struct mount
*mp
)
103 return mp
->mnt_wapbl
!= NULL
? metadelay
: syncdelay
;
107 * Create a new filesystem syncer vnode for the specified mount point.
110 vfs_allocate_syncvnode(struct mount
*mp
)
113 static int start
, incr
, next
;
116 /* Allocate a new vnode */
117 if ((error
= getnewvnode(VT_VFS
, mp
, sync_vnodeop_p
, &vp
)) != 0)
120 vp
->v_writecount
= 1;
124 * Place the vnode onto the syncer worklist. We attempt to
125 * scatter them about on the list so that they will go off
126 * at evenly distributed times even if all the filesystems
127 * are mounted at once.
131 if (next
== 0 || next
> syncer_maxdelay
) {
135 start
= syncer_maxdelay
/ 2;
136 incr
= syncer_maxdelay
;
140 mutex_enter(&vp
->v_interlock
);
141 vdelay
= sync_delay(mp
);
142 vn_syncer_add_to_worklist(vp
, vdelay
> 0 ? next
% vdelay
: 0);
143 mutex_exit(&vp
->v_interlock
);
149 * Destroy the filesystem syncer vnode for the specified mount point.
152 vfs_deallocate_syncvnode(struct mount
*mp
)
157 mp
->mnt_syncer
= NULL
;
158 mutex_enter(&vp
->v_interlock
);
159 vn_syncer_remove_from_worklist(vp
);
160 vp
->v_writecount
= 0;
161 mutex_exit(&vp
->v_interlock
);
166 * Do a lazy sync of the filesystem.
171 struct vop_fsync_args
/* {
178 struct vnode
*syncvp
= ap
->a_vp
;
179 struct mount
*mp
= syncvp
->v_mount
;
182 * We only need to do something if this is a lazy evaluation.
184 if (!(ap
->a_flags
& FSYNC_LAZY
))
188 * Move ourselves to the back of the sync list.
190 mutex_enter(&syncvp
->v_interlock
);
191 vn_syncer_add_to_worklist(syncvp
, sync_delay(mp
));
192 mutex_exit(&syncvp
->v_interlock
);
195 * Walk the list of vnodes pushing all that are dirty and
196 * not already on the sync list.
198 if (vfs_busy(mp
, NULL
) == 0) {
199 VFS_SYNC(mp
, MNT_LAZY
, ap
->a_cred
);
200 vfs_unbusy(mp
, false, NULL
);
206 * The syncer vnode is no longer needed and is being decommissioned.
209 sync_inactive(void *v
)
211 struct vop_inactive_args
/* {
215 struct vnode
*vp
= ap
->a_vp
;
222 sync_reclaim(void *v
)
229 * Print out a syncer vnode.
235 printf("syncer vnode\n");