| @@ -1,803 +1,804 @@ | | | @@ -1,803 +1,804 @@ |
1 | /* $NetBSD: p2k.c,v 1.4 2008/09/30 17:18:46 pooka Exp $ */ | | 1 | /* $NetBSD: p2k.c,v 1.5 2008/10/07 23:14:58 pooka Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2007 Antti Kantee. All Rights Reserved. | | 4 | * Copyright (c) 2007 Antti Kantee. All Rights Reserved. |
5 | * | | 5 | * |
6 | * Development of this software was supported by Google Summer of Code. | | 6 | * Development of this software was supported by Google Summer of Code. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * | | 16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
18 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | | 18 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | | 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
20 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | | 20 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. | | 27 | * SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | /* | | 30 | /* |
31 | * puffs 2k, i.e. puffs 2 kernel. Converts the puffs protocol to | | 31 | * puffs 2k, i.e. puffs 2 kernel. Converts the puffs protocol to |
32 | * the kernel vfs protocol and vice versa. | | 32 | * the kernel vfs protocol and vice versa. |
33 | * | | 33 | * |
34 | * A word about reference counting: puffs in the kernel is the king of | | 34 | * A word about reference counting: puffs in the kernel is the king of |
35 | * reference counting. We must maintain a vnode alive and kicking | | 35 | * reference counting. We must maintain a vnode alive and kicking |
36 | * until the kernel tells us to reclaim it. Therefore we make sure | | 36 | * until the kernel tells us to reclaim it. Therefore we make sure |
37 | * we never accidentally lose a vnode. Before calling operations which | | 37 | * we never accidentally lose a vnode. Before calling operations which |
38 | * decrease the refcount we always bump the refcount up to compensate. | | 38 | * decrease the refcount we always bump the refcount up to compensate. |
39 | * Come inactive, if the file system thinks that the vnode should be | | 39 | * Come inactive, if the file system thinks that the vnode should be |
40 | * put out of its misery, it will set the recycle flag. We use this | | 40 | * put out of its misery, it will set the recycle flag. We use this |
41 | * to tell the kernel to reclaim the vnode. Only in reclaim do we | | 41 | * to tell the kernel to reclaim the vnode. Only in reclaim do we |
42 | * really nuke the last reference. | | 42 | * really nuke the last reference. |
43 | */ | | 43 | */ |
44 | | | 44 | |
45 | #include <sys/cdefs.h> | | 45 | #include <sys/cdefs.h> |
46 | #include <sys/mount.h> | | 46 | #include <sys/mount.h> |
47 | #include <sys/param.h> | | 47 | #include <sys/param.h> |
48 | #include <sys/vnode.h> | | 48 | #include <sys/vnode.h> |
49 | #include <sys/lock.h> | | 49 | #include <sys/lock.h> |
50 | #include <sys/namei.h> | | 50 | #include <sys/namei.h> |
51 | #include <sys/dirent.h> | | 51 | #include <sys/dirent.h> |
52 | | | 52 | |
53 | #include <assert.h> | | 53 | #include <assert.h> |
54 | #include <errno.h> | | 54 | #include <errno.h> |
55 | #include <puffs.h> | | 55 | #include <puffs.h> |
56 | #include <stdlib.h> | | 56 | #include <stdlib.h> |
57 | | | 57 | |
58 | #include <rump/rump.h> | | 58 | #include <rump/rump.h> |
59 | #include <rump/p2k.h> | | 59 | #include <rump/p2k.h> |
60 | #include <rump/ukfs.h> | | 60 | #include <rump/ukfs.h> |
61 | | | 61 | |
62 | PUFFSOP_PROTOS(p2k) | | 62 | PUFFSOP_PROTOS(p2k) |
63 | | | 63 | |
64 | static kauth_cred_t | | 64 | static kauth_cred_t |
65 | cred_create(const struct puffs_cred *pcr) | | 65 | cred_create(const struct puffs_cred *pcr) |
66 | { | | 66 | { |
67 | gid_t groups[NGROUPS]; | | 67 | gid_t groups[NGROUPS]; |
68 | uid_t uid; | | 68 | uid_t uid; |
69 | gid_t gid; | | 69 | gid_t gid; |
70 | short ngroups = 0; | | 70 | short ngroups = 0; |
71 | | | 71 | |
72 | if (puffs_cred_getuid(pcr, &uid) == -1) | | 72 | if (puffs_cred_getuid(pcr, &uid) == -1) |
73 | uid = 0; | | 73 | uid = 0; |
74 | if (puffs_cred_getgid(pcr, &gid) == -1) | | 74 | if (puffs_cred_getgid(pcr, &gid) == -1) |
75 | gid = 0; | | 75 | gid = 0; |
76 | puffs_cred_getgroups(pcr, groups, &ngroups); | | 76 | puffs_cred_getgroups(pcr, groups, &ngroups); |
77 | | | 77 | |
78 | /* LINTED: ngroups is ok */ | | 78 | /* LINTED: ngroups is ok */ |
79 | return rump_cred_create(uid, gid, ngroups, groups); | | 79 | return rump_cred_create(uid, gid, ngroups, groups); |
80 | } | | 80 | } |
81 | | | 81 | |
82 | static __inline void | | 82 | static __inline void |
83 | cred_destroy(kauth_cred_t cred) | | 83 | cred_destroy(kauth_cred_t cred) |
84 | { | | 84 | { |
85 | | | 85 | |
86 | rump_cred_destroy(cred); | | 86 | rump_cred_destroy(cred); |
87 | } | | 87 | } |
88 | | | 88 | |
89 | static struct componentname * | | 89 | static struct componentname * |
90 | makecn(const struct puffs_cn *pcn) | | 90 | makecn(const struct puffs_cn *pcn) |
91 | { | | 91 | { |
92 | kauth_cred_t cred; | | 92 | kauth_cred_t cred; |
93 | | | 93 | |
94 | cred = cred_create(pcn->pcn_cred); | | 94 | cred = cred_create(pcn->pcn_cred); |
95 | /* LINTED: prehistoric types in first two args */ | | 95 | /* LINTED: prehistoric types in first two args */ |
96 | return rump_makecn(pcn->pcn_nameiop, pcn->pcn_flags, pcn->pcn_name, | | 96 | return rump_makecn(pcn->pcn_nameiop, pcn->pcn_flags, pcn->pcn_name, |
97 | pcn->pcn_namelen, cred, curlwp); | | 97 | pcn->pcn_namelen, cred, curlwp); |
98 | } | | 98 | } |
99 | | | 99 | |
100 | static __inline void | | 100 | static __inline void |
101 | freecn(struct componentname *cnp, int flags) | | 101 | freecn(struct componentname *cnp, int flags) |
102 | { | | 102 | { |
103 | | | 103 | |
104 | rump_freecn(cnp, flags | RUMPCN_FREECRED); | | 104 | rump_freecn(cnp, flags | RUMPCN_FREECRED); |
105 | } | | 105 | } |
106 | | | 106 | |
107 | static void | | 107 | static void |
108 | makelwp(struct puffs_usermount *pu) | | 108 | makelwp(struct puffs_usermount *pu) |
109 | { | | 109 | { |
110 | pid_t pid; | | 110 | pid_t pid; |
111 | lwpid_t lid; | | 111 | lwpid_t lid; |
112 | | | 112 | |
113 | puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid); | | 113 | puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid); |
114 | rump_setup_curlwp(pid, lid, 1); | | 114 | rump_setup_curlwp(pid, lid, 1); |
115 | } | | 115 | } |
116 | | | 116 | |
117 | /*ARGSUSED*/ | | 117 | /*ARGSUSED*/ |
118 | static void | | 118 | static void |
119 | clearlwp(struct puffs_usermount *pu) | | 119 | clearlwp(struct puffs_usermount *pu) |
120 | { | | 120 | { |
121 | | | 121 | |
122 | /* | | 122 | /* |
123 | * XXX: because of the vnode reference counting lossage, we | | 123 | * XXX: because of the vnode reference counting lossage, we |
124 | * can't clear the curlwp if we unmounted succesfully. | | 124 | * can't clear the curlwp if we unmounted succesfully. |
125 | * Therefore, don't do it to avoid a diagnostic panic. | | 125 | * Therefore, don't do it to avoid a diagnostic panic. |
126 | * So this currently leaks a process structure in that case, | | 126 | * So this currently leaks a process structure in that case, |
127 | * but since p2k is rarely used multiple times in a single | | 127 | * but since p2k is rarely used multiple times in a single |
128 | * process, it's more like a feature than a bug (yea, I'm | | 128 | * process, it's more like a feature than a bug (yea, I'm |
129 | * good at lying to myself). | | 129 | * good at lying to myself). |
130 | */ | | 130 | */ |
131 | if (__predict_false(puffs_getstate(pu) != PUFFS_STATE_UNMOUNTED)) | | 131 | if (__predict_false(puffs_getstate(pu) != PUFFS_STATE_UNMOUNTED)) |
132 | rump_clear_curlwp(); | | 132 | rump_clear_curlwp(); |
133 | } | | 133 | } |
134 | | | 134 | |
135 | int | | 135 | int |
136 | p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath, | | 136 | p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath, |
137 | int mntflags, void *arg, size_t alen, uint32_t puffs_flags) | | 137 | int mntflags, void *arg, size_t alen, uint32_t puffs_flags) |
138 | { | | 138 | { |
139 | char typebuf[PUFFS_TYPELEN]; | | 139 | char typebuf[PUFFS_TYPELEN]; |
140 | struct puffs_ops *pops; | | 140 | struct puffs_ops *pops; |
141 | struct puffs_usermount *pu; | | 141 | struct puffs_usermount *pu; |
142 | struct puffs_node *pn_root; | | 142 | struct puffs_node *pn_root; |
143 | struct vnode *rvp; | | 143 | struct vnode *rvp; |
144 | struct ukfs *ukfs; | | 144 | struct ukfs *ukfs; |
145 | extern int puffs_fakecc; | | 145 | extern int puffs_fakecc; |
146 | int rv, sverrno; | | 146 | int rv, sverrno; |
147 | | | 147 | |
148 | rv = -1; | | 148 | rv = -1; |
149 | ukfs_init(); | | 149 | if (ukfs_init() == -1) |
| | | 150 | return -1; |
150 | ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags, arg, alen); | | 151 | ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags, arg, alen); |
151 | if (ukfs == NULL) | | 152 | if (ukfs == NULL) |
152 | return -1; | | 153 | return -1; |
153 | | | 154 | |
154 | PUFFSOP_INIT(pops); | | 155 | PUFFSOP_INIT(pops); |
155 | | | 156 | |
156 | PUFFSOP_SET(pops, p2k, fs, statvfs); | | 157 | PUFFSOP_SET(pops, p2k, fs, statvfs); |
157 | PUFFSOP_SET(pops, p2k, fs, unmount); | | 158 | PUFFSOP_SET(pops, p2k, fs, unmount); |
158 | PUFFSOP_SET(pops, p2k, fs, sync); | | 159 | PUFFSOP_SET(pops, p2k, fs, sync); |
159 | PUFFSOP_SET(pops, p2k, fs, fhtonode); | | 160 | PUFFSOP_SET(pops, p2k, fs, fhtonode); |
160 | PUFFSOP_SET(pops, p2k, fs, nodetofh); | | 161 | PUFFSOP_SET(pops, p2k, fs, nodetofh); |
161 | | | 162 | |
162 | PUFFSOP_SET(pops, p2k, node, lookup); | | 163 | PUFFSOP_SET(pops, p2k, node, lookup); |
163 | PUFFSOP_SET(pops, p2k, node, create); | | 164 | PUFFSOP_SET(pops, p2k, node, create); |
164 | PUFFSOP_SET(pops, p2k, node, mknod); | | 165 | PUFFSOP_SET(pops, p2k, node, mknod); |
165 | PUFFSOP_SET(pops, p2k, node, open); | | 166 | PUFFSOP_SET(pops, p2k, node, open); |
166 | PUFFSOP_SET(pops, p2k, node, close); | | 167 | PUFFSOP_SET(pops, p2k, node, close); |
167 | PUFFSOP_SET(pops, p2k, node, access); | | 168 | PUFFSOP_SET(pops, p2k, node, access); |
168 | PUFFSOP_SET(pops, p2k, node, getattr); | | 169 | PUFFSOP_SET(pops, p2k, node, getattr); |
169 | PUFFSOP_SET(pops, p2k, node, setattr); | | 170 | PUFFSOP_SET(pops, p2k, node, setattr); |
170 | #if 0 | | 171 | #if 0 |
171 | PUFFSOP_SET(pops, p2k, node, poll); | | 172 | PUFFSOP_SET(pops, p2k, node, poll); |
172 | #endif | | 173 | #endif |
173 | PUFFSOP_SET(pops, p2k, node, mmap); | | 174 | PUFFSOP_SET(pops, p2k, node, mmap); |
174 | PUFFSOP_SET(pops, p2k, node, fsync); | | 175 | PUFFSOP_SET(pops, p2k, node, fsync); |
175 | PUFFSOP_SET(pops, p2k, node, seek); | | 176 | PUFFSOP_SET(pops, p2k, node, seek); |
176 | PUFFSOP_SET(pops, p2k, node, remove); | | 177 | PUFFSOP_SET(pops, p2k, node, remove); |
177 | PUFFSOP_SET(pops, p2k, node, link); | | 178 | PUFFSOP_SET(pops, p2k, node, link); |
178 | PUFFSOP_SET(pops, p2k, node, rename); | | 179 | PUFFSOP_SET(pops, p2k, node, rename); |
179 | PUFFSOP_SET(pops, p2k, node, mkdir); | | 180 | PUFFSOP_SET(pops, p2k, node, mkdir); |
180 | PUFFSOP_SET(pops, p2k, node, rmdir); | | 181 | PUFFSOP_SET(pops, p2k, node, rmdir); |
181 | PUFFSOP_SET(pops, p2k, node, symlink); | | 182 | PUFFSOP_SET(pops, p2k, node, symlink); |
182 | PUFFSOP_SET(pops, p2k, node, readdir); | | 183 | PUFFSOP_SET(pops, p2k, node, readdir); |
183 | PUFFSOP_SET(pops, p2k, node, readlink); | | 184 | PUFFSOP_SET(pops, p2k, node, readlink); |
184 | PUFFSOP_SET(pops, p2k, node, read); | | 185 | PUFFSOP_SET(pops, p2k, node, read); |
185 | PUFFSOP_SET(pops, p2k, node, write); | | 186 | PUFFSOP_SET(pops, p2k, node, write); |
186 | | | 187 | |
187 | PUFFSOP_SET(pops, p2k, node, inactive); | | 188 | PUFFSOP_SET(pops, p2k, node, inactive); |
188 | PUFFSOP_SET(pops, p2k, node, reclaim); | | 189 | PUFFSOP_SET(pops, p2k, node, reclaim); |
189 | | | 190 | |
190 | strcpy(typebuf, "p2k|"); | | 191 | strcpy(typebuf, "p2k|"); |
191 | if (strcmp(vfsname, "puffs") == 0) { /* XXX */ | | 192 | if (strcmp(vfsname, "puffs") == 0) { /* XXX */ |
192 | struct puffs_kargs *args = arg; | | 193 | struct puffs_kargs *args = arg; |
193 | strlcat(typebuf, args->pa_typename, sizeof(typebuf)); | | 194 | strlcat(typebuf, args->pa_typename, sizeof(typebuf)); |
194 | } else { | | 195 | } else { |
195 | strlcat(typebuf, vfsname, sizeof(typebuf)); | | 196 | strlcat(typebuf, vfsname, sizeof(typebuf)); |
196 | } | | 197 | } |
197 | | | 198 | |
198 | pu = puffs_init(pops, devpath, typebuf, ukfs_getmp(ukfs), puffs_flags); | | 199 | pu = puffs_init(pops, devpath, typebuf, ukfs_getmp(ukfs), puffs_flags); |
199 | if (pu == NULL) | | 200 | if (pu == NULL) |
200 | goto out; | | 201 | goto out; |
201 | | | 202 | |
202 | rvp = ukfs_getrvp(ukfs); | | 203 | rvp = ukfs_getrvp(ukfs); |
203 | pn_root = puffs_pn_new(pu, rvp); | | 204 | pn_root = puffs_pn_new(pu, rvp); |
204 | puffs_setroot(pu, pn_root); | | 205 | puffs_setroot(pu, pn_root); |
205 | puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH); | | 206 | puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH); |
206 | puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN); | | 207 | puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN); |
207 | puffs_fakecc = 1; | | 208 | puffs_fakecc = 1; |
208 | | | 209 | |
209 | puffs_set_prepost(pu, makelwp, clearlwp); | | 210 | puffs_set_prepost(pu, makelwp, clearlwp); |
210 | | | 211 | |
211 | if ((rv = puffs_mount(pu, mountpath, mntflags, rvp))== -1) | | 212 | if ((rv = puffs_mount(pu, mountpath, mntflags, rvp))== -1) |
212 | goto out; | | 213 | goto out; |
213 | rv = puffs_mainloop(pu); | | 214 | rv = puffs_mainloop(pu); |
214 | | | 215 | |
215 | out: | | 216 | out: |
216 | sverrno = errno; | | 217 | sverrno = errno; |
217 | ukfs_release(ukfs, UKFS_RELFLAG_NOUNMOUNT); | | 218 | ukfs_release(ukfs, UKFS_RELFLAG_NOUNMOUNT); |
218 | if (rv) { | | 219 | if (rv) { |
219 | errno = sverrno; | | 220 | errno = sverrno; |
220 | rv = -1; | | 221 | rv = -1; |
221 | } | | 222 | } |
222 | | | 223 | |
223 | return rv; | | 224 | return rv; |
224 | } | | 225 | } |
225 | | | 226 | |
226 | /* XXX: vn_lock() */ | | 227 | /* XXX: vn_lock() */ |
227 | #define VLE(a) RUMP_VOP_LOCK(a, LK_EXCLUSIVE) | | 228 | #define VLE(a) RUMP_VOP_LOCK(a, LK_EXCLUSIVE) |
228 | #define VLS(a) RUMP_VOP_LOCK(a, LK_SHARED) | | 229 | #define VLS(a) RUMP_VOP_LOCK(a, LK_SHARED) |
229 | #define VUL(a) RUMP_VOP_UNLOCK(a, 0); | | 230 | #define VUL(a) RUMP_VOP_UNLOCK(a, 0); |
230 | #define AUL(a) assert(RUMP_VOP_ISLOCKED(a) == 0) | | 231 | #define AUL(a) assert(RUMP_VOP_ISLOCKED(a) == 0) |
231 | | | 232 | |
232 | int | | 233 | int |
233 | p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp) | | 234 | p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp) |
234 | { | | 235 | { |
235 | struct mount *mp = puffs_getspecific(pu); | | 236 | struct mount *mp = puffs_getspecific(pu); |
236 | | | 237 | |
237 | return rump_vfs_statvfs(mp, sbp); | | 238 | return rump_vfs_statvfs(mp, sbp); |
238 | } | | 239 | } |
239 | | | 240 | |
240 | int | | 241 | int |
241 | p2k_fs_unmount(struct puffs_usermount *pu, int flags) | | 242 | p2k_fs_unmount(struct puffs_usermount *pu, int flags) |
242 | { | | 243 | { |
243 | struct mount *mp = puffs_getspecific(pu); | | 244 | struct mount *mp = puffs_getspecific(pu); |
244 | struct puffs_node *pn_root = puffs_getroot(pu); | | 245 | struct puffs_node *pn_root = puffs_getroot(pu); |
245 | struct vnode *rvp = pn_root->pn_data, *rvp2; | | 246 | struct vnode *rvp = pn_root->pn_data, *rvp2; |
246 | int rv; | | 247 | int rv; |
247 | | | 248 | |
248 | /* | | 249 | /* |
249 | * We recycle the root node already here (god knows how | | 250 | * We recycle the root node already here (god knows how |
250 | * many references it has due to lookup). This is good | | 251 | * many references it has due to lookup). This is good |
251 | * because VFS_UNMOUNT would do it anyway. But it is | | 252 | * because VFS_UNMOUNT would do it anyway. But it is |
252 | * very bad if VFS_UNMOUNT fails for a reason or another | | 253 | * very bad if VFS_UNMOUNT fails for a reason or another |
253 | * (puffs guards against busy fs, but there might be other | | 254 | * (puffs guards against busy fs, but there might be other |
254 | * reasons). | | 255 | * reasons). |
255 | * | | 256 | * |
256 | * Theoretically we're going south, sinking fast & dying | | 257 | * Theoretically we're going south, sinking fast & dying |
257 | * out here because the old vnode will be freed and we are | | 258 | * out here because the old vnode will be freed and we are |
258 | * unlikely to get a vnode at the same address. But try | | 259 | * unlikely to get a vnode at the same address. But try |
259 | * anyway. | | 260 | * anyway. |
260 | * | | 261 | * |
261 | * XXX: reallyfixmesomeday. either introduce VFS_ROOT to | | 262 | * XXX: reallyfixmesomeday. either introduce VFS_ROOT to |
262 | * puffs (blah) or check the cookie in every routine | | 263 | * puffs (blah) or check the cookie in every routine |
263 | * against the root cookie, which might change (blah2). | | 264 | * against the root cookie, which might change (blah2). |
264 | */ | | 265 | */ |
265 | rump_vp_recycle_nokidding(rvp); | | 266 | rump_vp_recycle_nokidding(rvp); |
266 | rv = rump_vfs_unmount(mp, flags); | | 267 | rv = rump_vfs_unmount(mp, flags); |
267 | if (rv) { | | 268 | if (rv) { |
268 | int rv2; | | 269 | int rv2; |
269 | | | 270 | |
270 | rv2 = rump_vfs_root(mp, &rvp2, 0); | | 271 | rv2 = rump_vfs_root(mp, &rvp2, 0); |
271 | assert(rv2 == 0 && rvp == rvp2); | | 272 | assert(rv2 == 0 && rvp == rvp2); |
272 | } | | 273 | } |
273 | return rv; | | 274 | return rv; |
274 | } | | 275 | } |
275 | | | 276 | |
276 | int | | 277 | int |
277 | p2k_fs_sync(struct puffs_usermount *pu, int waitfor, | | 278 | p2k_fs_sync(struct puffs_usermount *pu, int waitfor, |
278 | const struct puffs_cred *pcr) | | 279 | const struct puffs_cred *pcr) |
279 | { | | 280 | { |
280 | struct mount *mp = puffs_getspecific(pu); | | 281 | struct mount *mp = puffs_getspecific(pu); |
281 | kauth_cred_t cred; | | 282 | kauth_cred_t cred; |
282 | int rv; | | 283 | int rv; |
283 | | | 284 | |
284 | cred = cred_create(pcr); | | 285 | cred = cred_create(pcr); |
285 | rv = rump_vfs_sync(mp, waitfor, (kauth_cred_t)cred); | | 286 | rv = rump_vfs_sync(mp, waitfor, (kauth_cred_t)cred); |
286 | cred_destroy(cred); | | 287 | cred_destroy(cred); |
287 | | | 288 | |
288 | rump_bioops_sync(); | | 289 | rump_bioops_sync(); |
289 | | | 290 | |
290 | return rv; | | 291 | return rv; |
291 | } | | 292 | } |
292 | | | 293 | |
293 | /*ARGSUSED*/ | | 294 | /*ARGSUSED*/ |
294 | int | | 295 | int |
295 | p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize, | | 296 | p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize, |
296 | struct puffs_newinfo *pni) | | 297 | struct puffs_newinfo *pni) |
297 | { | | 298 | { |
298 | struct mount *mp = puffs_getspecific(pu); | | 299 | struct mount *mp = puffs_getspecific(pu); |
299 | struct vnode *vp; | | 300 | struct vnode *vp; |
300 | enum vtype vtype; | | 301 | enum vtype vtype; |
301 | voff_t vsize; | | 302 | voff_t vsize; |
302 | dev_t rdev; | | 303 | dev_t rdev; |
303 | int rv; | | 304 | int rv; |
304 | | | 305 | |
305 | rv = rump_vfs_fhtovp(mp, fid, &vp); | | 306 | rv = rump_vfs_fhtovp(mp, fid, &vp); |
306 | if (rv) | | 307 | if (rv) |
307 | return rv; | | 308 | return rv; |
308 | | | 309 | |
309 | puffs_newinfo_setcookie(pni, vp); | | 310 | puffs_newinfo_setcookie(pni, vp); |
310 | rump_getvninfo(vp, &vtype, &vsize, &rdev); | | 311 | rump_getvninfo(vp, &vtype, &vsize, &rdev); |
311 | puffs_newinfo_setvtype(pni, vtype); | | 312 | puffs_newinfo_setvtype(pni, vtype); |
312 | puffs_newinfo_setsize(pni, vsize); | | 313 | puffs_newinfo_setsize(pni, vsize); |
313 | puffs_newinfo_setrdev(pni, rdev); | | 314 | puffs_newinfo_setrdev(pni, rdev); |
314 | | | 315 | |
315 | return 0; | | 316 | return 0; |
316 | } | | 317 | } |
317 | | | 318 | |
318 | /*ARGSUSED*/ | | 319 | /*ARGSUSED*/ |
319 | int | | 320 | int |
320 | p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid, | | 321 | p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid, |
321 | size_t *fidsize) | | 322 | size_t *fidsize) |
322 | { | | 323 | { |
323 | struct vnode *vp = cookie; | | 324 | struct vnode *vp = cookie; |
324 | | | 325 | |
325 | return rump_vfs_vptofh(vp, fid, fidsize); | | 326 | return rump_vfs_vptofh(vp, fid, fidsize); |
326 | } | | 327 | } |
327 | | | 328 | |
328 | /*ARGSUSED*/ | | 329 | /*ARGSUSED*/ |
329 | int | | 330 | int |
330 | p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, | | 331 | p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, |
331 | struct puffs_newinfo *pni, const struct puffs_cn *pcn) | | 332 | struct puffs_newinfo *pni, const struct puffs_cn *pcn) |
332 | { | | 333 | { |
333 | struct componentname *cn; | | 334 | struct componentname *cn; |
334 | struct vnode *vp; | | 335 | struct vnode *vp; |
335 | enum vtype vtype; | | 336 | enum vtype vtype; |
336 | voff_t vsize; | | 337 | voff_t vsize; |
337 | dev_t rdev; | | 338 | dev_t rdev; |
338 | int rv; | | 339 | int rv; |
339 | | | 340 | |
340 | cn = makecn(pcn); | | 341 | cn = makecn(pcn); |
341 | VLE(opc); | | 342 | VLE(opc); |
342 | rv = RUMP_VOP_LOOKUP(opc, &vp, cn); | | 343 | rv = RUMP_VOP_LOOKUP(opc, &vp, cn); |
343 | VUL(opc); | | 344 | VUL(opc); |
344 | freecn(cn, RUMPCN_ISLOOKUP); | | 345 | freecn(cn, RUMPCN_ISLOOKUP); |
345 | if (rv) { | | 346 | if (rv) { |
346 | if (rv == EJUSTRETURN) | | 347 | if (rv == EJUSTRETURN) |
347 | rv = ENOENT; | | 348 | rv = ENOENT; |
348 | return rv; | | 349 | return rv; |
349 | } | | 350 | } |
350 | VUL(vp); | | 351 | VUL(vp); |
351 | | | 352 | |
352 | puffs_newinfo_setcookie(pni, vp); | | 353 | puffs_newinfo_setcookie(pni, vp); |
353 | rump_getvninfo(vp, &vtype, &vsize, &rdev); | | 354 | rump_getvninfo(vp, &vtype, &vsize, &rdev); |
354 | puffs_newinfo_setvtype(pni, vtype); | | 355 | puffs_newinfo_setvtype(pni, vtype); |
355 | puffs_newinfo_setsize(pni, vsize); | | 356 | puffs_newinfo_setsize(pni, vsize); |
356 | puffs_newinfo_setrdev(pni, rdev); | | 357 | puffs_newinfo_setrdev(pni, rdev); |
357 | | | 358 | |
358 | return 0; | | 359 | return 0; |
359 | } | | 360 | } |
360 | | | 361 | |
361 | /*ARGSUSED*/ | | 362 | /*ARGSUSED*/ |
362 | int | | 363 | int |
363 | p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc, | | 364 | p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc, |
364 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | | 365 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, |
365 | const struct vattr *vap) | | 366 | const struct vattr *vap) |
366 | { | | 367 | { |
367 | struct componentname *cn; | | 368 | struct componentname *cn; |
368 | struct vnode *vp; | | 369 | struct vnode *vp; |
369 | int rv; | | 370 | int rv; |
370 | | | 371 | |
371 | cn = makecn(pcn); | | 372 | cn = makecn(pcn); |
372 | VLE(opc); | | 373 | VLE(opc); |
373 | rump_vp_incref(opc); | | 374 | rump_vp_incref(opc); |
374 | rv = RUMP_VOP_CREATE(opc, &vp, cn, __UNCONST(vap)); | | 375 | rv = RUMP_VOP_CREATE(opc, &vp, cn, __UNCONST(vap)); |
375 | AUL(opc); | | 376 | AUL(opc); |
376 | freecn(cn, 0); | | 377 | freecn(cn, 0); |
377 | if (rv == 0) { | | 378 | if (rv == 0) { |
378 | VUL(vp); | | 379 | VUL(vp); |
379 | puffs_newinfo_setcookie(pni, vp); | | 380 | puffs_newinfo_setcookie(pni, vp); |
380 | } | | 381 | } |
381 | | | 382 | |
382 | return rv; | | 383 | return rv; |
383 | } | | 384 | } |
384 | | | 385 | |
385 | /*ARGSUSED*/ | | 386 | /*ARGSUSED*/ |
386 | int | | 387 | int |
387 | p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc, | | 388 | p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc, |
388 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | | 389 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, |
389 | const struct vattr *vap) | | 390 | const struct vattr *vap) |
390 | { | | 391 | { |
391 | struct componentname *cn; | | 392 | struct componentname *cn; |
392 | struct vnode *vp; | | 393 | struct vnode *vp; |
393 | int rv; | | 394 | int rv; |
394 | | | 395 | |
395 | cn = makecn(pcn); | | 396 | cn = makecn(pcn); |
396 | VLE(opc); | | 397 | VLE(opc); |
397 | rump_vp_incref(opc); | | 398 | rump_vp_incref(opc); |
398 | rv = RUMP_VOP_MKNOD(opc, &vp, cn, __UNCONST(vap)); | | 399 | rv = RUMP_VOP_MKNOD(opc, &vp, cn, __UNCONST(vap)); |
399 | AUL(opc); | | 400 | AUL(opc); |
400 | freecn(cn, 0); | | 401 | freecn(cn, 0); |
401 | if (rv == 0) { | | 402 | if (rv == 0) { |
402 | VUL(vp); | | 403 | VUL(vp); |
403 | puffs_newinfo_setcookie(pni, vp); | | 404 | puffs_newinfo_setcookie(pni, vp); |
404 | } | | 405 | } |
405 | | | 406 | |
406 | return rv; | | 407 | return rv; |
407 | } | | 408 | } |
408 | | | 409 | |
409 | /*ARGSUSED*/ | | 410 | /*ARGSUSED*/ |
410 | int | | 411 | int |
411 | p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, | | 412 | p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, |
412 | const struct puffs_cred *pcr) | | 413 | const struct puffs_cred *pcr) |
413 | { | | 414 | { |
414 | kauth_cred_t cred; | | 415 | kauth_cred_t cred; |
415 | int rv; | | 416 | int rv; |
416 | | | 417 | |
417 | cred = cred_create(pcr); | | 418 | cred = cred_create(pcr); |
418 | VLE(opc); | | 419 | VLE(opc); |
419 | rv = RUMP_VOP_OPEN(opc, mode, cred); | | 420 | rv = RUMP_VOP_OPEN(opc, mode, cred); |
420 | VUL(opc); | | 421 | VUL(opc); |
421 | cred_destroy(cred); | | 422 | cred_destroy(cred); |
422 | | | 423 | |
423 | return rv; | | 424 | return rv; |
424 | } | | 425 | } |
425 | | | 426 | |
426 | /*ARGSUSED*/ | | 427 | /*ARGSUSED*/ |
427 | int | | 428 | int |
428 | p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags, | | 429 | p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags, |
429 | const struct puffs_cred *pcr) | | 430 | const struct puffs_cred *pcr) |
430 | { | | 431 | { |
431 | kauth_cred_t cred; | | 432 | kauth_cred_t cred; |
432 | | | 433 | |
433 | cred = cred_create(pcr); | | 434 | cred = cred_create(pcr); |
434 | VLE(opc); | | 435 | VLE(opc); |
435 | RUMP_VOP_CLOSE(opc, flags, cred); | | 436 | RUMP_VOP_CLOSE(opc, flags, cred); |
436 | VUL(opc); | | 437 | VUL(opc); |
437 | cred_destroy(cred); | | 438 | cred_destroy(cred); |
438 | | | 439 | |
439 | return 0; | | 440 | return 0; |
440 | } | | 441 | } |
441 | | | 442 | |
442 | /*ARGSUSED*/ | | 443 | /*ARGSUSED*/ |
443 | int | | 444 | int |
444 | p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, | | 445 | p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, |
445 | const struct puffs_cred *pcr) | | 446 | const struct puffs_cred *pcr) |
446 | { | | 447 | { |
447 | kauth_cred_t cred; | | 448 | kauth_cred_t cred; |
448 | int rv; | | 449 | int rv; |
449 | | | 450 | |
450 | cred = cred_create(pcr); | | 451 | cred = cred_create(pcr); |
451 | VLE(opc); | | 452 | VLE(opc); |
452 | rv = RUMP_VOP_ACCESS(opc, mode, cred); | | 453 | rv = RUMP_VOP_ACCESS(opc, mode, cred); |
453 | VUL(opc); | | 454 | VUL(opc); |
454 | cred_destroy(cred); | | 455 | cred_destroy(cred); |
455 | | | 456 | |
456 | return rv; | | 457 | return rv; |
457 | } | | 458 | } |
458 | | | 459 | |
459 | /*ARGSUSED*/ | | 460 | /*ARGSUSED*/ |
460 | int | | 461 | int |
461 | p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, | | 462 | p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, |
462 | struct vattr *vap, const struct puffs_cred *pcr) | | 463 | struct vattr *vap, const struct puffs_cred *pcr) |
463 | { | | 464 | { |
464 | kauth_cred_t cred; | | 465 | kauth_cred_t cred; |
465 | int rv; | | 466 | int rv; |
466 | | | 467 | |
467 | cred = cred_create(pcr); | | 468 | cred = cred_create(pcr); |
468 | VLE(opc); | | 469 | VLE(opc); |
469 | rv = RUMP_VOP_GETATTR(opc, vap, cred); | | 470 | rv = RUMP_VOP_GETATTR(opc, vap, cred); |
470 | VUL(opc); | | 471 | VUL(opc); |
471 | cred_destroy(cred); | | 472 | cred_destroy(cred); |
472 | | | 473 | |
473 | return rv; | | 474 | return rv; |
474 | } | | 475 | } |
475 | | | 476 | |
476 | /*ARGSUSED*/ | | 477 | /*ARGSUSED*/ |
477 | int | | 478 | int |
478 | p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc, | | 479 | p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc, |
479 | const struct vattr *vap, const struct puffs_cred *pcr) | | 480 | const struct vattr *vap, const struct puffs_cred *pcr) |
480 | { | | 481 | { |
481 | kauth_cred_t cred; | | 482 | kauth_cred_t cred; |
482 | int rv; | | 483 | int rv; |
483 | | | 484 | |
484 | cred = cred_create(pcr); | | 485 | cred = cred_create(pcr); |
485 | VLE(opc); | | 486 | VLE(opc); |
486 | rv = RUMP_VOP_SETATTR(opc, __UNCONST(vap), cred); | | 487 | rv = RUMP_VOP_SETATTR(opc, __UNCONST(vap), cred); |
487 | VUL(opc); | | 488 | VUL(opc); |
488 | cred_destroy(cred); | | 489 | cred_destroy(cred); |
489 | | | 490 | |
490 | return rv; | | 491 | return rv; |
491 | } | | 492 | } |
492 | | | 493 | |
493 | /*ARGSUSED*/ | | 494 | /*ARGSUSED*/ |
494 | int | | 495 | int |
495 | p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc, | | 496 | p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc, |
496 | const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi) | | 497 | const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi) |
497 | { | | 498 | { |
498 | kauth_cred_t cred; | | 499 | kauth_cred_t cred; |
499 | int rv; | | 500 | int rv; |
500 | | | 501 | |
501 | cred = cred_create(pcr); | | 502 | cred = cred_create(pcr); |
502 | VLE(opc); | | 503 | VLE(opc); |
503 | rv = RUMP_VOP_FSYNC(opc, cred, flags, offlo, offhi); | | 504 | rv = RUMP_VOP_FSYNC(opc, cred, flags, offlo, offhi); |
504 | VUL(opc); | | 505 | VUL(opc); |
505 | cred_destroy(cred); | | 506 | cred_destroy(cred); |
506 | | | 507 | |
507 | return rv; | | 508 | return rv; |
508 | } | | 509 | } |
509 | | | 510 | |
510 | /*ARGSUSED*/ | | 511 | /*ARGSUSED*/ |
511 | int | | 512 | int |
512 | p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags, | | 513 | p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags, |
513 | const struct puffs_cred *pcr) | | 514 | const struct puffs_cred *pcr) |
514 | { | | 515 | { |
515 | kauth_cred_t cred; | | 516 | kauth_cred_t cred; |
516 | int rv; | | 517 | int rv; |
517 | | | 518 | |
518 | cred = cred_create(pcr); | | 519 | cred = cred_create(pcr); |
519 | rv = RUMP_VOP_MMAP(opc, flags, cred); | | 520 | rv = RUMP_VOP_MMAP(opc, flags, cred); |
520 | cred_destroy(cred); | | 521 | cred_destroy(cred); |
521 | | | 522 | |
522 | return rv; | | 523 | return rv; |
523 | } | | 524 | } |
524 | | | 525 | |
525 | /*ARGSUSED*/ | | 526 | /*ARGSUSED*/ |
526 | int | | 527 | int |
527 | p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc, | | 528 | p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc, |
528 | off_t oldoff, off_t newoff, const struct puffs_cred *pcr) | | 529 | off_t oldoff, off_t newoff, const struct puffs_cred *pcr) |
529 | { | | 530 | { |
530 | kauth_cred_t cred; | | 531 | kauth_cred_t cred; |
531 | int rv; | | 532 | int rv; |
532 | | | 533 | |
533 | cred = cred_create(pcr); | | 534 | cred = cred_create(pcr); |
534 | VLE(opc); | | 535 | VLE(opc); |
535 | rv = RUMP_VOP_SEEK(opc, oldoff, newoff, cred); | | 536 | rv = RUMP_VOP_SEEK(opc, oldoff, newoff, cred); |
536 | VUL(opc); | | 537 | VUL(opc); |
537 | cred_destroy(cred); | | 538 | cred_destroy(cred); |
538 | | | 539 | |
539 | return rv; | | 540 | return rv; |
540 | } | | 541 | } |
541 | | | 542 | |
542 | /*ARGSUSED*/ | | 543 | /*ARGSUSED*/ |
543 | int | | 544 | int |
544 | p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, | | 545 | p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, |
545 | puffs_cookie_t targ, const struct puffs_cn *pcn) | | 546 | puffs_cookie_t targ, const struct puffs_cn *pcn) |
546 | { | | 547 | { |
547 | struct componentname *cn; | | 548 | struct componentname *cn; |
548 | int rv; | | 549 | int rv; |
549 | | | 550 | |
550 | cn = makecn(pcn); | | 551 | cn = makecn(pcn); |
551 | VLE(opc); | | 552 | VLE(opc); |
552 | rump_vp_incref(opc); | | 553 | rump_vp_incref(opc); |
553 | VLE(targ); | | 554 | VLE(targ); |
554 | rump_vp_incref(targ); | | 555 | rump_vp_incref(targ); |
555 | rv = RUMP_VOP_REMOVE(opc, targ, cn); | | 556 | rv = RUMP_VOP_REMOVE(opc, targ, cn); |
556 | AUL(opc); | | 557 | AUL(opc); |
557 | AUL(targ); | | 558 | AUL(targ); |
558 | freecn(cn, 0); | | 559 | freecn(cn, 0); |
559 | | | 560 | |
560 | return rv; | | 561 | return rv; |
561 | } | | 562 | } |
562 | | | 563 | |
563 | /*ARGSUSED*/ | | 564 | /*ARGSUSED*/ |
564 | int | | 565 | int |
565 | p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc, | | 566 | p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc, |
566 | puffs_cookie_t targ, const struct puffs_cn *pcn) | | 567 | puffs_cookie_t targ, const struct puffs_cn *pcn) |
567 | { | | 568 | { |
568 | struct componentname *cn; | | 569 | struct componentname *cn; |
569 | int rv; | | 570 | int rv; |
570 | | | 571 | |
571 | cn = makecn(pcn); | | 572 | cn = makecn(pcn); |
572 | VLE(opc); | | 573 | VLE(opc); |
573 | rump_vp_incref(opc); | | 574 | rump_vp_incref(opc); |
574 | rv = RUMP_VOP_LINK(opc, targ, cn); | | 575 | rv = RUMP_VOP_LINK(opc, targ, cn); |
575 | freecn(cn, 0); | | 576 | freecn(cn, 0); |
576 | | | 577 | |
577 | return rv; | | 578 | return rv; |
578 | } | | 579 | } |
579 | | | 580 | |
580 | /*ARGSUSED*/ | | 581 | /*ARGSUSED*/ |
581 | int | | 582 | int |
582 | p2k_node_rename(struct puffs_usermount *pu, | | 583 | p2k_node_rename(struct puffs_usermount *pu, |
583 | puffs_cookie_t src_dir, puffs_cookie_t src, | | 584 | puffs_cookie_t src_dir, puffs_cookie_t src, |
584 | const struct puffs_cn *pcn_src, | | 585 | const struct puffs_cn *pcn_src, |
585 | puffs_cookie_t targ_dir, puffs_cookie_t targ, | | 586 | puffs_cookie_t targ_dir, puffs_cookie_t targ, |
586 | const struct puffs_cn *pcn_targ) | | 587 | const struct puffs_cn *pcn_targ) |
587 | { | | 588 | { |
588 | struct componentname *cn_src, *cn_targ; | | 589 | struct componentname *cn_src, *cn_targ; |
589 | int rv; | | 590 | int rv; |
590 | | | 591 | |
591 | cn_src = makecn(pcn_src); | | 592 | cn_src = makecn(pcn_src); |
592 | cn_targ = makecn(pcn_targ); | | 593 | cn_targ = makecn(pcn_targ); |
593 | rump_vp_incref(src_dir); | | 594 | rump_vp_incref(src_dir); |
594 | rump_vp_incref(src); | | 595 | rump_vp_incref(src); |
595 | VLE(targ_dir); | | 596 | VLE(targ_dir); |
596 | rump_vp_incref(targ_dir); | | 597 | rump_vp_incref(targ_dir); |
597 | if (targ) { | | 598 | if (targ) { |
598 | VLE(targ); | | 599 | VLE(targ); |
599 | rump_vp_incref(targ); | | 600 | rump_vp_incref(targ); |
600 | } | | 601 | } |
601 | rv = RUMP_VOP_RENAME(src_dir, src, cn_src, targ_dir, targ, cn_targ); | | 602 | rv = RUMP_VOP_RENAME(src_dir, src, cn_src, targ_dir, targ, cn_targ); |
602 | AUL(targ_dir); | | 603 | AUL(targ_dir); |
603 | if (targ) | | 604 | if (targ) |
604 | AUL(targ); | | 605 | AUL(targ); |
605 | freecn(cn_src, 0); | | 606 | freecn(cn_src, 0); |
606 | freecn(cn_targ, 0); | | 607 | freecn(cn_targ, 0); |
607 | | | 608 | |
608 | return rv; | | 609 | return rv; |
609 | } | | 610 | } |
610 | | | 611 | |
611 | /*ARGSUSED*/ | | 612 | /*ARGSUSED*/ |
612 | int | | 613 | int |
613 | p2k_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc, | | 614 | p2k_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc, |
614 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | | 615 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, |
615 | const struct vattr *vap) | | 616 | const struct vattr *vap) |
616 | { | | 617 | { |
617 | struct componentname *cn; | | 618 | struct componentname *cn; |
618 | struct vnode *vp; | | 619 | struct vnode *vp; |
619 | int rv; | | 620 | int rv; |
620 | | | 621 | |
621 | cn = makecn(pcn); | | 622 | cn = makecn(pcn); |
622 | VLE(opc); | | 623 | VLE(opc); |
623 | rump_vp_incref(opc); | | 624 | rump_vp_incref(opc); |
624 | rv = RUMP_VOP_MKDIR(opc, &vp, cn, __UNCONST(vap)); | | 625 | rv = RUMP_VOP_MKDIR(opc, &vp, cn, __UNCONST(vap)); |
625 | AUL(opc); | | 626 | AUL(opc); |
626 | freecn(cn, 0); | | 627 | freecn(cn, 0); |
627 | if (rv == 0) { | | 628 | if (rv == 0) { |
628 | VUL(vp); | | 629 | VUL(vp); |
629 | puffs_newinfo_setcookie(pni, vp); | | 630 | puffs_newinfo_setcookie(pni, vp); |
630 | } | | 631 | } |
631 | | | 632 | |
632 | return rv; | | 633 | return rv; |
633 | } | | 634 | } |
634 | | | 635 | |
635 | /*ARGSUSED*/ | | 636 | /*ARGSUSED*/ |
636 | int | | 637 | int |
637 | p2k_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc, | | 638 | p2k_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc, |
638 | puffs_cookie_t targ, const struct puffs_cn *pcn) | | 639 | puffs_cookie_t targ, const struct puffs_cn *pcn) |
639 | { | | 640 | { |
640 | struct componentname *cn; | | 641 | struct componentname *cn; |
641 | int rv; | | 642 | int rv; |
642 | | | 643 | |
643 | cn = makecn(pcn); | | 644 | cn = makecn(pcn); |
644 | VLE(opc); | | 645 | VLE(opc); |
645 | rump_vp_incref(opc); | | 646 | rump_vp_incref(opc); |
646 | VLE(targ); | | 647 | VLE(targ); |
647 | rump_vp_incref(targ); | | 648 | rump_vp_incref(targ); |
648 | rv = RUMP_VOP_RMDIR(opc, targ, cn); | | 649 | rv = RUMP_VOP_RMDIR(opc, targ, cn); |
649 | AUL(targ); | | 650 | AUL(targ); |
650 | AUL(opc); | | 651 | AUL(opc); |
651 | freecn(cn, 0); | | 652 | freecn(cn, 0); |
652 | | | 653 | |
653 | return rv; | | 654 | return rv; |
654 | } | | 655 | } |
655 | | | 656 | |
656 | /*ARGSUSED*/ | | 657 | /*ARGSUSED*/ |
657 | int | | 658 | int |
658 | p2k_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc, | | 659 | p2k_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc, |
659 | struct puffs_newinfo *pni, const struct puffs_cn *pcn_src, | | 660 | struct puffs_newinfo *pni, const struct puffs_cn *pcn_src, |
660 | const struct vattr *vap, const char *link_target) | | 661 | const struct vattr *vap, const char *link_target) |
661 | { | | 662 | { |
662 | struct componentname *cn; | | 663 | struct componentname *cn; |
663 | struct vnode *vp; | | 664 | struct vnode *vp; |
664 | int rv; | | 665 | int rv; |
665 | | | 666 | |
666 | cn = makecn(pcn_src); | | 667 | cn = makecn(pcn_src); |
667 | VLE(opc); | | 668 | VLE(opc); |
668 | rump_vp_incref(opc); | | 669 | rump_vp_incref(opc); |
669 | rv = RUMP_VOP_SYMLINK(opc, &vp, cn, | | 670 | rv = RUMP_VOP_SYMLINK(opc, &vp, cn, |
670 | __UNCONST(vap), __UNCONST(link_target)); | | 671 | __UNCONST(vap), __UNCONST(link_target)); |
671 | AUL(opc); | | 672 | AUL(opc); |
672 | freecn(cn, 0); | | 673 | freecn(cn, 0); |
673 | if (rv == 0) { | | 674 | if (rv == 0) { |
674 | VUL(vp); | | 675 | VUL(vp); |
675 | puffs_newinfo_setcookie(pni, vp); | | 676 | puffs_newinfo_setcookie(pni, vp); |
676 | } | | 677 | } |
677 | | | 678 | |
678 | return rv; | | 679 | return rv; |
679 | } | | 680 | } |
680 | | | 681 | |
681 | /*ARGSUSED*/ | | 682 | /*ARGSUSED*/ |
682 | int | | 683 | int |
683 | p2k_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc, | | 684 | p2k_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc, |
684 | struct dirent *dent, off_t *readoff, size_t *reslen, | | 685 | struct dirent *dent, off_t *readoff, size_t *reslen, |
685 | const struct puffs_cred *pcr, int *eofflag, | | 686 | const struct puffs_cred *pcr, int *eofflag, |
686 | off_t *cookies, size_t *ncookies) | | 687 | off_t *cookies, size_t *ncookies) |
687 | { | | 688 | { |
688 | kauth_cred_t cred; | | 689 | kauth_cred_t cred; |
689 | struct uio *uio; | | 690 | struct uio *uio; |
690 | off_t *vop_cookies; | | 691 | off_t *vop_cookies; |
691 | int vop_ncookies; | | 692 | int vop_ncookies; |
692 | int rv; | | 693 | int rv; |
693 | | | 694 | |
694 | cred = cred_create(pcr); | | 695 | cred = cred_create(pcr); |
695 | uio = rump_uio_setup(dent, *reslen, *readoff, RUMPUIO_READ); | | 696 | uio = rump_uio_setup(dent, *reslen, *readoff, RUMPUIO_READ); |
696 | VLS(opc); | | 697 | VLS(opc); |
697 | if (cookies) { | | 698 | if (cookies) { |
698 | rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag, | | 699 | rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag, |
699 | &vop_cookies, &vop_ncookies); | | 700 | &vop_cookies, &vop_ncookies); |
700 | memcpy(cookies, vop_cookies, vop_ncookies * sizeof(*cookies)); | | 701 | memcpy(cookies, vop_cookies, vop_ncookies * sizeof(*cookies)); |
701 | *ncookies = vop_ncookies; | | 702 | *ncookies = vop_ncookies; |
702 | free(vop_cookies); | | 703 | free(vop_cookies); |
703 | } else { | | 704 | } else { |
704 | rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag, NULL, NULL); | | 705 | rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag, NULL, NULL); |
705 | } | | 706 | } |
706 | VUL(opc); | | 707 | VUL(opc); |
707 | if (rv == 0) { | | 708 | if (rv == 0) { |
708 | *reslen = rump_uio_getresid(uio); | | 709 | *reslen = rump_uio_getresid(uio); |
709 | *readoff = rump_uio_getoff(uio); | | 710 | *readoff = rump_uio_getoff(uio); |
710 | } | | 711 | } |
711 | rump_uio_free(uio); | | 712 | rump_uio_free(uio); |
712 | cred_destroy(cred); | | 713 | cred_destroy(cred); |
713 | | | 714 | |
714 | return rv; | | 715 | return rv; |
715 | } | | 716 | } |
716 | | | 717 | |
717 | /*ARGSUSED*/ | | 718 | /*ARGSUSED*/ |
718 | int | | 719 | int |
719 | p2k_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc, | | 720 | p2k_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc, |
720 | const struct puffs_cred *pcr, char *linkname, size_t *linklen) | | 721 | const struct puffs_cred *pcr, char *linkname, size_t *linklen) |
721 | { | | 722 | { |
722 | kauth_cred_t cred; | | 723 | kauth_cred_t cred; |
723 | struct uio *uio; | | 724 | struct uio *uio; |
724 | int rv; | | 725 | int rv; |
725 | | | 726 | |
726 | cred = cred_create(pcr); | | 727 | cred = cred_create(pcr); |
727 | uio = rump_uio_setup(linkname, *linklen, 0, RUMPUIO_READ); | | 728 | uio = rump_uio_setup(linkname, *linklen, 0, RUMPUIO_READ); |
728 | VLE(opc); | | 729 | VLE(opc); |
729 | rv = RUMP_VOP_READLINK(opc, uio, cred); | | 730 | rv = RUMP_VOP_READLINK(opc, uio, cred); |
730 | VUL(opc); | | 731 | VUL(opc); |
731 | *linklen -= rump_uio_free(uio); | | 732 | *linklen -= rump_uio_free(uio); |
732 | cred_destroy(cred); | | 733 | cred_destroy(cred); |
733 | | | 734 | |
734 | return rv; | | 735 | return rv; |
735 | } | | 736 | } |
736 | | | 737 | |
737 | /*ARGSUSED*/ | | 738 | /*ARGSUSED*/ |
738 | int | | 739 | int |
739 | p2k_node_read(struct puffs_usermount *pu, puffs_cookie_t opc, | | 740 | p2k_node_read(struct puffs_usermount *pu, puffs_cookie_t opc, |
740 | uint8_t *buf, off_t offset, size_t *resid, | | 741 | uint8_t *buf, off_t offset, size_t *resid, |
741 | const struct puffs_cred *pcr, int ioflag) | | 742 | const struct puffs_cred *pcr, int ioflag) |
742 | { | | 743 | { |
743 | kauth_cred_t cred; | | 744 | kauth_cred_t cred; |
744 | struct uio *uio; | | 745 | struct uio *uio; |
745 | int rv; | | 746 | int rv; |
746 | | | 747 | |
747 | cred = cred_create(pcr); | | 748 | cred = cred_create(pcr); |
748 | uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_READ); | | 749 | uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_READ); |
749 | VLS(opc); | | 750 | VLS(opc); |
750 | rv = RUMP_VOP_READ(opc, uio, ioflag, cred); | | 751 | rv = RUMP_VOP_READ(opc, uio, ioflag, cred); |
751 | VUL(opc); | | 752 | VUL(opc); |
752 | *resid = rump_uio_free(uio); | | 753 | *resid = rump_uio_free(uio); |
753 | cred_destroy(cred); | | 754 | cred_destroy(cred); |
754 | | | 755 | |
755 | return rv; | | 756 | return rv; |
756 | } | | 757 | } |
757 | | | 758 | |
758 | /*ARGSUSED*/ | | 759 | /*ARGSUSED*/ |
759 | int | | 760 | int |
760 | p2k_node_write(struct puffs_usermount *pu, puffs_cookie_t opc, | | 761 | p2k_node_write(struct puffs_usermount *pu, puffs_cookie_t opc, |
761 | uint8_t *buf, off_t offset, size_t *resid, | | 762 | uint8_t *buf, off_t offset, size_t *resid, |
762 | const struct puffs_cred *pcr, int ioflag) | | 763 | const struct puffs_cred *pcr, int ioflag) |
763 | { | | 764 | { |
764 | kauth_cred_t cred; | | 765 | kauth_cred_t cred; |
765 | struct uio *uio; | | 766 | struct uio *uio; |
766 | int rv; | | 767 | int rv; |
767 | | | 768 | |
768 | cred = cred_create(pcr); | | 769 | cred = cred_create(pcr); |
769 | uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_WRITE); | | 770 | uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_WRITE); |
770 | VLE(opc); | | 771 | VLE(opc); |
771 | rv = RUMP_VOP_WRITE(opc, uio, ioflag, cred); | | 772 | rv = RUMP_VOP_WRITE(opc, uio, ioflag, cred); |
772 | VUL(opc); | | 773 | VUL(opc); |
773 | *resid = rump_uio_free(uio); | | 774 | *resid = rump_uio_free(uio); |
774 | cred_destroy(cred); | | 775 | cred_destroy(cred); |
775 | | | 776 | |
776 | return rv; | | 777 | return rv; |
777 | } | | 778 | } |
778 | | | 779 | |
779 | int | | 780 | int |
780 | p2k_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc) | | 781 | p2k_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc) |
781 | { | | 782 | { |
782 | struct vnode *vp = opc; | | 783 | struct vnode *vp = opc; |
783 | bool recycle; | | 784 | bool recycle; |
784 | int rv; | | 785 | int rv; |
785 | | | 786 | |
786 | rump_vp_interlock(vp); | | 787 | rump_vp_interlock(vp); |
787 | (void) RUMP_VOP_PUTPAGES(vp, 0, 0, PGO_ALLPAGES); | | 788 | (void) RUMP_VOP_PUTPAGES(vp, 0, 0, PGO_ALLPAGES); |
788 | VLE(vp); | | 789 | VLE(vp); |
789 | rv = RUMP_VOP_INACTIVE(vp, &recycle); | | 790 | rv = RUMP_VOP_INACTIVE(vp, &recycle); |
790 | if (recycle) | | 791 | if (recycle) |
791 | puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1); | | 792 | puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1); |
792 | | | 793 | |
793 | return rv; | | 794 | return rv; |
794 | } | | 795 | } |
795 | | | 796 | |
796 | /*ARGSUSED*/ | | 797 | /*ARGSUSED*/ |
797 | int | | 798 | int |
798 | p2k_node_reclaim(struct puffs_usermount *pu, puffs_croissant_t opc) | | 799 | p2k_node_reclaim(struct puffs_usermount *pu, puffs_croissant_t opc) |
799 | { | | 800 | { |
800 | | | 801 | |
801 | rump_vp_recycle_nokidding(opc); | | 802 | rump_vp_recycle_nokidding(opc); |
802 | return 0; | | 803 | return 0; |
803 | } | | 804 | } |