Move the code for iterating over the multiple RPC calls in a quota proplib XML packet to vfs_quotactl.c out of sys/ufs/ufs. Add a dummy extra arg to VFS_QUOTACTL for compile safety. Note: this change requires a kernel version bump.diff -r1.2 -r1.3 src/sys/kern/vfs_quotactl.c
(dholland)
--- src/sys/kern/vfs_quotactl.c 2012/01/29 06:29:05 1.2
+++ src/sys/kern/vfs_quotactl.c 2012/01/29 06:32:43 1.3
@@ -1,47 +1,118 @@ | @@ -1,47 +1,118 @@ | |||
1 | /* $NetBSD: vfs_quotactl.c,v 1.2 2012/01/29 06:29:05 dholland Exp $ */ | 1 | /* $NetBSD: vfs_quotactl.c,v 1.3 2012/01/29 06:32:43 dholland Exp $ */ | |
2 | ||||
3 | /* | |||
4 | * Copyright (c) 1991, 1993, 1994 | |||
5 | * The Regents of the University of California. All rights reserved. | |||
6 | * (c) UNIX System Laboratories, Inc. | |||
7 | * All or some portions of this file are derived from material licensed | |||
8 | * to the University of California by American Telephone and Telegraph | |||
9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | |||
10 | * the permission of UNIX System Laboratories, Inc. | |||
11 | * | |||
12 | * Redistribution and use in source and binary forms, with or without | |||
13 | * modification, are permitted provided that the following conditions | |||
14 | * are met: | |||
15 | * 1. Redistributions of source code must retain the above copyright | |||
16 | * notice, this list of conditions and the following disclaimer. | |||
17 | * 2. Redistributions in binary form must reproduce the above copyright | |||
18 | * notice, this list of conditions and the following disclaimer in the | |||
19 | * documentation and/or other materials provided with the distribution. | |||
20 | * 3. Neither the name of the University nor the names of its contributors | |||
21 | * may be used to endorse or promote products derived from this software | |||
22 | * without specific prior written permission. | |||
23 | * | |||
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
34 | * SUCH DAMAGE. | |||
35 | * | |||
36 | * @(#)ufs_vfsops.c 8.8 (Berkeley) 5/20/95 | |||
37 | * From NetBSD: ufs_vfsops.c,v 1.42 2011/03/24 17:05:46 bouyer Exp | |||
38 | */ | |||
2 | 39 | |||
3 | /* | 40 | /* | |
4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | 41 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | |
5 | * The Regents of the University of California. All rights reserved. | 42 | * The Regents of the University of California. All rights reserved. | |
6 | * | 43 | * | |
7 | * This code is derived from software contributed to Berkeley by | 44 | * This code is derived from software contributed to Berkeley by | |
8 | * Robert Elz at The University of Melbourne. | 45 | * Robert Elz at The University of Melbourne. | |
9 | * | 46 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 47 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 48 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 49 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 50 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 51 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 52 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 53 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 54 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. Neither the name of the University nor the names of its contributors | 55 | * 3. Neither the name of the University nor the names of its contributors | |
19 | * may be used to endorse or promote products derived from this software | 56 | * may be used to endorse or promote products derived from this software | |
20 | * without specific prior written permission. | 57 | * without specific prior written permission. | |
21 | * | 58 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 59 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 60 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 61 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 62 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 63 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 64 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 65 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 66 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 67 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 68 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 69 | * SUCH DAMAGE. | |
33 | * | 70 | * | |
34 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | 71 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | |
35 | * From ufs_quota.c,v 1.70 2011/03/24 17:05:46 bouyer Exp | 72 | * From NetBSD: ufs_quota.c,v 1.70 2011/03/24 17:05:46 bouyer Exp | |
73 | */ | |||
74 | ||||
75 | /* | |||
76 | * Note that both of the copyrights above are moderately spurious; | |||
77 | * this code should almost certainly have the Copyright 2010 Manuel | |||
78 | * Bouyer notice and license found in e.g. sys/ufs/ufs/quota2_subr.c. | |||
79 | * However, they're what was on the files this code was sliced out of. | |||
36 | */ | 80 | */ | |
37 | 81 | |||
38 | #include <sys/cdefs.h> | 82 | #include <sys/cdefs.h> | |
39 | __KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.2 2012/01/29 06:29:05 dholland Exp $"); | 83 | __KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.3 2012/01/29 06:32:43 dholland Exp $"); | |
40 | 84 | |||
41 | #include <sys/mount.h> | 85 | #include <sys/mount.h> | |
86 | #include <quota/quotaprop.h> | |||
42 | 87 | |||
43 | int | 88 | int | |
44 | vfs_quotactl(struct mount *mp, prop_dictionary_t dict) | 89 | vfs_quotactl(struct mount *mp, prop_dictionary_t dict) | |
45 | { | 90 | { | |
46 | return VFS_QUOTACTL(mp, dict); | 91 | prop_dictionary_t cmddict; | |
92 | prop_array_t commands; | |||
93 | prop_object_iterator_t iter; | |||
94 | int error; | |||
95 | ||||
96 | error = quota_get_cmds(dict, &commands); | |||
97 | if (error) { | |||
98 | return error; | |||
99 | } | |||
100 | ||||
101 | iter = prop_array_iterator(commands); | |||
102 | if (iter == NULL) { | |||
103 | return ENOMEM; | |||
104 | } | |||
105 | ||||
106 | while ((cmddict = prop_object_iterator_next(iter)) != NULL) { | |||
107 | if (prop_object_type(cmddict) != PROP_TYPE_DICTIONARY) { | |||
108 | /* XXX shouldn't this be an error? */ | |||
109 | continue; | |||
110 | } | |||
111 | error = VFS_QUOTACTL(mp, cmddict, 0/*dummy*/); | |||
112 | if (error) { | |||
113 | break; | |||
114 | } | |||
115 | } | |||
116 | prop_object_iterator_release(iter); | |||
117 | return error; | |||
47 | } | 118 | } |
--- src/sys/kern/vfs_subr.c 2011/12/02 12:32:38 1.426
+++ src/sys/kern/vfs_subr.c 2012/01/29 06:32:43 1.427
@@ -1,1308 +1,1308 @@ | @@ -1,1308 +1,1308 @@ | |||
1 | /* $NetBSD: vfs_subr.c,v 1.426 2011/12/02 12:32:38 yamt Exp $ */ | 1 | /* $NetBSD: vfs_subr.c,v 1.427 2012/01/29 06:32:43 dholland Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | 8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | |
9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. | 9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * | 19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | * POSSIBILITY OF SUCH DAMAGE. | 30 | * POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | /* | 33 | /* | |
34 | * Copyright (c) 1989, 1993 | 34 | * Copyright (c) 1989, 1993 | |
35 | * The Regents of the University of California. All rights reserved. | 35 | * The Regents of the University of California. All rights reserved. | |
36 | * (c) UNIX System Laboratories, Inc. | 36 | * (c) UNIX System Laboratories, Inc. | |
37 | * All or some portions of this file are derived from material licensed | 37 | * All or some portions of this file are derived from material licensed | |
38 | * to the University of California by American Telephone and Telegraph | 38 | * to the University of California by American Telephone and Telegraph | |
39 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | 39 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | |
40 | * the permission of UNIX System Laboratories, Inc. | 40 | * the permission of UNIX System Laboratories, Inc. | |
41 | * | 41 | * | |
42 | * Redistribution and use in source and binary forms, with or without | 42 | * Redistribution and use in source and binary forms, with or without | |
43 | * modification, are permitted provided that the following conditions | 43 | * modification, are permitted provided that the following conditions | |
44 | * are met: | 44 | * are met: | |
45 | * 1. Redistributions of source code must retain the above copyright | 45 | * 1. Redistributions of source code must retain the above copyright | |
46 | * notice, this list of conditions and the following disclaimer. | 46 | * notice, this list of conditions and the following disclaimer. | |
47 | * 2. Redistributions in binary form must reproduce the above copyright | 47 | * 2. Redistributions in binary form must reproduce the above copyright | |
48 | * notice, this list of conditions and the following disclaimer in the | 48 | * notice, this list of conditions and the following disclaimer in the | |
49 | * documentation and/or other materials provided with the distribution. | 49 | * documentation and/or other materials provided with the distribution. | |
50 | * 3. Neither the name of the University nor the names of its contributors | 50 | * 3. Neither the name of the University nor the names of its contributors | |
51 | * may be used to endorse or promote products derived from this software | 51 | * may be used to endorse or promote products derived from this software | |
52 | * without specific prior written permission. | 52 | * without specific prior written permission. | |
53 | * | 53 | * | |
54 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 54 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
55 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 55 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
56 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 56 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
64 | * SUCH DAMAGE. | 64 | * SUCH DAMAGE. | |
65 | * | 65 | * | |
66 | * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 | 66 | * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 | |
67 | */ | 67 | */ | |
68 | 68 | |||
69 | #include <sys/cdefs.h> | 69 | #include <sys/cdefs.h> | |
70 | __KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.426 2011/12/02 12:32:38 yamt Exp $"); | 70 | __KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.427 2012/01/29 06:32:43 dholland Exp $"); | |
71 | 71 | |||
72 | #include "opt_ddb.h" | 72 | #include "opt_ddb.h" | |
73 | #include "opt_compat_netbsd.h" | 73 | #include "opt_compat_netbsd.h" | |
74 | #include "opt_compat_43.h" | 74 | #include "opt_compat_43.h" | |
75 | 75 | |||
76 | #include <sys/param.h> | 76 | #include <sys/param.h> | |
77 | #include <sys/systm.h> | 77 | #include <sys/systm.h> | |
78 | #include <sys/conf.h> | 78 | #include <sys/conf.h> | |
79 | #include <sys/dirent.h> | 79 | #include <sys/dirent.h> | |
80 | #include <sys/filedesc.h> | 80 | #include <sys/filedesc.h> | |
81 | #include <sys/kernel.h> | 81 | #include <sys/kernel.h> | |
82 | #include <sys/mount.h> | 82 | #include <sys/mount.h> | |
83 | #include <sys/vnode.h> | 83 | #include <sys/vnode.h> | |
84 | #include <sys/stat.h> | 84 | #include <sys/stat.h> | |
85 | #include <sys/sysctl.h> | 85 | #include <sys/sysctl.h> | |
86 | #include <sys/namei.h> | 86 | #include <sys/namei.h> | |
87 | #include <sys/buf.h> | 87 | #include <sys/buf.h> | |
88 | #include <sys/errno.h> | 88 | #include <sys/errno.h> | |
89 | #include <sys/kmem.h> | 89 | #include <sys/kmem.h> | |
90 | #include <sys/syscallargs.h> | 90 | #include <sys/syscallargs.h> | |
91 | #include <sys/kauth.h> | 91 | #include <sys/kauth.h> | |
92 | #include <sys/module.h> | 92 | #include <sys/module.h> | |
93 | 93 | |||
94 | #include <miscfs/genfs/genfs.h> | 94 | #include <miscfs/genfs/genfs.h> | |
95 | #include <miscfs/syncfs/syncfs.h> | 95 | #include <miscfs/syncfs/syncfs.h> | |
96 | #include <miscfs/specfs/specdev.h> | 96 | #include <miscfs/specfs/specdev.h> | |
97 | #include <uvm/uvm_ddb.h> | 97 | #include <uvm/uvm_ddb.h> | |
98 | 98 | |||
99 | const enum vtype iftovt_tab[16] = { | 99 | const enum vtype iftovt_tab[16] = { | |
100 | VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, | 100 | VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, | |
101 | VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, | 101 | VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, | |
102 | }; | 102 | }; | |
103 | const int vttoif_tab[9] = { | 103 | const int vttoif_tab[9] = { | |
104 | 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, | 104 | 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, | |
105 | S_IFSOCK, S_IFIFO, S_IFMT, | 105 | S_IFSOCK, S_IFIFO, S_IFMT, | |
106 | }; | 106 | }; | |
107 | 107 | |||
108 | /* | 108 | /* | |
109 | * Insq/Remq for the vnode usage lists. | 109 | * Insq/Remq for the vnode usage lists. | |
110 | */ | 110 | */ | |
111 | #define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs) | 111 | #define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs) | |
112 | #define bufremvn(bp) { \ | 112 | #define bufremvn(bp) { \ | |
113 | LIST_REMOVE(bp, b_vnbufs); \ | 113 | LIST_REMOVE(bp, b_vnbufs); \ | |
114 | (bp)->b_vnbufs.le_next = NOLIST; \ | 114 | (bp)->b_vnbufs.le_next = NOLIST; \ | |
115 | } | 115 | } | |
116 | 116 | |||
117 | int doforce = 1; /* 1 => permit forcible unmounting */ | 117 | int doforce = 1; /* 1 => permit forcible unmounting */ | |
118 | int prtactive = 0; /* 1 => print out reclaim of active vnodes */ | 118 | int prtactive = 0; /* 1 => print out reclaim of active vnodes */ | |
119 | 119 | |||
120 | /* | 120 | /* | |
121 | * Local declarations. | 121 | * Local declarations. | |
122 | */ | 122 | */ | |
123 | 123 | |||
124 | static int getdevvp(dev_t, vnode_t **, enum vtype); | 124 | static int getdevvp(dev_t, vnode_t **, enum vtype); | |
125 | 125 | |||
126 | /* | 126 | /* | |
127 | * Initialize the vnode management data structures. | 127 | * Initialize the vnode management data structures. | |
128 | */ | 128 | */ | |
129 | void | 129 | void | |
130 | vntblinit(void) | 130 | vntblinit(void) | |
131 | { | 131 | { | |
132 | 132 | |||
133 | vn_initialize_syncerd(); | 133 | vn_initialize_syncerd(); | |
134 | vfs_vnode_sysinit(); | 134 | vfs_vnode_sysinit(); | |
135 | vfs_mount_sysinit(); | 135 | vfs_mount_sysinit(); | |
136 | } | 136 | } | |
137 | 137 | |||
138 | /* | 138 | /* | |
139 | * Flush out and invalidate all buffers associated with a vnode. | 139 | * Flush out and invalidate all buffers associated with a vnode. | |
140 | * Called with the underlying vnode locked, which should prevent new dirty | 140 | * Called with the underlying vnode locked, which should prevent new dirty | |
141 | * buffers from being queued. | 141 | * buffers from being queued. | |
142 | */ | 142 | */ | |
143 | int | 143 | int | |
144 | vinvalbuf(struct vnode *vp, int flags, kauth_cred_t cred, struct lwp *l, | 144 | vinvalbuf(struct vnode *vp, int flags, kauth_cred_t cred, struct lwp *l, | |
145 | bool catch, int slptimeo) | 145 | bool catch, int slptimeo) | |
146 | { | 146 | { | |
147 | struct buf *bp, *nbp; | 147 | struct buf *bp, *nbp; | |
148 | int error; | 148 | int error; | |
149 | int flushflags = PGO_ALLPAGES | PGO_FREE | PGO_SYNCIO | | 149 | int flushflags = PGO_ALLPAGES | PGO_FREE | PGO_SYNCIO | | |
150 | (flags & V_SAVE ? PGO_CLEANIT | PGO_RECLAIM : 0); | 150 | (flags & V_SAVE ? PGO_CLEANIT | PGO_RECLAIM : 0); | |
151 | 151 | |||
152 | /* XXXUBC this doesn't look at flags or slp* */ | 152 | /* XXXUBC this doesn't look at flags or slp* */ | |
153 | mutex_enter(vp->v_interlock); | 153 | mutex_enter(vp->v_interlock); | |
154 | error = VOP_PUTPAGES(vp, 0, 0, flushflags); | 154 | error = VOP_PUTPAGES(vp, 0, 0, flushflags); | |
155 | if (error) { | 155 | if (error) { | |
156 | return error; | 156 | return error; | |
157 | } | 157 | } | |
158 | 158 | |||
159 | if (flags & V_SAVE) { | 159 | if (flags & V_SAVE) { | |
160 | error = VOP_FSYNC(vp, cred, FSYNC_WAIT|FSYNC_RECLAIM, 0, 0); | 160 | error = VOP_FSYNC(vp, cred, FSYNC_WAIT|FSYNC_RECLAIM, 0, 0); | |
161 | if (error) | 161 | if (error) | |
162 | return (error); | 162 | return (error); | |
163 | KASSERT(LIST_EMPTY(&vp->v_dirtyblkhd)); | 163 | KASSERT(LIST_EMPTY(&vp->v_dirtyblkhd)); | |
164 | } | 164 | } | |
165 | 165 | |||
166 | mutex_enter(&bufcache_lock); | 166 | mutex_enter(&bufcache_lock); | |
167 | restart: | 167 | restart: | |
168 | for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { | 168 | for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { | |
169 | KASSERT(bp->b_vp == vp); | 169 | KASSERT(bp->b_vp == vp); | |
170 | nbp = LIST_NEXT(bp, b_vnbufs); | 170 | nbp = LIST_NEXT(bp, b_vnbufs); | |
171 | error = bbusy(bp, catch, slptimeo, NULL); | 171 | error = bbusy(bp, catch, slptimeo, NULL); | |
172 | if (error != 0) { | 172 | if (error != 0) { | |
173 | if (error == EPASSTHROUGH) | 173 | if (error == EPASSTHROUGH) | |
174 | goto restart; | 174 | goto restart; | |
175 | mutex_exit(&bufcache_lock); | 175 | mutex_exit(&bufcache_lock); | |
176 | return (error); | 176 | return (error); | |
177 | } | 177 | } | |
178 | brelsel(bp, BC_INVAL | BC_VFLUSH); | 178 | brelsel(bp, BC_INVAL | BC_VFLUSH); | |
179 | } | 179 | } | |
180 | 180 | |||
181 | for (bp = LIST_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { | 181 | for (bp = LIST_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { | |
182 | KASSERT(bp->b_vp == vp); | 182 | KASSERT(bp->b_vp == vp); | |
183 | nbp = LIST_NEXT(bp, b_vnbufs); | 183 | nbp = LIST_NEXT(bp, b_vnbufs); | |
184 | error = bbusy(bp, catch, slptimeo, NULL); | 184 | error = bbusy(bp, catch, slptimeo, NULL); | |
185 | if (error != 0) { | 185 | if (error != 0) { | |
186 | if (error == EPASSTHROUGH) | 186 | if (error == EPASSTHROUGH) | |
187 | goto restart; | 187 | goto restart; | |
188 | mutex_exit(&bufcache_lock); | 188 | mutex_exit(&bufcache_lock); | |
189 | return (error); | 189 | return (error); | |
190 | } | 190 | } | |
191 | /* | 191 | /* | |
192 | * XXX Since there are no node locks for NFS, I believe | 192 | * XXX Since there are no node locks for NFS, I believe | |
193 | * there is a slight chance that a delayed write will | 193 | * there is a slight chance that a delayed write will | |
194 | * occur while sleeping just above, so check for it. | 194 | * occur while sleeping just above, so check for it. | |
195 | */ | 195 | */ | |
196 | if ((bp->b_oflags & BO_DELWRI) && (flags & V_SAVE)) { | 196 | if ((bp->b_oflags & BO_DELWRI) && (flags & V_SAVE)) { | |
197 | #ifdef DEBUG | 197 | #ifdef DEBUG | |
198 | printf("buffer still DELWRI\n"); | 198 | printf("buffer still DELWRI\n"); | |
199 | #endif | 199 | #endif | |
200 | bp->b_cflags |= BC_BUSY | BC_VFLUSH; | 200 | bp->b_cflags |= BC_BUSY | BC_VFLUSH; | |
201 | mutex_exit(&bufcache_lock); | 201 | mutex_exit(&bufcache_lock); | |
202 | VOP_BWRITE(bp->b_vp, bp); | 202 | VOP_BWRITE(bp->b_vp, bp); | |
203 | mutex_enter(&bufcache_lock); | 203 | mutex_enter(&bufcache_lock); | |
204 | goto restart; | 204 | goto restart; | |
205 | } | 205 | } | |
206 | brelsel(bp, BC_INVAL | BC_VFLUSH); | 206 | brelsel(bp, BC_INVAL | BC_VFLUSH); | |
207 | } | 207 | } | |
208 | 208 | |||
209 | #ifdef DIAGNOSTIC | 209 | #ifdef DIAGNOSTIC | |
210 | if (!LIST_EMPTY(&vp->v_cleanblkhd) || !LIST_EMPTY(&vp->v_dirtyblkhd)) | 210 | if (!LIST_EMPTY(&vp->v_cleanblkhd) || !LIST_EMPTY(&vp->v_dirtyblkhd)) | |
211 | panic("vinvalbuf: flush failed, vp %p", vp); | 211 | panic("vinvalbuf: flush failed, vp %p", vp); | |
212 | #endif | 212 | #endif | |
213 | 213 | |||
214 | mutex_exit(&bufcache_lock); | 214 | mutex_exit(&bufcache_lock); | |
215 | 215 | |||
216 | return (0); | 216 | return (0); | |
217 | } | 217 | } | |
218 | 218 | |||
219 | /* | 219 | /* | |
220 | * Destroy any in core blocks past the truncation length. | 220 | * Destroy any in core blocks past the truncation length. | |
221 | * Called with the underlying vnode locked, which should prevent new dirty | 221 | * Called with the underlying vnode locked, which should prevent new dirty | |
222 | * buffers from being queued. | 222 | * buffers from being queued. | |
223 | */ | 223 | */ | |
224 | int | 224 | int | |
225 | vtruncbuf(struct vnode *vp, daddr_t lbn, bool catch, int slptimeo) | 225 | vtruncbuf(struct vnode *vp, daddr_t lbn, bool catch, int slptimeo) | |
226 | { | 226 | { | |
227 | struct buf *bp, *nbp; | 227 | struct buf *bp, *nbp; | |
228 | int error; | 228 | int error; | |
229 | voff_t off; | 229 | voff_t off; | |
230 | 230 | |||
231 | off = round_page((voff_t)lbn << vp->v_mount->mnt_fs_bshift); | 231 | off = round_page((voff_t)lbn << vp->v_mount->mnt_fs_bshift); | |
232 | mutex_enter(vp->v_interlock); | 232 | mutex_enter(vp->v_interlock); | |
233 | error = VOP_PUTPAGES(vp, off, 0, PGO_FREE | PGO_SYNCIO); | 233 | error = VOP_PUTPAGES(vp, off, 0, PGO_FREE | PGO_SYNCIO); | |
234 | if (error) { | 234 | if (error) { | |
235 | return error; | 235 | return error; | |
236 | } | 236 | } | |
237 | 237 | |||
238 | mutex_enter(&bufcache_lock); | 238 | mutex_enter(&bufcache_lock); | |
239 | restart: | 239 | restart: | |
240 | for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { | 240 | for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { | |
241 | KASSERT(bp->b_vp == vp); | 241 | KASSERT(bp->b_vp == vp); | |
242 | nbp = LIST_NEXT(bp, b_vnbufs); | 242 | nbp = LIST_NEXT(bp, b_vnbufs); | |
243 | if (bp->b_lblkno < lbn) | 243 | if (bp->b_lblkno < lbn) | |
244 | continue; | 244 | continue; | |
245 | error = bbusy(bp, catch, slptimeo, NULL); | 245 | error = bbusy(bp, catch, slptimeo, NULL); | |
246 | if (error != 0) { | 246 | if (error != 0) { | |
247 | if (error == EPASSTHROUGH) | 247 | if (error == EPASSTHROUGH) | |
248 | goto restart; | 248 | goto restart; | |
249 | mutex_exit(&bufcache_lock); | 249 | mutex_exit(&bufcache_lock); | |
250 | return (error); | 250 | return (error); | |
251 | } | 251 | } | |
252 | brelsel(bp, BC_INVAL | BC_VFLUSH); | 252 | brelsel(bp, BC_INVAL | BC_VFLUSH); | |
253 | } | 253 | } | |
254 | 254 | |||
255 | for (bp = LIST_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { | 255 | for (bp = LIST_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { | |
256 | KASSERT(bp->b_vp == vp); | 256 | KASSERT(bp->b_vp == vp); | |
257 | nbp = LIST_NEXT(bp, b_vnbufs); | 257 | nbp = LIST_NEXT(bp, b_vnbufs); | |
258 | if (bp->b_lblkno < lbn) | 258 | if (bp->b_lblkno < lbn) | |
259 | continue; | 259 | continue; | |
260 | error = bbusy(bp, catch, slptimeo, NULL); | 260 | error = bbusy(bp, catch, slptimeo, NULL); | |
261 | if (error != 0) { | 261 | if (error != 0) { | |
262 | if (error == EPASSTHROUGH) | 262 | if (error == EPASSTHROUGH) | |
263 | goto restart; | 263 | goto restart; | |
264 | mutex_exit(&bufcache_lock); | 264 | mutex_exit(&bufcache_lock); | |
265 | return (error); | 265 | return (error); | |
266 | } | 266 | } | |
267 | brelsel(bp, BC_INVAL | BC_VFLUSH); | 267 | brelsel(bp, BC_INVAL | BC_VFLUSH); | |
268 | } | 268 | } | |
269 | mutex_exit(&bufcache_lock); | 269 | mutex_exit(&bufcache_lock); | |
270 | 270 | |||
271 | return (0); | 271 | return (0); | |
272 | } | 272 | } | |
273 | 273 | |||
274 | /* | 274 | /* | |
275 | * Flush all dirty buffers from a vnode. | 275 | * Flush all dirty buffers from a vnode. | |
276 | * Called with the underlying vnode locked, which should prevent new dirty | 276 | * Called with the underlying vnode locked, which should prevent new dirty | |
277 | * buffers from being queued. | 277 | * buffers from being queued. | |
278 | */ | 278 | */ | |
279 | int | 279 | int | |
280 | vflushbuf(struct vnode *vp, int sync) | 280 | vflushbuf(struct vnode *vp, int sync) | |
281 | { | 281 | { | |
282 | struct buf *bp, *nbp; | 282 | struct buf *bp, *nbp; | |
283 | int error, flags = PGO_CLEANIT | PGO_ALLPAGES | (sync ? PGO_SYNCIO : 0); | 283 | int error, flags = PGO_CLEANIT | PGO_ALLPAGES | (sync ? PGO_SYNCIO : 0); | |
284 | bool dirty; | 284 | bool dirty; | |
285 | 285 | |||
286 | mutex_enter(vp->v_interlock); | 286 | mutex_enter(vp->v_interlock); | |
287 | (void) VOP_PUTPAGES(vp, 0, 0, flags); | 287 | (void) VOP_PUTPAGES(vp, 0, 0, flags); | |
288 | 288 | |||
289 | loop: | 289 | loop: | |
290 | mutex_enter(&bufcache_lock); | 290 | mutex_enter(&bufcache_lock); | |
291 | for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { | 291 | for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { | |
292 | KASSERT(bp->b_vp == vp); | 292 | KASSERT(bp->b_vp == vp); | |
293 | nbp = LIST_NEXT(bp, b_vnbufs); | 293 | nbp = LIST_NEXT(bp, b_vnbufs); | |
294 | if ((bp->b_cflags & BC_BUSY)) | 294 | if ((bp->b_cflags & BC_BUSY)) | |
295 | continue; | 295 | continue; | |
296 | if ((bp->b_oflags & BO_DELWRI) == 0) | 296 | if ((bp->b_oflags & BO_DELWRI) == 0) | |
297 | panic("vflushbuf: not dirty, bp %p", bp); | 297 | panic("vflushbuf: not dirty, bp %p", bp); | |
298 | bp->b_cflags |= BC_BUSY | BC_VFLUSH; | 298 | bp->b_cflags |= BC_BUSY | BC_VFLUSH; | |
299 | mutex_exit(&bufcache_lock); | 299 | mutex_exit(&bufcache_lock); | |
300 | /* | 300 | /* | |
301 | * Wait for I/O associated with indirect blocks to complete, | 301 | * Wait for I/O associated with indirect blocks to complete, | |
302 | * since there is no way to quickly wait for them below. | 302 | * since there is no way to quickly wait for them below. | |
303 | */ | 303 | */ | |
304 | if (bp->b_vp == vp || sync == 0) | 304 | if (bp->b_vp == vp || sync == 0) | |
305 | (void) bawrite(bp); | 305 | (void) bawrite(bp); | |
306 | else { | 306 | else { | |
307 | error = bwrite(bp); | 307 | error = bwrite(bp); | |
308 | if (error) | 308 | if (error) | |
309 | return error; | 309 | return error; | |
310 | } | 310 | } | |
311 | goto loop; | 311 | goto loop; | |
312 | } | 312 | } | |
313 | mutex_exit(&bufcache_lock); | 313 | mutex_exit(&bufcache_lock); | |
314 | 314 | |||
315 | if (sync == 0) | 315 | if (sync == 0) | |
316 | return 0; | 316 | return 0; | |
317 | 317 | |||
318 | mutex_enter(vp->v_interlock); | 318 | mutex_enter(vp->v_interlock); | |
319 | while (vp->v_numoutput != 0) | 319 | while (vp->v_numoutput != 0) | |
320 | cv_wait(&vp->v_cv, vp->v_interlock); | 320 | cv_wait(&vp->v_cv, vp->v_interlock); | |
321 | dirty = !LIST_EMPTY(&vp->v_dirtyblkhd); | 321 | dirty = !LIST_EMPTY(&vp->v_dirtyblkhd); | |
322 | mutex_exit(vp->v_interlock); | 322 | mutex_exit(vp->v_interlock); | |
323 | 323 | |||
324 | if (dirty) { | 324 | if (dirty) { | |
325 | vprint("vflushbuf: dirty", vp); | 325 | vprint("vflushbuf: dirty", vp); | |
326 | goto loop; | 326 | goto loop; | |
327 | } | 327 | } | |
328 | 328 | |||
329 | return 0; | 329 | return 0; | |
330 | } | 330 | } | |
331 | 331 | |||
332 | /* | 332 | /* | |
333 | * Create a vnode for a block device. | 333 | * Create a vnode for a block device. | |
334 | * Used for root filesystem and swap areas. | 334 | * Used for root filesystem and swap areas. | |
335 | * Also used for memory file system special devices. | 335 | * Also used for memory file system special devices. | |
336 | */ | 336 | */ | |
337 | int | 337 | int | |
338 | bdevvp(dev_t dev, vnode_t **vpp) | 338 | bdevvp(dev_t dev, vnode_t **vpp) | |
339 | { | 339 | { | |
340 | 340 | |||
341 | return (getdevvp(dev, vpp, VBLK)); | 341 | return (getdevvp(dev, vpp, VBLK)); | |
342 | } | 342 | } | |
343 | 343 | |||
344 | /* | 344 | /* | |
345 | * Create a vnode for a character device. | 345 | * Create a vnode for a character device. | |
346 | * Used for kernfs and some console handling. | 346 | * Used for kernfs and some console handling. | |
347 | */ | 347 | */ | |
348 | int | 348 | int | |
349 | cdevvp(dev_t dev, vnode_t **vpp) | 349 | cdevvp(dev_t dev, vnode_t **vpp) | |
350 | { | 350 | { | |
351 | 351 | |||
352 | return (getdevvp(dev, vpp, VCHR)); | 352 | return (getdevvp(dev, vpp, VCHR)); | |
353 | } | 353 | } | |
354 | 354 | |||
355 | /* | 355 | /* | |
356 | * Associate a buffer with a vnode. There must already be a hold on | 356 | * Associate a buffer with a vnode. There must already be a hold on | |
357 | * the vnode. | 357 | * the vnode. | |
358 | */ | 358 | */ | |
359 | void | 359 | void | |
360 | bgetvp(struct vnode *vp, struct buf *bp) | 360 | bgetvp(struct vnode *vp, struct buf *bp) | |
361 | { | 361 | { | |
362 | 362 | |||
363 | KASSERT(bp->b_vp == NULL); | 363 | KASSERT(bp->b_vp == NULL); | |
364 | KASSERT(bp->b_objlock == &buffer_lock); | 364 | KASSERT(bp->b_objlock == &buffer_lock); | |
365 | KASSERT(mutex_owned(vp->v_interlock)); | 365 | KASSERT(mutex_owned(vp->v_interlock)); | |
366 | KASSERT(mutex_owned(&bufcache_lock)); | 366 | KASSERT(mutex_owned(&bufcache_lock)); | |
367 | KASSERT((bp->b_cflags & BC_BUSY) != 0); | 367 | KASSERT((bp->b_cflags & BC_BUSY) != 0); | |
368 | KASSERT(!cv_has_waiters(&bp->b_done)); | 368 | KASSERT(!cv_has_waiters(&bp->b_done)); | |
369 | 369 | |||
370 | vholdl(vp); | 370 | vholdl(vp); | |
371 | bp->b_vp = vp; | 371 | bp->b_vp = vp; | |
372 | if (vp->v_type == VBLK || vp->v_type == VCHR) | 372 | if (vp->v_type == VBLK || vp->v_type == VCHR) | |
373 | bp->b_dev = vp->v_rdev; | 373 | bp->b_dev = vp->v_rdev; | |
374 | else | 374 | else | |
375 | bp->b_dev = NODEV; | 375 | bp->b_dev = NODEV; | |
376 | 376 | |||
377 | /* | 377 | /* | |
378 | * Insert onto list for new vnode. | 378 | * Insert onto list for new vnode. | |
379 | */ | 379 | */ | |
380 | bufinsvn(bp, &vp->v_cleanblkhd); | 380 | bufinsvn(bp, &vp->v_cleanblkhd); | |
381 | bp->b_objlock = vp->v_interlock; | 381 | bp->b_objlock = vp->v_interlock; | |
382 | } | 382 | } | |
383 | 383 | |||
384 | /* | 384 | /* | |
385 | * Disassociate a buffer from a vnode. | 385 | * Disassociate a buffer from a vnode. | |
386 | */ | 386 | */ | |
387 | void | 387 | void | |
388 | brelvp(struct buf *bp) | 388 | brelvp(struct buf *bp) | |
389 | { | 389 | { | |
390 | struct vnode *vp = bp->b_vp; | 390 | struct vnode *vp = bp->b_vp; | |
391 | 391 | |||
392 | KASSERT(vp != NULL); | 392 | KASSERT(vp != NULL); | |
393 | KASSERT(bp->b_objlock == vp->v_interlock); | 393 | KASSERT(bp->b_objlock == vp->v_interlock); | |
394 | KASSERT(mutex_owned(vp->v_interlock)); | 394 | KASSERT(mutex_owned(vp->v_interlock)); | |
395 | KASSERT(mutex_owned(&bufcache_lock)); | 395 | KASSERT(mutex_owned(&bufcache_lock)); | |
396 | KASSERT((bp->b_cflags & BC_BUSY) != 0); | 396 | KASSERT((bp->b_cflags & BC_BUSY) != 0); | |
397 | KASSERT(!cv_has_waiters(&bp->b_done)); | 397 | KASSERT(!cv_has_waiters(&bp->b_done)); | |
398 | 398 | |||
399 | /* | 399 | /* | |
400 | * Delete from old vnode list, if on one. | 400 | * Delete from old vnode list, if on one. | |
401 | */ | 401 | */ | |
402 | if (LIST_NEXT(bp, b_vnbufs) != NOLIST) | 402 | if (LIST_NEXT(bp, b_vnbufs) != NOLIST) | |
403 | bufremvn(bp); | 403 | bufremvn(bp); | |
404 | 404 | |||
405 | if (vp->v_uobj.uo_npages == 0 && (vp->v_iflag & VI_ONWORKLST) && | 405 | if (vp->v_uobj.uo_npages == 0 && (vp->v_iflag & VI_ONWORKLST) && | |
406 | LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { | 406 | LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { | |
407 | vp->v_iflag &= ~VI_WRMAPDIRTY; | 407 | vp->v_iflag &= ~VI_WRMAPDIRTY; | |
408 | vn_syncer_remove_from_worklist(vp); | 408 | vn_syncer_remove_from_worklist(vp); | |
409 | } | 409 | } | |
410 | 410 | |||
411 | bp->b_objlock = &buffer_lock; | 411 | bp->b_objlock = &buffer_lock; | |
412 | bp->b_vp = NULL; | 412 | bp->b_vp = NULL; | |
413 | holdrelel(vp); | 413 | holdrelel(vp); | |
414 | } | 414 | } | |
415 | 415 | |||
416 | /* | 416 | /* | |
417 | * Reassign a buffer from one vnode list to another. | 417 | * Reassign a buffer from one vnode list to another. | |
418 | * The list reassignment must be within the same vnode. | 418 | * The list reassignment must be within the same vnode. | |
419 | * Used to assign file specific control information | 419 | * Used to assign file specific control information | |
420 | * (indirect blocks) to the list to which they belong. | 420 | * (indirect blocks) to the list to which they belong. | |
421 | */ | 421 | */ | |
422 | void | 422 | void | |
423 | reassignbuf(struct buf *bp, struct vnode *vp) | 423 | reassignbuf(struct buf *bp, struct vnode *vp) | |
424 | { | 424 | { | |
425 | struct buflists *listheadp; | 425 | struct buflists *listheadp; | |
426 | int delayx; | 426 | int delayx; | |
427 | 427 | |||
428 | KASSERT(mutex_owned(&bufcache_lock)); | 428 | KASSERT(mutex_owned(&bufcache_lock)); | |
429 | KASSERT(bp->b_objlock == vp->v_interlock); | 429 | KASSERT(bp->b_objlock == vp->v_interlock); | |
430 | KASSERT(mutex_owned(vp->v_interlock)); | 430 | KASSERT(mutex_owned(vp->v_interlock)); | |
431 | KASSERT((bp->b_cflags & BC_BUSY) != 0); | 431 | KASSERT((bp->b_cflags & BC_BUSY) != 0); | |
432 | 432 | |||
433 | /* | 433 | /* | |
434 | * Delete from old vnode list, if on one. | 434 | * Delete from old vnode list, if on one. | |
435 | */ | 435 | */ | |
436 | if (LIST_NEXT(bp, b_vnbufs) != NOLIST) | 436 | if (LIST_NEXT(bp, b_vnbufs) != NOLIST) | |
437 | bufremvn(bp); | 437 | bufremvn(bp); | |
438 | 438 | |||
439 | /* | 439 | /* | |
440 | * If dirty, put on list of dirty buffers; | 440 | * If dirty, put on list of dirty buffers; | |
441 | * otherwise insert onto list of clean buffers. | 441 | * otherwise insert onto list of clean buffers. | |
442 | */ | 442 | */ | |
443 | if ((bp->b_oflags & BO_DELWRI) == 0) { | 443 | if ((bp->b_oflags & BO_DELWRI) == 0) { | |
444 | listheadp = &vp->v_cleanblkhd; | 444 | listheadp = &vp->v_cleanblkhd; | |
445 | if (vp->v_uobj.uo_npages == 0 && | 445 | if (vp->v_uobj.uo_npages == 0 && | |
446 | (vp->v_iflag & VI_ONWORKLST) && | 446 | (vp->v_iflag & VI_ONWORKLST) && | |
447 | LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { | 447 | LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { | |
448 | vp->v_iflag &= ~VI_WRMAPDIRTY; | 448 | vp->v_iflag &= ~VI_WRMAPDIRTY; | |
449 | vn_syncer_remove_from_worklist(vp); | 449 | vn_syncer_remove_from_worklist(vp); | |
450 | } | 450 | } | |
451 | } else { | 451 | } else { | |
452 | listheadp = &vp->v_dirtyblkhd; | 452 | listheadp = &vp->v_dirtyblkhd; | |
453 | if ((vp->v_iflag & VI_ONWORKLST) == 0) { | 453 | if ((vp->v_iflag & VI_ONWORKLST) == 0) { | |
454 | switch (vp->v_type) { | 454 | switch (vp->v_type) { | |
455 | case VDIR: | 455 | case VDIR: | |
456 | delayx = dirdelay; | 456 | delayx = dirdelay; | |
457 | break; | 457 | break; | |
458 | case VBLK: | 458 | case VBLK: | |
459 | if (vp->v_specmountpoint != NULL) { | 459 | if (vp->v_specmountpoint != NULL) { | |
460 | delayx = metadelay; | 460 | delayx = metadelay; | |
461 | break; | 461 | break; | |
462 | } | 462 | } | |
463 | /* fall through */ | 463 | /* fall through */ | |
464 | default: | 464 | default: | |
465 | delayx = filedelay; | 465 | delayx = filedelay; | |
466 | break; | 466 | break; | |
467 | } | 467 | } | |
468 | if (!vp->v_mount || | 468 | if (!vp->v_mount || | |
469 | (vp->v_mount->mnt_flag & MNT_ASYNC) == 0) | 469 | (vp->v_mount->mnt_flag & MNT_ASYNC) == 0) | |
470 | vn_syncer_add_to_worklist(vp, delayx); | 470 | vn_syncer_add_to_worklist(vp, delayx); | |
471 | } | 471 | } | |
472 | } | 472 | } | |
473 | bufinsvn(bp, listheadp); | 473 | bufinsvn(bp, listheadp); | |
474 | } | 474 | } | |
475 | 475 | |||
476 | /* | 476 | /* | |
477 | * Create a vnode for a device. | 477 | * Create a vnode for a device. | |
478 | * Used by bdevvp (block device) for root file system etc., | 478 | * Used by bdevvp (block device) for root file system etc., | |
479 | * and by cdevvp (character device) for console and kernfs. | 479 | * and by cdevvp (character device) for console and kernfs. | |
480 | */ | 480 | */ | |
481 | static int | 481 | static int | |
482 | getdevvp(dev_t dev, vnode_t **vpp, enum vtype type) | 482 | getdevvp(dev_t dev, vnode_t **vpp, enum vtype type) | |
483 | { | 483 | { | |
484 | vnode_t *vp; | 484 | vnode_t *vp; | |
485 | vnode_t *nvp; | 485 | vnode_t *nvp; | |
486 | int error; | 486 | int error; | |
487 | 487 | |||
488 | if (dev == NODEV) { | 488 | if (dev == NODEV) { | |
489 | *vpp = NULL; | 489 | *vpp = NULL; | |
490 | return (0); | 490 | return (0); | |
491 | } | 491 | } | |
492 | error = getnewvnode(VT_NON, NULL, spec_vnodeop_p, NULL, &nvp); | 492 | error = getnewvnode(VT_NON, NULL, spec_vnodeop_p, NULL, &nvp); | |
493 | if (error) { | 493 | if (error) { | |
494 | *vpp = NULL; | 494 | *vpp = NULL; | |
495 | return (error); | 495 | return (error); | |
496 | } | 496 | } | |
497 | vp = nvp; | 497 | vp = nvp; | |
498 | vp->v_type = type; | 498 | vp->v_type = type; | |
499 | vp->v_vflag |= VV_MPSAFE; | 499 | vp->v_vflag |= VV_MPSAFE; | |
500 | uvm_vnp_setsize(vp, 0); | 500 | uvm_vnp_setsize(vp, 0); | |
501 | spec_node_init(vp, dev); | 501 | spec_node_init(vp, dev); | |
502 | *vpp = vp; | 502 | *vpp = vp; | |
503 | return (0); | 503 | return (0); | |
504 | } | 504 | } | |
505 | 505 | |||
506 | /* | 506 | /* | |
507 | * Lookup a vnode by device number and return it referenced. | 507 | * Lookup a vnode by device number and return it referenced. | |
508 | */ | 508 | */ | |
509 | int | 509 | int | |
510 | vfinddev(dev_t dev, enum vtype type, vnode_t **vpp) | 510 | vfinddev(dev_t dev, enum vtype type, vnode_t **vpp) | |
511 | { | 511 | { | |
512 | vnode_t *vp; | 512 | vnode_t *vp; | |
513 | 513 | |||
514 | mutex_enter(&device_lock); | 514 | mutex_enter(&device_lock); | |
515 | for (vp = specfs_hash[SPECHASH(dev)]; vp; vp = vp->v_specnext) { | 515 | for (vp = specfs_hash[SPECHASH(dev)]; vp; vp = vp->v_specnext) { | |
516 | if (type == vp->v_type && dev == vp->v_rdev) | 516 | if (type == vp->v_type && dev == vp->v_rdev) | |
517 | break; | 517 | break; | |
518 | } | 518 | } | |
519 | if (vp == NULL) { | 519 | if (vp == NULL) { | |
520 | mutex_exit(&device_lock); | 520 | mutex_exit(&device_lock); | |
521 | return 0; | 521 | return 0; | |
522 | } | 522 | } | |
523 | mutex_enter(vp->v_interlock); | 523 | mutex_enter(vp->v_interlock); | |
524 | mutex_exit(&device_lock); | 524 | mutex_exit(&device_lock); | |
525 | if (vget(vp, 0) != 0) | 525 | if (vget(vp, 0) != 0) | |
526 | return 0; | 526 | return 0; | |
527 | *vpp = vp; | 527 | *vpp = vp; | |
528 | return 1; | 528 | return 1; | |
529 | } | 529 | } | |
530 | 530 | |||
531 | /* | 531 | /* | |
532 | * Revoke all the vnodes corresponding to the specified minor number | 532 | * Revoke all the vnodes corresponding to the specified minor number | |
533 | * range (endpoints inclusive) of the specified major. | 533 | * range (endpoints inclusive) of the specified major. | |
534 | */ | 534 | */ | |
535 | void | 535 | void | |
536 | vdevgone(int maj, int minl, int minh, enum vtype type) | 536 | vdevgone(int maj, int minl, int minh, enum vtype type) | |
537 | { | 537 | { | |
538 | vnode_t *vp, **vpp; | 538 | vnode_t *vp, **vpp; | |
539 | dev_t dev; | 539 | dev_t dev; | |
540 | int mn; | 540 | int mn; | |
541 | 541 | |||
542 | vp = NULL; /* XXX gcc */ | 542 | vp = NULL; /* XXX gcc */ | |
543 | 543 | |||
544 | mutex_enter(&device_lock); | 544 | mutex_enter(&device_lock); | |
545 | for (mn = minl; mn <= minh; mn++) { | 545 | for (mn = minl; mn <= minh; mn++) { | |
546 | dev = makedev(maj, mn); | 546 | dev = makedev(maj, mn); | |
547 | vpp = &specfs_hash[SPECHASH(dev)]; | 547 | vpp = &specfs_hash[SPECHASH(dev)]; | |
548 | for (vp = *vpp; vp != NULL;) { | 548 | for (vp = *vpp; vp != NULL;) { | |
549 | mutex_enter(vp->v_interlock); | 549 | mutex_enter(vp->v_interlock); | |
550 | if ((vp->v_iflag & VI_CLEAN) != 0 || | 550 | if ((vp->v_iflag & VI_CLEAN) != 0 || | |
551 | type != vp->v_type || dev != vp->v_rdev) { | 551 | type != vp->v_type || dev != vp->v_rdev) { | |
552 | mutex_exit(vp->v_interlock); | 552 | mutex_exit(vp->v_interlock); | |
553 | vp = vp->v_specnext; | 553 | vp = vp->v_specnext; | |
554 | continue; | 554 | continue; | |
555 | } | 555 | } | |
556 | mutex_exit(&device_lock); | 556 | mutex_exit(&device_lock); | |
557 | if (vget(vp, 0) == 0) { | 557 | if (vget(vp, 0) == 0) { | |
558 | VOP_REVOKE(vp, REVOKEALL); | 558 | VOP_REVOKE(vp, REVOKEALL); | |
559 | vrele(vp); | 559 | vrele(vp); | |
560 | } | 560 | } | |
561 | mutex_enter(&device_lock); | 561 | mutex_enter(&device_lock); | |
562 | vp = *vpp; | 562 | vp = *vpp; | |
563 | } | 563 | } | |
564 | } | 564 | } | |
565 | mutex_exit(&device_lock); | 565 | mutex_exit(&device_lock); | |
566 | } | 566 | } | |
567 | 567 | |||
568 | /* | 568 | /* | |
569 | * sysctl helper routine to return list of supported fstypes | 569 | * sysctl helper routine to return list of supported fstypes | |
570 | */ | 570 | */ | |
571 | int | 571 | int | |
572 | sysctl_vfs_generic_fstypes(SYSCTLFN_ARGS) | 572 | sysctl_vfs_generic_fstypes(SYSCTLFN_ARGS) | |
573 | { | 573 | { | |
574 | char bf[sizeof(((struct statvfs *)NULL)->f_fstypename)]; | 574 | char bf[sizeof(((struct statvfs *)NULL)->f_fstypename)]; | |
575 | char *where = oldp; | 575 | char *where = oldp; | |
576 | struct vfsops *v; | 576 | struct vfsops *v; | |
577 | size_t needed, left, slen; | 577 | size_t needed, left, slen; | |
578 | int error, first; | 578 | int error, first; | |
579 | 579 | |||
580 | if (newp != NULL) | 580 | if (newp != NULL) | |
581 | return (EPERM); | 581 | return (EPERM); | |
582 | if (namelen != 0) | 582 | if (namelen != 0) | |
583 | return (EINVAL); | 583 | return (EINVAL); | |
584 | 584 | |||
585 | first = 1; | 585 | first = 1; | |
586 | error = 0; | 586 | error = 0; | |
587 | needed = 0; | 587 | needed = 0; | |
588 | left = *oldlenp; | 588 | left = *oldlenp; | |
589 | 589 | |||
590 | sysctl_unlock(); | 590 | sysctl_unlock(); | |
591 | mutex_enter(&vfs_list_lock); | 591 | mutex_enter(&vfs_list_lock); | |
592 | LIST_FOREACH(v, &vfs_list, vfs_list) { | 592 | LIST_FOREACH(v, &vfs_list, vfs_list) { | |
593 | if (where == NULL) | 593 | if (where == NULL) | |
594 | needed += strlen(v->vfs_name) + 1; | 594 | needed += strlen(v->vfs_name) + 1; | |
595 | else { | 595 | else { | |
596 | memset(bf, 0, sizeof(bf)); | 596 | memset(bf, 0, sizeof(bf)); | |
597 | if (first) { | 597 | if (first) { | |
598 | strncpy(bf, v->vfs_name, sizeof(bf)); | 598 | strncpy(bf, v->vfs_name, sizeof(bf)); | |
599 | first = 0; | 599 | first = 0; | |
600 | } else { | 600 | } else { | |
601 | bf[0] = ' '; | 601 | bf[0] = ' '; | |
602 | strncpy(bf + 1, v->vfs_name, sizeof(bf) - 1); | 602 | strncpy(bf + 1, v->vfs_name, sizeof(bf) - 1); | |
603 | } | 603 | } | |
604 | bf[sizeof(bf)-1] = '\0'; | 604 | bf[sizeof(bf)-1] = '\0'; | |
605 | slen = strlen(bf); | 605 | slen = strlen(bf); | |
606 | if (left < slen + 1) | 606 | if (left < slen + 1) | |
607 | break; | 607 | break; | |
608 | v->vfs_refcount++; | 608 | v->vfs_refcount++; | |
609 | mutex_exit(&vfs_list_lock); | 609 | mutex_exit(&vfs_list_lock); | |
610 | /* +1 to copy out the trailing NUL byte */ | 610 | /* +1 to copy out the trailing NUL byte */ | |
611 | error = copyout(bf, where, slen + 1); | 611 | error = copyout(bf, where, slen + 1); | |
612 | mutex_enter(&vfs_list_lock); | 612 | mutex_enter(&vfs_list_lock); | |
613 | v->vfs_refcount--; | 613 | v->vfs_refcount--; | |
614 | if (error) | 614 | if (error) | |
615 | break; | 615 | break; | |
616 | where += slen; | 616 | where += slen; | |
617 | needed += slen; | 617 | needed += slen; | |
618 | left -= slen; | 618 | left -= slen; | |
619 | } | 619 | } | |
620 | } | 620 | } | |
621 | mutex_exit(&vfs_list_lock); | 621 | mutex_exit(&vfs_list_lock); | |
622 | sysctl_relock(); | 622 | sysctl_relock(); | |
623 | *oldlenp = needed; | 623 | *oldlenp = needed; | |
624 | return (error); | 624 | return (error); | |
625 | } | 625 | } | |
626 | 626 | |||
627 | int kinfo_vdebug = 1; | 627 | int kinfo_vdebug = 1; | |
628 | int kinfo_vgetfailed; | 628 | int kinfo_vgetfailed; | |
629 | 629 | |||
630 | #define KINFO_VNODESLOP 10 | 630 | #define KINFO_VNODESLOP 10 | |
631 | 631 | |||
632 | /* | 632 | /* | |
633 | * Dump vnode list (via sysctl). | 633 | * Dump vnode list (via sysctl). | |
634 | * Copyout address of vnode followed by vnode. | 634 | * Copyout address of vnode followed by vnode. | |
635 | */ | 635 | */ | |
636 | int | 636 | int | |
637 | sysctl_kern_vnode(SYSCTLFN_ARGS) | 637 | sysctl_kern_vnode(SYSCTLFN_ARGS) | |
638 | { | 638 | { | |
639 | char *where = oldp; | 639 | char *where = oldp; | |
640 | size_t *sizep = oldlenp; | 640 | size_t *sizep = oldlenp; | |
641 | struct mount *mp, *nmp; | 641 | struct mount *mp, *nmp; | |
642 | vnode_t *vp, *mvp, vbuf; | 642 | vnode_t *vp, *mvp, vbuf; | |
643 | char *bp = where; | 643 | char *bp = where; | |
644 | char *ewhere; | 644 | char *ewhere; | |
645 | int error; | 645 | int error; | |
646 | 646 | |||
647 | if (namelen != 0) | 647 | if (namelen != 0) | |
648 | return (EOPNOTSUPP); | 648 | return (EOPNOTSUPP); | |
649 | if (newp != NULL) | 649 | if (newp != NULL) | |
650 | return (EPERM); | 650 | return (EPERM); | |
651 | 651 | |||
652 | #define VPTRSZ sizeof(vnode_t *) | 652 | #define VPTRSZ sizeof(vnode_t *) | |
653 | #define VNODESZ sizeof(vnode_t) | 653 | #define VNODESZ sizeof(vnode_t) | |
654 | if (where == NULL) { | 654 | if (where == NULL) { | |
655 | *sizep = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ); | 655 | *sizep = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ); | |
656 | return (0); | 656 | return (0); | |
657 | } | 657 | } | |
658 | ewhere = where + *sizep; | 658 | ewhere = where + *sizep; | |
659 | 659 | |||
660 | sysctl_unlock(); | 660 | sysctl_unlock(); | |
661 | mutex_enter(&mountlist_lock); | 661 | mutex_enter(&mountlist_lock); | |
662 | for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; | 662 | for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; | |
663 | mp = nmp) { | 663 | mp = nmp) { | |
664 | if (vfs_busy(mp, &nmp)) { | 664 | if (vfs_busy(mp, &nmp)) { | |
665 | continue; | 665 | continue; | |
666 | } | 666 | } | |
667 | /* Allocate a marker vnode. */ | 667 | /* Allocate a marker vnode. */ | |
668 | mvp = vnalloc(mp); | 668 | mvp = vnalloc(mp); | |
669 | /* Should never fail for mp != NULL */ | 669 | /* Should never fail for mp != NULL */ | |
670 | KASSERT(mvp != NULL); | 670 | KASSERT(mvp != NULL); | |
671 | mutex_enter(&mntvnode_lock); | 671 | mutex_enter(&mntvnode_lock); | |
672 | for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; | 672 | for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; | |
673 | vp = vunmark(mvp)) { | 673 | vp = vunmark(mvp)) { | |
674 | vmark(mvp, vp); | 674 | vmark(mvp, vp); | |
675 | /* | 675 | /* | |
676 | * Check that the vp is still associated with | 676 | * Check that the vp is still associated with | |
677 | * this filesystem. RACE: could have been | 677 | * this filesystem. RACE: could have been | |
678 | * recycled onto the same filesystem. | 678 | * recycled onto the same filesystem. | |
679 | */ | 679 | */ | |
680 | if (vp->v_mount != mp || vismarker(vp)) | 680 | if (vp->v_mount != mp || vismarker(vp)) | |
681 | continue; | 681 | continue; | |
682 | if (bp + VPTRSZ + VNODESZ > ewhere) { | 682 | if (bp + VPTRSZ + VNODESZ > ewhere) { | |
683 | (void)vunmark(mvp); | 683 | (void)vunmark(mvp); | |
684 | mutex_exit(&mntvnode_lock); | 684 | mutex_exit(&mntvnode_lock); | |
685 | vnfree(mvp); | 685 | vnfree(mvp); | |
686 | vfs_unbusy(mp, false, NULL); | 686 | vfs_unbusy(mp, false, NULL); | |
687 | sysctl_relock(); | 687 | sysctl_relock(); | |
688 | *sizep = bp - where; | 688 | *sizep = bp - where; | |
689 | return (ENOMEM); | 689 | return (ENOMEM); | |
690 | } | 690 | } | |
691 | memcpy(&vbuf, vp, VNODESZ); | 691 | memcpy(&vbuf, vp, VNODESZ); | |
692 | mutex_exit(&mntvnode_lock); | 692 | mutex_exit(&mntvnode_lock); | |
693 | if ((error = copyout(&vp, bp, VPTRSZ)) || | 693 | if ((error = copyout(&vp, bp, VPTRSZ)) || | |
694 | (error = copyout(&vbuf, bp + VPTRSZ, VNODESZ))) { | 694 | (error = copyout(&vbuf, bp + VPTRSZ, VNODESZ))) { | |
695 | mutex_enter(&mntvnode_lock); | 695 | mutex_enter(&mntvnode_lock); | |
696 | (void)vunmark(mvp); | 696 | (void)vunmark(mvp); | |
697 | mutex_exit(&mntvnode_lock); | 697 | mutex_exit(&mntvnode_lock); | |
698 | vnfree(mvp); | 698 | vnfree(mvp); | |
699 | vfs_unbusy(mp, false, NULL); | 699 | vfs_unbusy(mp, false, NULL); | |
700 | sysctl_relock(); | 700 | sysctl_relock(); | |
701 | return (error); | 701 | return (error); | |
702 | } | 702 | } | |
703 | bp += VPTRSZ + VNODESZ; | 703 | bp += VPTRSZ + VNODESZ; | |
704 | mutex_enter(&mntvnode_lock); | 704 | mutex_enter(&mntvnode_lock); | |
705 | } | 705 | } | |
706 | mutex_exit(&mntvnode_lock); | 706 | mutex_exit(&mntvnode_lock); | |
707 | vnfree(mvp); | 707 | vnfree(mvp); | |
708 | vfs_unbusy(mp, false, &nmp); | 708 | vfs_unbusy(mp, false, &nmp); | |
709 | } | 709 | } | |
710 | mutex_exit(&mountlist_lock); | 710 | mutex_exit(&mountlist_lock); | |
711 | sysctl_relock(); | 711 | sysctl_relock(); | |
712 | 712 | |||
713 | *sizep = bp - where; | 713 | *sizep = bp - where; | |
714 | return (0); | 714 | return (0); | |
715 | } | 715 | } | |
716 | 716 | |||
717 | /* | 717 | /* | |
718 | * Set vnode attributes to VNOVAL | 718 | * Set vnode attributes to VNOVAL | |
719 | */ | 719 | */ | |
720 | void | 720 | void | |
721 | vattr_null(struct vattr *vap) | 721 | vattr_null(struct vattr *vap) | |
722 | { | 722 | { | |
723 | 723 | |||
724 | memset(vap, 0, sizeof(*vap)); | 724 | memset(vap, 0, sizeof(*vap)); | |
725 | 725 | |||
726 | vap->va_type = VNON; | 726 | vap->va_type = VNON; | |
727 | 727 | |||
728 | /* | 728 | /* | |
729 | * Assign individually so that it is safe even if size and | 729 | * Assign individually so that it is safe even if size and | |
730 | * sign of each member are varied. | 730 | * sign of each member are varied. | |
731 | */ | 731 | */ | |
732 | vap->va_mode = VNOVAL; | 732 | vap->va_mode = VNOVAL; | |
733 | vap->va_nlink = VNOVAL; | 733 | vap->va_nlink = VNOVAL; | |
734 | vap->va_uid = VNOVAL; | 734 | vap->va_uid = VNOVAL; | |
735 | vap->va_gid = VNOVAL; | 735 | vap->va_gid = VNOVAL; | |
736 | vap->va_fsid = VNOVAL; | 736 | vap->va_fsid = VNOVAL; | |
737 | vap->va_fileid = VNOVAL; | 737 | vap->va_fileid = VNOVAL; | |
738 | vap->va_size = VNOVAL; | 738 | vap->va_size = VNOVAL; | |
739 | vap->va_blocksize = VNOVAL; | 739 | vap->va_blocksize = VNOVAL; | |
740 | vap->va_atime.tv_sec = | 740 | vap->va_atime.tv_sec = | |
741 | vap->va_mtime.tv_sec = | 741 | vap->va_mtime.tv_sec = | |
742 | vap->va_ctime.tv_sec = | 742 | vap->va_ctime.tv_sec = | |
743 | vap->va_birthtime.tv_sec = VNOVAL; | 743 | vap->va_birthtime.tv_sec = VNOVAL; | |
744 | vap->va_atime.tv_nsec = | 744 | vap->va_atime.tv_nsec = | |
745 | vap->va_mtime.tv_nsec = | 745 | vap->va_mtime.tv_nsec = | |
746 | vap->va_ctime.tv_nsec = | 746 | vap->va_ctime.tv_nsec = | |
747 | vap->va_birthtime.tv_nsec = VNOVAL; | 747 | vap->va_birthtime.tv_nsec = VNOVAL; | |
748 | vap->va_gen = VNOVAL; | 748 | vap->va_gen = VNOVAL; | |
749 | vap->va_flags = VNOVAL; | 749 | vap->va_flags = VNOVAL; | |
750 | vap->va_rdev = VNOVAL; | 750 | vap->va_rdev = VNOVAL; | |
751 | vap->va_bytes = VNOVAL; | 751 | vap->va_bytes = VNOVAL; | |
752 | } | 752 | } | |
753 | 753 | |||
754 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | 754 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | |
755 | #define ARRAY_PRINT(idx, arr) \ | 755 | #define ARRAY_PRINT(idx, arr) \ | |
756 | ((unsigned int)(idx) < ARRAY_SIZE(arr) ? (arr)[(idx)] : "UNKNOWN") | 756 | ((unsigned int)(idx) < ARRAY_SIZE(arr) ? (arr)[(idx)] : "UNKNOWN") | |
757 | 757 | |||
758 | const char * const vnode_tags[] = { VNODE_TAGS }; | 758 | const char * const vnode_tags[] = { VNODE_TAGS }; | |
759 | const char * const vnode_types[] = { VNODE_TYPES }; | 759 | const char * const vnode_types[] = { VNODE_TYPES }; | |
760 | const char vnode_flagbits[] = VNODE_FLAGBITS; | 760 | const char vnode_flagbits[] = VNODE_FLAGBITS; | |
761 | 761 | |||
762 | /* | 762 | /* | |
763 | * Print out a description of a vnode. | 763 | * Print out a description of a vnode. | |
764 | */ | 764 | */ | |
765 | void | 765 | void | |
766 | vprint(const char *label, struct vnode *vp) | 766 | vprint(const char *label, struct vnode *vp) | |
767 | { | 767 | { | |
768 | char bf[96]; | 768 | char bf[96]; | |
769 | int flag; | 769 | int flag; | |
770 | 770 | |||
771 | flag = vp->v_iflag | vp->v_vflag | vp->v_uflag; | 771 | flag = vp->v_iflag | vp->v_vflag | vp->v_uflag; | |
772 | snprintb(bf, sizeof(bf), vnode_flagbits, flag); | 772 | snprintb(bf, sizeof(bf), vnode_flagbits, flag); | |
773 | 773 | |||
774 | if (label != NULL) | 774 | if (label != NULL) | |
775 | printf("%s: ", label); | 775 | printf("%s: ", label); | |
776 | printf("vnode @ %p, flags (%s)\n\ttag %s(%d), type %s(%d), " | 776 | printf("vnode @ %p, flags (%s)\n\ttag %s(%d), type %s(%d), " | |
777 | "usecount %d, writecount %d, holdcount %d\n" | 777 | "usecount %d, writecount %d, holdcount %d\n" | |
778 | "\tfreelisthd %p, mount %p, data %p lock %p\n", | 778 | "\tfreelisthd %p, mount %p, data %p lock %p\n", | |
779 | vp, bf, ARRAY_PRINT(vp->v_tag, vnode_tags), vp->v_tag, | 779 | vp, bf, ARRAY_PRINT(vp->v_tag, vnode_tags), vp->v_tag, | |
780 | ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, | 780 | ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, | |
781 | vp->v_usecount, vp->v_writecount, vp->v_holdcnt, | 781 | vp->v_usecount, vp->v_writecount, vp->v_holdcnt, | |
782 | vp->v_freelisthd, vp->v_mount, vp->v_data, &vp->v_lock); | 782 | vp->v_freelisthd, vp->v_mount, vp->v_data, &vp->v_lock); | |
783 | if (vp->v_data != NULL) { | 783 | if (vp->v_data != NULL) { | |
784 | printf("\t"); | 784 | printf("\t"); | |
785 | VOP_PRINT(vp); | 785 | VOP_PRINT(vp); | |
786 | } | 786 | } | |
787 | } | 787 | } | |
788 | 788 | |||
789 | /* Deprecated. Kept for KPI compatibility. */ | 789 | /* Deprecated. Kept for KPI compatibility. */ | |
790 | int | 790 | int | |
791 | vaccess(enum vtype type, mode_t file_mode, uid_t uid, gid_t gid, | 791 | vaccess(enum vtype type, mode_t file_mode, uid_t uid, gid_t gid, | |
792 | mode_t acc_mode, kauth_cred_t cred) | 792 | mode_t acc_mode, kauth_cred_t cred) | |
793 | { | 793 | { | |
794 | 794 | |||
795 | #ifdef DIAGNOSTIC | 795 | #ifdef DIAGNOSTIC | |
796 | printf("vaccess: deprecated interface used.\n"); | 796 | printf("vaccess: deprecated interface used.\n"); | |
797 | #endif /* DIAGNOSTIC */ | 797 | #endif /* DIAGNOSTIC */ | |
798 | 798 | |||
799 | return genfs_can_access(type, file_mode, uid, gid, acc_mode, cred); | 799 | return genfs_can_access(type, file_mode, uid, gid, acc_mode, cred); | |
800 | } | 800 | } | |
801 | 801 | |||
802 | /* | 802 | /* | |
803 | * Given a file system name, look up the vfsops for that | 803 | * Given a file system name, look up the vfsops for that | |
804 | * file system, or return NULL if file system isn't present | 804 | * file system, or return NULL if file system isn't present | |
805 | * in the kernel. | 805 | * in the kernel. | |
806 | */ | 806 | */ | |
807 | struct vfsops * | 807 | struct vfsops * | |
808 | vfs_getopsbyname(const char *name) | 808 | vfs_getopsbyname(const char *name) | |
809 | { | 809 | { | |
810 | struct vfsops *v; | 810 | struct vfsops *v; | |
811 | 811 | |||
812 | mutex_enter(&vfs_list_lock); | 812 | mutex_enter(&vfs_list_lock); | |
813 | LIST_FOREACH(v, &vfs_list, vfs_list) { | 813 | LIST_FOREACH(v, &vfs_list, vfs_list) { | |
814 | if (strcmp(v->vfs_name, name) == 0) | 814 | if (strcmp(v->vfs_name, name) == 0) | |
815 | break; | 815 | break; | |
816 | } | 816 | } | |
817 | if (v != NULL) | 817 | if (v != NULL) | |
818 | v->vfs_refcount++; | 818 | v->vfs_refcount++; | |
819 | mutex_exit(&vfs_list_lock); | 819 | mutex_exit(&vfs_list_lock); | |
820 | 820 | |||
821 | return (v); | 821 | return (v); | |
822 | } | 822 | } | |
823 | 823 | |||
824 | void | 824 | void | |
825 | copy_statvfs_info(struct statvfs *sbp, const struct mount *mp) | 825 | copy_statvfs_info(struct statvfs *sbp, const struct mount *mp) | |
826 | { | 826 | { | |
827 | const struct statvfs *mbp; | 827 | const struct statvfs *mbp; | |
828 | 828 | |||
829 | if (sbp == (mbp = &mp->mnt_stat)) | 829 | if (sbp == (mbp = &mp->mnt_stat)) | |
830 | return; | 830 | return; | |
831 | 831 | |||
832 | (void)memcpy(&sbp->f_fsidx, &mbp->f_fsidx, sizeof(sbp->f_fsidx)); | 832 | (void)memcpy(&sbp->f_fsidx, &mbp->f_fsidx, sizeof(sbp->f_fsidx)); | |
833 | sbp->f_fsid = mbp->f_fsid; | 833 | sbp->f_fsid = mbp->f_fsid; | |
834 | sbp->f_owner = mbp->f_owner; | 834 | sbp->f_owner = mbp->f_owner; | |
835 | sbp->f_flag = mbp->f_flag; | 835 | sbp->f_flag = mbp->f_flag; | |
836 | sbp->f_syncwrites = mbp->f_syncwrites; | 836 | sbp->f_syncwrites = mbp->f_syncwrites; | |
837 | sbp->f_asyncwrites = mbp->f_asyncwrites; | 837 | sbp->f_asyncwrites = mbp->f_asyncwrites; | |
838 | sbp->f_syncreads = mbp->f_syncreads; | 838 | sbp->f_syncreads = mbp->f_syncreads; | |
839 | sbp->f_asyncreads = mbp->f_asyncreads; | 839 | sbp->f_asyncreads = mbp->f_asyncreads; | |
840 | (void)memcpy(sbp->f_spare, mbp->f_spare, sizeof(mbp->f_spare)); | 840 | (void)memcpy(sbp->f_spare, mbp->f_spare, sizeof(mbp->f_spare)); | |
841 | (void)memcpy(sbp->f_fstypename, mbp->f_fstypename, | 841 | (void)memcpy(sbp->f_fstypename, mbp->f_fstypename, | |
842 | sizeof(sbp->f_fstypename)); | 842 | sizeof(sbp->f_fstypename)); | |
843 | (void)memcpy(sbp->f_mntonname, mbp->f_mntonname, | 843 | (void)memcpy(sbp->f_mntonname, mbp->f_mntonname, | |
844 | sizeof(sbp->f_mntonname)); | 844 | sizeof(sbp->f_mntonname)); | |
845 | (void)memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, | 845 | (void)memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, | |
846 | sizeof(sbp->f_mntfromname)); | 846 | sizeof(sbp->f_mntfromname)); | |
847 | sbp->f_namemax = mbp->f_namemax; | 847 | sbp->f_namemax = mbp->f_namemax; | |
848 | } | 848 | } | |
849 | 849 | |||
850 | int | 850 | int | |
851 | set_statvfs_info(const char *onp, int ukon, const char *fromp, int ukfrom, | 851 | set_statvfs_info(const char *onp, int ukon, const char *fromp, int ukfrom, | |
852 | const char *vfsname, struct mount *mp, struct lwp *l) | 852 | const char *vfsname, struct mount *mp, struct lwp *l) | |
853 | { | 853 | { | |
854 | int error; | 854 | int error; | |
855 | size_t size; | 855 | size_t size; | |
856 | struct statvfs *sfs = &mp->mnt_stat; | 856 | struct statvfs *sfs = &mp->mnt_stat; | |
857 | int (*fun)(const void *, void *, size_t, size_t *); | 857 | int (*fun)(const void *, void *, size_t, size_t *); | |
858 | 858 | |||
859 | (void)strlcpy(mp->mnt_stat.f_fstypename, vfsname, | 859 | (void)strlcpy(mp->mnt_stat.f_fstypename, vfsname, | |
860 | sizeof(mp->mnt_stat.f_fstypename)); | 860 | sizeof(mp->mnt_stat.f_fstypename)); | |
861 | 861 | |||
862 | if (onp) { | 862 | if (onp) { | |
863 | struct cwdinfo *cwdi = l->l_proc->p_cwdi; | 863 | struct cwdinfo *cwdi = l->l_proc->p_cwdi; | |
864 | fun = (ukon == UIO_SYSSPACE) ? copystr : copyinstr; | 864 | fun = (ukon == UIO_SYSSPACE) ? copystr : copyinstr; | |
865 | if (cwdi->cwdi_rdir != NULL) { | 865 | if (cwdi->cwdi_rdir != NULL) { | |
866 | size_t len; | 866 | size_t len; | |
867 | char *bp; | 867 | char *bp; | |
868 | char *path = PNBUF_GET(); | 868 | char *path = PNBUF_GET(); | |
869 | 869 | |||
870 | bp = path + MAXPATHLEN; | 870 | bp = path + MAXPATHLEN; | |
871 | *--bp = '\0'; | 871 | *--bp = '\0'; | |
872 | rw_enter(&cwdi->cwdi_lock, RW_READER); | 872 | rw_enter(&cwdi->cwdi_lock, RW_READER); | |
873 | error = getcwd_common(cwdi->cwdi_rdir, rootvnode, &bp, | 873 | error = getcwd_common(cwdi->cwdi_rdir, rootvnode, &bp, | |
874 | path, MAXPATHLEN / 2, 0, l); | 874 | path, MAXPATHLEN / 2, 0, l); | |
875 | rw_exit(&cwdi->cwdi_lock); | 875 | rw_exit(&cwdi->cwdi_lock); | |
876 | if (error) { | 876 | if (error) { | |
877 | PNBUF_PUT(path); | 877 | PNBUF_PUT(path); | |
878 | return error; | 878 | return error; | |
879 | } | 879 | } | |
880 | 880 | |||
881 | len = strlen(bp); | 881 | len = strlen(bp); | |
882 | if (len > sizeof(sfs->f_mntonname) - 1) | 882 | if (len > sizeof(sfs->f_mntonname) - 1) | |
883 | len = sizeof(sfs->f_mntonname) - 1; | 883 | len = sizeof(sfs->f_mntonname) - 1; | |
884 | (void)strncpy(sfs->f_mntonname, bp, len); | 884 | (void)strncpy(sfs->f_mntonname, bp, len); | |
885 | PNBUF_PUT(path); | 885 | PNBUF_PUT(path); | |
886 | 886 | |||
887 | if (len < sizeof(sfs->f_mntonname) - 1) { | 887 | if (len < sizeof(sfs->f_mntonname) - 1) { | |
888 | error = (*fun)(onp, &sfs->f_mntonname[len], | 888 | error = (*fun)(onp, &sfs->f_mntonname[len], | |
889 | sizeof(sfs->f_mntonname) - len - 1, &size); | 889 | sizeof(sfs->f_mntonname) - len - 1, &size); | |
890 | if (error) | 890 | if (error) | |
891 | return error; | 891 | return error; | |
892 | size += len; | 892 | size += len; | |
893 | } else { | 893 | } else { | |
894 | size = len; | 894 | size = len; | |
895 | } | 895 | } | |
896 | } else { | 896 | } else { | |
897 | error = (*fun)(onp, &sfs->f_mntonname, | 897 | error = (*fun)(onp, &sfs->f_mntonname, | |
898 | sizeof(sfs->f_mntonname) - 1, &size); | 898 | sizeof(sfs->f_mntonname) - 1, &size); | |
899 | if (error) | 899 | if (error) | |
900 | return error; | 900 | return error; | |
901 | } | 901 | } | |
902 | (void)memset(sfs->f_mntonname + size, 0, | 902 | (void)memset(sfs->f_mntonname + size, 0, | |
903 | sizeof(sfs->f_mntonname) - size); | 903 | sizeof(sfs->f_mntonname) - size); | |
904 | } | 904 | } | |
905 | 905 | |||
906 | if (fromp) { | 906 | if (fromp) { | |
907 | fun = (ukfrom == UIO_SYSSPACE) ? copystr : copyinstr; | 907 | fun = (ukfrom == UIO_SYSSPACE) ? copystr : copyinstr; | |
908 | error = (*fun)(fromp, sfs->f_mntfromname, | 908 | error = (*fun)(fromp, sfs->f_mntfromname, | |
909 | sizeof(sfs->f_mntfromname) - 1, &size); | 909 | sizeof(sfs->f_mntfromname) - 1, &size); | |
910 | if (error) | 910 | if (error) | |
911 | return error; | 911 | return error; | |
912 | (void)memset(sfs->f_mntfromname + size, 0, | 912 | (void)memset(sfs->f_mntfromname + size, 0, | |
913 | sizeof(sfs->f_mntfromname) - size); | 913 | sizeof(sfs->f_mntfromname) - size); | |
914 | } | 914 | } | |
915 | return 0; | 915 | return 0; | |
916 | } | 916 | } | |
917 | 917 | |||
918 | void | 918 | void | |
919 | vfs_timestamp(struct timespec *ts) | 919 | vfs_timestamp(struct timespec *ts) | |
920 | { | 920 | { | |
921 | 921 | |||
922 | nanotime(ts); | 922 | nanotime(ts); | |
923 | } | 923 | } | |
924 | 924 | |||
925 | time_t rootfstime; /* recorded root fs time, if known */ | 925 | time_t rootfstime; /* recorded root fs time, if known */ | |
926 | void | 926 | void | |
927 | setrootfstime(time_t t) | 927 | setrootfstime(time_t t) | |
928 | { | 928 | { | |
929 | rootfstime = t; | 929 | rootfstime = t; | |
930 | } | 930 | } | |
931 | 931 | |||
932 | static const uint8_t vttodt_tab[9] = { | 932 | static const uint8_t vttodt_tab[9] = { | |
933 | DT_UNKNOWN, /* VNON */ | 933 | DT_UNKNOWN, /* VNON */ | |
934 | DT_REG, /* VREG */ | 934 | DT_REG, /* VREG */ | |
935 | DT_DIR, /* VDIR */ | 935 | DT_DIR, /* VDIR */ | |
936 | DT_BLK, /* VBLK */ | 936 | DT_BLK, /* VBLK */ | |
937 | DT_CHR, /* VCHR */ | 937 | DT_CHR, /* VCHR */ | |
938 | DT_LNK, /* VLNK */ | 938 | DT_LNK, /* VLNK */ | |
939 | DT_SOCK, /* VSUCK */ | 939 | DT_SOCK, /* VSUCK */ | |
940 | DT_FIFO, /* VFIFO */ | 940 | DT_FIFO, /* VFIFO */ | |
941 | DT_UNKNOWN /* VBAD */ | 941 | DT_UNKNOWN /* VBAD */ | |
942 | }; | 942 | }; | |
943 | 943 | |||
944 | uint8_t | 944 | uint8_t | |
945 | vtype2dt(enum vtype vt) | 945 | vtype2dt(enum vtype vt) | |
946 | { | 946 | { | |
947 | 947 | |||
948 | CTASSERT(VBAD == __arraycount(vttodt_tab) - 1); | 948 | CTASSERT(VBAD == __arraycount(vttodt_tab) - 1); | |
949 | return vttodt_tab[vt]; | 949 | return vttodt_tab[vt]; | |
950 | } | 950 | } | |
951 | 951 | |||
952 | int | 952 | int | |
953 | VFS_MOUNT(struct mount *mp, const char *a, void *b, size_t *c) | 953 | VFS_MOUNT(struct mount *mp, const char *a, void *b, size_t *c) | |
954 | { | 954 | { | |
955 | int error; | 955 | int error; | |
956 | 956 | |||
957 | KERNEL_LOCK(1, NULL); | 957 | KERNEL_LOCK(1, NULL); | |
958 | error = (*(mp->mnt_op->vfs_mount))(mp, a, b, c); | 958 | error = (*(mp->mnt_op->vfs_mount))(mp, a, b, c); | |
959 | KERNEL_UNLOCK_ONE(NULL); | 959 | KERNEL_UNLOCK_ONE(NULL); | |
960 | 960 | |||
961 | return error; | 961 | return error; | |
962 | } | 962 | } | |
963 | 963 | |||
964 | int | 964 | int | |
965 | VFS_START(struct mount *mp, int a) | 965 | VFS_START(struct mount *mp, int a) | |
966 | { | 966 | { | |
967 | int error; | 967 | int error; | |
968 | 968 | |||
969 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 969 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
970 | KERNEL_LOCK(1, NULL); | 970 | KERNEL_LOCK(1, NULL); | |
971 | } | 971 | } | |
972 | error = (*(mp->mnt_op->vfs_start))(mp, a); | 972 | error = (*(mp->mnt_op->vfs_start))(mp, a); | |
973 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 973 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
974 | KERNEL_UNLOCK_ONE(NULL); | 974 | KERNEL_UNLOCK_ONE(NULL); | |
975 | } | 975 | } | |
976 | 976 | |||
977 | return error; | 977 | return error; | |
978 | } | 978 | } | |
979 | 979 | |||
980 | int | 980 | int | |
981 | VFS_UNMOUNT(struct mount *mp, int a) | 981 | VFS_UNMOUNT(struct mount *mp, int a) | |
982 | { | 982 | { | |
983 | int error; | 983 | int error; | |
984 | 984 | |||
985 | KERNEL_LOCK(1, NULL); | 985 | KERNEL_LOCK(1, NULL); | |
986 | error = (*(mp->mnt_op->vfs_unmount))(mp, a); | 986 | error = (*(mp->mnt_op->vfs_unmount))(mp, a); | |
987 | KERNEL_UNLOCK_ONE(NULL); | 987 | KERNEL_UNLOCK_ONE(NULL); | |
988 | 988 | |||
989 | return error; | 989 | return error; | |
990 | } | 990 | } | |
991 | 991 | |||
992 | int | 992 | int | |
993 | VFS_ROOT(struct mount *mp, struct vnode **a) | 993 | VFS_ROOT(struct mount *mp, struct vnode **a) | |
994 | { | 994 | { | |
995 | int error; | 995 | int error; | |
996 | 996 | |||
997 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 997 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
998 | KERNEL_LOCK(1, NULL); | 998 | KERNEL_LOCK(1, NULL); | |
999 | } | 999 | } | |
1000 | error = (*(mp->mnt_op->vfs_root))(mp, a); | 1000 | error = (*(mp->mnt_op->vfs_root))(mp, a); | |
1001 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1001 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1002 | KERNEL_UNLOCK_ONE(NULL); | 1002 | KERNEL_UNLOCK_ONE(NULL); | |
1003 | } | 1003 | } | |
1004 | 1004 | |||
1005 | return error; | 1005 | return error; | |
1006 | } | 1006 | } | |
1007 | 1007 | |||
1008 | int | 1008 | int | |
1009 | VFS_QUOTACTL(struct mount *mp, prop_dictionary_t dict) | 1009 | VFS_QUOTACTL(struct mount *mp, prop_dictionary_t dict, int dummy) | |
1010 | { | 1010 | { | |
1011 | int error; | 1011 | int error; | |
1012 | 1012 | |||
1013 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1013 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1014 | KERNEL_LOCK(1, NULL); | 1014 | KERNEL_LOCK(1, NULL); | |
1015 | } | 1015 | } | |
1016 | error = (*(mp->mnt_op->vfs_quotactl))(mp, dict); | 1016 | error = (*(mp->mnt_op->vfs_quotactl))(mp, dict, dummy); | |
1017 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1017 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1018 | KERNEL_UNLOCK_ONE(NULL); | 1018 | KERNEL_UNLOCK_ONE(NULL); | |
1019 | } | 1019 | } | |
1020 | 1020 | |||
1021 | return error; | 1021 | return error; | |
1022 | } | 1022 | } | |
1023 | 1023 | |||
1024 | int | 1024 | int | |
1025 | VFS_STATVFS(struct mount *mp, struct statvfs *a) | 1025 | VFS_STATVFS(struct mount *mp, struct statvfs *a) | |
1026 | { | 1026 | { | |
1027 | int error; | 1027 | int error; | |
1028 | 1028 | |||
1029 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1029 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1030 | KERNEL_LOCK(1, NULL); | 1030 | KERNEL_LOCK(1, NULL); | |
1031 | } | 1031 | } | |
1032 | error = (*(mp->mnt_op->vfs_statvfs))(mp, a); | 1032 | error = (*(mp->mnt_op->vfs_statvfs))(mp, a); | |
1033 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1033 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1034 | KERNEL_UNLOCK_ONE(NULL); | 1034 | KERNEL_UNLOCK_ONE(NULL); | |
1035 | } | 1035 | } | |
1036 | 1036 | |||
1037 | return error; | 1037 | return error; | |
1038 | } | 1038 | } | |
1039 | 1039 | |||
1040 | int | 1040 | int | |
1041 | VFS_SYNC(struct mount *mp, int a, struct kauth_cred *b) | 1041 | VFS_SYNC(struct mount *mp, int a, struct kauth_cred *b) | |
1042 | { | 1042 | { | |
1043 | int error; | 1043 | int error; | |
1044 | 1044 | |||
1045 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1045 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1046 | KERNEL_LOCK(1, NULL); | 1046 | KERNEL_LOCK(1, NULL); | |
1047 | } | 1047 | } | |
1048 | error = (*(mp->mnt_op->vfs_sync))(mp, a, b); | 1048 | error = (*(mp->mnt_op->vfs_sync))(mp, a, b); | |
1049 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1049 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1050 | KERNEL_UNLOCK_ONE(NULL); | 1050 | KERNEL_UNLOCK_ONE(NULL); | |
1051 | } | 1051 | } | |
1052 | 1052 | |||
1053 | return error; | 1053 | return error; | |
1054 | } | 1054 | } | |
1055 | 1055 | |||
1056 | int | 1056 | int | |
1057 | VFS_FHTOVP(struct mount *mp, struct fid *a, struct vnode **b) | 1057 | VFS_FHTOVP(struct mount *mp, struct fid *a, struct vnode **b) | |
1058 | { | 1058 | { | |
1059 | int error; | 1059 | int error; | |
1060 | 1060 | |||
1061 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1061 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1062 | KERNEL_LOCK(1, NULL); | 1062 | KERNEL_LOCK(1, NULL); | |
1063 | } | 1063 | } | |
1064 | error = (*(mp->mnt_op->vfs_fhtovp))(mp, a, b); | 1064 | error = (*(mp->mnt_op->vfs_fhtovp))(mp, a, b); | |
1065 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1065 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1066 | KERNEL_UNLOCK_ONE(NULL); | 1066 | KERNEL_UNLOCK_ONE(NULL); | |
1067 | } | 1067 | } | |
1068 | 1068 | |||
1069 | return error; | 1069 | return error; | |
1070 | } | 1070 | } | |
1071 | 1071 | |||
1072 | int | 1072 | int | |
1073 | VFS_VPTOFH(struct vnode *vp, struct fid *a, size_t *b) | 1073 | VFS_VPTOFH(struct vnode *vp, struct fid *a, size_t *b) | |
1074 | { | 1074 | { | |
1075 | int error; | 1075 | int error; | |
1076 | 1076 | |||
1077 | if ((vp->v_vflag & VV_MPSAFE) == 0) { | 1077 | if ((vp->v_vflag & VV_MPSAFE) == 0) { | |
1078 | KERNEL_LOCK(1, NULL); | 1078 | KERNEL_LOCK(1, NULL); | |
1079 | } | 1079 | } | |
1080 | error = (*(vp->v_mount->mnt_op->vfs_vptofh))(vp, a, b); | 1080 | error = (*(vp->v_mount->mnt_op->vfs_vptofh))(vp, a, b); | |
1081 | if ((vp->v_vflag & VV_MPSAFE) == 0) { | 1081 | if ((vp->v_vflag & VV_MPSAFE) == 0) { | |
1082 | KERNEL_UNLOCK_ONE(NULL); | 1082 | KERNEL_UNLOCK_ONE(NULL); | |
1083 | } | 1083 | } | |
1084 | 1084 | |||
1085 | return error; | 1085 | return error; | |
1086 | } | 1086 | } | |
1087 | 1087 | |||
1088 | int | 1088 | int | |
1089 | VFS_SNAPSHOT(struct mount *mp, struct vnode *a, struct timespec *b) | 1089 | VFS_SNAPSHOT(struct mount *mp, struct vnode *a, struct timespec *b) | |
1090 | { | 1090 | { | |
1091 | int error; | 1091 | int error; | |
1092 | 1092 | |||
1093 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1093 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1094 | KERNEL_LOCK(1, NULL); | 1094 | KERNEL_LOCK(1, NULL); | |
1095 | } | 1095 | } | |
1096 | error = (*(mp->mnt_op->vfs_snapshot))(mp, a, b); | 1096 | error = (*(mp->mnt_op->vfs_snapshot))(mp, a, b); | |
1097 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1097 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1098 | KERNEL_UNLOCK_ONE(NULL); | 1098 | KERNEL_UNLOCK_ONE(NULL); | |
1099 | } | 1099 | } | |
1100 | 1100 | |||
1101 | return error; | 1101 | return error; | |
1102 | } | 1102 | } | |
1103 | 1103 | |||
1104 | int | 1104 | int | |
1105 | VFS_EXTATTRCTL(struct mount *mp, int a, struct vnode *b, int c, const char *d) | 1105 | VFS_EXTATTRCTL(struct mount *mp, int a, struct vnode *b, int c, const char *d) | |
1106 | { | 1106 | { | |
1107 | int error; | 1107 | int error; | |
1108 | 1108 | |||
1109 | KERNEL_LOCK(1, NULL); /* XXXSMP check ffs */ | 1109 | KERNEL_LOCK(1, NULL); /* XXXSMP check ffs */ | |
1110 | error = (*(mp->mnt_op->vfs_extattrctl))(mp, a, b, c, d); | 1110 | error = (*(mp->mnt_op->vfs_extattrctl))(mp, a, b, c, d); | |
1111 | KERNEL_UNLOCK_ONE(NULL); /* XXX */ | 1111 | KERNEL_UNLOCK_ONE(NULL); /* XXX */ | |
1112 | 1112 | |||
1113 | return error; | 1113 | return error; | |
1114 | } | 1114 | } | |
1115 | 1115 | |||
1116 | int | 1116 | int | |
1117 | VFS_SUSPENDCTL(struct mount *mp, int a) | 1117 | VFS_SUSPENDCTL(struct mount *mp, int a) | |
1118 | { | 1118 | { | |
1119 | int error; | 1119 | int error; | |
1120 | 1120 | |||
1121 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1121 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1122 | KERNEL_LOCK(1, NULL); | 1122 | KERNEL_LOCK(1, NULL); | |
1123 | } | 1123 | } | |
1124 | error = (*(mp->mnt_op->vfs_suspendctl))(mp, a); | 1124 | error = (*(mp->mnt_op->vfs_suspendctl))(mp, a); | |
1125 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | 1125 | if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { | |
1126 | KERNEL_UNLOCK_ONE(NULL); | 1126 | KERNEL_UNLOCK_ONE(NULL); | |
1127 | } | 1127 | } | |
1128 | 1128 | |||
1129 | return error; | 1129 | return error; | |
1130 | } | 1130 | } | |
1131 | 1131 | |||
1132 | #if defined(DDB) || defined(DEBUGPRINT) | 1132 | #if defined(DDB) || defined(DEBUGPRINT) | |
1133 | static const char buf_flagbits[] = BUF_FLAGBITS; | 1133 | static const char buf_flagbits[] = BUF_FLAGBITS; | |
1134 | 1134 | |||
1135 | void | 1135 | void | |
1136 | vfs_buf_print(struct buf *bp, int full, void (*pr)(const char *, ...)) | 1136 | vfs_buf_print(struct buf *bp, int full, void (*pr)(const char *, ...)) | |
1137 | { | 1137 | { | |
1138 | char bf[1024]; | 1138 | char bf[1024]; | |
1139 | 1139 | |||
1140 | (*pr)(" vp %p lblkno 0x%"PRIx64" blkno 0x%"PRIx64" rawblkno 0x%" | 1140 | (*pr)(" vp %p lblkno 0x%"PRIx64" blkno 0x%"PRIx64" rawblkno 0x%" | |
1141 | PRIx64 " dev 0x%x\n", | 1141 | PRIx64 " dev 0x%x\n", | |
1142 | bp->b_vp, bp->b_lblkno, bp->b_blkno, bp->b_rawblkno, bp->b_dev); | 1142 | bp->b_vp, bp->b_lblkno, bp->b_blkno, bp->b_rawblkno, bp->b_dev); | |
1143 | 1143 | |||
1144 | snprintb(bf, sizeof(bf), | 1144 | snprintb(bf, sizeof(bf), | |
1145 | buf_flagbits, bp->b_flags | bp->b_oflags | bp->b_cflags); | 1145 | buf_flagbits, bp->b_flags | bp->b_oflags | bp->b_cflags); | |
1146 | (*pr)(" error %d flags 0x%s\n", bp->b_error, bf); | 1146 | (*pr)(" error %d flags 0x%s\n", bp->b_error, bf); | |
1147 | 1147 | |||
1148 | (*pr)(" bufsize 0x%lx bcount 0x%lx resid 0x%lx\n", | 1148 | (*pr)(" bufsize 0x%lx bcount 0x%lx resid 0x%lx\n", | |
1149 | bp->b_bufsize, bp->b_bcount, bp->b_resid); | 1149 | bp->b_bufsize, bp->b_bcount, bp->b_resid); | |
1150 | (*pr)(" data %p saveaddr %p\n", | 1150 | (*pr)(" data %p saveaddr %p\n", | |
1151 | bp->b_data, bp->b_saveaddr); | 1151 | bp->b_data, bp->b_saveaddr); | |
1152 | (*pr)(" iodone %p objlock %p\n", bp->b_iodone, bp->b_objlock); | 1152 | (*pr)(" iodone %p objlock %p\n", bp->b_iodone, bp->b_objlock); | |
1153 | } | 1153 | } | |
1154 | 1154 | |||
1155 | void | 1155 | void | |
1156 | vfs_vnode_print(struct vnode *vp, int full, void (*pr)(const char *, ...)) | 1156 | vfs_vnode_print(struct vnode *vp, int full, void (*pr)(const char *, ...)) | |
1157 | { | 1157 | { | |
1158 | char bf[256]; | 1158 | char bf[256]; | |
1159 | 1159 | |||
1160 | uvm_object_printit(&vp->v_uobj, full, pr); | 1160 | uvm_object_printit(&vp->v_uobj, full, pr); | |
1161 | snprintb(bf, sizeof(bf), | 1161 | snprintb(bf, sizeof(bf), | |
1162 | vnode_flagbits, vp->v_iflag | vp->v_vflag | vp->v_uflag); | 1162 | vnode_flagbits, vp->v_iflag | vp->v_vflag | vp->v_uflag); | |
1163 | (*pr)("\nVNODE flags %s\n", bf); | 1163 | (*pr)("\nVNODE flags %s\n", bf); | |
1164 | (*pr)("mp %p numoutput %d size 0x%llx writesize 0x%llx\n", | 1164 | (*pr)("mp %p numoutput %d size 0x%llx writesize 0x%llx\n", | |
1165 | vp->v_mount, vp->v_numoutput, vp->v_size, vp->v_writesize); | 1165 | vp->v_mount, vp->v_numoutput, vp->v_size, vp->v_writesize); | |
1166 | 1166 | |||
1167 | (*pr)("data %p writecount %ld holdcnt %ld\n", | 1167 | (*pr)("data %p writecount %ld holdcnt %ld\n", | |
1168 | vp->v_data, vp->v_writecount, vp->v_holdcnt); | 1168 | vp->v_data, vp->v_writecount, vp->v_holdcnt); | |
1169 | 1169 | |||
1170 | (*pr)("tag %s(%d) type %s(%d) mount %p typedata %p\n", | 1170 | (*pr)("tag %s(%d) type %s(%d) mount %p typedata %p\n", | |
1171 | ARRAY_PRINT(vp->v_tag, vnode_tags), vp->v_tag, | 1171 | ARRAY_PRINT(vp->v_tag, vnode_tags), vp->v_tag, | |
1172 | ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, | 1172 | ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, | |
1173 | vp->v_mount, vp->v_mountedhere); | 1173 | vp->v_mount, vp->v_mountedhere); | |
1174 | 1174 | |||
1175 | (*pr)("v_lock %p\n", &vp->v_lock); | 1175 | (*pr)("v_lock %p\n", &vp->v_lock); | |
1176 | 1176 | |||
1177 | if (full) { | 1177 | if (full) { | |
1178 | struct buf *bp; | 1178 | struct buf *bp; | |
1179 | 1179 | |||
1180 | (*pr)("clean bufs:\n"); | 1180 | (*pr)("clean bufs:\n"); | |
1181 | LIST_FOREACH(bp, &vp->v_cleanblkhd, b_vnbufs) { | 1181 | LIST_FOREACH(bp, &vp->v_cleanblkhd, b_vnbufs) { | |
1182 | (*pr)(" bp %p\n", bp); | 1182 | (*pr)(" bp %p\n", bp); | |
1183 | vfs_buf_print(bp, full, pr); | 1183 | vfs_buf_print(bp, full, pr); | |
1184 | } | 1184 | } | |
1185 | 1185 | |||
1186 | (*pr)("dirty bufs:\n"); | 1186 | (*pr)("dirty bufs:\n"); | |
1187 | LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) { | 1187 | LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) { | |
1188 | (*pr)(" bp %p\n", bp); | 1188 | (*pr)(" bp %p\n", bp); | |
1189 | vfs_buf_print(bp, full, pr); | 1189 | vfs_buf_print(bp, full, pr); | |
1190 | } | 1190 | } | |
1191 | } | 1191 | } | |
1192 | } | 1192 | } | |
1193 | 1193 | |||
1194 | void | 1194 | void | |
1195 | vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...)) | 1195 | vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...)) | |
1196 | { | 1196 | { | |
1197 | char sbuf[256]; | 1197 | char sbuf[256]; | |
1198 | 1198 | |||
1199 | (*pr)("vnodecovered = %p syncer = %p data = %p\n", | 1199 | (*pr)("vnodecovered = %p syncer = %p data = %p\n", | |
1200 | mp->mnt_vnodecovered,mp->mnt_syncer,mp->mnt_data); | 1200 | mp->mnt_vnodecovered,mp->mnt_syncer,mp->mnt_data); | |
1201 | 1201 | |||
1202 | (*pr)("fs_bshift %d dev_bshift = %d\n", | 1202 | (*pr)("fs_bshift %d dev_bshift = %d\n", | |
1203 | mp->mnt_fs_bshift,mp->mnt_dev_bshift); | 1203 | mp->mnt_fs_bshift,mp->mnt_dev_bshift); | |
1204 | 1204 | |||
1205 | snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_flag); | 1205 | snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_flag); | |
1206 | (*pr)("flag = %s\n", sbuf); | 1206 | (*pr)("flag = %s\n", sbuf); | |
1207 | 1207 | |||
1208 | snprintb(sbuf, sizeof(sbuf), __IMNT_FLAG_BITS, mp->mnt_iflag); | 1208 | snprintb(sbuf, sizeof(sbuf), __IMNT_FLAG_BITS, mp->mnt_iflag); | |
1209 | (*pr)("iflag = %s\n", sbuf); | 1209 | (*pr)("iflag = %s\n", sbuf); | |
1210 | 1210 | |||
1211 | (*pr)("refcnt = %d unmounting @ %p updating @ %p\n", mp->mnt_refcnt, | 1211 | (*pr)("refcnt = %d unmounting @ %p updating @ %p\n", mp->mnt_refcnt, | |
1212 | &mp->mnt_unmounting, &mp->mnt_updating); | 1212 | &mp->mnt_unmounting, &mp->mnt_updating); | |
1213 | 1213 | |||
1214 | (*pr)("statvfs cache:\n"); | 1214 | (*pr)("statvfs cache:\n"); | |
1215 | (*pr)("\tbsize = %lu\n",mp->mnt_stat.f_bsize); | 1215 | (*pr)("\tbsize = %lu\n",mp->mnt_stat.f_bsize); | |
1216 | (*pr)("\tfrsize = %lu\n",mp->mnt_stat.f_frsize); | 1216 | (*pr)("\tfrsize = %lu\n",mp->mnt_stat.f_frsize); | |
1217 | (*pr)("\tiosize = %lu\n",mp->mnt_stat.f_iosize); | 1217 | (*pr)("\tiosize = %lu\n",mp->mnt_stat.f_iosize); | |
1218 | 1218 | |||
1219 | (*pr)("\tblocks = %"PRIu64"\n",mp->mnt_stat.f_blocks); | 1219 | (*pr)("\tblocks = %"PRIu64"\n",mp->mnt_stat.f_blocks); | |
1220 | (*pr)("\tbfree = %"PRIu64"\n",mp->mnt_stat.f_bfree); | 1220 | (*pr)("\tbfree = %"PRIu64"\n",mp->mnt_stat.f_bfree); | |
1221 | (*pr)("\tbavail = %"PRIu64"\n",mp->mnt_stat.f_bavail); | 1221 | (*pr)("\tbavail = %"PRIu64"\n",mp->mnt_stat.f_bavail); | |
1222 | (*pr)("\tbresvd = %"PRIu64"\n",mp->mnt_stat.f_bresvd); | 1222 | (*pr)("\tbresvd = %"PRIu64"\n",mp->mnt_stat.f_bresvd); | |
1223 | 1223 | |||
1224 | (*pr)("\tfiles = %"PRIu64"\n",mp->mnt_stat.f_files); | 1224 | (*pr)("\tfiles = %"PRIu64"\n",mp->mnt_stat.f_files); | |
1225 | (*pr)("\tffree = %"PRIu64"\n",mp->mnt_stat.f_ffree); | 1225 | (*pr)("\tffree = %"PRIu64"\n",mp->mnt_stat.f_ffree); | |
1226 | (*pr)("\tfavail = %"PRIu64"\n",mp->mnt_stat.f_favail); | 1226 | (*pr)("\tfavail = %"PRIu64"\n",mp->mnt_stat.f_favail); | |
1227 | (*pr)("\tfresvd = %"PRIu64"\n",mp->mnt_stat.f_fresvd); | 1227 | (*pr)("\tfresvd = %"PRIu64"\n",mp->mnt_stat.f_fresvd); | |
1228 | 1228 | |||
1229 | (*pr)("\tf_fsidx = { 0x%"PRIx32", 0x%"PRIx32" }\n", | 1229 | (*pr)("\tf_fsidx = { 0x%"PRIx32", 0x%"PRIx32" }\n", | |
1230 | mp->mnt_stat.f_fsidx.__fsid_val[0], | 1230 | mp->mnt_stat.f_fsidx.__fsid_val[0], | |
1231 | mp->mnt_stat.f_fsidx.__fsid_val[1]); | 1231 | mp->mnt_stat.f_fsidx.__fsid_val[1]); | |
1232 | 1232 | |||
1233 | (*pr)("\towner = %"PRIu32"\n",mp->mnt_stat.f_owner); | 1233 | (*pr)("\towner = %"PRIu32"\n",mp->mnt_stat.f_owner); | |
1234 | (*pr)("\tnamemax = %lu\n",mp->mnt_stat.f_namemax); | 1234 | (*pr)("\tnamemax = %lu\n",mp->mnt_stat.f_namemax); | |
1235 | 1235 | |||
1236 | snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_stat.f_flag); | 1236 | snprintb(sbuf, sizeof(sbuf), __MNT_FLAG_BITS, mp->mnt_stat.f_flag); | |
1237 | 1237 | |||
1238 | (*pr)("\tflag = %s\n",sbuf); | 1238 | (*pr)("\tflag = %s\n",sbuf); | |
1239 | (*pr)("\tsyncwrites = %" PRIu64 "\n",mp->mnt_stat.f_syncwrites); | 1239 | (*pr)("\tsyncwrites = %" PRIu64 "\n",mp->mnt_stat.f_syncwrites); | |
1240 | (*pr)("\tasyncwrites = %" PRIu64 "\n",mp->mnt_stat.f_asyncwrites); | 1240 | (*pr)("\tasyncwrites = %" PRIu64 "\n",mp->mnt_stat.f_asyncwrites); | |
1241 | (*pr)("\tsyncreads = %" PRIu64 "\n",mp->mnt_stat.f_syncreads); | 1241 | (*pr)("\tsyncreads = %" PRIu64 "\n",mp->mnt_stat.f_syncreads); | |
1242 | (*pr)("\tasyncreads = %" PRIu64 "\n",mp->mnt_stat.f_asyncreads); | 1242 | (*pr)("\tasyncreads = %" PRIu64 "\n",mp->mnt_stat.f_asyncreads); | |
1243 | (*pr)("\tfstypename = %s\n",mp->mnt_stat.f_fstypename); | 1243 | (*pr)("\tfstypename = %s\n",mp->mnt_stat.f_fstypename); | |
1244 | (*pr)("\tmntonname = %s\n",mp->mnt_stat.f_mntonname); | 1244 | (*pr)("\tmntonname = %s\n",mp->mnt_stat.f_mntonname); | |
1245 | (*pr)("\tmntfromname = %s\n",mp->mnt_stat.f_mntfromname); | 1245 | (*pr)("\tmntfromname = %s\n",mp->mnt_stat.f_mntfromname); | |
1246 | 1246 | |||
1247 | { | 1247 | { | |
1248 | int cnt = 0; | 1248 | int cnt = 0; | |
1249 | struct vnode *vp; | 1249 | struct vnode *vp; | |
1250 | (*pr)("locked vnodes ="); | 1250 | (*pr)("locked vnodes ="); | |
1251 | TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) { | 1251 | TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) { | |
1252 | if (VOP_ISLOCKED(vp)) { | 1252 | if (VOP_ISLOCKED(vp)) { | |
1253 | if ((++cnt % 6) == 0) { | 1253 | if ((++cnt % 6) == 0) { | |
1254 | (*pr)(" %p,\n\t", vp); | 1254 | (*pr)(" %p,\n\t", vp); | |
1255 | } else { | 1255 | } else { | |
1256 | (*pr)(" %p,", vp); | 1256 | (*pr)(" %p,", vp); | |
1257 | } | 1257 | } | |
1258 | } | 1258 | } | |
1259 | } | 1259 | } | |
1260 | (*pr)("\n"); | 1260 | (*pr)("\n"); | |
1261 | } | 1261 | } | |
1262 | 1262 | |||
1263 | if (full) { | 1263 | if (full) { | |
1264 | int cnt = 0; | 1264 | int cnt = 0; | |
1265 | struct vnode *vp; | 1265 | struct vnode *vp; | |
1266 | (*pr)("all vnodes ="); | 1266 | (*pr)("all vnodes ="); | |
1267 | TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) { | 1267 | TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) { | |
1268 | if (!TAILQ_NEXT(vp, v_mntvnodes)) { | 1268 | if (!TAILQ_NEXT(vp, v_mntvnodes)) { | |
1269 | (*pr)(" %p", vp); | 1269 | (*pr)(" %p", vp); | |
1270 | } else if ((++cnt % 6) == 0) { | 1270 | } else if ((++cnt % 6) == 0) { | |
1271 | (*pr)(" %p,\n\t", vp); | 1271 | (*pr)(" %p,\n\t", vp); | |
1272 | } else { | 1272 | } else { | |
1273 | (*pr)(" %p,", vp); | 1273 | (*pr)(" %p,", vp); | |
1274 | } | 1274 | } | |
1275 | } | 1275 | } | |
1276 | (*pr)("\n", vp); | 1276 | (*pr)("\n", vp); | |
1277 | } | 1277 | } | |
1278 | } | 1278 | } | |
1279 | 1279 | |||
1280 | /* | 1280 | /* | |
1281 | * List all of the locked vnodes in the system. | 1281 | * List all of the locked vnodes in the system. | |
1282 | */ | 1282 | */ | |
1283 | void printlockedvnodes(void); | 1283 | void printlockedvnodes(void); | |
1284 | 1284 | |||
1285 | void | 1285 | void | |
1286 | printlockedvnodes(void) | 1286 | printlockedvnodes(void) | |
1287 | { | 1287 | { | |
1288 | struct mount *mp, *nmp; | 1288 | struct mount *mp, *nmp; | |
1289 | struct vnode *vp; | 1289 | struct vnode *vp; | |
1290 | 1290 | |||
1291 | printf("Locked vnodes\n"); | 1291 | printf("Locked vnodes\n"); | |
1292 | mutex_enter(&mountlist_lock); | 1292 | mutex_enter(&mountlist_lock); | |
1293 | for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; | 1293 | for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; | |
1294 | mp = nmp) { | 1294 | mp = nmp) { | |
1295 | if (vfs_busy(mp, &nmp)) { | 1295 | if (vfs_busy(mp, &nmp)) { | |
1296 | continue; | 1296 | continue; | |
1297 | } | 1297 | } | |
1298 | TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) { | 1298 | TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) { | |
1299 | if (VOP_ISLOCKED(vp)) | 1299 | if (VOP_ISLOCKED(vp)) | |
1300 | vprint(NULL, vp); | 1300 | vprint(NULL, vp); | |
1301 | } | 1301 | } | |
1302 | mutex_enter(&mountlist_lock); | 1302 | mutex_enter(&mountlist_lock); | |
1303 | vfs_unbusy(mp, false, &nmp); | 1303 | vfs_unbusy(mp, false, &nmp); | |
1304 | } | 1304 | } | |
1305 | mutex_exit(&mountlist_lock); | 1305 | mutex_exit(&mountlist_lock); | |
1306 | } | 1306 | } | |
1307 | 1307 | |||
1308 | #endif /* DDB || DEBUGPRINT */ | 1308 | #endif /* DDB || DEBUGPRINT */ |
--- src/sys/miscfs/genfs/layer_extern.h 2011/07/11 08:27:38 1.29
+++ src/sys/miscfs/genfs/layer_extern.h 2012/01/29 06:32:44 1.30
@@ -1,120 +1,120 @@ | @@ -1,120 +1,120 @@ | |||
1 | /* $NetBSD: layer_extern.h,v 1.29 2011/07/11 08:27:38 hannken Exp $ */ | 1 | /* $NetBSD: layer_extern.h,v 1.30 2012/01/29 06:32:44 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1999 National Aeronautics & Space Administration | 4 | * Copyright (c) 1999 National Aeronautics & Space Administration | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This software was written by William Studenmund of the | 7 | * This software was written by William Studenmund of the | |
8 | * Numerical Aerospace Simulation Facility, NASA Ames Research Center. | 8 | * Numerical Aerospace Simulation Facility, NASA Ames Research Center. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. Neither the name of the National Aeronautics & Space Administration | 18 | * 3. Neither the name of the National Aeronautics & Space Administration | |
19 | * nor the names of its contributors may be used to endorse or promote | 19 | * nor the names of its contributors may be used to endorse or promote | |
20 | * products derived from this software without specific prior written | 20 | * products derived from this software without specific prior written | |
21 | * permission. | 21 | * permission. | |
22 | * | 22 | * | |
23 | * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION | 23 | * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION | |
24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB- | 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB- | |
27 | * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | 27 | * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
28 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 28 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
33 | * POSSIBILITY OF SUCH DAMAGE. | 33 | * POSSIBILITY OF SUCH DAMAGE. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | /* | 36 | /* | |
37 | * Copyright (c) 1992, 1993, 1995 | 37 | * Copyright (c) 1992, 1993, 1995 | |
38 | * The Regents of the University of California. All rights reserved. | 38 | * The Regents of the University of California. All rights reserved. | |
39 | * | 39 | * | |
40 | * This code is derived from software donated to Berkeley by | 40 | * This code is derived from software donated to Berkeley by | |
41 | * Jan-Simon Pendry. | 41 | * Jan-Simon Pendry. | |
42 | * | 42 | * | |
43 | * Redistribution and use in source and binary forms, with or without | 43 | * Redistribution and use in source and binary forms, with or without | |
44 | * modification, are permitted provided that the following conditions | 44 | * modification, are permitted provided that the following conditions | |
45 | * are met: | 45 | * are met: | |
46 | * 1. Redistributions of source code must retain the above copyright | 46 | * 1. Redistributions of source code must retain the above copyright | |
47 | * notice, this list of conditions and the following disclaimer. | 47 | * notice, this list of conditions and the following disclaimer. | |
48 | * 2. Redistributions in binary form must reproduce the above copyright | 48 | * 2. Redistributions in binary form must reproduce the above copyright | |
49 | * notice, this list of conditions and the following disclaimer in the | 49 | * notice, this list of conditions and the following disclaimer in the | |
50 | * documentation and/or other materials provided with the distribution. | 50 | * documentation and/or other materials provided with the distribution. | |
51 | * 3. Neither the name of the University nor the names of its contributors | 51 | * 3. Neither the name of the University nor the names of its contributors | |
52 | * may be used to endorse or promote products derived from this software | 52 | * may be used to endorse or promote products derived from this software | |
53 | * without specific prior written permission. | 53 | * without specific prior written permission. | |
54 | * | 54 | * | |
55 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 55 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
56 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 56 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
57 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 57 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
58 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 58 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
59 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 59 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
60 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 60 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
61 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 61 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
62 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 62 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
63 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 63 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
64 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 64 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
65 | * SUCH DAMAGE. | 65 | * SUCH DAMAGE. | |
66 | * | 66 | * | |
67 | */ | 67 | */ | |
68 | 68 | |||
69 | #ifndef _MISCFS_GENFS_LAYER_EXTERN_H_ | 69 | #ifndef _MISCFS_GENFS_LAYER_EXTERN_H_ | |
70 | #define _MISCFS_GENFS_LAYER_EXTERN_H_ | 70 | #define _MISCFS_GENFS_LAYER_EXTERN_H_ | |
71 | 71 | |||
72 | /* | 72 | /* | |
73 | * Routines defined by layerfs | 73 | * Routines defined by layerfs | |
74 | */ | 74 | */ | |
75 | 75 | |||
76 | /* Routines to manage nodes. */ | 76 | /* Routines to manage nodes. */ | |
77 | void layerfs_init(void); | 77 | void layerfs_init(void); | |
78 | void layerfs_done(void); | 78 | void layerfs_done(void); | |
79 | int layer_node_alloc(struct mount *, struct vnode *, struct vnode **); | 79 | int layer_node_alloc(struct mount *, struct vnode *, struct vnode **); | |
80 | int layer_node_create(struct mount *, struct vnode *, struct vnode **); | 80 | int layer_node_create(struct mount *, struct vnode *, struct vnode **); | |
81 | struct vnode *layer_node_find(struct mount *, struct vnode *); | 81 | struct vnode *layer_node_find(struct mount *, struct vnode *); | |
82 | 82 | |||
83 | #define LOG2_SIZEVNODE 7 /* log2(sizeof struct vnode) */ | 83 | #define LOG2_SIZEVNODE 7 /* log2(sizeof struct vnode) */ | |
84 | #define LAYER_NHASH(lmp, vp) \ | 84 | #define LAYER_NHASH(lmp, vp) \ | |
85 | (&((lmp)->layerm_node_hashtbl[(((u_long)vp)>>LOG2_SIZEVNODE) & \ | 85 | (&((lmp)->layerm_node_hashtbl[(((u_long)vp)>>LOG2_SIZEVNODE) & \ | |
86 | (lmp)->layerm_node_hash])) | 86 | (lmp)->layerm_node_hash])) | |
87 | 87 | |||
88 | /* VFS routines */ | 88 | /* VFS routines */ | |
89 | int layerfs_start(struct mount *, int); | 89 | int layerfs_start(struct mount *, int); | |
90 | int layerfs_root(struct mount *, struct vnode **); | 90 | int layerfs_root(struct mount *, struct vnode **); | |
91 | int layerfs_quotactl(struct mount *, prop_dictionary_t); | 91 | int layerfs_quotactl(struct mount *, prop_dictionary_t, int); | |
92 | int layerfs_statvfs(struct mount *, struct statvfs *); | 92 | int layerfs_statvfs(struct mount *, struct statvfs *); | |
93 | int layerfs_sync(struct mount *, int, struct kauth_cred *); | 93 | int layerfs_sync(struct mount *, int, struct kauth_cred *); | |
94 | int layerfs_vget(struct mount *, ino_t, struct vnode **); | 94 | int layerfs_vget(struct mount *, ino_t, struct vnode **); | |
95 | int layerfs_fhtovp(struct mount *, struct fid *, struct vnode **); | 95 | int layerfs_fhtovp(struct mount *, struct fid *, struct vnode **); | |
96 | int layerfs_vptofh(struct vnode *, struct fid *, size_t *); | 96 | int layerfs_vptofh(struct vnode *, struct fid *, size_t *); | |
97 | int layerfs_snapshot(struct mount *, struct vnode *, struct timespec *); | 97 | int layerfs_snapshot(struct mount *, struct vnode *, struct timespec *); | |
98 | int layerfs_renamelock_enter(struct mount *); | 98 | int layerfs_renamelock_enter(struct mount *); | |
99 | void layerfs_renamelock_exit(struct mount *); | 99 | void layerfs_renamelock_exit(struct mount *); | |
100 | 100 | |||
101 | /* VOP routines */ | 101 | /* VOP routines */ | |
102 | int layer_bypass(void *); | 102 | int layer_bypass(void *); | |
103 | int layer_getattr(void *); | 103 | int layer_getattr(void *); | |
104 | int layer_inactive(void *); | 104 | int layer_inactive(void *); | |
105 | int layer_reclaim(void *); | 105 | int layer_reclaim(void *); | |
106 | int layer_print(void *); | 106 | int layer_print(void *); | |
107 | int layer_bmap(void *); | 107 | int layer_bmap(void *); | |
108 | int layer_fsync(void *); | 108 | int layer_fsync(void *); | |
109 | int layer_lookup(void *); | 109 | int layer_lookup(void *); | |
110 | int layer_setattr(void *); | 110 | int layer_setattr(void *); | |
111 | int layer_access(void *); | 111 | int layer_access(void *); | |
112 | int layer_open(void *); | 112 | int layer_open(void *); | |
113 | int layer_remove(void *); | 113 | int layer_remove(void *); | |
114 | int layer_rename(void *); | 114 | int layer_rename(void *); | |
115 | int layer_revoke(void *); | 115 | int layer_revoke(void *); | |
116 | int layer_rmdir(void *); | 116 | int layer_rmdir(void *); | |
117 | int layer_getpages(void *); | 117 | int layer_getpages(void *); | |
118 | int layer_putpages(void *); | 118 | int layer_putpages(void *); | |
119 | 119 | |||
120 | #endif /* _MISCFS_GENFS_LAYER_EXTERN_H_ */ | 120 | #endif /* _MISCFS_GENFS_LAYER_EXTERN_H_ */ |
--- src/sys/miscfs/genfs/layer_vfsops.c 2011/03/06 17:08:36 1.34
+++ src/sys/miscfs/genfs/layer_vfsops.c 2012/01/29 06:32:44 1.35
@@ -1,307 +1,307 @@ | @@ -1,307 +1,307 @@ | |||
1 | /* $NetBSD: layer_vfsops.c,v 1.34 2011/03/06 17:08:36 bouyer Exp $ */ | 1 | /* $NetBSD: layer_vfsops.c,v 1.35 2012/01/29 06:32:44 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1999 National Aeronautics & Space Administration | 4 | * Copyright (c) 1999 National Aeronautics & Space Administration | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This software was written by William Studenmund of the | 7 | * This software was written by William Studenmund of the | |
8 | * Numerical Aerospace Simulation Facility, NASA Ames Research Center. | 8 | * Numerical Aerospace Simulation Facility, NASA Ames Research Center. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. Neither the name of the National Aeronautics & Space Administration | 18 | * 3. Neither the name of the National Aeronautics & Space Administration | |
19 | * nor the names of its contributors may be used to endorse or promote | 19 | * nor the names of its contributors may be used to endorse or promote | |
20 | * products derived from this software without specific prior written | 20 | * products derived from this software without specific prior written | |
21 | * permission. | 21 | * permission. | |
22 | * | 22 | * | |
23 | * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION | 23 | * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION | |
24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB- | 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB- | |
27 | * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | 27 | * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
28 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 28 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
33 | * POSSIBILITY OF SUCH DAMAGE. | 33 | * POSSIBILITY OF SUCH DAMAGE. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | /* | 36 | /* | |
37 | * Copyright (c) 1992, 1993, 1995 | 37 | * Copyright (c) 1992, 1993, 1995 | |
38 | * The Regents of the University of California. All rights reserved. | 38 | * The Regents of the University of California. All rights reserved. | |
39 | * | 39 | * | |
40 | * This code is derived from software donated to Berkeley by | 40 | * This code is derived from software donated to Berkeley by | |
41 | * Jan-Simon Pendry. | 41 | * Jan-Simon Pendry. | |
42 | * | 42 | * | |
43 | * Redistribution and use in source and binary forms, with or without | 43 | * Redistribution and use in source and binary forms, with or without | |
44 | * modification, are permitted provided that the following conditions | 44 | * modification, are permitted provided that the following conditions | |
45 | * are met: | 45 | * are met: | |
46 | * 1. Redistributions of source code must retain the above copyright | 46 | * 1. Redistributions of source code must retain the above copyright | |
47 | * notice, this list of conditions and the following disclaimer. | 47 | * notice, this list of conditions and the following disclaimer. | |
48 | * 2. Redistributions in binary form must reproduce the above copyright | 48 | * 2. Redistributions in binary form must reproduce the above copyright | |
49 | * notice, this list of conditions and the following disclaimer in the | 49 | * notice, this list of conditions and the following disclaimer in the | |
50 | * documentation and/or other materials provided with the distribution. | 50 | * documentation and/or other materials provided with the distribution. | |
51 | * 3. Neither the name of the University nor the names of its contributors | 51 | * 3. Neither the name of the University nor the names of its contributors | |
52 | * may be used to endorse or promote products derived from this software | 52 | * may be used to endorse or promote products derived from this software | |
53 | * without specific prior written permission. | 53 | * without specific prior written permission. | |
54 | * | 54 | * | |
55 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 55 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
56 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 56 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
57 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 57 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
58 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 58 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
59 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 59 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
60 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 60 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
61 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 61 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
62 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 62 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
63 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 63 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
64 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 64 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
65 | * SUCH DAMAGE. | 65 | * SUCH DAMAGE. | |
66 | * | 66 | * | |
67 | * from: Id: lofs_vfsops.c,v 1.9 1992/05/30 10:26:24 jsp Exp | 67 | * from: Id: lofs_vfsops.c,v 1.9 1992/05/30 10:26:24 jsp Exp | |
68 | * from: @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92 | 68 | * from: @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92 | |
69 | * @(#)null_vfsops.c 8.7 (Berkeley) 5/14/95 | 69 | * @(#)null_vfsops.c 8.7 (Berkeley) 5/14/95 | |
70 | */ | 70 | */ | |
71 | 71 | |||
72 | /* | 72 | /* | |
73 | * Generic layer VFS operations. | 73 | * Generic layer VFS operations. | |
74 | */ | 74 | */ | |
75 | 75 | |||
76 | #include <sys/cdefs.h> | 76 | #include <sys/cdefs.h> | |
77 | __KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.34 2011/03/06 17:08:36 bouyer Exp $"); | 77 | __KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.35 2012/01/29 06:32:44 dholland Exp $"); | |
78 | 78 | |||
79 | #include <sys/param.h> | 79 | #include <sys/param.h> | |
80 | #include <sys/sysctl.h> | 80 | #include <sys/sysctl.h> | |
81 | #include <sys/systm.h> | 81 | #include <sys/systm.h> | |
82 | #include <sys/vnode.h> | 82 | #include <sys/vnode.h> | |
83 | #include <sys/mount.h> | 83 | #include <sys/mount.h> | |
84 | #include <sys/namei.h> | 84 | #include <sys/namei.h> | |
85 | #include <sys/malloc.h> | 85 | #include <sys/malloc.h> | |
86 | #include <sys/kauth.h> | 86 | #include <sys/kauth.h> | |
87 | #include <sys/module.h> | 87 | #include <sys/module.h> | |
88 | 88 | |||
89 | #include <miscfs/genfs/layer.h> | 89 | #include <miscfs/genfs/layer.h> | |
90 | #include <miscfs/genfs/layer_extern.h> | 90 | #include <miscfs/genfs/layer_extern.h> | |
91 | 91 | |||
92 | MODULE(MODULE_CLASS_MISC, layerfs, NULL); | 92 | MODULE(MODULE_CLASS_MISC, layerfs, NULL); | |
93 | 93 | |||
94 | static int | 94 | static int | |
95 | layerfs_modcmd(modcmd_t cmd, void *arg) | 95 | layerfs_modcmd(modcmd_t cmd, void *arg) | |
96 | { | 96 | { | |
97 | 97 | |||
98 | switch (cmd) { | 98 | switch (cmd) { | |
99 | case MODULE_CMD_INIT: | 99 | case MODULE_CMD_INIT: | |
100 | return 0; | 100 | return 0; | |
101 | case MODULE_CMD_FINI: | 101 | case MODULE_CMD_FINI: | |
102 | return 0; | 102 | return 0; | |
103 | default: | 103 | default: | |
104 | return ENOTTY; | 104 | return ENOTTY; | |
105 | } | 105 | } | |
106 | return 0; | 106 | return 0; | |
107 | } | 107 | } | |
108 | 108 | |||
109 | /* | 109 | /* | |
110 | * VFS start. Nothing needed here - the start routine on the underlying | 110 | * VFS start. Nothing needed here - the start routine on the underlying | |
111 | * filesystem will have been called when that filesystem was mounted. | 111 | * filesystem will have been called when that filesystem was mounted. | |
112 | */ | 112 | */ | |
113 | int | 113 | int | |
114 | layerfs_start(struct mount *mp, int flags) | 114 | layerfs_start(struct mount *mp, int flags) | |
115 | { | 115 | { | |
116 | 116 | |||
117 | #ifdef notyet | 117 | #ifdef notyet | |
118 | return VFS_START(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, flags); | 118 | return VFS_START(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, flags); | |
119 | #else | 119 | #else | |
120 | return 0; | 120 | return 0; | |
121 | #endif | 121 | #endif | |
122 | } | 122 | } | |
123 | 123 | |||
124 | int | 124 | int | |
125 | layerfs_root(struct mount *mp, struct vnode **vpp) | 125 | layerfs_root(struct mount *mp, struct vnode **vpp) | |
126 | { | 126 | { | |
127 | struct vnode *vp; | 127 | struct vnode *vp; | |
128 | 128 | |||
129 | vp = MOUNTTOLAYERMOUNT(mp)->layerm_rootvp; | 129 | vp = MOUNTTOLAYERMOUNT(mp)->layerm_rootvp; | |
130 | if (vp == NULL) { | 130 | if (vp == NULL) { | |
131 | *vpp = NULL; | 131 | *vpp = NULL; | |
132 | return EINVAL; | 132 | return EINVAL; | |
133 | } | 133 | } | |
134 | /* | 134 | /* | |
135 | * Return root vnode with locked and with a reference held. | 135 | * Return root vnode with locked and with a reference held. | |
136 | */ | 136 | */ | |
137 | vref(vp); | 137 | vref(vp); | |
138 | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); | 138 | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); | |
139 | *vpp = vp; | 139 | *vpp = vp; | |
140 | return 0; | 140 | return 0; | |
141 | } | 141 | } | |
142 | 142 | |||
143 | int | 143 | int | |
144 | layerfs_quotactl(struct mount *mp, prop_dictionary_t dict) | 144 | layerfs_quotactl(struct mount *mp, prop_dictionary_t dict, int dummy) | |
145 | { | 145 | { | |
146 | 146 | |||
147 | return VFS_QUOTACTL(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, dict); | 147 | return VFS_QUOTACTL(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, dict, dummy); | |
148 | } | 148 | } | |
149 | 149 | |||
150 | int | 150 | int | |
151 | layerfs_statvfs(struct mount *mp, struct statvfs *sbp) | 151 | layerfs_statvfs(struct mount *mp, struct statvfs *sbp) | |
152 | { | 152 | { | |
153 | struct statvfs *sbuf; | 153 | struct statvfs *sbuf; | |
154 | int error; | 154 | int error; | |
155 | 155 | |||
156 | sbuf = kmem_zalloc(sizeof(*sbuf), KM_SLEEP); | 156 | sbuf = kmem_zalloc(sizeof(*sbuf), KM_SLEEP); | |
157 | if (sbuf == NULL) { | 157 | if (sbuf == NULL) { | |
158 | return ENOMEM; | 158 | return ENOMEM; | |
159 | } | 159 | } | |
160 | error = VFS_STATVFS(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, sbuf); | 160 | error = VFS_STATVFS(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, sbuf); | |
161 | if (error) { | 161 | if (error) { | |
162 | goto done; | 162 | goto done; | |
163 | } | 163 | } | |
164 | /* Copy across the relevant data and fake the rest. */ | 164 | /* Copy across the relevant data and fake the rest. */ | |
165 | sbp->f_flag = sbuf->f_flag; | 165 | sbp->f_flag = sbuf->f_flag; | |
166 | sbp->f_bsize = sbuf->f_bsize; | 166 | sbp->f_bsize = sbuf->f_bsize; | |
167 | sbp->f_frsize = sbuf->f_frsize; | 167 | sbp->f_frsize = sbuf->f_frsize; | |
168 | sbp->f_iosize = sbuf->f_iosize; | 168 | sbp->f_iosize = sbuf->f_iosize; | |
169 | sbp->f_blocks = sbuf->f_blocks; | 169 | sbp->f_blocks = sbuf->f_blocks; | |
170 | sbp->f_bfree = sbuf->f_bfree; | 170 | sbp->f_bfree = sbuf->f_bfree; | |
171 | sbp->f_bavail = sbuf->f_bavail; | 171 | sbp->f_bavail = sbuf->f_bavail; | |
172 | sbp->f_bresvd = sbuf->f_bresvd; | 172 | sbp->f_bresvd = sbuf->f_bresvd; | |
173 | sbp->f_files = sbuf->f_files; | 173 | sbp->f_files = sbuf->f_files; | |
174 | sbp->f_ffree = sbuf->f_ffree; | 174 | sbp->f_ffree = sbuf->f_ffree; | |
175 | sbp->f_favail = sbuf->f_favail; | 175 | sbp->f_favail = sbuf->f_favail; | |
176 | sbp->f_fresvd = sbuf->f_fresvd; | 176 | sbp->f_fresvd = sbuf->f_fresvd; | |
177 | sbp->f_namemax = sbuf->f_namemax; | 177 | sbp->f_namemax = sbuf->f_namemax; | |
178 | copy_statvfs_info(sbp, mp); | 178 | copy_statvfs_info(sbp, mp); | |
179 | done: | 179 | done: | |
180 | kmem_free(sbuf, sizeof(*sbuf)); | 180 | kmem_free(sbuf, sizeof(*sbuf)); | |
181 | return error; | 181 | return error; | |
182 | } | 182 | } | |
183 | 183 | |||
184 | int | 184 | int | |
185 | layerfs_sync(struct mount *mp, int waitfor, | 185 | layerfs_sync(struct mount *mp, int waitfor, | |
186 | kauth_cred_t cred) | 186 | kauth_cred_t cred) | |
187 | { | 187 | { | |
188 | 188 | |||
189 | /* | 189 | /* | |
190 | * XXX - Assumes no data cached at layer. | 190 | * XXX - Assumes no data cached at layer. | |
191 | */ | 191 | */ | |
192 | return 0; | 192 | return 0; | |
193 | } | 193 | } | |
194 | 194 | |||
195 | int | 195 | int | |
196 | layerfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) | 196 | layerfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) | |
197 | { | 197 | { | |
198 | struct vnode *vp; | 198 | struct vnode *vp; | |
199 | int error; | 199 | int error; | |
200 | 200 | |||
201 | error = VFS_VGET(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, ino, &vp); | 201 | error = VFS_VGET(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, ino, &vp); | |
202 | if (error) { | 202 | if (error) { | |
203 | *vpp = NULL; | 203 | *vpp = NULL; | |
204 | return error; | 204 | return error; | |
205 | } | 205 | } | |
206 | error = layer_node_create(mp, vp, vpp); | 206 | error = layer_node_create(mp, vp, vpp); | |
207 | if (error) { | 207 | if (error) { | |
208 | vput(vp); | 208 | vput(vp); | |
209 | *vpp = NULL; | 209 | *vpp = NULL; | |
210 | return error; | 210 | return error; | |
211 | } | 211 | } | |
212 | return 0; | 212 | return 0; | |
213 | } | 213 | } | |
214 | 214 | |||
215 | int | 215 | int | |
216 | layerfs_fhtovp(struct mount *mp, struct fid *fidp, struct vnode **vpp) | 216 | layerfs_fhtovp(struct mount *mp, struct fid *fidp, struct vnode **vpp) | |
217 | { | 217 | { | |
218 | struct vnode *vp; | 218 | struct vnode *vp; | |
219 | int error; | 219 | int error; | |
220 | 220 | |||
221 | error = VFS_FHTOVP(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, fidp, &vp); | 221 | error = VFS_FHTOVP(MOUNTTOLAYERMOUNT(mp)->layerm_vfs, fidp, &vp); | |
222 | if (error) { | 222 | if (error) { | |
223 | return error; | 223 | return error; | |
224 | } | 224 | } | |
225 | error = layer_node_create(mp, vp, vpp); | 225 | error = layer_node_create(mp, vp, vpp); | |
226 | if (error) { | 226 | if (error) { | |
227 | vput(vp); | 227 | vput(vp); | |
228 | *vpp = NULL; | 228 | *vpp = NULL; | |
229 | return (error); | 229 | return (error); | |
230 | } | 230 | } | |
231 | return 0; | 231 | return 0; | |
232 | } | 232 | } | |
233 | 233 | |||
234 | int | 234 | int | |
235 | layerfs_vptofh(struct vnode *vp, struct fid *fhp, size_t *fh_size) | 235 | layerfs_vptofh(struct vnode *vp, struct fid *fhp, size_t *fh_size) | |
236 | { | 236 | { | |
237 | 237 | |||
238 | return VFS_VPTOFH(LAYERVPTOLOWERVP(vp), fhp, fh_size); | 238 | return VFS_VPTOFH(LAYERVPTOLOWERVP(vp), fhp, fh_size); | |
239 | } | 239 | } | |
240 | 240 | |||
241 | /* | 241 | /* | |
242 | * layerfs_snapshot - handle a snapshot through a layered file system | 242 | * layerfs_snapshot - handle a snapshot through a layered file system | |
243 | * | 243 | * | |
244 | * At present, we do NOT support snapshotting through a layered file | 244 | * At present, we do NOT support snapshotting through a layered file | |
245 | * system as the ffs implementation changes v_vnlock of the snapshot | 245 | * system as the ffs implementation changes v_vnlock of the snapshot | |
246 | * vnodes to point to one common lock. As there is no way for us to | 246 | * vnodes to point to one common lock. As there is no way for us to | |
247 | * absolutely pass this change up the stack, a layered file system | 247 | * absolutely pass this change up the stack, a layered file system | |
248 | * would end up referencing the wrong lock. | 248 | * would end up referencing the wrong lock. | |
249 | * | 249 | * | |
250 | * This routine serves as a central resource for this behavior; all | 250 | * This routine serves as a central resource for this behavior; all | |
251 | * layered file systems don't need to worry about the above. Also, if | 251 | * layered file systems don't need to worry about the above. Also, if | |
252 | * things get fixed, all layers get the benefit. | 252 | * things get fixed, all layers get the benefit. | |
253 | */ | 253 | */ | |
254 | int | 254 | int | |
255 | layerfs_snapshot(struct mount *mp, struct vnode *vp, | 255 | layerfs_snapshot(struct mount *mp, struct vnode *vp, | |
256 | struct timespec *ts) | 256 | struct timespec *ts) | |
257 | { | 257 | { | |
258 | 258 | |||
259 | return EOPNOTSUPP; | 259 | return EOPNOTSUPP; | |
260 | } | 260 | } | |
261 | 261 | |||
262 | SYSCTL_SETUP(sysctl_vfs_layerfs_setup, "sysctl vfs.layerfs subtree setup") | 262 | SYSCTL_SETUP(sysctl_vfs_layerfs_setup, "sysctl vfs.layerfs subtree setup") | |
263 | { | 263 | { | |
264 | const struct sysctlnode *layerfs_node = NULL; | 264 | const struct sysctlnode *layerfs_node = NULL; | |
265 | 265 | |||
266 | sysctl_createv(clog, 0, NULL, NULL, | 266 | sysctl_createv(clog, 0, NULL, NULL, | |
267 | CTLFLAG_PERMANENT, | 267 | CTLFLAG_PERMANENT, | |
268 | CTLTYPE_NODE, "vfs", NULL, | 268 | CTLTYPE_NODE, "vfs", NULL, | |
269 | NULL, 0, NULL, 0, | 269 | NULL, 0, NULL, 0, | |
270 | CTL_VFS, CTL_EOL); | 270 | CTL_VFS, CTL_EOL); | |
271 | sysctl_createv(clog, 0, NULL, &layerfs_node, | 271 | sysctl_createv(clog, 0, NULL, &layerfs_node, | |
272 | CTLFLAG_PERMANENT, | 272 | CTLFLAG_PERMANENT, | |
273 | CTLTYPE_NODE, "layerfs", | 273 | CTLTYPE_NODE, "layerfs", | |
274 | SYSCTL_DESCR("Generic layered file system"), | 274 | SYSCTL_DESCR("Generic layered file system"), | |
275 | NULL, 0, NULL, 0, | 275 | NULL, 0, NULL, 0, | |
276 | CTL_VFS, CTL_CREATE); | 276 | CTL_VFS, CTL_CREATE); | |
277 | 277 | |||
278 | #ifdef LAYERFS_DIAGNOSTIC | 278 | #ifdef LAYERFS_DIAGNOSTIC | |
279 | sysctl_createv(clog, 0, &layerfs_node, NULL, | 279 | sysctl_createv(clog, 0, &layerfs_node, NULL, | |
280 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, | 280 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, | |
281 | CTLTYPE_INT, | 281 | CTLTYPE_INT, | |
282 | "debug", | 282 | "debug", | |
283 | SYSCTL_DESCR("Verbose debugging messages"), | 283 | SYSCTL_DESCR("Verbose debugging messages"), | |
284 | NULL, 0, &layerfs_debug, 0, | 284 | NULL, 0, &layerfs_debug, 0, | |
285 | CTL_CREATE, CTL_EOL); | 285 | CTL_CREATE, CTL_EOL); | |
286 | #endif | 286 | #endif | |
287 | 287 | |||
288 | /* | 288 | /* | |
289 | * other subtrees should really be aliases to this, but since | 289 | * other subtrees should really be aliases to this, but since | |
290 | * they can't tell if layerfs has been instantiated yet, they | 290 | * they can't tell if layerfs has been instantiated yet, they | |
291 | * can't do that...not easily. not yet. :-) | 291 | * can't do that...not easily. not yet. :-) | |
292 | */ | 292 | */ | |
293 | } | 293 | } | |
294 | 294 | |||
295 | int | 295 | int | |
296 | layerfs_renamelock_enter(struct mount *mp) | 296 | layerfs_renamelock_enter(struct mount *mp) | |
297 | { | 297 | { | |
298 | 298 | |||
299 | return VFS_RENAMELOCK_ENTER(MOUNTTOLAYERMOUNT(mp)->layerm_vfs); | 299 | return VFS_RENAMELOCK_ENTER(MOUNTTOLAYERMOUNT(mp)->layerm_vfs); | |
300 | } | 300 | } | |
301 | 301 | |||
302 | void | 302 | void | |
303 | layerfs_renamelock_exit(struct mount *mp) | 303 | layerfs_renamelock_exit(struct mount *mp) | |
304 | { | 304 | { | |
305 | 305 | |||
306 | VFS_RENAMELOCK_EXIT(MOUNTTOLAYERMOUNT(mp)->layerm_vfs); | 306 | VFS_RENAMELOCK_EXIT(MOUNTTOLAYERMOUNT(mp)->layerm_vfs); | |
307 | } | 307 | } |
--- src/sys/sys/mount.h 2012/01/29 06:29:04 1.202
+++ src/sys/sys/mount.h 2012/01/29 06:32:43 1.203
@@ -1,467 +1,467 @@ | @@ -1,467 +1,467 @@ | |||
1 | /* $NetBSD: mount.h,v 1.202 2012/01/29 06:29:04 dholland Exp $ */ | 1 | /* $NetBSD: mount.h,v 1.203 2012/01/29 06:32:43 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1989, 1991, 1993 | 4 | * Copyright (c) 1989, 1991, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * 3. Neither the name of the University nor the names of its contributors | 15 | * 3. Neither the name of the University nor the names of its contributors | |
16 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software | |
17 | * without specific prior written permission. | 17 | * without specific prior written permission. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
29 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. | |
30 | * | 30 | * | |
31 | * @(#)mount.h 8.21 (Berkeley) 5/20/95 | 31 | * @(#)mount.h 8.21 (Berkeley) 5/20/95 | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #ifndef _SYS_MOUNT_H_ | 34 | #ifndef _SYS_MOUNT_H_ | |
35 | #define _SYS_MOUNT_H_ | 35 | #define _SYS_MOUNT_H_ | |
36 | 36 | |||
37 | #ifndef _KERNEL | 37 | #ifndef _KERNEL | |
38 | #include <sys/featuretest.h> | 38 | #include <sys/featuretest.h> | |
39 | #if defined(_NETBSD_SOURCE) | 39 | #if defined(_NETBSD_SOURCE) | |
40 | #include <sys/stat.h> | 40 | #include <sys/stat.h> | |
41 | #endif /* _NETBSD_SOURCE */ | 41 | #endif /* _NETBSD_SOURCE */ | |
42 | #endif | 42 | #endif | |
43 | 43 | |||
44 | #ifndef _STANDALONE | 44 | #ifndef _STANDALONE | |
45 | #include <sys/param.h> /* precautionary upon removal from ucred.h */ | 45 | #include <sys/param.h> /* precautionary upon removal from ucred.h */ | |
46 | #include <sys/time.h> | 46 | #include <sys/time.h> | |
47 | #include <sys/uio.h> | 47 | #include <sys/uio.h> | |
48 | #include <sys/ucred.h> | 48 | #include <sys/ucred.h> | |
49 | #include <sys/fstypes.h> | 49 | #include <sys/fstypes.h> | |
50 | #include <sys/queue.h> | 50 | #include <sys/queue.h> | |
51 | #include <sys/rwlock.h> | 51 | #include <sys/rwlock.h> | |
52 | #include <sys/statvfs.h> | 52 | #include <sys/statvfs.h> | |
53 | #include <sys/specificdata.h> | 53 | #include <sys/specificdata.h> | |
54 | #include <sys/condvar.h> | 54 | #include <sys/condvar.h> | |
55 | #endif /* !_STANDALONE */ | 55 | #endif /* !_STANDALONE */ | |
56 | 56 | |||
57 | /* | 57 | /* | |
58 | * file system statistics | 58 | * file system statistics | |
59 | */ | 59 | */ | |
60 | 60 | |||
61 | #define MNAMELEN 90 /* length of buffer for returned name */ | 61 | #define MNAMELEN 90 /* length of buffer for returned name */ | |
62 | 62 | |||
63 | /* | 63 | /* | |
64 | * File system types. | 64 | * File system types. | |
65 | */ | 65 | */ | |
66 | #define MOUNT_FFS "ffs" /* UNIX "Fast" Filesystem */ | 66 | #define MOUNT_FFS "ffs" /* UNIX "Fast" Filesystem */ | |
67 | #define MOUNT_UFS MOUNT_FFS /* for compatibility */ | 67 | #define MOUNT_UFS MOUNT_FFS /* for compatibility */ | |
68 | #define MOUNT_NFS "nfs" /* Network Filesystem */ | 68 | #define MOUNT_NFS "nfs" /* Network Filesystem */ | |
69 | #define MOUNT_MFS "mfs" /* Memory Filesystem */ | 69 | #define MOUNT_MFS "mfs" /* Memory Filesystem */ | |
70 | #define MOUNT_MSDOS "msdos" /* MSDOS Filesystem */ | 70 | #define MOUNT_MSDOS "msdos" /* MSDOS Filesystem */ | |
71 | #define MOUNT_LFS "lfs" /* Log-based Filesystem */ | 71 | #define MOUNT_LFS "lfs" /* Log-based Filesystem */ | |
72 | #define MOUNT_FDESC "fdesc" /* File Descriptor Filesystem */ | 72 | #define MOUNT_FDESC "fdesc" /* File Descriptor Filesystem */ | |
73 | #define MOUNT_NULL "null" /* Minimal Filesystem Layer */ | 73 | #define MOUNT_NULL "null" /* Minimal Filesystem Layer */ | |
74 | #define MOUNT_OVERLAY "overlay" /* Minimal Overlay Filesystem Layer */ | 74 | #define MOUNT_OVERLAY "overlay" /* Minimal Overlay Filesystem Layer */ | |
75 | #define MOUNT_UMAP "umap" /* User/Group Identifier Remapping Filesystem */ | 75 | #define MOUNT_UMAP "umap" /* User/Group Identifier Remapping Filesystem */ | |
76 | #define MOUNT_KERNFS "kernfs" /* Kernel Information Filesystem */ | 76 | #define MOUNT_KERNFS "kernfs" /* Kernel Information Filesystem */ | |
77 | #define MOUNT_PROCFS "procfs" /* /proc Filesystem */ | 77 | #define MOUNT_PROCFS "procfs" /* /proc Filesystem */ | |
78 | #define MOUNT_AFS "afs" /* Andrew Filesystem */ | 78 | #define MOUNT_AFS "afs" /* Andrew Filesystem */ | |
79 | #define MOUNT_CD9660 "cd9660" /* ISO9660 (aka CDROM) Filesystem */ | 79 | #define MOUNT_CD9660 "cd9660" /* ISO9660 (aka CDROM) Filesystem */ | |
80 | #define MOUNT_UNION "union" /* Union (translucent) Filesystem */ | 80 | #define MOUNT_UNION "union" /* Union (translucent) Filesystem */ | |
81 | #define MOUNT_ADOSFS "adosfs" /* AmigaDOS Filesystem */ | 81 | #define MOUNT_ADOSFS "adosfs" /* AmigaDOS Filesystem */ | |
82 | #define MOUNT_EXT2FS "ext2fs" /* Second Extended Filesystem */ | 82 | #define MOUNT_EXT2FS "ext2fs" /* Second Extended Filesystem */ | |
83 | #define MOUNT_CFS "coda" /* Coda Filesystem */ | 83 | #define MOUNT_CFS "coda" /* Coda Filesystem */ | |
84 | #define MOUNT_CODA MOUNT_CFS /* Coda Filesystem */ | 84 | #define MOUNT_CODA MOUNT_CFS /* Coda Filesystem */ | |
85 | #define MOUNT_FILECORE "filecore" /* Acorn Filecore Filesystem */ | 85 | #define MOUNT_FILECORE "filecore" /* Acorn Filecore Filesystem */ | |
86 | #define MOUNT_NTFS "ntfs" /* Windows/NT Filesystem */ | 86 | #define MOUNT_NTFS "ntfs" /* Windows/NT Filesystem */ | |
87 | #define MOUNT_SMBFS "smbfs" /* CIFS (SMB) */ | 87 | #define MOUNT_SMBFS "smbfs" /* CIFS (SMB) */ | |
88 | #define MOUNT_PTYFS "ptyfs" /* Pseudo tty filesystem */ | 88 | #define MOUNT_PTYFS "ptyfs" /* Pseudo tty filesystem */ | |
89 | #define MOUNT_TMPFS "tmpfs" /* Efficient memory file-system */ | 89 | #define MOUNT_TMPFS "tmpfs" /* Efficient memory file-system */ | |
90 | #define MOUNT_UDF "udf" /* UDF CD/DVD filesystem */ | 90 | #define MOUNT_UDF "udf" /* UDF CD/DVD filesystem */ | |
91 | #define MOUNT_SYSVBFS "sysvbfs" /* System V Boot Filesystem */ | 91 | #define MOUNT_SYSVBFS "sysvbfs" /* System V Boot Filesystem */ | |
92 | #define MOUNT_PUFFS "puffs" /* Pass-to-Userspace filesystem */ | 92 | #define MOUNT_PUFFS "puffs" /* Pass-to-Userspace filesystem */ | |
93 | #define MOUNT_HFS "hfs" /* Apple HFS+ Filesystem */ | 93 | #define MOUNT_HFS "hfs" /* Apple HFS+ Filesystem */ | |
94 | #define MOUNT_EFS "efs" /* SGI's Extent Filesystem */ | 94 | #define MOUNT_EFS "efs" /* SGI's Extent Filesystem */ | |
95 | #define MOUNT_ZFS "zfs" /* Sun ZFS */ | 95 | #define MOUNT_ZFS "zfs" /* Sun ZFS */ | |
96 | #define MOUNT_NILFS "nilfs" /* NTT's NiLFS(2) logging file system */ | 96 | #define MOUNT_NILFS "nilfs" /* NTT's NiLFS(2) logging file system */ | |
97 | #define MOUNT_RUMPFS "rumpfs" /* rump virtual file system */ | 97 | #define MOUNT_RUMPFS "rumpfs" /* rump virtual file system */ | |
98 | #define MOUNT_V7FS "v7fs" /* 7th Edition of Unix Filesystem */ | 98 | #define MOUNT_V7FS "v7fs" /* 7th Edition of Unix Filesystem */ | |
99 | 99 | |||
100 | #ifndef _STANDALONE | 100 | #ifndef _STANDALONE | |
101 | 101 | |||
102 | struct vnode; | 102 | struct vnode; | |
103 | 103 | |||
104 | /* | 104 | /* | |
105 | * Structure per mounted file system. Each mounted file system has an | 105 | * Structure per mounted file system. Each mounted file system has an | |
106 | * array of operations and an instance record. The file systems are | 106 | * array of operations and an instance record. The file systems are | |
107 | * put on a doubly linked list. | 107 | * put on a doubly linked list. | |
108 | */ | 108 | */ | |
109 | struct mount { | 109 | struct mount { | |
110 | CIRCLEQ_ENTRY(mount) mnt_list; /* mount list */ | 110 | CIRCLEQ_ENTRY(mount) mnt_list; /* mount list */ | |
111 | TAILQ_HEAD(, vnode) mnt_vnodelist; /* list of vnodes this mount */ | 111 | TAILQ_HEAD(, vnode) mnt_vnodelist; /* list of vnodes this mount */ | |
112 | struct vfsops *mnt_op; /* operations on fs */ | 112 | struct vfsops *mnt_op; /* operations on fs */ | |
113 | struct vnode *mnt_vnodecovered; /* vnode we mounted on */ | 113 | struct vnode *mnt_vnodecovered; /* vnode we mounted on */ | |
114 | struct vnode *mnt_syncer; /* syncer vnode */ | 114 | struct vnode *mnt_syncer; /* syncer vnode */ | |
115 | void *mnt_transinfo; /* for FS-internal use */ | 115 | void *mnt_transinfo; /* for FS-internal use */ | |
116 | void *mnt_data; /* private data */ | 116 | void *mnt_data; /* private data */ | |
117 | krwlock_t mnt_unmounting; /* to prevent new activity */ | 117 | krwlock_t mnt_unmounting; /* to prevent new activity */ | |
118 | kmutex_t mnt_renamelock; /* per-fs rename lock */ | 118 | kmutex_t mnt_renamelock; /* per-fs rename lock */ | |
119 | int mnt_refcnt; /* ref count on this structure */ | 119 | int mnt_refcnt; /* ref count on this structure */ | |
120 | int mnt_recursecnt; /* count of write locks */ | 120 | int mnt_recursecnt; /* count of write locks */ | |
121 | int mnt_flag; /* flags */ | 121 | int mnt_flag; /* flags */ | |
122 | int mnt_iflag; /* internal flags */ | 122 | int mnt_iflag; /* internal flags */ | |
123 | int mnt_fs_bshift; /* offset shift for lblkno */ | 123 | int mnt_fs_bshift; /* offset shift for lblkno */ | |
124 | int mnt_dev_bshift; /* shift for device sectors */ | 124 | int mnt_dev_bshift; /* shift for device sectors */ | |
125 | struct statvfs mnt_stat; /* cache of filesystem stats */ | 125 | struct statvfs mnt_stat; /* cache of filesystem stats */ | |
126 | specificdata_reference | 126 | specificdata_reference | |
127 | mnt_specdataref; /* subsystem specific data */ | 127 | mnt_specdataref; /* subsystem specific data */ | |
128 | kmutex_t mnt_updating; /* to serialize updates */ | 128 | kmutex_t mnt_updating; /* to serialize updates */ | |
129 | struct wapbl_ops | 129 | struct wapbl_ops | |
130 | *mnt_wapbl_op; /* logging ops */ | 130 | *mnt_wapbl_op; /* logging ops */ | |
131 | struct wapbl *mnt_wapbl; /* log info */ | 131 | struct wapbl *mnt_wapbl; /* log info */ | |
132 | struct wapbl_replay | 132 | struct wapbl_replay | |
133 | *mnt_wapbl_replay; /* replay support XXX: what? */ | 133 | *mnt_wapbl_replay; /* replay support XXX: what? */ | |
134 | uint64_t mnt_gen; | 134 | uint64_t mnt_gen; | |
135 | }; | 135 | }; | |
136 | 136 | |||
137 | /* | 137 | /* | |
138 | * Sysctl CTL_VFS definitions. | 138 | * Sysctl CTL_VFS definitions. | |
139 | * | 139 | * | |
140 | * Second level identifier specifies which filesystem. Second level | 140 | * Second level identifier specifies which filesystem. Second level | |
141 | * identifier VFS_GENERIC returns information about all filesystems. | 141 | * identifier VFS_GENERIC returns information about all filesystems. | |
142 | * | 142 | * | |
143 | * Note the slightly non-flat nature of these sysctl numbers. Oh for | 143 | * Note the slightly non-flat nature of these sysctl numbers. Oh for | |
144 | * a better sysctl interface. | 144 | * a better sysctl interface. | |
145 | */ | 145 | */ | |
146 | #define VFS_GENERIC 0 /* generic filesystem information */ | 146 | #define VFS_GENERIC 0 /* generic filesystem information */ | |
147 | #define VFS_MAXTYPENUM 1 /* int: highest defined fs type */ | 147 | #define VFS_MAXTYPENUM 1 /* int: highest defined fs type */ | |
148 | #define VFS_CONF 2 /* struct: vfsconf for filesystem given | 148 | #define VFS_CONF 2 /* struct: vfsconf for filesystem given | |
149 | as next argument */ | 149 | as next argument */ | |
150 | #define VFS_USERMOUNT 3 /* enable/disable fs mnt by non-root */ | 150 | #define VFS_USERMOUNT 3 /* enable/disable fs mnt by non-root */ | |
151 | #define VFS_MAGICLINKS 4 /* expand 'magic' symlinks */ | 151 | #define VFS_MAGICLINKS 4 /* expand 'magic' symlinks */ | |
152 | #define VFSGEN_MAXID 5 /* number of valid vfs.generic ids */ | 152 | #define VFSGEN_MAXID 5 /* number of valid vfs.generic ids */ | |
153 | 153 | |||
154 | /* | 154 | /* | |
155 | * USE THE SAME NAMES AS MOUNT_*! | 155 | * USE THE SAME NAMES AS MOUNT_*! | |
156 | * | 156 | * | |
157 | * Only need to add new entry here if the filesystem actually supports | 157 | * Only need to add new entry here if the filesystem actually supports | |
158 | * sysctl(2). | 158 | * sysctl(2). | |
159 | */ | 159 | */ | |
160 | #define CTL_VFS_NAMES { \ | 160 | #define CTL_VFS_NAMES { \ | |
161 | { "generic", CTLTYPE_NODE }, \ | 161 | { "generic", CTLTYPE_NODE }, \ | |
162 | { MOUNT_FFS, CTLTYPE_NODE }, \ | 162 | { MOUNT_FFS, CTLTYPE_NODE }, \ | |
163 | { MOUNT_NFS, CTLTYPE_NODE }, \ | 163 | { MOUNT_NFS, CTLTYPE_NODE }, \ | |
164 | { MOUNT_MFS, CTLTYPE_NODE }, \ | 164 | { MOUNT_MFS, CTLTYPE_NODE }, \ | |
165 | { MOUNT_MSDOS, CTLTYPE_NODE }, \ | 165 | { MOUNT_MSDOS, CTLTYPE_NODE }, \ | |
166 | { MOUNT_LFS, CTLTYPE_NODE }, \ | 166 | { MOUNT_LFS, CTLTYPE_NODE }, \ | |
167 | { 0, 0 }, /* MOUNT_LOFS */ \ | 167 | { 0, 0 }, /* MOUNT_LOFS */ \ | |
168 | { MOUNT_FDESC, CTLTYPE_NODE }, \ | 168 | { MOUNT_FDESC, CTLTYPE_NODE }, \ | |
169 | { MOUNT_NULL, CTLTYPE_NODE }, \ | 169 | { MOUNT_NULL, CTLTYPE_NODE }, \ | |
170 | { MOUNT_UMAP, CTLTYPE_NODE }, \ | 170 | { MOUNT_UMAP, CTLTYPE_NODE }, \ | |
171 | { MOUNT_KERNFS, CTLTYPE_NODE }, \ | 171 | { MOUNT_KERNFS, CTLTYPE_NODE }, \ | |
172 | { MOUNT_PROCFS, CTLTYPE_NODE }, \ | 172 | { MOUNT_PROCFS, CTLTYPE_NODE }, \ | |
173 | { MOUNT_AFS, CTLTYPE_NODE }, \ | 173 | { MOUNT_AFS, CTLTYPE_NODE }, \ | |
174 | { MOUNT_CD9660, CTLTYPE_NODE }, \ | 174 | { MOUNT_CD9660, CTLTYPE_NODE }, \ | |
175 | { MOUNT_UNION, CTLTYPE_NODE }, \ | 175 | { MOUNT_UNION, CTLTYPE_NODE }, \ | |
176 | { MOUNT_ADOSFS, CTLTYPE_NODE }, \ | 176 | { MOUNT_ADOSFS, CTLTYPE_NODE }, \ | |
177 | { MOUNT_EXT2FS, CTLTYPE_NODE }, \ | 177 | { MOUNT_EXT2FS, CTLTYPE_NODE }, \ | |
178 | { MOUNT_CODA, CTLTYPE_NODE }, \ | 178 | { MOUNT_CODA, CTLTYPE_NODE }, \ | |
179 | { MOUNT_FILECORE, CTLTYPE_NODE }, \ | 179 | { MOUNT_FILECORE, CTLTYPE_NODE }, \ | |
180 | { MOUNT_NTFS, CTLTYPE_NODE }, \ | 180 | { MOUNT_NTFS, CTLTYPE_NODE }, \ | |
181 | } | 181 | } | |
182 | 182 | |||
183 | #define VFS_MAXID 20 /* number of valid vfs ids */ | 183 | #define VFS_MAXID 20 /* number of valid vfs ids */ | |
184 | 184 | |||
185 | #define CTL_VFSGENCTL_NAMES { \ | 185 | #define CTL_VFSGENCTL_NAMES { \ | |
186 | { 0, 0 }, \ | 186 | { 0, 0 }, \ | |
187 | { "maxtypenum", CTLTYPE_INT }, \ | 187 | { "maxtypenum", CTLTYPE_INT }, \ | |
188 | { "conf", CTLTYPE_NODE }, /* Special */ \ | 188 | { "conf", CTLTYPE_NODE }, /* Special */ \ | |
189 | { "usermount", CTLTYPE_INT }, \ | 189 | { "usermount", CTLTYPE_INT }, \ | |
190 | { "magiclinks", CTLTYPE_INT }, \ | 190 | { "magiclinks", CTLTYPE_INT }, \ | |
191 | } | 191 | } | |
192 | 192 | |||
193 | #if defined(_KERNEL) | 193 | #if defined(_KERNEL) | |
194 | #include <prop/proplib.h> | 194 | #include <prop/proplib.h> | |
195 | #if __STDC__ | 195 | #if __STDC__ | |
196 | struct nameidata; | 196 | struct nameidata; | |
197 | #endif | 197 | #endif | |
198 | 198 | |||
199 | /* | 199 | /* | |
200 | * Operations supported on mounted file system. | 200 | * Operations supported on mounted file system. | |
201 | */ | 201 | */ | |
202 | 202 | |||
203 | struct vfsops { | 203 | struct vfsops { | |
204 | const char *vfs_name; | 204 | const char *vfs_name; | |
205 | size_t vfs_min_mount_data; | 205 | size_t vfs_min_mount_data; | |
206 | int (*vfs_mount) (struct mount *, const char *, void *, | 206 | int (*vfs_mount) (struct mount *, const char *, void *, | |
207 | size_t *); | 207 | size_t *); | |
208 | int (*vfs_start) (struct mount *, int); | 208 | int (*vfs_start) (struct mount *, int); | |
209 | int (*vfs_unmount) (struct mount *, int); | 209 | int (*vfs_unmount) (struct mount *, int); | |
210 | int (*vfs_root) (struct mount *, struct vnode **); | 210 | int (*vfs_root) (struct mount *, struct vnode **); | |
211 | int (*vfs_quotactl) (struct mount *, prop_dictionary_t); | 211 | int (*vfs_quotactl) (struct mount *, prop_dictionary_t, int); | |
212 | int (*vfs_statvfs) (struct mount *, struct statvfs *); | 212 | int (*vfs_statvfs) (struct mount *, struct statvfs *); | |
213 | int (*vfs_sync) (struct mount *, int, struct kauth_cred *); | 213 | int (*vfs_sync) (struct mount *, int, struct kauth_cred *); | |
214 | int (*vfs_vget) (struct mount *, ino_t, struct vnode **); | 214 | int (*vfs_vget) (struct mount *, ino_t, struct vnode **); | |
215 | int (*vfs_fhtovp) (struct mount *, struct fid *, | 215 | int (*vfs_fhtovp) (struct mount *, struct fid *, | |
216 | struct vnode **); | 216 | struct vnode **); | |
217 | int (*vfs_vptofh) (struct vnode *, struct fid *, size_t *); | 217 | int (*vfs_vptofh) (struct vnode *, struct fid *, size_t *); | |
218 | void (*vfs_init) (void); | 218 | void (*vfs_init) (void); | |
219 | void (*vfs_reinit) (void); | 219 | void (*vfs_reinit) (void); | |
220 | void (*vfs_done) (void); | 220 | void (*vfs_done) (void); | |
221 | int (*vfs_mountroot)(void); | 221 | int (*vfs_mountroot)(void); | |
222 | int (*vfs_snapshot) (struct mount *, struct vnode *, | 222 | int (*vfs_snapshot) (struct mount *, struct vnode *, | |
223 | struct timespec *); | 223 | struct timespec *); | |
224 | int (*vfs_extattrctl) (struct mount *, int, | 224 | int (*vfs_extattrctl) (struct mount *, int, | |
225 | struct vnode *, int, const char *); | 225 | struct vnode *, int, const char *); | |
226 | int (*vfs_suspendctl) (struct mount *, int); | 226 | int (*vfs_suspendctl) (struct mount *, int); | |
227 | int (*vfs_renamelock_enter)(struct mount *); | 227 | int (*vfs_renamelock_enter)(struct mount *); | |
228 | void (*vfs_renamelock_exit)(struct mount *); | 228 | void (*vfs_renamelock_exit)(struct mount *); | |
229 | int (*vfs_fsync) (struct vnode *, int); | 229 | int (*vfs_fsync) (struct vnode *, int); | |
230 | const struct vnodeopv_desc * const *vfs_opv_descs; | 230 | const struct vnodeopv_desc * const *vfs_opv_descs; | |
231 | int vfs_refcount; | 231 | int vfs_refcount; | |
232 | LIST_ENTRY(vfsops) vfs_list; | 232 | LIST_ENTRY(vfsops) vfs_list; | |
233 | }; | 233 | }; | |
234 | 234 | |||
235 | /* XXX vget is actually file system internal. */ | 235 | /* XXX vget is actually file system internal. */ | |
236 | #define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP) | 236 | #define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP) | |
237 | 237 | |||
238 | #define VFS_RENAMELOCK_ENTER(MP) (*(MP)->mnt_op->vfs_renamelock_enter)(MP) | 238 | #define VFS_RENAMELOCK_ENTER(MP) (*(MP)->mnt_op->vfs_renamelock_enter)(MP) | |
239 | #define VFS_RENAMELOCK_EXIT(MP) (*(MP)->mnt_op->vfs_renamelock_exit)(MP) | 239 | #define VFS_RENAMELOCK_EXIT(MP) (*(MP)->mnt_op->vfs_renamelock_exit)(MP) | |
240 | #define VFS_FSYNC(MP, VP, FLG) (*(MP)->mnt_op->vfs_fsync)(VP, FLG) | 240 | #define VFS_FSYNC(MP, VP, FLG) (*(MP)->mnt_op->vfs_fsync)(VP, FLG) | |
241 | 241 | |||
242 | int VFS_MOUNT(struct mount *, const char *, void *, size_t *); | 242 | int VFS_MOUNT(struct mount *, const char *, void *, size_t *); | |
243 | int VFS_START(struct mount *, int); | 243 | int VFS_START(struct mount *, int); | |
244 | int VFS_UNMOUNT(struct mount *, int); | 244 | int VFS_UNMOUNT(struct mount *, int); | |
245 | int VFS_ROOT(struct mount *, struct vnode **); | 245 | int VFS_ROOT(struct mount *, struct vnode **); | |
246 | int VFS_QUOTACTL(struct mount *, prop_dictionary_t); | 246 | int VFS_QUOTACTL(struct mount *, prop_dictionary_t, int); | |
247 | int VFS_STATVFS(struct mount *, struct statvfs *); | 247 | int VFS_STATVFS(struct mount *, struct statvfs *); | |
248 | int VFS_SYNC(struct mount *, int, struct kauth_cred *); | 248 | int VFS_SYNC(struct mount *, int, struct kauth_cred *); | |
249 | int VFS_FHTOVP(struct mount *, struct fid *, struct vnode **); | 249 | int VFS_FHTOVP(struct mount *, struct fid *, struct vnode **); | |
250 | int VFS_VPTOFH(struct vnode *, struct fid *, size_t *); | 250 | int VFS_VPTOFH(struct vnode *, struct fid *, size_t *); | |
251 | int VFS_SNAPSHOT(struct mount *, struct vnode *, struct timespec *); | 251 | int VFS_SNAPSHOT(struct mount *, struct vnode *, struct timespec *); | |
252 | int VFS_EXTATTRCTL(struct mount *, int, struct vnode *, int, const char *); | 252 | int VFS_EXTATTRCTL(struct mount *, int, struct vnode *, int, const char *); | |
253 | int VFS_SUSPENDCTL(struct mount *, int); | 253 | int VFS_SUSPENDCTL(struct mount *, int); | |
254 | 254 | |||
255 | #endif /* _KERNEL */ | 255 | #endif /* _KERNEL */ | |
256 | 256 | |||
257 | #ifdef _KERNEL | 257 | #ifdef _KERNEL | |
258 | #if __STDC__ | 258 | #if __STDC__ | |
259 | struct mbuf; | 259 | struct mbuf; | |
260 | struct vnodeopv_desc; | 260 | struct vnodeopv_desc; | |
261 | struct kauth_cred; | 261 | struct kauth_cred; | |
262 | #endif | 262 | #endif | |
263 | 263 | |||
264 | #define VFS_MAX_MOUNT_DATA 8192 | 264 | #define VFS_MAX_MOUNT_DATA 8192 | |
265 | 265 | |||
266 | #define VFS_PROTOS(fsname) \ | 266 | #define VFS_PROTOS(fsname) \ | |
267 | int fsname##_mount(struct mount *, const char *, void *, \ | 267 | int fsname##_mount(struct mount *, const char *, void *, \ | |
268 | size_t *); \ | 268 | size_t *); \ | |
269 | int fsname##_start(struct mount *, int); \ | 269 | int fsname##_start(struct mount *, int); \ | |
270 | int fsname##_unmount(struct mount *, int); \ | 270 | int fsname##_unmount(struct mount *, int); \ | |
271 | int fsname##_root(struct mount *, struct vnode **); \ | 271 | int fsname##_root(struct mount *, struct vnode **); \ | |
272 | int fsname##_quotactl(struct mount *, prop_dictionary_t); \ | 272 | int fsname##_quotactl(struct mount *, prop_dictionary_t); \ | |
273 | int fsname##_statvfs(struct mount *, struct statvfs *); \ | 273 | int fsname##_statvfs(struct mount *, struct statvfs *); \ | |
274 | int fsname##_sync(struct mount *, int, struct kauth_cred *); \ | 274 | int fsname##_sync(struct mount *, int, struct kauth_cred *); \ | |
275 | int fsname##_vget(struct mount *, ino_t, struct vnode **); \ | 275 | int fsname##_vget(struct mount *, ino_t, struct vnode **); \ | |
276 | int fsname##_fhtovp(struct mount *, struct fid *, struct vnode **); \ | 276 | int fsname##_fhtovp(struct mount *, struct fid *, struct vnode **); \ | |
277 | int fsname##_vptofh(struct vnode *, struct fid *, size_t *); \ | 277 | int fsname##_vptofh(struct vnode *, struct fid *, size_t *); \ | |
278 | void fsname##_init(void); \ | 278 | void fsname##_init(void); \ | |
279 | void fsname##_reinit(void); \ | 279 | void fsname##_reinit(void); \ | |
280 | void fsname##_done(void); \ | 280 | void fsname##_done(void); \ | |
281 | int fsname##_mountroot(void); \ | 281 | int fsname##_mountroot(void); \ | |
282 | int fsname##_snapshot(struct mount *, struct vnode *, \ | 282 | int fsname##_snapshot(struct mount *, struct vnode *, \ | |
283 | struct timespec *); \ | 283 | struct timespec *); \ | |
284 | int fsname##_extattrctl(struct mount *, int, struct vnode *, int, \ | 284 | int fsname##_extattrctl(struct mount *, int, struct vnode *, int, \ | |
285 | const char *); \ | 285 | const char *); \ | |
286 | int fsname##_suspendctl(struct mount *, int) | 286 | int fsname##_suspendctl(struct mount *, int) | |
287 | 287 | |||
288 | /* | 288 | /* | |
289 | * This operations vector is so wapbl can be wrapped into a filesystem lkm. | 289 | * This operations vector is so wapbl can be wrapped into a filesystem lkm. | |
290 | * XXX Eventually, we want to move this functionality | 290 | * XXX Eventually, we want to move this functionality | |
291 | * down into the filesystems themselves so that this isn't needed. | 291 | * down into the filesystems themselves so that this isn't needed. | |
292 | */ | 292 | */ | |
293 | struct wapbl_ops { | 293 | struct wapbl_ops { | |
294 | void (*wo_wapbl_discard)(struct wapbl *); | 294 | void (*wo_wapbl_discard)(struct wapbl *); | |
295 | int (*wo_wapbl_replay_isopen)(struct wapbl_replay *); | 295 | int (*wo_wapbl_replay_isopen)(struct wapbl_replay *); | |
296 | int (*wo_wapbl_replay_can_read)(struct wapbl_replay *, daddr_t, long); | 296 | int (*wo_wapbl_replay_can_read)(struct wapbl_replay *, daddr_t, long); | |
297 | int (*wo_wapbl_replay_read)(struct wapbl_replay *, void *, daddr_t, long); | 297 | int (*wo_wapbl_replay_read)(struct wapbl_replay *, void *, daddr_t, long); | |
298 | void (*wo_wapbl_add_buf)(struct wapbl *, struct buf *); | 298 | void (*wo_wapbl_add_buf)(struct wapbl *, struct buf *); | |
299 | void (*wo_wapbl_remove_buf)(struct wapbl *, struct buf *); | 299 | void (*wo_wapbl_remove_buf)(struct wapbl *, struct buf *); | |
300 | void (*wo_wapbl_resize_buf)(struct wapbl *, struct buf *, long, long); | 300 | void (*wo_wapbl_resize_buf)(struct wapbl *, struct buf *, long, long); | |
301 | int (*wo_wapbl_begin)(struct wapbl *, const char *, int); | 301 | int (*wo_wapbl_begin)(struct wapbl *, const char *, int); | |
302 | void (*wo_wapbl_end)(struct wapbl *); | 302 | void (*wo_wapbl_end)(struct wapbl *); | |
303 | void (*wo_wapbl_junlock_assert)(struct wapbl *); | 303 | void (*wo_wapbl_junlock_assert)(struct wapbl *); | |
304 | void (*wo_wapbl_biodone)(struct buf *); | 304 | void (*wo_wapbl_biodone)(struct buf *); | |
305 | }; | 305 | }; | |
306 | #define WAPBL_DISCARD(MP) \ | 306 | #define WAPBL_DISCARD(MP) \ | |
307 | (*(MP)->mnt_wapbl_op->wo_wapbl_discard)((MP)->mnt_wapbl) | 307 | (*(MP)->mnt_wapbl_op->wo_wapbl_discard)((MP)->mnt_wapbl) | |
308 | #define WAPBL_REPLAY_ISOPEN(MP) \ | 308 | #define WAPBL_REPLAY_ISOPEN(MP) \ | |
309 | (*(MP)->mnt_wapbl_op->wo_wapbl_replay_isopen)((MP)->mnt_wapbl_replay) | 309 | (*(MP)->mnt_wapbl_op->wo_wapbl_replay_isopen)((MP)->mnt_wapbl_replay) | |
310 | #define WAPBL_REPLAY_CAN_READ(MP, BLK, LEN) \ | 310 | #define WAPBL_REPLAY_CAN_READ(MP, BLK, LEN) \ | |
311 | (*(MP)->mnt_wapbl_op->wo_wapbl_replay_can_read)((MP)->mnt_wapbl_replay, \ | 311 | (*(MP)->mnt_wapbl_op->wo_wapbl_replay_can_read)((MP)->mnt_wapbl_replay, \ | |
312 | (BLK), (LEN)) | 312 | (BLK), (LEN)) | |
313 | #define WAPBL_REPLAY_READ(MP, DATA, BLK, LEN) \ | 313 | #define WAPBL_REPLAY_READ(MP, DATA, BLK, LEN) \ | |
314 | (*(MP)->mnt_wapbl_op->wo_wapbl_replay_read)((MP)->mnt_wapbl_replay, \ | 314 | (*(MP)->mnt_wapbl_op->wo_wapbl_replay_read)((MP)->mnt_wapbl_replay, \ | |
315 | (DATA), (BLK), (LEN)) | 315 | (DATA), (BLK), (LEN)) | |
316 | #define WAPBL_ADD_BUF(MP, BP) \ | 316 | #define WAPBL_ADD_BUF(MP, BP) \ | |
317 | (*(MP)->mnt_wapbl_op->wo_wapbl_add_buf)((MP)->mnt_wapbl, (BP)) | 317 | (*(MP)->mnt_wapbl_op->wo_wapbl_add_buf)((MP)->mnt_wapbl, (BP)) | |
318 | #define WAPBL_REMOVE_BUF(MP, BP) \ | 318 | #define WAPBL_REMOVE_BUF(MP, BP) \ | |
319 | (*(MP)->mnt_wapbl_op->wo_wapbl_remove_buf)((MP)->mnt_wapbl, (BP)) | 319 | (*(MP)->mnt_wapbl_op->wo_wapbl_remove_buf)((MP)->mnt_wapbl, (BP)) | |
320 | #define WAPBL_RESIZE_BUF(MP, BP, OLDSZ, OLDCNT) \ | 320 | #define WAPBL_RESIZE_BUF(MP, BP, OLDSZ, OLDCNT) \ | |
321 | (*(MP)->mnt_wapbl_op->wo_wapbl_resize_buf)((MP)->mnt_wapbl, (BP), \ | 321 | (*(MP)->mnt_wapbl_op->wo_wapbl_resize_buf)((MP)->mnt_wapbl, (BP), \ | |
322 | (OLDSZ), (OLDCNT)) | 322 | (OLDSZ), (OLDCNT)) | |
323 | #define WAPBL_BEGIN(MP) \ | 323 | #define WAPBL_BEGIN(MP) \ | |
324 | (*(MP)->mnt_wapbl_op->wo_wapbl_begin)((MP)->mnt_wapbl, \ | 324 | (*(MP)->mnt_wapbl_op->wo_wapbl_begin)((MP)->mnt_wapbl, \ | |
325 | __FILE__, __LINE__) | 325 | __FILE__, __LINE__) | |
326 | #define WAPBL_END(MP) \ | 326 | #define WAPBL_END(MP) \ | |
327 | (*(MP)->mnt_wapbl_op->wo_wapbl_end)((MP)->mnt_wapbl) | 327 | (*(MP)->mnt_wapbl_op->wo_wapbl_end)((MP)->mnt_wapbl) | |
328 | #define WAPBL_JUNLOCK_ASSERT(MP) \ | 328 | #define WAPBL_JUNLOCK_ASSERT(MP) \ | |
329 | (*(MP)->mnt_wapbl_op->wo_wapbl_junlock_assert)((MP)->mnt_wapbl) | 329 | (*(MP)->mnt_wapbl_op->wo_wapbl_junlock_assert)((MP)->mnt_wapbl) | |
330 | 330 | |||
331 | struct vfs_hooks { | 331 | struct vfs_hooks { | |
332 | LIST_ENTRY(vfs_hooks) vfs_hooks_list; | 332 | LIST_ENTRY(vfs_hooks) vfs_hooks_list; | |
333 | void (*vh_unmount)(struct mount *); | 333 | void (*vh_unmount)(struct mount *); | |
334 | int (*vh_reexport)(struct mount *, const char *, void *); | 334 | int (*vh_reexport)(struct mount *, const char *, void *); | |
335 | void (*vh_future_expansion_1)(void); | 335 | void (*vh_future_expansion_1)(void); | |
336 | void (*vh_future_expansion_2)(void); | 336 | void (*vh_future_expansion_2)(void); | |
337 | void (*vh_future_expansion_3)(void); | 337 | void (*vh_future_expansion_3)(void); | |
338 | void (*vh_future_expansion_4)(void); | 338 | void (*vh_future_expansion_4)(void); | |
339 | void (*vh_future_expansion_5)(void); | 339 | void (*vh_future_expansion_5)(void); | |
340 | }; | 340 | }; | |
341 | 341 | |||
342 | void vfs_hooks_init(void); | 342 | void vfs_hooks_init(void); | |
343 | int vfs_hooks_attach(struct vfs_hooks *); | 343 | int vfs_hooks_attach(struct vfs_hooks *); | |
344 | int vfs_hooks_detach(struct vfs_hooks *); | 344 | int vfs_hooks_detach(struct vfs_hooks *); | |
345 | void vfs_hooks_unmount(struct mount *); | 345 | void vfs_hooks_unmount(struct mount *); | |
346 | int vfs_hooks_reexport(struct mount *, const char *, void *); | 346 | int vfs_hooks_reexport(struct mount *, const char *, void *); | |
347 | 347 | |||
348 | #endif /* _KERNEL */ | 348 | #endif /* _KERNEL */ | |
349 | 349 | |||
350 | /* | 350 | /* | |
351 | * Export arguments for local filesystem mount calls. | 351 | * Export arguments for local filesystem mount calls. | |
352 | * | 352 | * | |
353 | * This structure is deprecated and is only provided for compatibility | 353 | * This structure is deprecated and is only provided for compatibility | |
354 | * reasons with old binary utilities; several file systems expose an | 354 | * reasons with old binary utilities; several file systems expose an | |
355 | * instance of this structure in their mount arguments structure, thus | 355 | * instance of this structure in their mount arguments structure, thus | |
356 | * needing a padding in place of the old values. This definition cannot | 356 | * needing a padding in place of the old values. This definition cannot | |
357 | * change in the future due to this reason. | 357 | * change in the future due to this reason. | |
358 | * XXX: This should be moved to the compat subtree but cannot be done | 358 | * XXX: This should be moved to the compat subtree but cannot be done | |
359 | * until we can move the mount args structures themselves. | 359 | * until we can move the mount args structures themselves. | |
360 | * | 360 | * | |
361 | * The current export_args structure can be found in nfs/nfs.h. | 361 | * The current export_args structure can be found in nfs/nfs.h. | |
362 | */ | 362 | */ | |
363 | struct export_args30 { | 363 | struct export_args30 { | |
364 | int ex_flags; /* export related flags */ | 364 | int ex_flags; /* export related flags */ | |
365 | uid_t ex_root; /* mapping for root uid */ | 365 | uid_t ex_root; /* mapping for root uid */ | |
366 | struct uucred ex_anon; /* mapping for anonymous user */ | 366 | struct uucred ex_anon; /* mapping for anonymous user */ | |
367 | struct sockaddr *ex_addr; /* net address to which exported */ | 367 | struct sockaddr *ex_addr; /* net address to which exported */ | |
368 | int ex_addrlen; /* and the net address length */ | 368 | int ex_addrlen; /* and the net address length */ | |
369 | struct sockaddr *ex_mask; /* mask of valid bits in saddr */ | 369 | struct sockaddr *ex_mask; /* mask of valid bits in saddr */ | |
370 | int ex_masklen; /* and the smask length */ | 370 | int ex_masklen; /* and the smask length */ | |
371 | char *ex_indexfile; /* index file for WebNFS URLs */ | 371 | char *ex_indexfile; /* index file for WebNFS URLs */ | |
372 | }; | 372 | }; | |
373 | 373 | |||
374 | struct mnt_export_args30 { | 374 | struct mnt_export_args30 { | |
375 | const char *fspec; /* Always NULL */ | 375 | const char *fspec; /* Always NULL */ | |
376 | struct export_args30 eargs; | 376 | struct export_args30 eargs; | |
377 | }; | 377 | }; | |
378 | 378 | |||
379 | #ifdef _KERNEL | 379 | #ifdef _KERNEL | |
380 | 380 | |||
381 | /* | 381 | /* | |
382 | * exported VFS interface (see vfssubr(9)) | 382 | * exported VFS interface (see vfssubr(9)) | |
383 | */ | 383 | */ | |
384 | struct mount *vfs_getvfs(fsid_t *); /* return vfs given fsid */ | 384 | struct mount *vfs_getvfs(fsid_t *); /* return vfs given fsid */ | |
385 | int vfs_composefh(struct vnode *, fhandle_t *, size_t *); | 385 | int vfs_composefh(struct vnode *, fhandle_t *, size_t *); | |
386 | int vfs_composefh_alloc(struct vnode *, fhandle_t **); | 386 | int vfs_composefh_alloc(struct vnode *, fhandle_t **); | |
387 | void vfs_composefh_free(fhandle_t *); | 387 | void vfs_composefh_free(fhandle_t *); | |
388 | int vfs_fhtovp(fhandle_t *, struct vnode **); | 388 | int vfs_fhtovp(fhandle_t *, struct vnode **); | |
389 | int vfs_mountedon(struct vnode *);/* is a vfs mounted on vp */ | 389 | int vfs_mountedon(struct vnode *);/* is a vfs mounted on vp */ | |
390 | int vfs_mountroot(void); | 390 | int vfs_mountroot(void); | |
391 | void vfs_shutdown(void); /* unmount and sync file systems */ | 391 | void vfs_shutdown(void); /* unmount and sync file systems */ | |
392 | void vfs_sync_all(struct lwp *); | 392 | void vfs_sync_all(struct lwp *); | |
393 | bool vfs_unmountall(struct lwp *); /* unmount file systems */ | 393 | bool vfs_unmountall(struct lwp *); /* unmount file systems */ | |
394 | bool vfs_unmountall1(struct lwp *, bool, bool); | 394 | bool vfs_unmountall1(struct lwp *, bool, bool); | |
395 | bool vfs_unmount_forceone(struct lwp *); | 395 | bool vfs_unmount_forceone(struct lwp *); | |
396 | int vfs_busy(struct mount *, struct mount **); | 396 | int vfs_busy(struct mount *, struct mount **); | |
397 | int vfs_rootmountalloc(const char *, const char *, struct mount **); | 397 | int vfs_rootmountalloc(const char *, const char *, struct mount **); | |
398 | void vfs_unbusy(struct mount *, bool, struct mount **); | 398 | void vfs_unbusy(struct mount *, bool, struct mount **); | |
399 | int vfs_attach(struct vfsops *); | 399 | int vfs_attach(struct vfsops *); | |
400 | int vfs_detach(struct vfsops *); | 400 | int vfs_detach(struct vfsops *); | |
401 | void vfs_reinit(void); | 401 | void vfs_reinit(void); | |
402 | struct vfsops *vfs_getopsbyname(const char *); | 402 | struct vfsops *vfs_getopsbyname(const char *); | |
403 | void vfs_delref(struct vfsops *); | 403 | void vfs_delref(struct vfsops *); | |
404 | void vfs_destroy(struct mount *); | 404 | void vfs_destroy(struct mount *); | |
405 | void vfs_scrubvnlist(struct mount *); | 405 | void vfs_scrubvnlist(struct mount *); | |
406 | struct mount *vfs_mountalloc(struct vfsops *, struct vnode *); | 406 | struct mount *vfs_mountalloc(struct vfsops *, struct vnode *); | |
407 | int vfs_stdextattrctl(struct mount *, int, struct vnode *, | 407 | int vfs_stdextattrctl(struct mount *, int, struct vnode *, | |
408 | int, const char *); | 408 | int, const char *); | |
409 | void vfs_insmntque(struct vnode *, struct mount *); | 409 | void vfs_insmntque(struct vnode *, struct mount *); | |
410 | int vfs_quotactl(struct mount *, prop_dictionary_t); | 410 | int vfs_quotactl(struct mount *, prop_dictionary_t); | |
411 | 411 | |||
412 | extern CIRCLEQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */ | 412 | extern CIRCLEQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */ | |
413 | extern struct vfsops *vfssw[]; /* filesystem type table */ | 413 | extern struct vfsops *vfssw[]; /* filesystem type table */ | |
414 | extern int nvfssw; | 414 | extern int nvfssw; | |
415 | extern kmutex_t mountlist_lock; | 415 | extern kmutex_t mountlist_lock; | |
416 | extern kmutex_t vfs_list_lock; | 416 | extern kmutex_t vfs_list_lock; | |
417 | 417 | |||
418 | void vfs_mount_sysinit(void); | 418 | void vfs_mount_sysinit(void); | |
419 | long makefstype(const char *); | 419 | long makefstype(const char *); | |
420 | int mount_domount(struct lwp *, struct vnode **, struct vfsops *, | 420 | int mount_domount(struct lwp *, struct vnode **, struct vfsops *, | |
421 | const char *, int, void *, size_t *); | 421 | const char *, int, void *, size_t *); | |
422 | int dounmount(struct mount *, int, struct lwp *); | 422 | int dounmount(struct mount *, int, struct lwp *); | |
423 | int do_sys_mount(struct lwp *, struct vfsops *, const char *, const char *, | 423 | int do_sys_mount(struct lwp *, struct vfsops *, const char *, const char *, | |
424 | int, void *, enum uio_seg, size_t, register_t *); | 424 | int, void *, enum uio_seg, size_t, register_t *); | |
425 | void vfsinit(void); | 425 | void vfsinit(void); | |
426 | void vfs_opv_init(const struct vnodeopv_desc * const *); | 426 | void vfs_opv_init(const struct vnodeopv_desc * const *); | |
427 | void vfs_opv_free(const struct vnodeopv_desc * const *); | 427 | void vfs_opv_free(const struct vnodeopv_desc * const *); | |
428 | #ifdef DEBUG | 428 | #ifdef DEBUG | |
429 | void vfs_bufstats(void); | 429 | void vfs_bufstats(void); | |
430 | #endif | 430 | #endif | |
431 | 431 | |||
432 | int mount_specific_key_create(specificdata_key_t *, specificdata_dtor_t); | 432 | int mount_specific_key_create(specificdata_key_t *, specificdata_dtor_t); | |
433 | void mount_specific_key_delete(specificdata_key_t); | 433 | void mount_specific_key_delete(specificdata_key_t); | |
434 | void mount_initspecific(struct mount *); | 434 | void mount_initspecific(struct mount *); | |
435 | void mount_finispecific(struct mount *); | 435 | void mount_finispecific(struct mount *); | |
436 | void * mount_getspecific(struct mount *, specificdata_key_t); | 436 | void * mount_getspecific(struct mount *, specificdata_key_t); | |
437 | void mount_setspecific(struct mount *, specificdata_key_t, void *); | 437 | void mount_setspecific(struct mount *, specificdata_key_t, void *); | |
438 | 438 | |||
439 | int usermount_common_policy(struct mount *, u_long); | 439 | int usermount_common_policy(struct mount *, u_long); | |
440 | 440 | |||
441 | LIST_HEAD(vfs_list_head, vfsops); | 441 | LIST_HEAD(vfs_list_head, vfsops); | |
442 | extern struct vfs_list_head vfs_list; | 442 | extern struct vfs_list_head vfs_list; | |
443 | 443 | |||
444 | #else /* _KERNEL */ | 444 | #else /* _KERNEL */ | |
445 | 445 | |||
446 | #include <sys/cdefs.h> | 446 | #include <sys/cdefs.h> | |
447 | 447 | |||
448 | __BEGIN_DECLS | 448 | __BEGIN_DECLS | |
449 | #if !defined(__LIBC12_SOURCE__) && !defined(_STANDALONE) | 449 | #if !defined(__LIBC12_SOURCE__) && !defined(_STANDALONE) | |
450 | int getfh(const char *, void *, size_t *) | 450 | int getfh(const char *, void *, size_t *) | |
451 | __RENAME(__getfh30); | 451 | __RENAME(__getfh30); | |
452 | #endif | 452 | #endif | |
453 | 453 | |||
454 | int unmount(const char *, int); | 454 | int unmount(const char *, int); | |
455 | #if defined(_NETBSD_SOURCE) | 455 | #if defined(_NETBSD_SOURCE) | |
456 | #ifndef __LIBC12_SOURCE__ | 456 | #ifndef __LIBC12_SOURCE__ | |
457 | int mount(const char *, const char *, int, void *, size_t) __RENAME(__mount50); | 457 | int mount(const char *, const char *, int, void *, size_t) __RENAME(__mount50); | |
458 | int fhopen(const void *, size_t, int) __RENAME(__fhopen40); | 458 | int fhopen(const void *, size_t, int) __RENAME(__fhopen40); | |
459 | int fhstat(const void *, size_t, struct stat *) __RENAME(__fhstat50); | 459 | int fhstat(const void *, size_t, struct stat *) __RENAME(__fhstat50); | |
460 | #endif | 460 | #endif | |
461 | #endif /* _NETBSD_SOURCE */ | 461 | #endif /* _NETBSD_SOURCE */ | |
462 | __END_DECLS | 462 | __END_DECLS | |
463 | 463 | |||
464 | #endif /* _KERNEL */ | 464 | #endif /* _KERNEL */ | |
465 | #endif /* !_STANDALONE */ | 465 | #endif /* !_STANDALONE */ | |
466 | 466 | |||
467 | #endif /* !_SYS_MOUNT_H_ */ | 467 | #endif /* !_SYS_MOUNT_H_ */ |
--- src/sys/ufs/ufs/ufs_extern.h 2011/07/17 22:07:59 1.66
+++ src/sys/ufs/ufs/ufs_extern.h 2012/01/29 06:32:44 1.67
@@ -1,188 +1,188 @@ | @@ -1,188 +1,188 @@ | |||
1 | /* $NetBSD: ufs_extern.h,v 1.66 2011/07/17 22:07:59 dholland Exp $ */ | 1 | /* $NetBSD: ufs_extern.h,v 1.67 2012/01/29 06:32:44 dholland Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991, 1993, 1994 | 4 | * Copyright (c) 1991, 1993, 1994 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * 3. Neither the name of the University nor the names of its contributors | 15 | * 3. Neither the name of the University nor the names of its contributors | |
16 | * may be used to endorse or promote products derived from this software | 16 | * may be used to endorse or promote products derived from this software | |
17 | * without specific prior written permission. | 17 | * without specific prior written permission. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
29 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. | |
30 | * | 30 | * | |
31 | * @(#)ufs_extern.h 8.10 (Berkeley) 5/14/95 | 31 | * @(#)ufs_extern.h 8.10 (Berkeley) 5/14/95 | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #ifndef _UFS_UFS_EXTERN_H_ | 34 | #ifndef _UFS_UFS_EXTERN_H_ | |
35 | #define _UFS_UFS_EXTERN_H_ | 35 | #define _UFS_UFS_EXTERN_H_ | |
36 | 36 | |||
37 | #include <sys/mutex.h> | 37 | #include <sys/mutex.h> | |
38 | 38 | |||
39 | struct buf; | 39 | struct buf; | |
40 | struct componentname; | 40 | struct componentname; | |
41 | struct direct; | 41 | struct direct; | |
42 | struct disklabel; | 42 | struct disklabel; | |
43 | struct dquot; | 43 | struct dquot; | |
44 | struct fid; | 44 | struct fid; | |
45 | struct flock; | 45 | struct flock; | |
46 | struct indir; | 46 | struct indir; | |
47 | struct inode; | 47 | struct inode; | |
48 | struct mbuf; | 48 | struct mbuf; | |
49 | struct mount; | 49 | struct mount; | |
50 | struct nameidata; | 50 | struct nameidata; | |
51 | struct lwp; | 51 | struct lwp; | |
52 | struct ufid; | 52 | struct ufid; | |
53 | struct ufs_args; | 53 | struct ufs_args; | |
54 | struct ufs_lookup_results; | 54 | struct ufs_lookup_results; | |
55 | struct ufsmount; | 55 | struct ufsmount; | |
56 | struct uio; | 56 | struct uio; | |
57 | struct vattr; | 57 | struct vattr; | |
58 | struct vnode; | 58 | struct vnode; | |
59 | 59 | |||
60 | extern pool_cache_t ufs_direct_cache; /* memory pool for directs */ | 60 | extern pool_cache_t ufs_direct_cache; /* memory pool for directs */ | |
61 | 61 | |||
62 | __BEGIN_DECLS | 62 | __BEGIN_DECLS | |
63 | #define ufs_abortop genfs_abortop | 63 | #define ufs_abortop genfs_abortop | |
64 | int ufs_access(void *); | 64 | int ufs_access(void *); | |
65 | int ufs_advlock(void *); | 65 | int ufs_advlock(void *); | |
66 | int ufs_bmap(void *); | 66 | int ufs_bmap(void *); | |
67 | int ufs_close(void *); | 67 | int ufs_close(void *); | |
68 | int ufs_create(void *); | 68 | int ufs_create(void *); | |
69 | int ufs_getattr(void *); | 69 | int ufs_getattr(void *); | |
70 | int ufs_inactive(void *); | 70 | int ufs_inactive(void *); | |
71 | #define ufs_fcntl genfs_fcntl | 71 | #define ufs_fcntl genfs_fcntl | |
72 | #define ufs_ioctl genfs_enoioctl | 72 | #define ufs_ioctl genfs_enoioctl | |
73 | #define ufs_islocked genfs_islocked | 73 | #define ufs_islocked genfs_islocked | |
74 | int ufs_link(void *); | 74 | int ufs_link(void *); | |
75 | #define ufs_lock genfs_lock | 75 | #define ufs_lock genfs_lock | |
76 | int ufs_lookup(void *); | 76 | int ufs_lookup(void *); | |
77 | int ufs_mkdir(void *); | 77 | int ufs_mkdir(void *); | |
78 | int ufs_mknod(void *); | 78 | int ufs_mknod(void *); | |
79 | #define ufs_mmap genfs_mmap | 79 | #define ufs_mmap genfs_mmap | |
80 | #define ufs_revoke genfs_revoke | 80 | #define ufs_revoke genfs_revoke | |
81 | int ufs_open(void *); | 81 | int ufs_open(void *); | |
82 | int ufs_pathconf(void *); | 82 | int ufs_pathconf(void *); | |
83 | int ufs_print(void *); | 83 | int ufs_print(void *); | |
84 | int ufs_readdir(void *); | 84 | int ufs_readdir(void *); | |
85 | int ufs_readlink(void *); | 85 | int ufs_readlink(void *); | |
86 | int ufs_remove(void *); | 86 | int ufs_remove(void *); | |
87 | int ufs_rename(void *); | 87 | int ufs_rename(void *); | |
88 | int ufs_rmdir(void *); | 88 | int ufs_rmdir(void *); | |
89 | #define ufs_seek genfs_seek | 89 | #define ufs_seek genfs_seek | |
90 | #define ufs_poll genfs_poll | 90 | #define ufs_poll genfs_poll | |
91 | int ufs_setattr(void *); | 91 | int ufs_setattr(void *); | |
92 | int ufs_strategy(void *); | 92 | int ufs_strategy(void *); | |
93 | int ufs_symlink(void *); | 93 | int ufs_symlink(void *); | |
94 | #define ufs_unlock genfs_unlock | 94 | #define ufs_unlock genfs_unlock | |
95 | int ufs_whiteout(void *); | 95 | int ufs_whiteout(void *); | |
96 | int ufsspec_close(void *); | 96 | int ufsspec_close(void *); | |
97 | int ufsspec_read(void *); | 97 | int ufsspec_read(void *); | |
98 | int ufsspec_write(void *); | 98 | int ufsspec_write(void *); | |
99 | 99 | |||
100 | int ufsfifo_read(void *); | 100 | int ufsfifo_read(void *); | |
101 | int ufsfifo_write(void *); | 101 | int ufsfifo_write(void *); | |
102 | int ufsfifo_close(void *); | 102 | int ufsfifo_close(void *); | |
103 | 103 | |||
104 | /* ufs_bmap.c */ | 104 | /* ufs_bmap.c */ | |
105 | typedef bool (*ufs_issequential_callback_t)(const struct ufsmount *, | 105 | typedef bool (*ufs_issequential_callback_t)(const struct ufsmount *, | |
106 | daddr_t, daddr_t); | 106 | daddr_t, daddr_t); | |
107 | int ufs_bmaparray(struct vnode *, daddr_t, daddr_t *, struct indir *, | 107 | int ufs_bmaparray(struct vnode *, daddr_t, daddr_t *, struct indir *, | |
108 | int *, int *, ufs_issequential_callback_t); | 108 | int *, int *, ufs_issequential_callback_t); | |
109 | int ufs_getlbns(struct vnode *, daddr_t, struct indir *, int *); | 109 | int ufs_getlbns(struct vnode *, daddr_t, struct indir *, int *); | |
110 | 110 | |||
111 | /* ufs_ihash.c */ | 111 | /* ufs_ihash.c */ | |
112 | void ufs_ihashinit(void); | 112 | void ufs_ihashinit(void); | |
113 | void ufs_ihashreinit(void); | 113 | void ufs_ihashreinit(void); | |
114 | void ufs_ihashdone(void); | 114 | void ufs_ihashdone(void); | |
115 | struct vnode *ufs_ihashlookup(dev_t, ino_t); | 115 | struct vnode *ufs_ihashlookup(dev_t, ino_t); | |
116 | struct vnode *ufs_ihashget(dev_t, ino_t, int); | 116 | struct vnode *ufs_ihashget(dev_t, ino_t, int); | |
117 | void ufs_ihashins(struct inode *); | 117 | void ufs_ihashins(struct inode *); | |
118 | void ufs_ihashrem(struct inode *); | 118 | void ufs_ihashrem(struct inode *); | |
119 | 119 | |||
120 | /* ufs_inode.c */ | 120 | /* ufs_inode.c */ | |
121 | int ufs_reclaim(struct vnode *); | 121 | int ufs_reclaim(struct vnode *); | |
122 | int ufs_balloc_range(struct vnode *, off_t, off_t, kauth_cred_t, int); | 122 | int ufs_balloc_range(struct vnode *, off_t, off_t, kauth_cred_t, int); | |
123 | 123 | |||
124 | /* ufs_lookup.c */ | 124 | /* ufs_lookup.c */ | |
125 | void ufs_dirbad(struct inode *, doff_t, const char *); | 125 | void ufs_dirbad(struct inode *, doff_t, const char *); | |
126 | int ufs_dirbadentry(struct vnode *, struct direct *, int); | 126 | int ufs_dirbadentry(struct vnode *, struct direct *, int); | |
127 | void ufs_makedirentry(struct inode *, struct componentname *, | 127 | void ufs_makedirentry(struct inode *, struct componentname *, | |
128 | struct direct *); | 128 | struct direct *); | |
129 | int ufs_direnter(struct vnode *, const struct ufs_lookup_results *, | 129 | int ufs_direnter(struct vnode *, const struct ufs_lookup_results *, | |
130 | struct vnode *, struct direct *, | 130 | struct vnode *, struct direct *, | |
131 | struct componentname *, struct buf *); | 131 | struct componentname *, struct buf *); | |
132 | int ufs_dirremove(struct vnode *, const struct ufs_lookup_results *, | 132 | int ufs_dirremove(struct vnode *, const struct ufs_lookup_results *, | |
133 | struct inode *, int, int); | 133 | struct inode *, int, int); | |
134 | int ufs_dirrewrite(struct inode *, off_t, | 134 | int ufs_dirrewrite(struct inode *, off_t, | |
135 | struct inode *, ino_t, int, int, int); | 135 | struct inode *, ino_t, int, int, int); | |
136 | int ufs_dirempty(struct inode *, ino_t, kauth_cred_t); | 136 | int ufs_dirempty(struct inode *, ino_t, kauth_cred_t); | |
137 | int ufs_checkpath(struct inode *, struct inode *, kauth_cred_t); | 137 | int ufs_checkpath(struct inode *, struct inode *, kauth_cred_t); | |
138 | int ufs_parentcheck(struct vnode *, struct vnode *, kauth_cred_t, | 138 | int ufs_parentcheck(struct vnode *, struct vnode *, kauth_cred_t, | |
139 | int *, struct vnode **); | 139 | int *, struct vnode **); | |
140 | int ufs_blkatoff(struct vnode *, off_t, char **, struct buf **, bool); | 140 | int ufs_blkatoff(struct vnode *, off_t, char **, struct buf **, bool); | |
141 | 141 | |||
142 | /* ufs_quota.c */ | 142 | /* ufs_quota.c */ | |
143 | /* | 143 | /* | |
144 | * Flags to chkdq() and chkiq() | 144 | * Flags to chkdq() and chkiq() | |
145 | */ | 145 | */ | |
146 | #define FORCE 0x01 /* force usage changes independent of limits */ | 146 | #define FORCE 0x01 /* force usage changes independent of limits */ | |
147 | void ufsquota_init(struct inode *); | 147 | void ufsquota_init(struct inode *); | |
148 | void ufsquota_free(struct inode *); | 148 | void ufsquota_free(struct inode *); | |
149 | int chkdq(struct inode *, int64_t, kauth_cred_t, int); | 149 | int chkdq(struct inode *, int64_t, kauth_cred_t, int); | |
150 | int chkiq(struct inode *, int32_t, kauth_cred_t, int); | 150 | int chkiq(struct inode *, int32_t, kauth_cred_t, int); | |
151 | int quota_handle_cmd(struct mount *, struct lwp *, prop_dictionary_t); | 151 | int quota_handle_cmd(struct mount *, struct lwp *, prop_dictionary_t); | |
152 | int qsync(struct mount *); | 152 | int qsync(struct mount *); | |
153 | 153 | |||
154 | /* ufs_quota1.c */ | 154 | /* ufs_quota1.c */ | |
155 | int quota1_umount(struct mount *, int); | 155 | int quota1_umount(struct mount *, int); | |
156 | 156 | |||
157 | /* ufs_quota2.c */ | 157 | /* ufs_quota2.c */ | |
158 | int quota2_umount(struct mount *, int); | 158 | int quota2_umount(struct mount *, int); | |
159 | 159 | |||
160 | /* ufs_vfsops.c */ | 160 | /* ufs_vfsops.c */ | |
161 | void ufs_init(void); | 161 | void ufs_init(void); | |
162 | void ufs_reinit(void); | 162 | void ufs_reinit(void); | |
163 | void ufs_done(void); | 163 | void ufs_done(void); | |
164 | int ufs_start(struct mount *, int); | 164 | int ufs_start(struct mount *, int); | |
165 | int ufs_root(struct mount *, struct vnode **); | 165 | int ufs_root(struct mount *, struct vnode **); | |
166 | int ufs_quotactl(struct mount *, prop_dictionary_t); | 166 | int ufs_quotactl(struct mount *, prop_dictionary_t, int); | |
167 | int ufs_fhtovp(struct mount *, struct ufid *, struct vnode **); | 167 | int ufs_fhtovp(struct mount *, struct ufid *, struct vnode **); | |
168 | 168 | |||
169 | /* ufs_vnops.c */ | 169 | /* ufs_vnops.c */ | |
170 | void ufs_vinit(struct mount *, int (**)(void *), | 170 | void ufs_vinit(struct mount *, int (**)(void *), | |
171 | int (**)(void *), struct vnode **); | 171 | int (**)(void *), struct vnode **); | |
172 | int ufs_makeinode(int, struct vnode *, const struct ufs_lookup_results *, | 172 | int ufs_makeinode(int, struct vnode *, const struct ufs_lookup_results *, | |
173 | struct vnode **, struct componentname *); | 173 | struct vnode **, struct componentname *); | |
174 | int ufs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t); | 174 | int ufs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t); | |
175 | void ufs_gop_markupdate(struct vnode *, int); | 175 | void ufs_gop_markupdate(struct vnode *, int); | |
176 | 176 | |||
177 | /* | 177 | /* | |
178 | * Snapshot function prototypes. | 178 | * Snapshot function prototypes. | |
179 | */ | 179 | */ | |
180 | 180 | |||
181 | void ffs_snapgone(struct inode *); | 181 | void ffs_snapgone(struct inode *); | |
182 | 182 | |||
183 | __END_DECLS | 183 | __END_DECLS | |
184 | 184 | |||
185 | extern kmutex_t ufs_ihash_lock; | 185 | extern kmutex_t ufs_ihash_lock; | |
186 | extern kmutex_t ufs_hashlock; | 186 | extern kmutex_t ufs_hashlock; | |
187 | 187 | |||
188 | #endif /* !_UFS_UFS_EXTERN_H_ */ | 188 | #endif /* !_UFS_UFS_EXTERN_H_ */ |
--- src/sys/ufs/ufs/ufs_vfsops.c 2012/01/27 19:22:50 1.43
+++ src/sys/ufs/ufs/ufs_vfsops.c 2012/01/29 06:32:44 1.44
@@ -1,308 +1,292 @@ | @@ -1,308 +1,292 @@ | |||
1 | /* $NetBSD: ufs_vfsops.c,v 1.43 2012/01/27 19:22:50 para Exp $ */ | 1 | /* $NetBSD: ufs_vfsops.c,v 1.44 2012/01/29 06:32:44 dholland Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1991, 1993, 1994 | 4 | * Copyright (c) 1991, 1993, 1994 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * (c) UNIX System Laboratories, Inc. | 6 | * (c) UNIX System Laboratories, Inc. | |
7 | * All or some portions of this file are derived from material licensed | 7 | * All or some portions of this file are derived from material licensed | |
8 | * to the University of California by American Telephone and Telegraph | 8 | * to the University of California by American Telephone and Telegraph | |
9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | |
10 | * the permission of UNIX System Laboratories, Inc. | 10 | * the permission of UNIX System Laboratories, Inc. | |
11 | * | 11 | * | |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without | |
13 | * modification, are permitted provided that the following conditions | 13 | * modification, are permitted provided that the following conditions | |
14 | * are met: | 14 | * are met: | |
15 | * 1. Redistributions of source code must retain the above copyright | 15 | * 1. Redistributions of source code must retain the above copyright | |
16 | * notice, this list of conditions and the following disclaimer. | 16 | * notice, this list of conditions and the following disclaimer. | |
17 | * 2. Redistributions in binary form must reproduce the above copyright | 17 | * 2. Redistributions in binary form must reproduce the above copyright | |
18 | * notice, this list of conditions and the following disclaimer in the | 18 | * notice, this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | 19 | * documentation and/or other materials provided with the distribution. | |
20 | * 3. Neither the name of the University nor the names of its contributors | 20 | * 3. Neither the name of the University nor the names of its contributors | |
21 | * may be used to endorse or promote products derived from this software | 21 | * may be used to endorse or promote products derived from this software | |
22 | * without specific prior written permission. | 22 | * without specific prior written permission. | |
23 | * | 23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
34 | * SUCH DAMAGE. | 34 | * SUCH DAMAGE. | |
35 | * | 35 | * | |
36 | * @(#)ufs_vfsops.c 8.8 (Berkeley) 5/20/95 | 36 | * @(#)ufs_vfsops.c 8.8 (Berkeley) 5/20/95 | |
37 | */ | 37 | */ | |
38 | 38 | |||
39 | #include <sys/cdefs.h> | 39 | #include <sys/cdefs.h> | |
40 | __KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.43 2012/01/27 19:22:50 para Exp $"); | 40 | __KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.44 2012/01/29 06:32:44 dholland Exp $"); | |
41 | 41 | |||
42 | #if defined(_KERNEL_OPT) | 42 | #if defined(_KERNEL_OPT) | |
43 | #include "opt_ffs.h" | 43 | #include "opt_ffs.h" | |
44 | #include "opt_quota.h" | 44 | #include "opt_quota.h" | |
45 | #endif | 45 | #endif | |
46 | 46 | |||
47 | #include <sys/param.h> | 47 | #include <sys/param.h> | |
48 | #include <sys/mbuf.h> | 48 | #include <sys/mbuf.h> | |
49 | #include <sys/mount.h> | 49 | #include <sys/mount.h> | |
50 | #include <sys/proc.h> | 50 | #include <sys/proc.h> | |
51 | #include <sys/buf.h> | 51 | #include <sys/buf.h> | |
52 | #include <sys/vnode.h> | 52 | #include <sys/vnode.h> | |
53 | #include <sys/kmem.h> | 53 | #include <sys/kmem.h> | |
54 | #include <sys/kauth.h> | 54 | #include <sys/kauth.h> | |
55 | 55 | |||
56 | #include <miscfs/specfs/specdev.h> | 56 | #include <miscfs/specfs/specdev.h> | |
57 | 57 | |||
58 | #include <ufs/ufs/quota.h> | 58 | #include <ufs/ufs/quota.h> | |
59 | #include <ufs/ufs/inode.h> | 59 | #include <ufs/ufs/inode.h> | |
60 | #include <ufs/ufs/ufsmount.h> | 60 | #include <ufs/ufs/ufsmount.h> | |
61 | #include <ufs/ufs/ufs_extern.h> | 61 | #include <ufs/ufs/ufs_extern.h> | |
62 | #ifdef UFS_DIRHASH | 62 | #ifdef UFS_DIRHASH | |
63 | #include <ufs/ufs/dirhash.h> | 63 | #include <ufs/ufs/dirhash.h> | |
64 | #endif | 64 | #endif | |
65 | #include <quota/quotaprop.h> | 65 | #include <quota/quotaprop.h> | |
66 | 66 | |||
67 | /* how many times ufs_init() was called */ | 67 | /* how many times ufs_init() was called */ | |
68 | static int ufs_initcount = 0; | 68 | static int ufs_initcount = 0; | |
69 | 69 | |||
70 | pool_cache_t ufs_direct_cache; | 70 | pool_cache_t ufs_direct_cache; | |
71 | 71 | |||
72 | /* | 72 | /* | |
73 | * Make a filesystem operational. | 73 | * Make a filesystem operational. | |
74 | * Nothing to do at the moment. | 74 | * Nothing to do at the moment. | |
75 | */ | 75 | */ | |
76 | /* ARGSUSED */ | 76 | /* ARGSUSED */ | |
77 | int | 77 | int | |
78 | ufs_start(struct mount *mp, int flags) | 78 | ufs_start(struct mount *mp, int flags) | |
79 | { | 79 | { | |
80 | 80 | |||
81 | return (0); | 81 | return (0); | |
82 | } | 82 | } | |
83 | 83 | |||
84 | /* | 84 | /* | |
85 | * Return the root of a filesystem. | 85 | * Return the root of a filesystem. | |
86 | */ | 86 | */ | |
87 | int | 87 | int | |
88 | ufs_root(struct mount *mp, struct vnode **vpp) | 88 | ufs_root(struct mount *mp, struct vnode **vpp) | |
89 | { | 89 | { | |
90 | struct vnode *nvp; | 90 | struct vnode *nvp; | |
91 | int error; | 91 | int error; | |
92 | 92 | |||
93 | if ((error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp)) != 0) | 93 | if ((error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp)) != 0) | |
94 | return (error); | 94 | return (error); | |
95 | *vpp = nvp; | 95 | *vpp = nvp; | |
96 | return (0); | 96 | return (0); | |
97 | } | 97 | } | |
98 | 98 | |||
99 | /* | 99 | /* | |
100 | * Do operations associated with quotas | 100 | * Do operations associated with quotas | |
101 | */ | 101 | */ | |
102 | int | 102 | int | |
103 | ufs_quotactl(struct mount *mp, prop_dictionary_t dict) | 103 | ufs_quotactl(struct mount *mp, prop_dictionary_t cmddict, int dummy) | |
104 | { | 104 | { | |
105 | struct lwp *l = curlwp; | 105 | struct lwp *l = curlwp; | |
106 | 106 | |||
107 | #if !defined(QUOTA) && !defined(QUOTA2) | 107 | #if !defined(QUOTA) && !defined(QUOTA2) | |
108 | (void) mp; | 108 | (void) mp; | |
109 | (void) dict; | 109 | (void) cmddict; | |
110 | (void) dummy; | |||
110 | (void) l; | 111 | (void) l; | |
111 | return (EOPNOTSUPP); | 112 | return (EOPNOTSUPP); | |
112 | #else | 113 | #else | |
113 | int error; | 114 | int error; | |
114 | prop_dictionary_t cmddict; | 115 | ||
115 | prop_array_t commands; | 116 | KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY); | |
116 | prop_object_iterator_t iter; | |||
117 | 117 | |||
118 | /* Mark the mount busy, as we're passing it to kauth(9). */ | 118 | /* Mark the mount busy, as we're passing it to kauth(9). */ | |
119 | error = vfs_busy(mp, NULL); | 119 | error = vfs_busy(mp, NULL); | |
120 | if (error) | 120 | if (error) { | |
121 | return (error); | 121 | return (error); | |
122 | ||||
123 | error = quota_get_cmds(dict, &commands); | |||
124 | if (error) | |||
125 | goto out_vfs; | |||
126 | iter = prop_array_iterator(commands); | |||
127 | if (iter == NULL) { | |||
128 | error = ENOMEM; | |||
129 | goto out_vfs; | |||
130 | } | 122 | } | |
131 | ||||
132 | ||||
133 | mutex_enter(&mp->mnt_updating); | 123 | mutex_enter(&mp->mnt_updating); | |
134 | while ((cmddict = prop_object_iterator_next(iter)) != NULL) { | 124 | ||
135 | if (prop_object_type(cmddict) != PROP_TYPE_DICTIONARY) | 125 | error = quota_handle_cmd(mp, l, cmddict); | |
136 | continue; | 126 | ||
137 | error = quota_handle_cmd(mp, l, cmddict); | |||
138 | if (error) | |||
139 | break; | |||
140 | } | |||
141 | prop_object_iterator_release(iter); | |||
142 | mutex_exit(&mp->mnt_updating); | 127 | mutex_exit(&mp->mnt_updating); | |
143 | out_vfs: | |||
144 | vfs_unbusy(mp, false, NULL); | 128 | vfs_unbusy(mp, false, NULL); | |
145 | return (error); | 129 | return (error); | |
146 | #endif | 130 | #endif | |
147 | } | 131 | } | |
148 | 132 | |||
149 | #if 0 | 133 | #if 0 | |
150 | switch (cmd) { | 134 | switch (cmd) { | |
151 | case Q_SYNC: | 135 | case Q_SYNC: | |
152 | break; | 136 | break; | |
153 | 137 | |||
154 | case Q_GETQUOTA: | 138 | case Q_GETQUOTA: | |
155 | /* The user can always query about his own quota. */ | 139 | /* The user can always query about his own quota. */ | |
156 | if (uid == kauth_cred_getuid(l->l_cred)) | 140 | if (uid == kauth_cred_getuid(l->l_cred)) | |
157 | break; | 141 | break; | |
158 | 142 | |||
159 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | 143 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | |
160 | KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, KAUTH_ARG(uid), NULL); | 144 | KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, KAUTH_ARG(uid), NULL); | |
161 | 145 | |||
162 | break; | 146 | break; | |
163 | 147 | |||
164 | case Q_QUOTAON: | 148 | case Q_QUOTAON: | |
165 | case Q_QUOTAOFF: | 149 | case Q_QUOTAOFF: | |
166 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | 150 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | |
167 | KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF, mp, NULL, NULL); | 151 | KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF, mp, NULL, NULL); | |
168 | 152 | |||
169 | break; | 153 | break; | |
170 | 154 | |||
171 | case Q_SETQUOTA: | 155 | case Q_SETQUOTA: | |
172 | case Q_SETUSE: | 156 | case Q_SETUSE: | |
173 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | 157 | error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | |
174 | KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE, mp, KAUTH_ARG(uid), NULL); | 158 | KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE, mp, KAUTH_ARG(uid), NULL); | |
175 | 159 | |||
176 | break; | 160 | break; | |
177 | 161 | |||
178 | default: | 162 | default: | |
179 | error = EINVAL; | 163 | error = EINVAL; | |
180 | break; | 164 | break; | |
181 | } | 165 | } | |
182 | 166 | |||
183 | type = cmds & SUBCMDMASK; | 167 | type = cmds & SUBCMDMASK; | |
184 | if (!error) { | 168 | if (!error) { | |
185 | /* Only check if there was no error above. */ | 169 | /* Only check if there was no error above. */ | |
186 | if ((u_int)type >= MAXQUOTAS) | 170 | if ((u_int)type >= MAXQUOTAS) | |
187 | error = EINVAL; | 171 | error = EINVAL; | |
188 | } | 172 | } | |
189 | 173 | |||
190 | if (error) { | 174 | if (error) { | |
191 | vfs_unbusy(mp, false, NULL); | 175 | vfs_unbusy(mp, false, NULL); | |
192 | return (error); | 176 | return (error); | |
193 | } | 177 | } | |
194 | 178 | |||
195 | mutex_enter(&mp->mnt_updating); | 179 | mutex_enter(&mp->mnt_updating); | |
196 | switch (cmd) { | 180 | switch (cmd) { | |
197 | 181 | |||
198 | case Q_QUOTAON: | 182 | case Q_QUOTAON: | |
199 | error = quotaon(l, mp, type, arg); | 183 | error = quotaon(l, mp, type, arg); | |
200 | break; | 184 | break; | |
201 | 185 | |||
202 | case Q_QUOTAOFF: | 186 | case Q_QUOTAOFF: | |
203 | error = quotaoff(l, mp, type); | 187 | error = quotaoff(l, mp, type); | |
204 | break; | 188 | break; | |
205 | 189 | |||
206 | case Q_SETQUOTA: | 190 | case Q_SETQUOTA: | |
207 | error = setquota(mp, uid, type, arg); | 191 | error = setquota(mp, uid, type, arg); | |
208 | break; | 192 | break; | |
209 | 193 | |||
210 | case Q_SETUSE: | 194 | case Q_SETUSE: | |
211 | error = setuse(mp, uid, type, arg); | 195 | error = setuse(mp, uid, type, arg); | |
212 | break; | 196 | break; | |
213 | 197 | |||
214 | case Q_GETQUOTA: | 198 | case Q_GETQUOTA: | |
215 | error = getquota(mp, uid, type, arg); | 199 | error = getquota(mp, uid, type, arg); | |
216 | break; | 200 | break; | |
217 | 201 | |||
218 | case Q_SYNC: | 202 | case Q_SYNC: | |
219 | error = qsync(mp); | 203 | error = qsync(mp); | |
220 | break; | 204 | break; | |
221 | 205 | |||
222 | default: | 206 | default: | |
223 | error = EINVAL; | 207 | error = EINVAL; | |
224 | } | 208 | } | |
225 | mutex_exit(&mp->mnt_updating); | 209 | mutex_exit(&mp->mnt_updating); | |
226 | vfs_unbusy(mp, false, NULL); | 210 | vfs_unbusy(mp, false, NULL); | |
227 | return (error); | 211 | return (error); | |
228 | #endif | 212 | #endif | |
229 | 213 | |||
230 | /* | 214 | /* | |
231 | * This is the generic part of fhtovp called after the underlying | 215 | * This is the generic part of fhtovp called after the underlying | |
232 | * filesystem has validated the file handle. | 216 | * filesystem has validated the file handle. | |
233 | */ | 217 | */ | |
234 | int | 218 | int | |
235 | ufs_fhtovp(struct mount *mp, struct ufid *ufhp, struct vnode **vpp) | 219 | ufs_fhtovp(struct mount *mp, struct ufid *ufhp, struct vnode **vpp) | |
236 | { | 220 | { | |
237 | struct vnode *nvp; | 221 | struct vnode *nvp; | |
238 | struct inode *ip; | 222 | struct inode *ip; | |
239 | int error; | 223 | int error; | |
240 | 224 | |||
241 | if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) { | 225 | if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) { | |
242 | *vpp = NULLVP; | 226 | *vpp = NULLVP; | |
243 | return (error); | 227 | return (error); | |
244 | } | 228 | } | |
245 | ip = VTOI(nvp); | 229 | ip = VTOI(nvp); | |
246 | if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) { | 230 | if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) { | |
247 | vput(nvp); | 231 | vput(nvp); | |
248 | *vpp = NULLVP; | 232 | *vpp = NULLVP; | |
249 | return (ESTALE); | 233 | return (ESTALE); | |
250 | } | 234 | } | |
251 | *vpp = nvp; | 235 | *vpp = nvp; | |
252 | return (0); | 236 | return (0); | |
253 | } | 237 | } | |
254 | 238 | |||
255 | /* | 239 | /* | |
256 | * Initialize UFS filesystems, done only once. | 240 | * Initialize UFS filesystems, done only once. | |
257 | */ | 241 | */ | |
258 | void | 242 | void | |
259 | ufs_init(void) | 243 | ufs_init(void) | |
260 | { | 244 | { | |
261 | if (ufs_initcount++ > 0) | 245 | if (ufs_initcount++ > 0) | |
262 | return; | 246 | return; | |
263 | 247 | |||
264 | ufs_direct_cache = pool_cache_init(sizeof(struct direct), 0, 0, 0, | 248 | ufs_direct_cache = pool_cache_init(sizeof(struct direct), 0, 0, 0, | |
265 | "ufsdir", NULL, IPL_NONE, NULL, NULL, NULL); | 249 | "ufsdir", NULL, IPL_NONE, NULL, NULL, NULL); | |
266 | 250 | |||
267 | ufs_ihashinit(); | 251 | ufs_ihashinit(); | |
268 | #if defined(QUOTA) || defined(QUOTA2) | 252 | #if defined(QUOTA) || defined(QUOTA2) | |
269 | dqinit(); | 253 | dqinit(); | |
270 | #endif | 254 | #endif | |
271 | #ifdef UFS_DIRHASH | 255 | #ifdef UFS_DIRHASH | |
272 | ufsdirhash_init(); | 256 | ufsdirhash_init(); | |
273 | #endif | 257 | #endif | |
274 | #ifdef UFS_EXTATTR | 258 | #ifdef UFS_EXTATTR | |
275 | ufs_extattr_init(); | 259 | ufs_extattr_init(); | |
276 | #endif | 260 | #endif | |
277 | } | 261 | } | |
278 | 262 | |||
279 | void | 263 | void | |
280 | ufs_reinit(void) | 264 | ufs_reinit(void) | |
281 | { | 265 | { | |
282 | ufs_ihashreinit(); | 266 | ufs_ihashreinit(); | |
283 | #if defined(QUOTA) || defined(QUOTA2) | 267 | #if defined(QUOTA) || defined(QUOTA2) | |
284 | dqreinit(); | 268 | dqreinit(); | |
285 | #endif | 269 | #endif | |
286 | } | 270 | } | |
287 | 271 | |||
288 | /* | 272 | /* | |
289 | * Free UFS filesystem resources, done only once. | 273 | * Free UFS filesystem resources, done only once. | |
290 | */ | 274 | */ | |
291 | void | 275 | void | |
292 | ufs_done(void) | 276 | ufs_done(void) | |
293 | { | 277 | { | |
294 | if (--ufs_initcount > 0) | 278 | if (--ufs_initcount > 0) | |
295 | return; | 279 | return; | |
296 | 280 | |||
297 | ufs_ihashdone(); | 281 | ufs_ihashdone(); | |
298 | #if defined(QUOTA) || defined(QUOTA2) | 282 | #if defined(QUOTA) || defined(QUOTA2) | |
299 | dqdone(); | 283 | dqdone(); | |
300 | #endif | 284 | #endif | |
301 | pool_cache_destroy(ufs_direct_cache); | 285 | pool_cache_destroy(ufs_direct_cache); | |
302 | #ifdef UFS_DIRHASH | 286 | #ifdef UFS_DIRHASH | |
303 | ufsdirhash_done(); | 287 | ufsdirhash_done(); | |
304 | #endif | 288 | #endif | |
305 | #ifdef UFS_EXTATTR | 289 | #ifdef UFS_EXTATTR | |
306 | ufs_extattr_done(); | 290 | ufs_extattr_done(); | |
307 | #endif | 291 | #endif | |
308 | } | 292 | } |