File: | nfs/nfs_vnops.c |
Warning: | line 2634, column 2 Value stored to 'error' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: nfs_vnops.c,v 1.193 2023/04/26 10:00:37 beck Exp $ */ |
2 | /* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */ |
3 | |
4 | /* |
5 | * Copyright (c) 1989, 1993 |
6 | * The Regents of the University of California. All rights reserved. |
7 | * |
8 | * This code is derived from software contributed to Berkeley by |
9 | * Rick Macklem at The University of Guelph. |
10 | * |
11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions |
13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. |
16 | * 2. Redistributions in binary form must reproduce the above copyright |
17 | * notice, this list of conditions and the following disclaimer in the |
18 | * documentation and/or other materials provided with the distribution. |
19 | * 3. Neither the name of the University nor the names of its contributors |
20 | * may be used to endorse or promote products derived from this software |
21 | * without specific prior written permission. |
22 | * |
23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
33 | * SUCH DAMAGE. |
34 | * |
35 | * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 |
36 | */ |
37 | |
38 | |
39 | /* |
40 | * vnode op calls for Sun NFS version 2 and 3 |
41 | */ |
42 | |
43 | #include <sys/param.h> |
44 | #include <sys/kernel.h> |
45 | #include <sys/systm.h> |
46 | #include <sys/resourcevar.h> |
47 | #include <sys/proc.h> |
48 | #include <sys/mount.h> |
49 | #include <sys/buf.h> |
50 | #include <sys/malloc.h> |
51 | #include <sys/pool.h> |
52 | #include <sys/mbuf.h> |
53 | #include <sys/conf.h> |
54 | #include <sys/namei.h> |
55 | #include <sys/vnode.h> |
56 | #include <sys/lock.h> |
57 | #include <sys/dirent.h> |
58 | #include <sys/fcntl.h> |
59 | #include <sys/lockf.h> |
60 | #include <sys/queue.h> |
61 | #include <sys/specdev.h> |
62 | #include <sys/unistd.h> |
63 | |
64 | #include <miscfs/fifofs/fifo.h> |
65 | |
66 | #include <nfs/rpcv2.h> |
67 | #include <nfs/nfsproto.h> |
68 | #include <nfs/nfs.h> |
69 | #include <nfs/nfsnode.h> |
70 | #include <nfs/nfsmount.h> |
71 | #include <nfs/xdr_subs.h> |
72 | #include <nfs/nfsm_subs.h> |
73 | #include <nfs/nfs_var.h> |
74 | |
75 | #include <uvm/uvm_extern.h> |
76 | |
77 | #include <netinet/in.h> |
78 | |
79 | int nfs_access(void *); |
80 | int nfs_advlock(void *); |
81 | int nfs_bmap(void *); |
82 | int nfs_bwrite(void *); |
83 | int nfs_close(void *); |
84 | int nfs_commit(struct vnode *, u_quad_t, int, struct proc *); |
85 | int nfs_create(void *); |
86 | int nfs_flush(struct vnode *, struct ucred *, int, struct proc *, int); |
87 | int nfs_fsync(void *); |
88 | int nfs_getattr(void *); |
89 | int nfs_getreq(struct nfsrv_descript *, struct nfsd *, int); |
90 | int nfs_islocked(void *); |
91 | int nfs_link(void *); |
92 | int nfs_lock(void *); |
93 | int nfs_lookitup(struct vnode *, char *, int, struct ucred *, struct proc *, |
94 | struct nfsnode **); |
95 | int nfs_lookup(void *); |
96 | int nfs_mkdir(void *); |
97 | int nfs_mknod(void *); |
98 | int nfs_mknodrpc(struct vnode *, struct vnode **, struct componentname *, |
99 | struct vattr *); |
100 | int nfs_null(struct vnode *, struct ucred *, struct proc *); |
101 | int nfs_open(void *); |
102 | int nfs_pathconf(void *); |
103 | int nfs_print(void *); |
104 | int nfs_read(void *); |
105 | int nfs_readdir(void *); |
106 | int nfs_readdirplusrpc(struct vnode *, struct uio *, struct ucred *, int *, |
107 | struct proc *); |
108 | int nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *, int *); |
109 | int nfs_remove(void *); |
110 | int nfs_removerpc(struct vnode *, char *, int, struct ucred *, struct proc *); |
111 | int nfs_rename(void *); |
112 | int nfs_renameit(struct vnode *, struct componentname *, struct sillyrename *); |
113 | int nfs_renamerpc(struct vnode *, char *, int, struct vnode *, char *, int, |
114 | struct ucred *, struct proc *); |
115 | int nfs_rmdir(void *); |
116 | int nfs_setattr(void *); |
117 | int nfs_setattrrpc(struct vnode *, struct vattr *, struct ucred *, |
118 | struct proc *); |
119 | int nfs_sillyrename(struct vnode *, struct vnode *, |
120 | struct componentname *); |
121 | int nfs_strategy(void *); |
122 | int nfs_symlink(void *); |
123 | int nfs_unlock(void *); |
124 | |
125 | void nfs_cache_enter(struct vnode *, struct vnode *, struct componentname *); |
126 | |
127 | int nfsfifo_close(void *); |
128 | int nfsfifo_read(void *); |
129 | int nfsfifo_reclaim(void *); |
130 | int nfsfifo_write(void *); |
131 | |
132 | int nfsspec_access(void *); |
133 | int nfsspec_close(void *); |
134 | int nfsspec_read(void *); |
135 | int nfsspec_write(void *); |
136 | |
137 | /* Global vfs data structures for nfs. */ |
138 | const struct vops nfs_vops = { |
139 | .vop_lookup = nfs_lookup, |
140 | .vop_create = nfs_create, |
141 | .vop_mknod = nfs_mknod, |
142 | .vop_open = nfs_open, |
143 | .vop_close = nfs_close, |
144 | .vop_access = nfs_access, |
145 | .vop_getattr = nfs_getattr, |
146 | .vop_setattr = nfs_setattr, |
147 | .vop_read = nfs_read, |
148 | .vop_write = nfs_write, |
149 | .vop_ioctl = nfs_ioctl((int (*)(void *))enoioctl), |
150 | .vop_kqfilter = nfs_kqfilter, |
151 | .vop_revoke = vop_generic_revoke, |
152 | .vop_fsync = nfs_fsync, |
153 | .vop_remove = nfs_remove, |
154 | .vop_link = nfs_link, |
155 | .vop_rename = nfs_rename, |
156 | .vop_mkdir = nfs_mkdir, |
157 | .vop_rmdir = nfs_rmdir, |
158 | .vop_symlink = nfs_symlink, |
159 | .vop_readdir = nfs_readdir, |
160 | .vop_readlink = nfs_readlink, |
161 | .vop_abortop = vop_generic_abortop, |
162 | .vop_inactive = nfs_inactive, |
163 | .vop_reclaim = nfs_reclaim, |
164 | .vop_lock = nfs_lock, |
165 | .vop_unlock = nfs_unlock, |
166 | .vop_bmap = nfs_bmap, |
167 | .vop_strategy = nfs_strategy, |
168 | .vop_print = nfs_print, |
169 | .vop_islocked = nfs_islocked, |
170 | .vop_pathconf = nfs_pathconf, |
171 | .vop_advlock = nfs_advlock, |
172 | .vop_bwrite = nfs_bwrite |
173 | }; |
174 | |
175 | /* Special device vnode ops. */ |
176 | const struct vops nfs_specvops = { |
177 | .vop_close = nfsspec_close, |
178 | .vop_access = nfsspec_access, |
179 | .vop_getattr = nfs_getattr, |
180 | .vop_setattr = nfs_setattr, |
181 | .vop_read = nfsspec_read, |
182 | .vop_write = nfsspec_write, |
183 | .vop_fsync = nfs_fsync, |
184 | .vop_inactive = nfs_inactive, |
185 | .vop_reclaim = nfs_reclaim, |
186 | .vop_lock = nfs_lock, |
187 | .vop_unlock = nfs_unlock, |
188 | .vop_print = nfs_print, |
189 | .vop_islocked = nfs_islocked, |
190 | |
191 | /* XXX: Keep in sync with spec_vops. */ |
192 | .vop_lookup = vop_generic_lookup, |
193 | .vop_create = vop_generic_badop, |
194 | .vop_mknod = vop_generic_badop, |
195 | .vop_open = spec_open, |
196 | .vop_ioctl = spec_ioctl, |
197 | .vop_kqfilter = spec_kqfilter, |
198 | .vop_revoke = vop_generic_revoke, |
199 | .vop_remove = vop_generic_badop, |
200 | .vop_link = vop_generic_badop, |
201 | .vop_rename = vop_generic_badop, |
202 | .vop_mkdir = vop_generic_badop, |
203 | .vop_rmdir = vop_generic_badop, |
204 | .vop_symlink = vop_generic_badop, |
205 | .vop_readdir = vop_generic_badop, |
206 | .vop_readlink = vop_generic_badop, |
207 | .vop_abortop = vop_generic_badop, |
208 | .vop_bmap = vop_generic_bmap, |
209 | .vop_strategy = spec_strategy, |
210 | .vop_pathconf = spec_pathconf, |
211 | .vop_advlock = spec_advlock, |
212 | .vop_bwrite = vop_generic_bwrite, |
213 | }; |
214 | |
215 | #ifdef FIFO1 |
216 | const struct vops nfs_fifovops = { |
217 | .vop_close = nfsfifo_close, |
218 | .vop_access = nfsspec_access, |
219 | .vop_getattr = nfs_getattr, |
220 | .vop_setattr = nfs_setattr, |
221 | .vop_read = nfsfifo_read, |
222 | .vop_write = nfsfifo_write, |
223 | .vop_fsync = nfs_fsync, |
224 | .vop_inactive = nfs_inactive, |
225 | .vop_reclaim = nfsfifo_reclaim, |
226 | .vop_lock = nfs_lock, |
227 | .vop_unlock = nfs_unlock, |
228 | .vop_print = nfs_print, |
229 | .vop_islocked = nfs_islocked, |
230 | .vop_bwrite = vop_generic_bwrite, |
231 | |
232 | /* XXX: Keep in sync with fifo_vops. */ |
233 | .vop_lookup = vop_generic_lookup, |
234 | .vop_create = vop_generic_badop, |
235 | .vop_mknod = vop_generic_badop, |
236 | .vop_open = fifo_open, |
237 | .vop_ioctl = fifo_ioctl, |
238 | .vop_kqfilter = fifo_kqfilter, |
239 | .vop_revoke = vop_generic_revoke, |
240 | .vop_remove = vop_generic_badop, |
241 | .vop_link = vop_generic_badop, |
242 | .vop_rename = vop_generic_badop, |
243 | .vop_mkdir = vop_generic_badop, |
244 | .vop_rmdir = vop_generic_badop, |
245 | .vop_symlink = vop_generic_badop, |
246 | .vop_readdir = vop_generic_badop, |
247 | .vop_readlink = vop_generic_badop, |
248 | .vop_abortop = vop_generic_badop, |
249 | .vop_bmap = vop_generic_bmap, |
250 | .vop_strategy = vop_generic_badop, |
251 | .vop_pathconf = fifo_pathconf, |
252 | .vop_advlock = fifo_advlock, |
253 | }; |
254 | #endif /* FIFO */ |
255 | |
256 | /* |
257 | * Global variables |
258 | */ |
259 | extern u_int32_t nfs_true, nfs_false; |
260 | extern u_int32_t nfs_xdrneg1; |
261 | extern struct nfsstats nfsstats; |
262 | extern nfstype nfsv3_type[9]; |
263 | int nfs_numasync = 0; |
264 | |
265 | void |
266 | nfs_cache_enter(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) |
267 | { |
268 | struct nfsnode *np; |
269 | |
270 | if (vp != NULL((void *)0)) { |
271 | np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
272 | np->n_ctime = np->n_vattr.va_ctime.tv_sec; |
273 | } else { |
274 | np = VTONFS(dvp)((struct nfsnode *)(dvp)->v_data); |
275 | if (!np->n_ctime) |
276 | np->n_ctime = np->n_vattr.va_mtime.tv_sec; |
277 | } |
278 | |
279 | cache_enter(dvp, vp, cnp); |
280 | } |
281 | |
282 | /* |
283 | * nfs null call from vfs. |
284 | */ |
285 | int |
286 | nfs_null(struct vnode *vp, struct ucred *cred, struct proc *procp) |
287 | { |
288 | struct nfsm_info info; |
289 | int error = 0; |
290 | |
291 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(0); |
292 | error = nfs_request(vp, NFSPROC_NULL0, &info); |
293 | m_freem(info.nmi_mrep); |
294 | return (error); |
295 | } |
296 | |
297 | /* |
298 | * nfs access vnode op. |
299 | * For nfs version 2, just return ok. File accesses may fail later. |
300 | * For nfs version 3, use the access rpc to check accessibility. If file modes |
301 | * are changed on the server, accesses might still fail later. |
302 | */ |
303 | int |
304 | nfs_access(void *v) |
305 | { |
306 | struct vop_access_args *ap = v; |
307 | struct vnode *vp = ap->a_vp; |
308 | u_int32_t *tl; |
309 | int32_t t1; |
310 | caddr_t cp2; |
311 | int error = 0, attrflag; |
312 | u_int32_t mode, rmode; |
313 | int v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
314 | int cachevalid; |
315 | struct nfsm_info info; |
316 | |
317 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
318 | |
319 | /* |
320 | * Disallow write attempts on filesystems mounted read-only; |
321 | * unless the file is a socket, fifo, or a block or character |
322 | * device resident on the filesystem. |
323 | */ |
324 | if ((ap->a_mode & VWRITE00200) && (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001)) { |
325 | switch (vp->v_type) { |
326 | case VREG: |
327 | case VDIR: |
328 | case VLNK: |
329 | return (EROFS30); |
330 | default: |
331 | break; |
332 | } |
333 | } |
334 | |
335 | /* |
336 | * Check access cache first. If a request has been made for this uid |
337 | * shortly before, use the cached result. |
338 | */ |
339 | cachevalid = (np->n_accstamp != -1 && |
340 | (gettime() - np->n_accstamp) < nfs_attrtimeo(np) && |
341 | np->n_accuid == ap->a_cred->cr_uid); |
342 | |
343 | if (cachevalid) { |
344 | if (!np->n_accerror) { |
345 | if ((np->n_accmode & ap->a_mode) == ap->a_mode) |
346 | return (np->n_accerror); |
347 | } else if ((np->n_accmode & ap->a_mode) == np->n_accmode) |
348 | return (np->n_accerror); |
349 | } |
350 | |
351 | /* |
352 | * For nfs v3, do an access rpc, otherwise you are stuck emulating |
353 | * ufs_access() locally using the vattr. This may not be correct, |
354 | * since the server may apply other access criteria such as |
355 | * client uid-->server uid mapping that we do not know about, but |
356 | * this is better than just returning anything that is lying about |
357 | * in the cache. |
358 | */ |
359 | if (v3) { |
360 | nfsstats.rpccnt[NFSPROC_ACCESS4]++; |
361 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3)((v3) ? (64 + 4) : 32) + NFSX_UNSIGNED4); |
362 | nfsm_fhtom(&info, vp, v3); |
363 | tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4); |
364 | if (ap->a_mode & VREAD00400) |
365 | mode = NFSV3ACCESS_READ0x01; |
366 | else |
367 | mode = 0; |
368 | if (vp->v_type == VDIR) { |
369 | if (ap->a_mode & VWRITE00200) |
370 | mode |= (NFSV3ACCESS_MODIFY0x04 | NFSV3ACCESS_EXTEND0x08 | |
371 | NFSV3ACCESS_DELETE0x10); |
372 | if (ap->a_mode & VEXEC00100) |
373 | mode |= NFSV3ACCESS_LOOKUP0x02; |
374 | } else { |
375 | if (ap->a_mode & VWRITE00200) |
376 | mode |= (NFSV3ACCESS_MODIFY0x04 | NFSV3ACCESS_EXTEND0x08); |
377 | if (ap->a_mode & VEXEC00100) |
378 | mode |= NFSV3ACCESS_EXECUTE0x20; |
379 | } |
380 | *tl = txdr_unsigned(mode)((__uint32_t)(__builtin_constant_p((int32_t)(mode)) ? (__uint32_t )(((__uint32_t)((int32_t)(mode)) & 0xff) << 24 | (( __uint32_t)((int32_t)(mode)) & 0xff00) << 8 | ((__uint32_t )((int32_t)(mode)) & 0xff0000) >> 8 | ((__uint32_t) ((int32_t)(mode)) & 0xff000000) >> 24) : __swap32md ((int32_t)(mode)))); |
381 | |
382 | info.nmi_procp = ap->a_p; |
383 | info.nmi_cred = ap->a_cred; |
384 | error = nfs_request(vp, NFSPROC_ACCESS4, &info); |
385 | |
386 | nfsm_postop_attr(vp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (vp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (vp) = ttvp; } } }; |
387 | if (error) { |
388 | m_freem(info.nmi_mrep); |
389 | goto nfsmout; |
390 | } |
391 | |
392 | nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
393 | rmode = fxdr_unsigned(u_int32_t, *tl)((u_int32_t)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ( (__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(*tl)))); |
394 | /* |
395 | * The NFS V3 spec does not clarify whether or not |
396 | * the returned access bits can be a superset of |
397 | * the ones requested, so... |
398 | */ |
399 | if ((rmode & mode) != mode) |
400 | error = EACCES13; |
401 | |
402 | m_freem(info.nmi_mrep); |
403 | } else |
404 | return (nfsspec_access(ap)); |
405 | |
406 | |
407 | /* |
408 | * If we got the same result as for a previous, different request, OR |
409 | * it in. Don't update the timestamp in that case. |
410 | */ |
411 | if (!error || error == EACCES13) { |
412 | if (cachevalid && np->n_accstamp != -1 && |
413 | error == np->n_accerror) { |
414 | if (!error) |
415 | np->n_accmode |= ap->a_mode; |
416 | else { |
417 | if ((np->n_accmode & ap->a_mode) == ap->a_mode) |
418 | np->n_accmode = ap->a_mode; |
419 | } |
420 | } else { |
421 | np->n_accstamp = gettime(); |
422 | np->n_accuid = ap->a_cred->cr_uid; |
423 | np->n_accmode = ap->a_mode; |
424 | np->n_accerror = error; |
425 | } |
426 | } |
427 | nfsmout: |
428 | return (error); |
429 | } |
430 | |
431 | /* |
432 | * nfs open vnode op |
433 | * Check to see if the type is ok |
434 | * and that deletion is not in progress. |
435 | * For paged in text files, you will need to flush the page cache |
436 | * if consistency is lost. |
437 | */ |
438 | int |
439 | nfs_open(void *v) |
440 | { |
441 | struct vop_open_args *ap = v; |
442 | struct vnode *vp = ap->a_vp; |
443 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
444 | struct vattr vattr; |
445 | int error; |
446 | |
447 | if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) { |
448 | #ifdef DIAGNOSTIC1 |
449 | printf("open eacces vtyp=%d\n",vp->v_type); |
450 | #endif |
451 | return (EACCES13); |
452 | } |
453 | |
454 | /* |
455 | * Initialize read and write creds here, for swapfiles |
456 | * and other paths that don't set the creds themselves. |
457 | */ |
458 | |
459 | if (ap->a_mode & FREAD0x0001) { |
460 | if (np->n_rcred) { |
461 | crfree(np->n_rcred); |
462 | } |
463 | np->n_rcred = ap->a_cred; |
464 | crhold(np->n_rcred); |
465 | } |
466 | if (ap->a_mode & FWRITE0x0002) { |
467 | if (np->n_wcred) { |
468 | crfree(np->n_wcred); |
469 | } |
470 | np->n_wcred = ap->a_cred; |
471 | crhold(np->n_wcred); |
472 | } |
473 | |
474 | if (np->n_flag & NMODIFIED0x0004) { |
475 | error = nfs_vinvalbuf(vp, V_SAVE0x0001, ap->a_cred, ap->a_p); |
476 | if (error == EINTR4) |
477 | return (error); |
478 | uvm_vnp_uncache(vp); |
479 | NFS_INVALIDATE_ATTRCACHE(np)((np)->n_attrstamp = 0); |
480 | if (vp->v_type == VDIR) |
481 | np->n_direofoffsetn_un2.nd_direof = 0; |
482 | error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p); |
483 | if (error) |
484 | return (error); |
485 | np->n_mtime = vattr.va_mtime; |
486 | } else { |
487 | error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p); |
488 | if (error) |
489 | return (error); |
490 | if (timespeccmp(&np->n_mtime, &vattr.va_mtime, !=)(((&np->n_mtime)->tv_sec == (&vattr.va_mtime)-> tv_sec) ? ((&np->n_mtime)->tv_nsec != (&vattr.va_mtime )->tv_nsec) : ((&np->n_mtime)->tv_sec != (&vattr .va_mtime)->tv_sec))) { |
491 | if (vp->v_type == VDIR) |
492 | np->n_direofoffsetn_un2.nd_direof = 0; |
493 | error = nfs_vinvalbuf(vp, V_SAVE0x0001, ap->a_cred, ap->a_p); |
494 | if (error == EINTR4) |
495 | return (error); |
496 | uvm_vnp_uncache(vp); |
497 | np->n_mtime = vattr.va_mtime; |
498 | } |
499 | } |
500 | /* For open/close consistency. */ |
501 | NFS_INVALIDATE_ATTRCACHE(np)((np)->n_attrstamp = 0); |
502 | return (0); |
503 | } |
504 | |
505 | /* |
506 | * nfs close vnode op |
507 | * What an NFS client should do upon close after writing is a debatable issue. |
508 | * Most NFS clients push delayed writes to the server upon close, basically for |
509 | * two reasons: |
510 | * 1 - So that any write errors may be reported back to the client process |
511 | * doing the close system call. By far the two most likely errors are |
512 | * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure. |
513 | * 2 - To put a worst case upper bound on cache inconsistency between |
514 | * multiple clients for the file. |
515 | * There is also a consistency problem for Version 2 of the protocol w.r.t. |
516 | * not being able to tell if other clients are writing a file concurrently, |
517 | * since there is no way of knowing if the changed modify time in the reply |
518 | * is only due to the write for this client. |
519 | * (NFS Version 3 provides weak cache consistency data in the reply that |
520 | * should be sufficient to detect and handle this case.) |
521 | * |
522 | * The current code does the following: |
523 | * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers |
524 | * for NFS Version 3 - flush dirty buffers to the server but don't invalidate |
525 | * or commit them (this satisfies 1 and 2 except for the |
526 | * case where the server crashes after this close but |
527 | * before the commit RPC, which is felt to be "good |
528 | * enough". Changing the last argument to nfs_flush() to |
529 | * a 1 would force a commit operation, if it is felt a |
530 | * commit is necessary now. |
531 | */ |
532 | int |
533 | nfs_close(void *v) |
534 | { |
535 | struct vop_close_args *ap = v; |
536 | struct vnode *vp = ap->a_vp; |
537 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
538 | int error = 0; |
539 | |
540 | if (vp->v_type == VREG) { |
541 | if (np->n_flag & NMODIFIED0x0004) { |
542 | if (NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200)) { |
543 | error = nfs_flush(vp, ap->a_cred, MNT_WAIT1, ap->a_p, 0); |
544 | np->n_flag &= ~NMODIFIED0x0004; |
545 | } else |
546 | error = nfs_vinvalbuf(vp, V_SAVE0x0001, ap->a_cred, ap->a_p); |
547 | NFS_INVALIDATE_ATTRCACHE(np)((np)->n_attrstamp = 0); |
548 | } |
549 | if (np->n_flag & NWRITEERR0x0008) { |
550 | np->n_flag &= ~NWRITEERR0x0008; |
551 | error = np->n_error; |
552 | } |
553 | } |
554 | return (error); |
555 | } |
556 | |
557 | /* |
558 | * nfs getattr call from vfs. |
559 | */ |
560 | int |
561 | nfs_getattr(void *v) |
562 | { |
563 | struct vop_getattr_args *ap = v; |
564 | struct vnode *vp = ap->a_vp; |
565 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
566 | struct nfsm_info info; |
567 | int32_t t1; |
568 | int error = 0; |
569 | |
570 | info.nmi_v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
571 | |
572 | /* |
573 | * Update local times for special files. |
574 | */ |
575 | if (np->n_flag & (NACC0x0100 | NUPD0x0200)) |
576 | np->n_flag |= NCHG0x0400; |
577 | /* |
578 | * First look in the cache. |
579 | */ |
580 | if (nfs_getattrcache(vp, ap->a_vap) == 0) |
581 | return (0); |
582 | |
583 | nfsstats.rpccnt[NFSPROC_GETATTR1]++; |
584 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32)); |
585 | nfsm_fhtom(&info, vp, info.nmi_v3); |
586 | info.nmi_procp = ap->a_p; |
587 | info.nmi_cred = ap->a_cred; |
588 | error = nfs_request(vp, NFSPROC_GETATTR1, &info); |
589 | if (!error) |
590 | nfsm_loadattr(vp, ap->a_vap){ struct vnode *ttvp = (vp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (ap->a_vap))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (vp ) = ttvp; }; |
591 | m_freem(info.nmi_mrep); |
592 | nfsmout: |
593 | return (error); |
594 | } |
595 | |
596 | /* |
597 | * nfs setattr call. |
598 | */ |
599 | int |
600 | nfs_setattr(void *v) |
601 | { |
602 | struct vop_setattr_args *ap = v; |
603 | struct vnode *vp = ap->a_vp; |
604 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
605 | struct vattr *vap = ap->a_vap; |
606 | int hint = NOTE_ATTRIB0x0008; |
607 | int error = 0; |
608 | u_quad_t tsize = 0; |
609 | |
610 | /* |
611 | * Setting of flags is not supported. |
612 | */ |
613 | if (vap->va_flags != VNOVAL(-1)) |
614 | return (EOPNOTSUPP45); |
615 | |
616 | /* |
617 | * Disallow write attempts if the filesystem is mounted read-only. |
618 | */ |
619 | if ((vap->va_uid != (uid_t)VNOVAL(-1) || |
620 | vap->va_gid != (gid_t)VNOVAL(-1) || |
621 | vap->va_atime.tv_nsec != VNOVAL(-1) || |
622 | vap->va_mtime.tv_nsec != VNOVAL(-1) || |
623 | vap->va_mode != (mode_t)VNOVAL(-1)) && |
624 | (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001)) |
625 | return (EROFS30); |
626 | if (vap->va_size != VNOVAL(-1)) { |
627 | switch (vp->v_type) { |
628 | case VDIR: |
629 | return (EISDIR21); |
630 | case VCHR: |
631 | case VBLK: |
632 | case VSOCK: |
633 | case VFIFO: |
634 | if (vap->va_mtime.tv_nsec == VNOVAL(-1) && |
635 | vap->va_atime.tv_nsec == VNOVAL(-1) && |
636 | vap->va_mode == (mode_t)VNOVAL(-1) && |
637 | vap->va_uid == (uid_t)VNOVAL(-1) && |
638 | vap->va_gid == (gid_t)VNOVAL(-1)) |
639 | return (0); |
640 | vap->va_size = VNOVAL(-1); |
641 | break; |
642 | default: |
643 | /* |
644 | * Disallow write attempts if the filesystem is |
645 | * mounted read-only. |
646 | */ |
647 | if (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001) |
648 | return (EROFS30); |
649 | if (vap->va_size == 0) |
650 | error = nfs_vinvalbuf(vp, 0, |
651 | ap->a_cred, ap->a_p); |
652 | else |
653 | error = nfs_vinvalbuf(vp, V_SAVE0x0001, |
654 | ap->a_cred, ap->a_p); |
655 | if (error) |
656 | return (error); |
657 | tsize = np->n_size; |
658 | np->n_size = np->n_vattr.va_size = vap->va_size; |
659 | uvm_vnp_setsize(vp, np->n_size); |
660 | }; |
661 | } else if ((vap->va_mtime.tv_nsec != VNOVAL(-1) || |
662 | vap->va_atime.tv_nsec != VNOVAL(-1)) && |
663 | vp->v_type == VREG && |
664 | (error = nfs_vinvalbuf(vp, V_SAVE0x0001, ap->a_cred, |
665 | ap->a_p)) == EINTR4) |
666 | return (error); |
667 | error = nfs_setattrrpc(vp, vap, ap->a_cred, ap->a_p); |
668 | if (error && vap->va_size != VNOVAL(-1)) { |
669 | np->n_size = np->n_vattr.va_size = tsize; |
670 | uvm_vnp_setsize(vp, np->n_size); |
671 | } |
672 | |
673 | if (vap->va_size != VNOVAL(-1) && vap->va_size < tsize) |
674 | hint |= NOTE_TRUNCATE0x0080; |
675 | |
676 | VN_KNOTE(vp, hint)knote_locked(&vp->v_klist, (hint)); /* XXX setattrrpc? */ |
677 | |
678 | return (error); |
679 | } |
680 | |
681 | /* |
682 | * Do an nfs setattr rpc. |
683 | */ |
684 | int |
685 | nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred, |
686 | struct proc *procp) |
687 | { |
688 | struct nfsv2_sattr *sp; |
689 | struct nfsm_info info; |
690 | int32_t t1; |
691 | caddr_t cp2; |
692 | u_int32_t *tl; |
693 | int error = 0, wccflag = NFSV3_WCCRATTR0; |
694 | int v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
695 | |
696 | info.nmi_v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
697 | |
698 | nfsstats.rpccnt[NFSPROC_SETATTR2]++; |
699 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3)((v3) ? (64 + 4) : 32) + NFSX_SATTR(v3)((v3) ? 60 : 32)); |
700 | nfsm_fhtom(&info, vp, v3); |
701 | |
702 | if (info.nmi_v3) { |
703 | nfsm_v3attrbuild(&info.nmi_mb, vap, 1); |
704 | tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4); |
705 | *tl = nfs_false; |
706 | } else { |
707 | sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR32); |
708 | if (vap->va_mode == (mode_t)VNOVAL(-1)) |
709 | sp->sa_mode = nfs_xdrneg1; |
710 | else |
711 | sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode)((__uint32_t)(__builtin_constant_p((int32_t)(((vp->v_type) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode ))) : (int)((vttoif_tab[(int)((vp->v_type))]) | ((vap-> va_mode))))) ? (__uint32_t)(((__uint32_t)((int32_t)(((vp-> v_type) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap-> va_mode))) : (int)((vttoif_tab[(int)((vp->v_type))]) | ((vap ->va_mode))))) & 0xff) << 24 | ((__uint32_t)((int32_t )(((vp->v_type) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)] ) | ((vap->va_mode))) : (int)((vttoif_tab[(int)((vp->v_type ))]) | ((vap->va_mode))))) & 0xff00) << 8 | ((__uint32_t )((int32_t)(((vp->v_type) == VFIFO) ? (int)((vttoif_tab[(int )(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int)((vp ->v_type))]) | ((vap->va_mode))))) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(((vp->v_type) == VFIFO) ? (int )((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab [(int)((vp->v_type))]) | ((vap->va_mode))))) & 0xff000000 ) >> 24) : __swap32md((int32_t)(((vp->v_type) == VFIFO ) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : ( int)((vttoif_tab[(int)((vp->v_type))]) | ((vap->va_mode ))))))); |
712 | if (vap->va_uid == (uid_t)VNOVAL(-1)) |
713 | sp->sa_uid = nfs_xdrneg1; |
714 | else |
715 | sp->sa_uid = txdr_unsigned(vap->va_uid)((__uint32_t)(__builtin_constant_p((int32_t)(vap->va_uid)) ? (__uint32_t)(((__uint32_t)((int32_t)(vap->va_uid)) & 0xff) << 24 | ((__uint32_t)((int32_t)(vap->va_uid)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(vap->va_uid )) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(vap-> va_uid)) & 0xff000000) >> 24) : __swap32md((int32_t )(vap->va_uid)))); |
716 | if (vap->va_gid == (gid_t)VNOVAL(-1)) |
717 | sp->sa_gid = nfs_xdrneg1; |
718 | else |
719 | sp->sa_gid = txdr_unsigned(vap->va_gid)((__uint32_t)(__builtin_constant_p((int32_t)(vap->va_gid)) ? (__uint32_t)(((__uint32_t)((int32_t)(vap->va_gid)) & 0xff) << 24 | ((__uint32_t)((int32_t)(vap->va_gid)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(vap->va_gid )) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(vap-> va_gid)) & 0xff000000) >> 24) : __swap32md((int32_t )(vap->va_gid)))); |
720 | sp->sa_size = txdr_unsigned(vap->va_size)((__uint32_t)(__builtin_constant_p((int32_t)(vap->va_size) ) ? (__uint32_t)(((__uint32_t)((int32_t)(vap->va_size)) & 0xff) << 24 | ((__uint32_t)((int32_t)(vap->va_size) ) & 0xff00) << 8 | ((__uint32_t)((int32_t)(vap-> va_size)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t )(vap->va_size)) & 0xff000000) >> 24) : __swap32md ((int32_t)(vap->va_size)))); |
721 | txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); |
722 | txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); |
723 | } |
724 | |
725 | info.nmi_procp = procp; |
726 | info.nmi_cred = cred; |
727 | error = nfs_request(vp, NFSPROC_SETATTR2, &info); |
728 | |
729 | if (info.nmi_v3) |
730 | nfsm_wcc_data(vp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(vp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(vp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(vp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((vp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((vp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
731 | else if (error == 0) |
732 | nfsm_loadattr(vp, NULL){ struct vnode *ttvp = (vp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (vp ) = ttvp; }; |
733 | |
734 | m_freem(info.nmi_mrep); |
735 | nfsmout: |
736 | return (error); |
737 | } |
738 | |
739 | /* |
740 | * nfs lookup call, one step at a time... |
741 | * First look in cache |
742 | * If not found, unlock the directory nfsnode and do the rpc |
743 | */ |
744 | int |
745 | nfs_lookup(void *v) |
746 | { |
747 | struct vop_lookup_args *ap = v; |
748 | struct componentname *cnp = ap->a_cnp; |
749 | struct vnode *dvp = ap->a_dvp; |
750 | struct vnode **vpp = ap->a_vpp; |
751 | struct nfsm_info info; |
752 | int flags; |
753 | struct vnode *newvp; |
754 | u_int32_t *tl; |
755 | int32_t t1; |
756 | struct nfsmount *nmp; |
757 | caddr_t cp2; |
758 | long len; |
759 | nfsfh_t *fhp; |
760 | struct nfsnode *np; |
761 | int lockparent, wantparent, error = 0, attrflag, fhsize; |
762 | |
763 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
764 | |
765 | cnp->cn_flags &= ~PDIRUNLOCK0x200000; |
766 | flags = cnp->cn_flags; |
767 | |
768 | *vpp = NULLVP((struct vnode *)((void *)0)); |
769 | newvp = NULLVP((struct vnode *)((void *)0)); |
770 | if ((flags & ISLASTCN0x008000) && (dvp->v_mount->mnt_flag & MNT_RDONLY0x00000001) && |
771 | (cnp->cn_nameiop == DELETE2 || cnp->cn_nameiop == RENAME3)) |
772 | return (EROFS30); |
773 | if (dvp->v_type != VDIR) |
774 | return (ENOTDIR20); |
775 | lockparent = flags & LOCKPARENT0x0008; |
776 | wantparent = flags & (LOCKPARENT0x0008|WANTPARENT0x0010); |
777 | nmp = VFSTONFS(dvp->v_mount)((struct nfsmount *)((dvp->v_mount)->mnt_data)); |
778 | np = VTONFS(dvp)((struct nfsnode *)(dvp)->v_data); |
779 | |
780 | /* |
781 | * Before tediously performing a linear scan of the directory, |
782 | * check the name cache to see if the directory/name pair |
783 | * we are looking for is known already. |
784 | * If the directory/name pair is found in the name cache, |
785 | * we have to ensure the directory has not changed from |
786 | * the time the cache entry has been created. If it has, |
787 | * the cache entry has to be ignored. |
788 | */ |
789 | if ((error = cache_lookup(dvp, vpp, cnp)) >= 0) { |
790 | struct vattr vattr; |
791 | int err2; |
792 | |
793 | if (error && error != ENOENT2) { |
794 | *vpp = NULLVP((struct vnode *)((void *)0)); |
795 | return (error); |
796 | } |
797 | |
798 | if (cnp->cn_flags & PDIRUNLOCK0x200000) { |
799 | err2 = vn_lock(dvp, LK_EXCLUSIVE0x0001UL | LK_RETRY0x2000UL); |
800 | if (err2 != 0) { |
801 | *vpp = NULLVP((struct vnode *)((void *)0)); |
802 | return (err2); |
803 | } |
804 | cnp->cn_flags &= ~PDIRUNLOCK0x200000; |
805 | } |
806 | |
807 | err2 = VOP_ACCESS(dvp, VEXEC00100, cnp->cn_cred, cnp->cn_proc); |
808 | if (err2 != 0) { |
809 | if (error == 0) { |
810 | if (*vpp != dvp) |
811 | vput(*vpp); |
812 | else |
813 | vrele(*vpp); |
814 | } |
815 | *vpp = NULLVP((struct vnode *)((void *)0)); |
816 | return (err2); |
817 | } |
818 | |
819 | if (error == ENOENT2) { |
820 | if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred, |
821 | cnp->cn_proc) && vattr.va_mtime.tv_sec == |
822 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_ctime) |
823 | return (ENOENT2); |
824 | cache_purge(dvp); |
825 | np->n_ctime = 0; |
826 | goto dorpc; |
827 | } |
828 | |
829 | newvp = *vpp; |
830 | if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred, cnp->cn_proc) |
831 | && vattr.va_ctime.tv_sec == VTONFS(newvp)((struct nfsnode *)(newvp)->v_data)->n_ctime) |
832 | { |
833 | nfsstats.lookupcache_hits++; |
834 | if (cnp->cn_nameiop != LOOKUP0 && (flags & ISLASTCN0x008000)) |
835 | cnp->cn_flags |= SAVENAME0x000800; |
836 | if ((!lockparent || !(flags & ISLASTCN0x008000)) && |
837 | newvp != dvp) { |
838 | VOP_UNLOCK(dvp); |
839 | cnp->cn_flags |= PDIRUNLOCK0x200000; |
840 | } |
841 | return (0); |
842 | } |
843 | cache_purge(newvp); |
844 | if (newvp != dvp) |
845 | vput(newvp); |
846 | else |
847 | vrele(newvp); |
848 | *vpp = NULLVP((struct vnode *)((void *)0)); |
849 | } |
850 | dorpc: |
851 | error = 0; |
852 | newvp = NULLVP((struct vnode *)((void *)0)); |
853 | nfsstats.lookupcache_misses++; |
854 | nfsstats.rpccnt[NFSPROC_LOOKUP3]++; |
855 | len = cnp->cn_namelen; |
856 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
857 | NFSX_UNSIGNED4 + nfsm_rndup(len)(((len)+3)&(~0x3))); |
858 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
859 | nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN)if ((len) > (255)) { m_freem(info.nmi_mreq); error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb, (cnp->cn_nameptr ), (len)); |
860 | |
861 | info.nmi_procp = cnp->cn_proc; |
862 | info.nmi_cred = cnp->cn_cred; |
863 | error = nfs_request(dvp, NFSPROC_LOOKUP3, &info); |
864 | |
865 | if (error) { |
866 | if (info.nmi_v3) |
867 | nfsm_postop_attr(dvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (dvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (dvp) = ttvp; } } }; |
868 | m_freem(info.nmi_mrep); |
869 | goto nfsmout; |
870 | } |
871 | |
872 | nfsm_getfh(fhp, fhsize, info.nmi_v3){ if (info.nmi_v3) { { t1 = ((caddr_t)((info.nmi_md)->m_hdr .mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info .nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (((fhsize) = ((int)(__uint32_t)(__builtin_constant_p(( int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00 ) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(*tl))))) <= 0 || (fhsize) > 64) { m_freem(info.nmi_mrep); error = 72; goto nfsmout; } } else (fhsize) = 32; { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data )) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ((((fhsize)+3)&(~0x3)))) { ((fhp)) = (nfsfh_t *)(info.nmi_dpos ); info.nmi_dpos += ((((fhsize)+3)&(~0x3))); } else if (( t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, ((((fhsize )+3)&(~0x3))), t1, &cp2)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } else { ((fhp)) = (nfsfh_t *) cp2; } }; }; |
873 | |
874 | /* |
875 | * Handle RENAME case... |
876 | */ |
877 | if (cnp->cn_nameiop == RENAME3 && wantparent && (flags & ISLASTCN0x008000)) { |
878 | if (NFS_CMPFH(np, fhp, fhsize)((np)->n_fhsize == (fhsize) && !bcmp((caddr_t)(np) ->n_fhp, (caddr_t)(fhp), (fhsize)))) { |
879 | m_freem(info.nmi_mrep); |
880 | return (EISDIR21); |
881 | } |
882 | error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); |
883 | if (error) { |
884 | m_freem(info.nmi_mrep); |
885 | return (error); |
886 | } |
887 | newvp = NFSTOV(np)((np)->n_vnode); |
888 | if (info.nmi_v3) { |
889 | nfsm_postop_attr(newvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (newvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (newvp) = ttvp; } } }; |
890 | nfsm_postop_attr(dvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (dvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (dvp) = ttvp; } } }; |
891 | } else |
892 | nfsm_loadattr(newvp, NULL){ struct vnode *ttvp = (newvp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (newvp ) = ttvp; }; |
893 | *vpp = newvp; |
894 | m_freem(info.nmi_mrep); |
895 | cnp->cn_flags |= SAVENAME0x000800; |
896 | if (!lockparent) { |
897 | VOP_UNLOCK(dvp); |
898 | cnp->cn_flags |= PDIRUNLOCK0x200000; |
899 | } |
900 | return (0); |
901 | } |
902 | |
903 | /* |
904 | * The postop attr handling is duplicated for each if case, |
905 | * because it should be done while dvp is locked (unlocking |
906 | * dvp is different for each case). |
907 | */ |
908 | |
909 | if (NFS_CMPFH(np, fhp, fhsize)((np)->n_fhsize == (fhsize) && !bcmp((caddr_t)(np) ->n_fhp, (caddr_t)(fhp), (fhsize)))) { |
910 | vref(dvp); |
911 | newvp = dvp; |
912 | if (info.nmi_v3) { |
913 | nfsm_postop_attr(newvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (newvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (newvp) = ttvp; } } }; |
914 | nfsm_postop_attr(dvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (dvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (dvp) = ttvp; } } }; |
915 | } else |
916 | nfsm_loadattr(newvp, NULL){ struct vnode *ttvp = (newvp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (newvp ) = ttvp; }; |
917 | } else if (flags & ISDOTDOT0x002000) { |
918 | VOP_UNLOCK(dvp); |
919 | cnp->cn_flags |= PDIRUNLOCK0x200000; |
920 | |
921 | error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); |
922 | if (error) { |
923 | if (vn_lock(dvp, LK_EXCLUSIVE0x0001UL | LK_RETRY0x2000UL) == 0) |
924 | cnp->cn_flags &= ~PDIRUNLOCK0x200000; |
925 | m_freem(info.nmi_mrep); |
926 | return (error); |
927 | } |
928 | newvp = NFSTOV(np)((np)->n_vnode); |
929 | |
930 | if (info.nmi_v3) { |
931 | nfsm_postop_attr(newvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (newvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (newvp) = ttvp; } } }; |
932 | nfsm_postop_attr(dvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (dvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (dvp) = ttvp; } } }; |
933 | } else |
934 | nfsm_loadattr(newvp, NULL){ struct vnode *ttvp = (newvp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (newvp ) = ttvp; }; |
935 | |
936 | if (lockparent && (flags & ISLASTCN0x008000)) { |
937 | if ((error = vn_lock(dvp, LK_EXCLUSIVE0x0001UL))) { |
938 | m_freem(info.nmi_mrep); |
939 | vput(newvp); |
940 | return error; |
941 | } |
942 | cnp->cn_flags &= ~PDIRUNLOCK0x200000; |
943 | } |
944 | |
945 | } else { |
946 | error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); |
947 | if (error) { |
948 | m_freem(info.nmi_mrep); |
949 | return error; |
950 | } |
951 | newvp = NFSTOV(np)((np)->n_vnode); |
952 | if (info.nmi_v3) { |
953 | nfsm_postop_attr(newvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (newvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (newvp) = ttvp; } } }; |
954 | nfsm_postop_attr(dvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (dvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (dvp) = ttvp; } } }; |
955 | } else |
956 | nfsm_loadattr(newvp, NULL){ struct vnode *ttvp = (newvp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (newvp ) = ttvp; }; |
957 | if (!lockparent || !(flags & ISLASTCN0x008000)) { |
958 | VOP_UNLOCK(dvp); |
959 | cnp->cn_flags |= PDIRUNLOCK0x200000; |
960 | } |
961 | } |
962 | |
963 | if (cnp->cn_nameiop != LOOKUP0 && (flags & ISLASTCN0x008000)) |
964 | cnp->cn_flags |= SAVENAME0x000800; |
965 | if ((cnp->cn_flags & MAKEENTRY0x004000) && |
966 | (cnp->cn_nameiop != DELETE2 || !(flags & ISLASTCN0x008000))) { |
967 | nfs_cache_enter(dvp, newvp, cnp); |
968 | } |
969 | |
970 | *vpp = newvp; |
971 | m_freem(info.nmi_mrep); |
972 | |
973 | nfsmout: |
974 | if (error) { |
975 | /* |
976 | * We get here only because of errors returned by |
977 | * the RPC. Otherwise we'll have returned above |
978 | * (the nfsm_* macros will jump to nfsmout |
979 | * on error). |
980 | */ |
981 | if (error == ENOENT2 && (cnp->cn_flags & MAKEENTRY0x004000) && |
982 | cnp->cn_nameiop != CREATE1) { |
983 | nfs_cache_enter(dvp, NULL((void *)0), cnp); |
984 | } |
985 | if (newvp != NULLVP((struct vnode *)((void *)0))) { |
986 | if (newvp != dvp) |
987 | vput(newvp); |
988 | else |
989 | vrele(newvp); |
990 | } |
991 | if ((cnp->cn_nameiop == CREATE1 || cnp->cn_nameiop == RENAME3) && |
992 | (flags & ISLASTCN0x008000) && error == ENOENT2) { |
993 | if (dvp->v_mount->mnt_flag & MNT_RDONLY0x00000001) |
994 | error = EROFS30; |
995 | else |
996 | error = EJUSTRETURN-2; |
997 | } |
998 | if (cnp->cn_nameiop != LOOKUP0 && (flags & ISLASTCN0x008000)) |
999 | cnp->cn_flags |= SAVENAME0x000800; |
1000 | *vpp = NULL((void *)0); |
1001 | } |
1002 | return (error); |
1003 | } |
1004 | |
1005 | /* |
1006 | * nfs read call. |
1007 | * Just call nfs_bioread() to do the work. |
1008 | */ |
1009 | int |
1010 | nfs_read(void *v) |
1011 | { |
1012 | struct vop_read_args *ap = v; |
1013 | struct vnode *vp = ap->a_vp; |
1014 | |
1015 | if (vp->v_type != VREG) |
1016 | return (EPERM1); |
1017 | return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); |
1018 | } |
1019 | |
1020 | /* |
1021 | * nfs readlink call |
1022 | */ |
1023 | int |
1024 | nfs_readlink(void *v) |
1025 | { |
1026 | struct vop_readlink_args *ap = v; |
1027 | struct vnode *vp = ap->a_vp; |
1028 | |
1029 | if (vp->v_type != VLNK) |
1030 | return (EPERM1); |
1031 | return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); |
1032 | } |
1033 | |
1034 | /* |
1035 | * Lock an inode. |
1036 | */ |
1037 | int |
1038 | nfs_lock(void *v) |
1039 | { |
1040 | struct vop_lock_args *ap = v; |
1041 | struct vnode *vp = ap->a_vp; |
1042 | |
1043 | return rrw_enter(&VTONFS(vp)((struct nfsnode *)(vp)->v_data)->n_lock, ap->a_flags & LK_RWFLAGS(0x0001UL|0x0002UL|0x0040UL|0x0080UL|0x0100UL)); |
1044 | } |
1045 | |
1046 | /* |
1047 | * Unlock an inode. |
1048 | */ |
1049 | int |
1050 | nfs_unlock(void *v) |
1051 | { |
1052 | struct vop_unlock_args *ap = v; |
1053 | struct vnode *vp = ap->a_vp; |
1054 | |
1055 | rrw_exit(&VTONFS(vp)((struct nfsnode *)(vp)->v_data)->n_lock); |
1056 | return 0; |
1057 | } |
1058 | |
1059 | /* |
1060 | * Check for a locked inode. |
1061 | */ |
1062 | int |
1063 | nfs_islocked(void *v) |
1064 | { |
1065 | struct vop_islocked_args *ap = v; |
1066 | |
1067 | return rrw_status(&VTONFS(ap->a_vp)((struct nfsnode *)(ap->a_vp)->v_data)->n_lock); |
1068 | } |
1069 | |
1070 | /* |
1071 | * Do a readlink rpc. |
1072 | * Called by nfs_doio() from below the buffer cache. |
1073 | */ |
1074 | int |
1075 | nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) |
1076 | { |
1077 | struct nfsm_info info; |
1078 | u_int32_t *tl; |
1079 | int32_t t1; |
1080 | caddr_t cp2; |
1081 | int error = 0, len, attrflag; |
1082 | |
1083 | info.nmi_v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
1084 | |
1085 | nfsstats.rpccnt[NFSPROC_READLINK5]++; |
1086 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32)); |
1087 | nfsm_fhtom(&info, vp, info.nmi_v3); |
1088 | |
1089 | info.nmi_procp = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc; |
1090 | info.nmi_cred = cred; |
1091 | error = nfs_request(vp, NFSPROC_READLINK5, &info); |
1092 | |
1093 | if (info.nmi_v3) |
1094 | nfsm_postop_attr(vp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (vp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (vp) = ttvp; } } }; |
1095 | if (!error) { |
1096 | nfsm_strsiz(len, NFS_MAXPATHLEN){ { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info. nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { ( tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, ( 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep) ; goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if ((( len) = ((int32_t)(__uint32_t)(__builtin_constant_p((int32_t)( *tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) < 0 || (len) > (1024) ) { m_freem(info.nmi_mrep); error = 72; goto nfsmout; } }; |
1097 | nfsm_mtouio(uiop, len)if ((len) > 0 && (t1 = nfsm_mbuftouio(&info.nmi_md , (uiop), (len), &info.nmi_dpos)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; }; |
1098 | } |
1099 | |
1100 | m_freem(info.nmi_mrep); |
1101 | |
1102 | nfsmout: |
1103 | return (error); |
1104 | } |
1105 | |
1106 | /* |
1107 | * nfs read rpc call |
1108 | * Ditto above |
1109 | */ |
1110 | int |
1111 | nfs_readrpc(struct vnode *vp, struct uio *uiop) |
1112 | { |
1113 | struct nfsm_info info; |
1114 | u_int32_t *tl; |
1115 | int32_t t1; |
1116 | caddr_t cp2; |
1117 | struct nfsmount *nmp; |
1118 | int error = 0, len, retlen, tsiz, eof, attrflag; |
1119 | |
1120 | info.nmi_v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
1121 | |
1122 | eof = 0; |
1123 | |
1124 | nmp = VFSTONFS(vp->v_mount)((struct nfsmount *)((vp->v_mount)->mnt_data)); |
1125 | tsiz = uiop->uio_resid; |
1126 | if (uiop->uio_offset + tsiz > 0xffffffff && !info.nmi_v3) |
1127 | return (EFBIG27); |
1128 | while (tsiz > 0) { |
1129 | nfsstats.rpccnt[NFSPROC_READ6]++; |
1130 | len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; |
1131 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1132 | NFSX_UNSIGNED4 * 3); |
1133 | nfsm_fhtom(&info, vp, info.nmi_v3); |
1134 | tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4 * 3); |
1135 | if (info.nmi_v3) { |
1136 | txdr_hyper(uiop->uio_offset, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p ((u_int32_t)((uiop->uio_offset) >> 32)) ? (__uint32_t )(((__uint32_t)((u_int32_t)((uiop->uio_offset) >> 32 )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((uiop-> uio_offset) >> 32)) & 0xff00) << 8 | ((__uint32_t )((u_int32_t)((uiop->uio_offset) >> 32)) & 0xff0000 ) >> 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) >> 32)) & 0xff000000) >> 24) : __swap32md(( u_int32_t)((uiop->uio_offset) >> 32))); ((u_int32_t * )(tl))[1] = (__uint32_t)(__builtin_constant_p((u_int32_t)((uiop ->uio_offset) & 0xffffffff)) ? (__uint32_t)(((__uint32_t )((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff ) << 24 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) & 0xffffffff)) & 0xff00) << 8 | ((__uint32_t) ((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff0000 ) >> 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) & 0xffffffff)) & 0xff000000) >> 24) : __swap32md ((u_int32_t)((uiop->uio_offset) & 0xffffffff))); } while (0); |
1137 | *(tl + 2) = txdr_unsigned(len)((__uint32_t)(__builtin_constant_p((int32_t)(len)) ? (__uint32_t )(((__uint32_t)((int32_t)(len)) & 0xff) << 24 | ((__uint32_t )((int32_t)(len)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(len)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( len)) & 0xff000000) >> 24) : __swap32md((int32_t)(len )))); |
1138 | } else { |
1139 | *tl++ = txdr_unsigned(uiop->uio_offset)((__uint32_t)(__builtin_constant_p((int32_t)(uiop->uio_offset )) ? (__uint32_t)(((__uint32_t)((int32_t)(uiop->uio_offset )) & 0xff) << 24 | ((__uint32_t)((int32_t)(uiop-> uio_offset)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(uiop->uio_offset)) & 0xff0000) >> 8 | ((__uint32_t )((int32_t)(uiop->uio_offset)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(uiop->uio_offset)))); |
1140 | *tl++ = txdr_unsigned(len)((__uint32_t)(__builtin_constant_p((int32_t)(len)) ? (__uint32_t )(((__uint32_t)((int32_t)(len)) & 0xff) << 24 | ((__uint32_t )((int32_t)(len)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(len)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( len)) & 0xff000000) >> 24) : __swap32md((int32_t)(len )))); |
1141 | *tl = 0; |
1142 | } |
1143 | |
1144 | info.nmi_procp = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc; |
1145 | info.nmi_cred = VTONFS(vp)((struct nfsnode *)(vp)->v_data)->n_rcred; |
1146 | error = nfs_request(vp, NFSPROC_READ6, &info); |
1147 | if (info.nmi_v3) |
1148 | nfsm_postop_attr(vp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (vp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (vp) = ttvp; } } }; |
1149 | if (error) { |
1150 | m_freem(info.nmi_mrep); |
1151 | goto nfsmout; |
1152 | } |
1153 | |
1154 | if (info.nmi_v3) { |
1155 | nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (2 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
1156 | eof = fxdr_unsigned(int, *(tl + 1))((int)(__uint32_t)(__builtin_constant_p((int32_t)(*(tl + 1))) ? (__uint32_t)(((__uint32_t)((int32_t)(*(tl + 1))) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*(tl + 1))) & 0xff00 ) << 8 | ((__uint32_t)((int32_t)(*(tl + 1))) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*(tl + 1))) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*(tl + 1))))); |
1157 | } else { |
1158 | nfsm_loadattr(vp, NULL){ struct vnode *ttvp = (vp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (vp ) = ttvp; }; |
1159 | } |
1160 | |
1161 | nfsm_strsiz(retlen, nmp->nm_rsize){ { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info. nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { ( tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, ( 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep) ; goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if ((( retlen) = ((int32_t)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) < 0 || (retlen) > (nmp ->nm_rsize)) { m_freem(info.nmi_mrep); error = 72; goto nfsmout ; } }; |
1162 | nfsm_mtouio(uiop, retlen)if ((retlen) > 0 && (t1 = nfsm_mbuftouio(&info .nmi_md, (uiop), (retlen), &info.nmi_dpos)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; }; |
1163 | m_freem(info.nmi_mrep); |
1164 | tsiz -= retlen; |
1165 | if (info.nmi_v3) { |
1166 | if (eof || retlen == 0) |
1167 | tsiz = 0; |
1168 | } else if (retlen < len) |
1169 | tsiz = 0; |
1170 | } |
1171 | |
1172 | nfsmout: |
1173 | return (error); |
1174 | } |
1175 | |
1176 | /* |
1177 | * nfs write call |
1178 | */ |
1179 | int |
1180 | nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) |
1181 | { |
1182 | struct nfsm_info info; |
1183 | u_int32_t *tl; |
1184 | int32_t t1, backup; |
1185 | caddr_t cp2; |
1186 | struct nfsmount *nmp = VFSTONFS(vp->v_mount)((struct nfsmount *)((vp->v_mount)->mnt_data)); |
1187 | int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR0, rlen, commit; |
1188 | int committed = NFSV3WRITE_FILESYNC2; |
1189 | |
1190 | info.nmi_v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
1191 | |
1192 | #ifdef DIAGNOSTIC1 |
1193 | if (uiop->uio_iovcnt != 1) |
1194 | panic("nfs: writerpc iovcnt > 1"); |
1195 | #endif |
1196 | *must_commit = 0; |
1197 | tsiz = uiop->uio_resid; |
1198 | if (uiop->uio_offset + tsiz > 0xffffffff && !info.nmi_v3) |
1199 | return (EFBIG27); |
1200 | while (tsiz > 0) { |
1201 | nfsstats.rpccnt[NFSPROC_WRITE7]++; |
1202 | len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; |
1203 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) |
1204 | + 5 * NFSX_UNSIGNED4 + nfsm_rndup(len)(((len)+3)&(~0x3))); |
1205 | nfsm_fhtom(&info, vp, info.nmi_v3); |
1206 | if (info.nmi_v3) { |
1207 | tl = nfsm_build(&info.nmi_mb, 5 * NFSX_UNSIGNED4); |
1208 | txdr_hyper(uiop->uio_offset, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p ((u_int32_t)((uiop->uio_offset) >> 32)) ? (__uint32_t )(((__uint32_t)((u_int32_t)((uiop->uio_offset) >> 32 )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((uiop-> uio_offset) >> 32)) & 0xff00) << 8 | ((__uint32_t )((u_int32_t)((uiop->uio_offset) >> 32)) & 0xff0000 ) >> 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) >> 32)) & 0xff000000) >> 24) : __swap32md(( u_int32_t)((uiop->uio_offset) >> 32))); ((u_int32_t * )(tl))[1] = (__uint32_t)(__builtin_constant_p((u_int32_t)((uiop ->uio_offset) & 0xffffffff)) ? (__uint32_t)(((__uint32_t )((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff ) << 24 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) & 0xffffffff)) & 0xff00) << 8 | ((__uint32_t) ((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff0000 ) >> 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) & 0xffffffff)) & 0xff000000) >> 24) : __swap32md ((u_int32_t)((uiop->uio_offset) & 0xffffffff))); } while (0); |
1209 | tl += 2; |
1210 | *tl++ = txdr_unsigned(len)((__uint32_t)(__builtin_constant_p((int32_t)(len)) ? (__uint32_t )(((__uint32_t)((int32_t)(len)) & 0xff) << 24 | ((__uint32_t )((int32_t)(len)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(len)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( len)) & 0xff000000) >> 24) : __swap32md((int32_t)(len )))); |
1211 | *tl++ = txdr_unsigned(*iomode)((__uint32_t)(__builtin_constant_p((int32_t)(*iomode)) ? (__uint32_t )(((__uint32_t)((int32_t)(*iomode)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*iomode)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*iomode)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*iomode)) & 0xff000000) >> 24) : __swap32md((int32_t)(*iomode)))); |
1212 | *tl = txdr_unsigned(len)((__uint32_t)(__builtin_constant_p((int32_t)(len)) ? (__uint32_t )(((__uint32_t)((int32_t)(len)) & 0xff) << 24 | ((__uint32_t )((int32_t)(len)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(len)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( len)) & 0xff000000) >> 24) : __swap32md((int32_t)(len )))); |
1213 | } else { |
1214 | u_int32_t x; |
1215 | |
1216 | tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED4); |
1217 | /* Set both "begin" and "current" to non-garbage. */ |
1218 | x = txdr_unsigned((u_int32_t)uiop->uio_offset)((__uint32_t)(__builtin_constant_p((int32_t)((u_int32_t)uiop-> uio_offset)) ? (__uint32_t)(((__uint32_t)((int32_t)((u_int32_t )uiop->uio_offset)) & 0xff) << 24 | ((__uint32_t )((int32_t)((u_int32_t)uiop->uio_offset)) & 0xff00) << 8 | ((__uint32_t)((int32_t)((u_int32_t)uiop->uio_offset)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)((u_int32_t )uiop->uio_offset)) & 0xff000000) >> 24) : __swap32md ((int32_t)((u_int32_t)uiop->uio_offset)))); |
1219 | *tl++ = x; /* "begin offset" */ |
1220 | *tl++ = x; /* "current offset" */ |
1221 | x = txdr_unsigned(len)((__uint32_t)(__builtin_constant_p((int32_t)(len)) ? (__uint32_t )(((__uint32_t)((int32_t)(len)) & 0xff) << 24 | ((__uint32_t )((int32_t)(len)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(len)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( len)) & 0xff000000) >> 24) : __swap32md((int32_t)(len )))); |
1222 | *tl++ = x; /* total to this offset */ |
1223 | *tl = x; /* size of this write */ |
1224 | |
1225 | } |
1226 | nfsm_uiotombuf(&info.nmi_mb, uiop, len); |
1227 | |
1228 | info.nmi_procp = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc; |
1229 | info.nmi_cred = VTONFS(vp)((struct nfsnode *)(vp)->v_data)->n_wcred; |
1230 | error = nfs_request(vp, NFSPROC_WRITE7, &info); |
1231 | if (info.nmi_v3) { |
1232 | wccflag = NFSV3_WCCCHK1; |
1233 | nfsm_wcc_data(vp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(vp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(vp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(vp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((vp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((vp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1234 | } |
1235 | |
1236 | if (error) { |
1237 | m_freem(info.nmi_mrep); |
1238 | goto nfsmout; |
1239 | } |
1240 | |
1241 | if (info.nmi_v3) { |
1242 | wccflag = NFSV3_WCCCHK1; |
1243 | nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED{ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4 + 8)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4 + 8); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (2 * 4 + 8), t1, &cp2)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2 ; } } |
1244 | + NFSX_V3WRITEVERF){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4 + 8)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4 + 8); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (2 * 4 + 8), t1, &cp2)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2 ; } }; |
1245 | rlen = fxdr_unsigned(int, *tl++)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl++)) ? ( __uint32_t)(((__uint32_t)((int32_t)(*tl++)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl++)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl++)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl++)) & 0xff000000) >> 24) : __swap32md((int32_t)(*tl++)))); |
1246 | if (rlen <= 0) { |
1247 | error = NFSERR_IO5; |
1248 | break; |
1249 | } else if (rlen < len) { |
1250 | backup = len - rlen; |
1251 | uiop->uio_iov->iov_base = |
1252 | (char *)uiop->uio_iov->iov_base - |
1253 | backup; |
1254 | uiop->uio_iov->iov_len += backup; |
1255 | uiop->uio_offset -= backup; |
1256 | uiop->uio_resid += backup; |
1257 | len = rlen; |
1258 | } |
1259 | commit = fxdr_unsigned(int, *tl++)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl++)) ? ( __uint32_t)(((__uint32_t)((int32_t)(*tl++)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl++)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl++)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl++)) & 0xff000000) >> 24) : __swap32md((int32_t)(*tl++)))); |
1260 | |
1261 | /* |
1262 | * Return the lowest commitment level |
1263 | * obtained by any of the RPCs. |
1264 | */ |
1265 | if (committed == NFSV3WRITE_FILESYNC2) |
1266 | committed = commit; |
1267 | else if (committed == NFSV3WRITE_DATASYNC1 && |
1268 | commit == NFSV3WRITE_UNSTABLE0) |
1269 | committed = commit; |
1270 | if ((nmp->nm_flag & NFSMNT_HASWRITEVERF0x00040000) == 0) { |
1271 | bcopy(tl, nmp->nm_verf, |
1272 | NFSX_V3WRITEVERF8); |
1273 | nmp->nm_flag |= NFSMNT_HASWRITEVERF0x00040000; |
1274 | } else if (bcmp(tl, |
1275 | nmp->nm_verf, NFSX_V3WRITEVERF8)) { |
1276 | *must_commit = 1; |
1277 | bcopy(tl, nmp->nm_verf, |
1278 | NFSX_V3WRITEVERF8); |
1279 | } |
1280 | } else { |
1281 | nfsm_loadattr(vp, NULL){ struct vnode *ttvp = (vp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (vp ) = ttvp; }; |
1282 | } |
1283 | if (wccflag) |
1284 | VTONFS(vp)((struct nfsnode *)(vp)->v_data)->n_mtime = VTONFS(vp)((struct nfsnode *)(vp)->v_data)->n_vattr.va_mtime; |
1285 | m_freem(info.nmi_mrep); |
1286 | tsiz -= len; |
1287 | } |
1288 | nfsmout: |
1289 | *iomode = committed; |
1290 | if (error) |
1291 | uiop->uio_resid = tsiz; |
1292 | return (error); |
1293 | } |
1294 | |
1295 | /* |
1296 | * nfs mknod rpc |
1297 | * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the |
1298 | * mode set to specify the file type and the size field for rdev. |
1299 | */ |
1300 | int |
1301 | nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, |
1302 | struct vattr *vap) |
1303 | { |
1304 | struct nfsv2_sattr *sp; |
1305 | struct nfsm_info info; |
1306 | u_int32_t *tl; |
1307 | int32_t t1; |
1308 | struct vnode *newvp = NULL((void *)0); |
1309 | struct nfsnode *np = NULL((void *)0); |
1310 | char *cp2; |
1311 | int error = 0, wccflag = NFSV3_WCCRATTR0, gotvp = 0; |
1312 | u_int32_t rdev; |
1313 | |
1314 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
1315 | |
1316 | if (vap->va_type == VCHR || vap->va_type == VBLK) |
1317 | rdev = txdr_unsigned(vap->va_rdev)((__uint32_t)(__builtin_constant_p((int32_t)(vap->va_rdev) ) ? (__uint32_t)(((__uint32_t)((int32_t)(vap->va_rdev)) & 0xff) << 24 | ((__uint32_t)((int32_t)(vap->va_rdev) ) & 0xff00) << 8 | ((__uint32_t)((int32_t)(vap-> va_rdev)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t )(vap->va_rdev)) & 0xff000000) >> 24) : __swap32md ((int32_t)(vap->va_rdev)))); |
1318 | else if (vap->va_type == VFIFO || vap->va_type == VSOCK) |
1319 | rdev = nfs_xdrneg1; |
1320 | else { |
1321 | VOP_ABORTOP(dvp, cnp); |
1322 | return (EOPNOTSUPP45); |
1323 | } |
1324 | nfsstats.rpccnt[NFSPROC_MKNOD11]++; |
1325 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1326 | 4 * NFSX_UNSIGNED4 + nfsm_rndup(cnp->cn_namelen)(((cnp->cn_namelen)+3)&(~0x3)) + |
1327 | NFSX_SATTR(info.nmi_v3)((info.nmi_v3) ? 60 : 32)); |
1328 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
1329 | nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN)if ((cnp->cn_namelen) > (255)) { m_freem(info.nmi_mreq) ; error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb , (cnp->cn_nameptr), (cnp->cn_namelen)); |
1330 | |
1331 | if (info.nmi_v3) { |
1332 | tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4); |
1333 | *tl++ = vtonfsv3_type(vap->va_type)((__uint32_t)(__builtin_constant_p((int32_t)(nfsv3_type[((int32_t )(vap->va_type))])) ? (__uint32_t)(((__uint32_t)((int32_t) (nfsv3_type[((int32_t)(vap->va_type))])) & 0xff) << 24 | ((__uint32_t)((int32_t)(nfsv3_type[((int32_t)(vap->va_type ))])) & 0xff00) << 8 | ((__uint32_t)((int32_t)(nfsv3_type [((int32_t)(vap->va_type))])) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(nfsv3_type[((int32_t)(vap->va_type ))])) & 0xff000000) >> 24) : __swap32md((int32_t)(nfsv3_type [((int32_t)(vap->va_type))])))); |
1334 | nfsm_v3attrbuild(&info.nmi_mb, vap, 0); |
1335 | if (vap->va_type == VCHR || vap->va_type == VBLK) { |
1336 | tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4); |
1337 | *tl++ = txdr_unsigned(major(vap->va_rdev))((__uint32_t)(__builtin_constant_p((int32_t)((((unsigned)(vap ->va_rdev) >> 8) & 0xff))) ? (__uint32_t)(((__uint32_t )((int32_t)((((unsigned)(vap->va_rdev) >> 8) & 0xff ))) & 0xff) << 24 | ((__uint32_t)((int32_t)((((unsigned )(vap->va_rdev) >> 8) & 0xff))) & 0xff00) << 8 | ((__uint32_t)((int32_t)((((unsigned)(vap->va_rdev) >> 8) & 0xff))) & 0xff0000) >> 8 | ((__uint32_t)( (int32_t)((((unsigned)(vap->va_rdev) >> 8) & 0xff ))) & 0xff000000) >> 24) : __swap32md((int32_t)(((( unsigned)(vap->va_rdev) >> 8) & 0xff))))); |
1338 | *tl = txdr_unsigned(minor(vap->va_rdev))((__uint32_t)(__builtin_constant_p((int32_t)(((unsigned)((vap ->va_rdev) & 0xff) | (((vap->va_rdev) & 0xffff0000 ) >> 8)))) ? (__uint32_t)(((__uint32_t)((int32_t)(((unsigned )((vap->va_rdev) & 0xff) | (((vap->va_rdev) & 0xffff0000 ) >> 8)))) & 0xff) << 24 | ((__uint32_t)((int32_t )(((unsigned)((vap->va_rdev) & 0xff) | (((vap->va_rdev ) & 0xffff0000) >> 8)))) & 0xff00) << 8 | ((__uint32_t)((int32_t)(((unsigned)((vap->va_rdev) & 0xff ) | (((vap->va_rdev) & 0xffff0000) >> 8)))) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(((unsigned)(( vap->va_rdev) & 0xff) | (((vap->va_rdev) & 0xffff0000 ) >> 8)))) & 0xff000000) >> 24) : __swap32md( (int32_t)(((unsigned)((vap->va_rdev) & 0xff) | (((vap-> va_rdev) & 0xffff0000) >> 8)))))); |
1339 | } |
1340 | } else { |
1341 | sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR32); |
1342 | sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode)((__uint32_t)(__builtin_constant_p((int32_t)(((vap->va_type ) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode ))) : (int)((vttoif_tab[(int)((vap->va_type))]) | ((vap-> va_mode))))) ? (__uint32_t)(((__uint32_t)((int32_t)(((vap-> va_type) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap-> va_mode))) : (int)((vttoif_tab[(int)((vap->va_type))]) | ( (vap->va_mode))))) & 0xff) << 24 | ((__uint32_t) ((int32_t)(((vap->va_type) == VFIFO) ? (int)((vttoif_tab[( int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int) ((vap->va_type))]) | ((vap->va_mode))))) & 0xff00) << 8 | ((__uint32_t)((int32_t)(((vap->va_type) == VFIFO) ? ( int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : (int) ((vttoif_tab[(int)((vap->va_type))]) | ((vap->va_mode)) ))) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(((vap ->va_type) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ( (vap->va_mode))) : (int)((vttoif_tab[(int)((vap->va_type ))]) | ((vap->va_mode))))) & 0xff000000) >> 24) : __swap32md((int32_t)(((vap->va_type) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((vap->va_type))]) | ((vap->va_mode))))))); |
1343 | sp->sa_uid = nfs_xdrneg1; |
1344 | sp->sa_gid = nfs_xdrneg1; |
1345 | sp->sa_size = rdev; |
1346 | txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); |
1347 | txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); |
1348 | } |
1349 | |
1350 | KASSERT(cnp->cn_proc == curproc)((cnp->cn_proc == ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_curproc) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/nfs/nfs_vnops.c", 1350, "cnp->cn_proc == curproc" )); |
1351 | info.nmi_procp = cnp->cn_proc; |
1352 | info.nmi_cred = cnp->cn_cred; |
1353 | error = nfs_request(dvp, NFSPROC_MKNOD11, &info); |
1354 | if (!error) { |
1355 | nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp){ struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; if (info .nmi_v3) { { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data) ) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info .nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; (gotvp) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl)))); } else (gotvp) = 1; if (gotvp ) { { if ((info.nmi_v3)) { { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (((ttfhsize) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl))))) <= 0 || (ttfhsize ) > 64) { m_freem(info.nmi_mrep); error = 72; goto nfsmout ; } } else (ttfhsize) = 32; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= ((((ttfhsize)+3)&(~0x3)))) { ((ttfhp)) = ( nfsfh_t *)(info.nmi_dpos); info.nmi_dpos += ((((ttfhsize)+3)& (~0x3))); } else if ((t1 = nfsm_disct(&info.nmi_md, & info.nmi_dpos, ((((ttfhsize)+3)&(~0x3))), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { ((ttfhp)) = (nfsfh_t *)cp2; } }; }; if ((t1 = nfs_nget((dvp )->v_mount, ttfhp, ttfhsize, &ttnp)) != 0) { error = t1 ; m_freem(info.nmi_mrep); goto nfsmout; } (newvp) = ((ttnp)-> n_vnode); } if (info.nmi_v3) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (gotvp) (gotvp) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl)))); else if (((int )(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl))))) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ( 84)) { info.nmi_dpos += (84); } else if ((t1 = nfs_adv(&info .nmi_md, &info.nmi_dpos, (84), t1)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } }; } if (gotvp) { struct vnode *ttvp = ((newvp)); if ((t1 = nfs_loadattrcache(&ttvp, & info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } ((newvp)) = ttvp ; }; }; |
1356 | if (!gotvp) { |
1357 | error = nfs_lookitup(dvp, cnp->cn_nameptr, |
1358 | cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np); |
1359 | if (!error) |
1360 | newvp = NFSTOV(np)((np)->n_vnode); |
1361 | } |
1362 | } |
1363 | if (info.nmi_v3) |
1364 | nfsm_wcc_data(dvp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(dvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(dvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(dvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((dvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((dvp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1365 | m_freem(info.nmi_mrep); |
1366 | |
1367 | nfsmout: |
1368 | if (error) { |
1369 | if (newvp) |
1370 | vput(newvp); |
1371 | } else { |
1372 | if (cnp->cn_flags & MAKEENTRY0x004000) |
1373 | nfs_cache_enter(dvp, newvp, cnp); |
1374 | *vpp = newvp; |
1375 | } |
1376 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1377 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1378 | if (!wccflag) |
1379 | NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp))((((struct nfsnode *)(dvp)->v_data))->n_attrstamp = 0); |
1380 | return (error); |
1381 | } |
1382 | |
1383 | /* |
1384 | * nfs mknod vop |
1385 | * just call nfs_mknodrpc() to do the work. |
1386 | */ |
1387 | int |
1388 | nfs_mknod(void *v) |
1389 | { |
1390 | struct vop_mknod_args *ap = v; |
1391 | struct vnode *newvp; |
1392 | int error; |
1393 | |
1394 | error = nfs_mknodrpc(ap->a_dvp, &newvp, ap->a_cnp, ap->a_vap); |
1395 | if (!error) |
1396 | vput(newvp); |
1397 | |
1398 | VN_KNOTE(ap->a_dvp, NOTE_WRITE)knote_locked(&ap->a_dvp->v_klist, (0x0002)); |
1399 | |
1400 | return (error); |
1401 | } |
1402 | |
1403 | int |
1404 | nfs_create(void *v) |
1405 | { |
1406 | struct vop_create_args *ap = v; |
1407 | struct vnode *dvp = ap->a_dvp; |
1408 | struct vattr *vap = ap->a_vap; |
1409 | struct componentname *cnp = ap->a_cnp; |
1410 | struct nfsv2_sattr *sp; |
1411 | struct nfsm_info info; |
1412 | struct timespec ts; |
1413 | u_int32_t *tl; |
1414 | int32_t t1; |
1415 | struct nfsnode *np = NULL((void *)0); |
1416 | struct vnode *newvp = NULL((void *)0); |
1417 | caddr_t cp2; |
1418 | int error = 0, wccflag = NFSV3_WCCRATTR0, gotvp = 0, fmode = 0; |
1419 | |
1420 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
1421 | |
1422 | /* |
1423 | * Oops, not for me.. |
1424 | */ |
1425 | if (vap->va_type == VSOCK) |
1426 | return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap)); |
1427 | |
1428 | if (vap->va_vaflags & VA_EXCLUSIVE0x02) |
1429 | fmode |= O_EXCL0x0800; |
1430 | |
1431 | again: |
1432 | nfsstats.rpccnt[NFSPROC_CREATE8]++; |
1433 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1434 | 2 * NFSX_UNSIGNED4 + nfsm_rndup(cnp->cn_namelen)(((cnp->cn_namelen)+3)&(~0x3)) + |
1435 | NFSX_SATTR(info.nmi_v3)((info.nmi_v3) ? 60 : 32)); |
1436 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
1437 | nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN)if ((cnp->cn_namelen) > (255)) { m_freem(info.nmi_mreq) ; error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb , (cnp->cn_nameptr), (cnp->cn_namelen)); |
1438 | if (info.nmi_v3) { |
1439 | tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4); |
1440 | if (fmode & O_EXCL0x0800) { |
1441 | *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE)((__uint32_t)(__builtin_constant_p((int32_t)(2)) ? (__uint32_t )(((__uint32_t)((int32_t)(2)) & 0xff) << 24 | ((__uint32_t )((int32_t)(2)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(2)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(2) ) & 0xff000000) >> 24) : __swap32md((int32_t)(2)))); |
1442 | tl = nfsm_build(&info.nmi_mb, NFSX_V3CREATEVERF8); |
1443 | arc4random_buf(tl, sizeof(*tl) * 2); |
1444 | } else { |
1445 | *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED)((__uint32_t)(__builtin_constant_p((int32_t)(0)) ? (__uint32_t )(((__uint32_t)((int32_t)(0)) & 0xff) << 24 | ((__uint32_t )((int32_t)(0)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(0)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(0) ) & 0xff000000) >> 24) : __swap32md((int32_t)(0)))); |
1446 | nfsm_v3attrbuild(&info.nmi_mb, vap, 0); |
1447 | } |
1448 | } else { |
1449 | sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR32); |
1450 | sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode)((__uint32_t)(__builtin_constant_p((int32_t)(((vap->va_type ) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode ))) : (int)((vttoif_tab[(int)((vap->va_type))]) | ((vap-> va_mode))))) ? (__uint32_t)(((__uint32_t)((int32_t)(((vap-> va_type) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap-> va_mode))) : (int)((vttoif_tab[(int)((vap->va_type))]) | ( (vap->va_mode))))) & 0xff) << 24 | ((__uint32_t) ((int32_t)(((vap->va_type) == VFIFO) ? (int)((vttoif_tab[( int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int) ((vap->va_type))]) | ((vap->va_mode))))) & 0xff00) << 8 | ((__uint32_t)((int32_t)(((vap->va_type) == VFIFO) ? ( int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : (int) ((vttoif_tab[(int)((vap->va_type))]) | ((vap->va_mode)) ))) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(((vap ->va_type) == VFIFO) ? (int)((vttoif_tab[(int)(VCHR)]) | ( (vap->va_mode))) : (int)((vttoif_tab[(int)((vap->va_type ))]) | ((vap->va_mode))))) & 0xff000000) >> 24) : __swap32md((int32_t)(((vap->va_type) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((vap->va_type))]) | ((vap->va_mode))))))); |
1451 | sp->sa_uid = nfs_xdrneg1; |
1452 | sp->sa_gid = nfs_xdrneg1; |
1453 | sp->sa_size = 0; |
1454 | txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); |
1455 | txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); |
1456 | } |
1457 | |
1458 | KASSERT(cnp->cn_proc == curproc)((cnp->cn_proc == ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_curproc) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/nfs/nfs_vnops.c", 1458, "cnp->cn_proc == curproc" )); |
1459 | info.nmi_procp = cnp->cn_proc; |
1460 | info.nmi_cred = cnp->cn_cred; |
1461 | error = nfs_request(dvp, NFSPROC_CREATE8, &info); |
1462 | if (!error) { |
1463 | nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp){ struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; if (info .nmi_v3) { { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data) ) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info .nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; (gotvp) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl)))); } else (gotvp) = 1; if (gotvp ) { { if ((info.nmi_v3)) { { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (((ttfhsize) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl))))) <= 0 || (ttfhsize ) > 64) { m_freem(info.nmi_mrep); error = 72; goto nfsmout ; } } else (ttfhsize) = 32; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= ((((ttfhsize)+3)&(~0x3)))) { ((ttfhp)) = ( nfsfh_t *)(info.nmi_dpos); info.nmi_dpos += ((((ttfhsize)+3)& (~0x3))); } else if ((t1 = nfsm_disct(&info.nmi_md, & info.nmi_dpos, ((((ttfhsize)+3)&(~0x3))), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { ((ttfhp)) = (nfsfh_t *)cp2; } }; }; if ((t1 = nfs_nget((dvp )->v_mount, ttfhp, ttfhsize, &ttnp)) != 0) { error = t1 ; m_freem(info.nmi_mrep); goto nfsmout; } (newvp) = ((ttnp)-> n_vnode); } if (info.nmi_v3) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (gotvp) (gotvp) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl)))); else if (((int )(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl))))) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ( 84)) { info.nmi_dpos += (84); } else if ((t1 = nfs_adv(&info .nmi_md, &info.nmi_dpos, (84), t1)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } }; } if (gotvp) { struct vnode *ttvp = ((newvp)); if ((t1 = nfs_loadattrcache(&ttvp, & info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } ((newvp)) = ttvp ; }; }; |
1464 | if (!gotvp) { |
1465 | error = nfs_lookitup(dvp, cnp->cn_nameptr, |
1466 | cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np); |
1467 | if (!error) |
1468 | newvp = NFSTOV(np)((np)->n_vnode); |
1469 | } |
1470 | } |
1471 | if (info.nmi_v3) |
1472 | nfsm_wcc_data(dvp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(dvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(dvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(dvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((dvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((dvp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1473 | m_freem(info.nmi_mrep); |
1474 | |
1475 | nfsmout: |
1476 | if (error) { |
1477 | if (newvp) { |
1478 | vput(newvp); |
1479 | newvp = NULL((void *)0); |
1480 | } |
1481 | if (info.nmi_v3 && (fmode & O_EXCL0x0800) && error == NFSERR_NOTSUPP10004) { |
1482 | fmode &= ~O_EXCL0x0800; |
1483 | goto again; |
1484 | } |
1485 | } else if (info.nmi_v3 && (fmode & O_EXCL0x0800)) { |
1486 | getnanotime(&ts); |
1487 | if (vap->va_atime.tv_nsec == VNOVAL(-1)) |
1488 | vap->va_atime = ts; |
1489 | if (vap->va_mtime.tv_nsec == VNOVAL(-1)) |
1490 | vap->va_mtime = ts; |
1491 | error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_proc); |
1492 | } |
1493 | if (!error) { |
1494 | if (cnp->cn_flags & MAKEENTRY0x004000) |
1495 | nfs_cache_enter(dvp, newvp, cnp); |
1496 | *ap->a_vpp = newvp; |
1497 | } |
1498 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1499 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1500 | if (!wccflag) |
1501 | NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp))((((struct nfsnode *)(dvp)->v_data))->n_attrstamp = 0); |
1502 | VN_KNOTE(ap->a_dvp, NOTE_WRITE)knote_locked(&ap->a_dvp->v_klist, (0x0002)); |
1503 | return (error); |
1504 | } |
1505 | |
1506 | /* |
1507 | * nfs file remove call |
1508 | * To try and make nfs semantics closer to ufs semantics, a file that has |
1509 | * other processes using the vnode is renamed instead of removed and then |
1510 | * removed later on the last close. |
1511 | * - If v_usecount > 1 |
1512 | * If a rename is not already in the works |
1513 | * call nfs_sillyrename() to set it up |
1514 | * else |
1515 | * do the remove rpc |
1516 | */ |
1517 | int |
1518 | nfs_remove(void *v) |
1519 | { |
1520 | struct vop_remove_args *ap = v; |
1521 | struct vnode *vp = ap->a_vp; |
1522 | struct vnode *dvp = ap->a_dvp; |
1523 | struct componentname *cnp = ap->a_cnp; |
1524 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
1525 | int error = 0; |
1526 | struct vattr vattr; |
1527 | |
1528 | #ifdef DIAGNOSTIC1 |
1529 | if ((cnp->cn_flags & HASBUF0x000400) == 0) |
1530 | panic("nfs_remove: no name"); |
1531 | if (vp->v_usecount < 1) |
1532 | panic("nfs_remove: bad v_usecount"); |
1533 | #endif |
1534 | if (vp->v_type == VDIR) |
1535 | error = EPERM1; |
1536 | else if (vp->v_usecount == 1 || (np->n_sillyrename && |
1537 | VOP_GETATTR(vp, &vattr, cnp->cn_cred, cnp->cn_proc) == 0 && |
1538 | vattr.va_nlink > 1)) { |
1539 | /* |
1540 | * Purge the name cache so that the chance of a lookup for |
1541 | * the name succeeding while the remove is in progress is |
1542 | * minimized. Without node locking it can still happen, such |
1543 | * that an I/O op returns ESTALE, but since you get this if |
1544 | * another host removes the file.. |
1545 | */ |
1546 | cache_purge(vp); |
1547 | /* |
1548 | * throw away biocache buffers, mainly to avoid |
1549 | * unnecessary delayed writes later. |
1550 | */ |
1551 | error = nfs_vinvalbuf(vp, 0, cnp->cn_cred, cnp->cn_proc); |
1552 | /* Do the rpc */ |
1553 | if (error != EINTR4) |
1554 | error = nfs_removerpc(dvp, cnp->cn_nameptr, |
1555 | cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc); |
1556 | /* |
1557 | * Kludge City: If the first reply to the remove rpc is lost.. |
1558 | * the reply to the retransmitted request will be ENOENT |
1559 | * since the file was in fact removed |
1560 | * Therefore, we cheat and return success. |
1561 | */ |
1562 | if (error == ENOENT2) |
1563 | error = 0; |
1564 | } else if (!np->n_sillyrename) |
1565 | error = nfs_sillyrename(dvp, vp, cnp); |
1566 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1567 | NFS_INVALIDATE_ATTRCACHE(np)((np)->n_attrstamp = 0); |
1568 | VN_KNOTE(vp, NOTE_DELETE)knote_locked(&vp->v_klist, (0x0001)); |
1569 | VN_KNOTE(dvp, NOTE_WRITE)knote_locked(&dvp->v_klist, (0x0002)); |
1570 | if (vp == dvp) |
1571 | vrele(vp); |
1572 | else |
1573 | vput(vp); |
1574 | vput(dvp); |
1575 | return (error); |
1576 | } |
1577 | |
1578 | /* |
1579 | * nfs file remove rpc called from nfs_inactive |
1580 | */ |
1581 | int |
1582 | nfs_removeit(struct sillyrename *sp) |
1583 | { |
1584 | KASSERT(VOP_ISLOCKED(sp->s_dvp))((VOP_ISLOCKED(sp->s_dvp)) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/nfs/nfs_vnops.c", 1584, "VOP_ISLOCKED(sp->s_dvp)" )); |
1585 | /* |
1586 | * Make sure that the directory vnode is still valid. |
1587 | * |
1588 | * NFS can potentially try to nuke a silly *after* the directory |
1589 | * has already been pushed out on a forced unmount. Since the silly |
1590 | * is going to go away anyway, this is fine. |
1591 | */ |
1592 | if (sp->s_dvp->v_type == VBAD) |
1593 | return (0); |
1594 | return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred, |
1595 | NULL((void *)0))); |
1596 | } |
1597 | |
1598 | /* |
1599 | * Nfs remove rpc, called from nfs_remove() and nfs_removeit(). |
1600 | */ |
1601 | int |
1602 | nfs_removerpc(struct vnode *dvp, char *name, int namelen, struct ucred *cred, |
1603 | struct proc *proc) |
1604 | { |
1605 | struct nfsm_info info; |
1606 | u_int32_t *tl; |
1607 | int32_t t1; |
1608 | caddr_t cp2; |
1609 | int error = 0, wccflag = NFSV3_WCCRATTR0; |
1610 | |
1611 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
1612 | |
1613 | nfsstats.rpccnt[NFSPROC_REMOVE12]++; |
1614 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1615 | NFSX_UNSIGNED4 + nfsm_rndup(namelen)(((namelen)+3)&(~0x3))); |
1616 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
1617 | nfsm_strtom(name, namelen, NFS_MAXNAMLEN)if ((namelen) > (255)) { m_freem(info.nmi_mreq); error = 63 ; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb, (name), (namelen )); |
1618 | |
1619 | info.nmi_procp = proc; |
1620 | info.nmi_cred = cred; |
1621 | error = nfs_request(dvp, NFSPROC_REMOVE12, &info); |
1622 | if (info.nmi_v3) |
1623 | nfsm_wcc_data(dvp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(dvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(dvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(dvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((dvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((dvp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1624 | m_freem(info.nmi_mrep); |
1625 | |
1626 | nfsmout: |
1627 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1628 | if (!wccflag) |
1629 | NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp))((((struct nfsnode *)(dvp)->v_data))->n_attrstamp = 0); |
1630 | return (error); |
1631 | } |
1632 | |
1633 | /* |
1634 | * nfs file rename call |
1635 | */ |
1636 | int |
1637 | nfs_rename(void *v) |
1638 | { |
1639 | struct vop_rename_args *ap = v; |
1640 | struct vnode *fvp = ap->a_fvp; |
1641 | struct vnode *tvp = ap->a_tvp; |
1642 | struct vnode *fdvp = ap->a_fdvp; |
1643 | struct vnode *tdvp = ap->a_tdvp; |
1644 | struct componentname *tcnp = ap->a_tcnp; |
1645 | struct componentname *fcnp = ap->a_fcnp; |
1646 | int error; |
1647 | |
1648 | #ifdef DIAGNOSTIC1 |
1649 | if ((tcnp->cn_flags & HASBUF0x000400) == 0 || |
1650 | (fcnp->cn_flags & HASBUF0x000400) == 0) |
1651 | panic("nfs_rename: no name"); |
1652 | #endif |
1653 | /* Check for cross-device rename */ |
1654 | if ((fvp->v_mount != tdvp->v_mount) || |
1655 | (tvp && (fvp->v_mount != tvp->v_mount))) { |
1656 | error = EXDEV18; |
1657 | goto out; |
1658 | } |
1659 | |
1660 | /* |
1661 | * If the tvp exists and is in use, sillyrename it before doing the |
1662 | * rename of the new file over it. |
1663 | */ |
1664 | if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)((struct nfsnode *)(tvp)->v_data)->n_sillyrename && |
1665 | tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) { |
1666 | VN_KNOTE(tvp, NOTE_DELETE)knote_locked(&tvp->v_klist, (0x0001)); |
1667 | vput(tvp); |
1668 | tvp = NULL((void *)0); |
1669 | } |
1670 | |
1671 | error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen, |
1672 | tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred, |
1673 | tcnp->cn_proc); |
1674 | |
1675 | VN_KNOTE(fdvp, NOTE_WRITE)knote_locked(&fdvp->v_klist, (0x0002)); |
1676 | VN_KNOTE(tdvp, NOTE_WRITE)knote_locked(&tdvp->v_klist, (0x0002)); |
1677 | |
1678 | if (fvp->v_type == VDIR) { |
1679 | if (tvp != NULL((void *)0) && tvp->v_type == VDIR) |
1680 | cache_purge(tdvp); |
1681 | cache_purge(fdvp); |
1682 | } |
1683 | out: |
1684 | if (tdvp == tvp) |
1685 | vrele(tdvp); |
1686 | else |
1687 | vput(tdvp); |
1688 | if (tvp) |
1689 | vput(tvp); |
1690 | vrele(fdvp); |
1691 | vrele(fvp); |
1692 | /* |
1693 | * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. |
1694 | */ |
1695 | if (error == ENOENT2) |
1696 | error = 0; |
1697 | return (error); |
1698 | } |
1699 | |
1700 | /* |
1701 | * nfs file rename rpc called from nfs_remove() above |
1702 | */ |
1703 | int |
1704 | nfs_renameit(struct vnode *sdvp, struct componentname *scnp, |
1705 | struct sillyrename *sp) |
1706 | { |
1707 | return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, |
1708 | sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc)); |
1709 | } |
1710 | |
1711 | /* |
1712 | * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). |
1713 | */ |
1714 | int |
1715 | nfs_renamerpc(struct vnode *fdvp, char *fnameptr, int fnamelen, |
1716 | struct vnode *tdvp, char *tnameptr, int tnamelen, struct ucred *cred, |
1717 | struct proc *proc) |
1718 | { |
1719 | struct nfsm_info info; |
1720 | u_int32_t *tl; |
1721 | int32_t t1; |
1722 | caddr_t cp2; |
1723 | int error = 0, fwccflag = NFSV3_WCCRATTR0, twccflag = NFSV3_WCCRATTR0; |
1724 | |
1725 | info.nmi_v3 = NFS_ISV3(fdvp)(((struct nfsmount *)(((fdvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
1726 | |
1727 | nfsstats.rpccnt[NFSPROC_RENAME14]++; |
1728 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead((NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1729 | NFSX_UNSIGNED4) * 2 + nfsm_rndup(fnamelen)(((fnamelen)+3)&(~0x3)) + nfsm_rndup(tnamelen)(((tnamelen)+3)&(~0x3))); |
1730 | nfsm_fhtom(&info, fdvp, info.nmi_v3); |
1731 | nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN)if ((fnamelen) > (255)) { m_freem(info.nmi_mreq); error = 63 ; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb, (fnameptr) , (fnamelen)); |
1732 | nfsm_fhtom(&info, tdvp, info.nmi_v3); |
1733 | nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN)if ((tnamelen) > (255)) { m_freem(info.nmi_mreq); error = 63 ; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb, (tnameptr) , (tnamelen)); |
1734 | |
1735 | info.nmi_procp = proc; |
1736 | info.nmi_cred = cred; |
1737 | error = nfs_request(fdvp, NFSPROC_RENAME14, &info); |
1738 | if (info.nmi_v3) { |
1739 | nfsm_wcc_data(fdvp, fwccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (fwccflag ) { ttretf = (((&((struct nfsnode *)(fdvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(fdvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(fdvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((fdvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((fdvp)) = ttvp; } } }; if (fwccflag) { (fwccflag ) = ttretf; } else { (fwccflag) = ttattrf; } } } while (0); |
1740 | nfsm_wcc_data(tdvp, twccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (twccflag ) { ttretf = (((&((struct nfsnode *)(tdvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(tdvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(tdvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((tdvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((tdvp)) = ttvp; } } }; if (twccflag) { (twccflag ) = ttretf; } else { (twccflag) = ttattrf; } } } while (0); |
1741 | } |
1742 | m_freem(info.nmi_mrep); |
1743 | |
1744 | nfsmout: |
1745 | VTONFS(fdvp)((struct nfsnode *)(fdvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1746 | VTONFS(tdvp)((struct nfsnode *)(tdvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1747 | if (!fwccflag) |
1748 | NFS_INVALIDATE_ATTRCACHE(VTONFS(fdvp))((((struct nfsnode *)(fdvp)->v_data))->n_attrstamp = 0); |
1749 | if (!twccflag) |
1750 | NFS_INVALIDATE_ATTRCACHE(VTONFS(tdvp))((((struct nfsnode *)(tdvp)->v_data))->n_attrstamp = 0); |
1751 | return (error); |
1752 | } |
1753 | |
1754 | /* |
1755 | * nfs hard link create call |
1756 | */ |
1757 | int |
1758 | nfs_link(void *v) |
1759 | { |
1760 | struct vop_link_args *ap = v; |
1761 | struct vnode *vp = ap->a_vp; |
1762 | struct vnode *dvp = ap->a_dvp; |
1763 | struct componentname *cnp = ap->a_cnp; |
1764 | struct nfsm_info info; |
1765 | u_int32_t *tl; |
1766 | int32_t t1; |
1767 | caddr_t cp2; |
1768 | int error = 0, wccflag = NFSV3_WCCRATTR0, attrflag = 0; |
1769 | |
1770 | info.nmi_v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
1771 | |
1772 | if (dvp->v_mount != vp->v_mount) { |
1773 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1774 | vput(dvp); |
1775 | return (EXDEV18); |
1776 | } |
1777 | error = vn_lock(vp, LK_EXCLUSIVE0x0001UL); |
1778 | if (error != 0) { |
1779 | VOP_ABORTOP(dvp, cnp); |
1780 | vput(dvp); |
1781 | return (error); |
1782 | } |
1783 | |
1784 | /* |
1785 | * Push all writes to the server, so that the attribute cache |
1786 | * doesn't get "out of sync" with the server. |
1787 | * XXX There should be a better way! |
1788 | */ |
1789 | VOP_FSYNC(vp, cnp->cn_cred, MNT_WAIT1, cnp->cn_proc); |
1790 | |
1791 | nfsstats.rpccnt[NFSPROC_LINK15]++; |
1792 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(2 * NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1793 | NFSX_UNSIGNED4 + nfsm_rndup(cnp->cn_namelen)(((cnp->cn_namelen)+3)&(~0x3))); |
1794 | nfsm_fhtom(&info, vp, info.nmi_v3); |
1795 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
1796 | nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN)if ((cnp->cn_namelen) > (255)) { m_freem(info.nmi_mreq) ; error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb , (cnp->cn_nameptr), (cnp->cn_namelen)); |
1797 | |
1798 | info.nmi_procp = cnp->cn_proc; |
1799 | info.nmi_cred = cnp->cn_cred; |
1800 | error = nfs_request(vp, NFSPROC_LINK15, &info); |
1801 | if (info.nmi_v3) { |
1802 | nfsm_postop_attr(vp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (vp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (vp) = ttvp; } } }; |
1803 | nfsm_wcc_data(dvp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(dvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(dvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(dvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((dvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((dvp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1804 | } |
1805 | m_freem(info.nmi_mrep); |
1806 | nfsmout: |
1807 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1808 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1809 | if (!attrflag) |
1810 | NFS_INVALIDATE_ATTRCACHE(VTONFS(vp))((((struct nfsnode *)(vp)->v_data))->n_attrstamp = 0); |
1811 | if (!wccflag) |
1812 | NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp))((((struct nfsnode *)(dvp)->v_data))->n_attrstamp = 0); |
1813 | |
1814 | VN_KNOTE(vp, NOTE_LINK)knote_locked(&vp->v_klist, (0x0010)); |
1815 | VN_KNOTE(dvp, NOTE_WRITE)knote_locked(&dvp->v_klist, (0x0002)); |
1816 | VOP_UNLOCK(vp); |
1817 | vput(dvp); |
1818 | return (error); |
1819 | } |
1820 | |
1821 | /* |
1822 | * nfs symbolic link create call |
1823 | */ |
1824 | int |
1825 | nfs_symlink(void *v) |
1826 | { |
1827 | struct vop_symlink_args *ap = v; |
1828 | struct vnode *dvp = ap->a_dvp; |
1829 | struct vattr *vap = ap->a_vap; |
1830 | struct componentname *cnp = ap->a_cnp; |
1831 | struct nfsv2_sattr *sp; |
1832 | struct nfsm_info info; |
1833 | u_int32_t *tl; |
1834 | int32_t t1; |
1835 | caddr_t cp2; |
1836 | int slen, error = 0, wccflag = NFSV3_WCCRATTR0, gotvp; |
1837 | struct vnode *newvp = NULL((void *)0); |
1838 | |
1839 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
1840 | |
1841 | nfsstats.rpccnt[NFSPROC_SYMLINK10]++; |
1842 | slen = strlen(ap->a_target); |
1843 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1844 | 2 * NFSX_UNSIGNED4 + nfsm_rndup(cnp->cn_namelen)(((cnp->cn_namelen)+3)&(~0x3)) + nfsm_rndup(slen)(((slen)+3)&(~0x3)) + |
1845 | NFSX_SATTR(info.nmi_v3)((info.nmi_v3) ? 60 : 32)); |
1846 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
1847 | nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN)if ((cnp->cn_namelen) > (255)) { m_freem(info.nmi_mreq) ; error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb , (cnp->cn_nameptr), (cnp->cn_namelen)); |
1848 | if (info.nmi_v3) |
1849 | nfsm_v3attrbuild(&info.nmi_mb, vap, 0); |
1850 | nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN)if ((slen) > (1024)) { m_freem(info.nmi_mreq); error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb, (ap->a_target ), (slen)); |
1851 | if (!info.nmi_v3) { |
1852 | sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR32); |
1853 | sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode)((__uint32_t)(__builtin_constant_p((int32_t)(((VLNK) == VFIFO ) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : ( int)((vttoif_tab[(int)((VLNK))]) | ((vap->va_mode))))) ? ( __uint32_t)(((__uint32_t)((int32_t)(((VLNK) == VFIFO) ? (int) ((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab [(int)((VLNK))]) | ((vap->va_mode))))) & 0xff) << 24 | ((__uint32_t)((int32_t)(((VLNK) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VLNK))]) | ((vap->va_mode))))) & 0xff00) << 8 | ((__uint32_t)((int32_t)(((VLNK) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VLNK))]) | ((vap->va_mode))))) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(((VLNK) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VLNK))]) | ((vap->va_mode))))) & 0xff000000) >> 24) : __swap32md((int32_t)(((VLNK) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VLNK))]) | ((vap->va_mode))))))); |
1854 | sp->sa_uid = nfs_xdrneg1; |
1855 | sp->sa_gid = nfs_xdrneg1; |
1856 | sp->sa_size = nfs_xdrneg1; |
1857 | txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); |
1858 | txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); |
1859 | } |
1860 | |
1861 | info.nmi_procp = cnp->cn_proc; |
1862 | info.nmi_cred = cnp->cn_cred; |
1863 | error = nfs_request(dvp, NFSPROC_SYMLINK10, &info); |
1864 | if (info.nmi_v3) { |
1865 | if (!error) |
1866 | nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp){ struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; if (info .nmi_v3) { { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data) ) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info .nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; (gotvp) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl)))); } else (gotvp) = 1; if (gotvp ) { { if ((info.nmi_v3)) { { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (((ttfhsize) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl))))) <= 0 || (ttfhsize ) > 64) { m_freem(info.nmi_mrep); error = 72; goto nfsmout ; } } else (ttfhsize) = 32; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= ((((ttfhsize)+3)&(~0x3)))) { ((ttfhp)) = ( nfsfh_t *)(info.nmi_dpos); info.nmi_dpos += ((((ttfhsize)+3)& (~0x3))); } else if ((t1 = nfsm_disct(&info.nmi_md, & info.nmi_dpos, ((((ttfhsize)+3)&(~0x3))), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { ((ttfhp)) = (nfsfh_t *)cp2; } }; }; if ((t1 = nfs_nget((dvp )->v_mount, ttfhp, ttfhsize, &ttnp)) != 0) { error = t1 ; m_freem(info.nmi_mrep); goto nfsmout; } (newvp) = ((ttnp)-> n_vnode); } if (info.nmi_v3) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (gotvp) (gotvp) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl)))); else if (((int )(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl))))) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ( 84)) { info.nmi_dpos += (84); } else if ((t1 = nfs_adv(&info .nmi_md, &info.nmi_dpos, (84), t1)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } }; } if (gotvp) { struct vnode *ttvp = ((newvp)); if ((t1 = nfs_loadattrcache(&ttvp, & info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } ((newvp)) = ttvp ; }; }; |
1867 | nfsm_wcc_data(dvp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(dvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(dvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(dvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((dvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((dvp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1868 | } |
1869 | m_freem(info.nmi_mrep); |
1870 | |
1871 | nfsmout: |
1872 | if (newvp) |
1873 | vput(newvp); |
1874 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1875 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1876 | if (!wccflag) |
1877 | NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp))((((struct nfsnode *)(dvp)->v_data))->n_attrstamp = 0); |
1878 | VN_KNOTE(dvp, NOTE_WRITE)knote_locked(&dvp->v_klist, (0x0002)); |
1879 | vput(dvp); |
1880 | return (error); |
1881 | } |
1882 | |
1883 | /* |
1884 | * nfs make dir call |
1885 | */ |
1886 | int |
1887 | nfs_mkdir(void *v) |
1888 | { |
1889 | struct vop_mkdir_args *ap = v; |
1890 | struct vnode *dvp = ap->a_dvp; |
1891 | struct vattr *vap = ap->a_vap; |
1892 | struct componentname *cnp = ap->a_cnp; |
1893 | struct nfsv2_sattr *sp; |
1894 | struct nfsm_info info; |
1895 | u_int32_t *tl; |
1896 | int32_t t1; |
1897 | int len; |
1898 | struct nfsnode *np = NULL((void *)0); |
1899 | struct vnode *newvp = NULL((void *)0); |
1900 | caddr_t cp2; |
1901 | int error = 0, wccflag = NFSV3_WCCRATTR0; |
1902 | int gotvp = 0; |
1903 | |
1904 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
1905 | |
1906 | len = cnp->cn_namelen; |
1907 | nfsstats.rpccnt[NFSPROC_MKDIR9]++; |
1908 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1909 | NFSX_UNSIGNED4 + nfsm_rndup(len)(((len)+3)&(~0x3)) + NFSX_SATTR(info.nmi_v3)((info.nmi_v3) ? 60 : 32)); |
1910 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
1911 | nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN)if ((len) > (255)) { m_freem(info.nmi_mreq); error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb, (cnp->cn_nameptr ), (len)); |
1912 | |
1913 | if (info.nmi_v3) { |
1914 | nfsm_v3attrbuild(&info.nmi_mb, vap, 0); |
1915 | } else { |
1916 | sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR32); |
1917 | sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode)((__uint32_t)(__builtin_constant_p((int32_t)(((VDIR) == VFIFO ) ? (int)((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : ( int)((vttoif_tab[(int)((VDIR))]) | ((vap->va_mode))))) ? ( __uint32_t)(((__uint32_t)((int32_t)(((VDIR) == VFIFO) ? (int) ((vttoif_tab[(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab [(int)((VDIR))]) | ((vap->va_mode))))) & 0xff) << 24 | ((__uint32_t)((int32_t)(((VDIR) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VDIR))]) | ((vap->va_mode))))) & 0xff00) << 8 | ((__uint32_t)((int32_t)(((VDIR) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VDIR))]) | ((vap->va_mode))))) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(((VDIR) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VDIR))]) | ((vap->va_mode))))) & 0xff000000) >> 24) : __swap32md((int32_t)(((VDIR) == VFIFO) ? (int)((vttoif_tab [(int)(VCHR)]) | ((vap->va_mode))) : (int)((vttoif_tab[(int )((VDIR))]) | ((vap->va_mode))))))); |
1918 | sp->sa_uid = nfs_xdrneg1; |
1919 | sp->sa_gid = nfs_xdrneg1; |
1920 | sp->sa_size = nfs_xdrneg1; |
1921 | txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); |
1922 | txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); |
1923 | } |
1924 | |
1925 | info.nmi_procp = cnp->cn_proc; |
1926 | info.nmi_cred = cnp->cn_cred; |
1927 | error = nfs_request(dvp, NFSPROC_MKDIR9, &info); |
1928 | if (!error) |
1929 | nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp){ struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; if (info .nmi_v3) { { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data) ) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info .nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; (gotvp) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl)))); } else (gotvp) = 1; if (gotvp ) { { if ((info.nmi_v3)) { { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (((ttfhsize) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl))))) <= 0 || (ttfhsize ) > 64) { m_freem(info.nmi_mrep); error = 72; goto nfsmout ; } } else (ttfhsize) = 32; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= ((((ttfhsize)+3)&(~0x3)))) { ((ttfhp)) = ( nfsfh_t *)(info.nmi_dpos); info.nmi_dpos += ((((ttfhsize)+3)& (~0x3))); } else if ((t1 = nfsm_disct(&info.nmi_md, & info.nmi_dpos, ((((ttfhsize)+3)&(~0x3))), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { ((ttfhp)) = (nfsfh_t *)cp2; } }; }; if ((t1 = nfs_nget((dvp )->v_mount, ttfhp, ttfhsize, &ttnp)) != 0) { error = t1 ; m_freem(info.nmi_mrep); goto nfsmout; } (newvp) = ((ttnp)-> n_vnode); } if (info.nmi_v3) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (gotvp) (gotvp) = ((int)(__uint32_t)(__builtin_constant_p ((int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*tl)))); else if (((int )(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl))))) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ( 84)) { info.nmi_dpos += (84); } else if ((t1 = nfs_adv(&info .nmi_md, &info.nmi_dpos, (84), t1)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } }; } if (gotvp) { struct vnode *ttvp = ((newvp)); if ((t1 = nfs_loadattrcache(&ttvp, & info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } ((newvp)) = ttvp ; }; }; |
1930 | if (info.nmi_v3) |
1931 | nfsm_wcc_data(dvp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(dvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(dvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(dvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((dvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((dvp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1932 | m_freem(info.nmi_mrep); |
1933 | |
1934 | nfsmout: |
1935 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1936 | if (!wccflag) |
1937 | NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp))((((struct nfsnode *)(dvp)->v_data))->n_attrstamp = 0); |
1938 | |
1939 | if (error == 0 && newvp == NULL((void *)0)) { |
1940 | error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred, |
1941 | cnp->cn_proc, &np); |
1942 | if (!error) { |
1943 | newvp = NFSTOV(np)((np)->n_vnode); |
1944 | if (newvp->v_type != VDIR) |
1945 | error = EEXIST17; |
1946 | } |
1947 | } |
1948 | if (error) { |
1949 | if (newvp) |
1950 | vput(newvp); |
1951 | } else { |
1952 | VN_KNOTE(dvp, NOTE_WRITE|NOTE_LINK)knote_locked(&dvp->v_klist, (0x0002|0x0010)); |
1953 | if (cnp->cn_flags & MAKEENTRY0x004000) |
1954 | nfs_cache_enter(dvp, newvp, cnp); |
1955 | *ap->a_vpp = newvp; |
1956 | } |
1957 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1958 | vput(dvp); |
1959 | return (error); |
1960 | } |
1961 | |
1962 | /* |
1963 | * nfs remove directory call |
1964 | */ |
1965 | int |
1966 | nfs_rmdir(void *v) |
1967 | { |
1968 | struct vop_rmdir_args *ap = v; |
1969 | struct vnode *vp = ap->a_vp; |
1970 | struct vnode *dvp = ap->a_dvp; |
1971 | struct componentname *cnp = ap->a_cnp; |
1972 | struct nfsm_info info; |
1973 | u_int32_t *tl; |
1974 | int32_t t1; |
1975 | caddr_t cp2; |
1976 | int error = 0, wccflag = NFSV3_WCCRATTR0; |
1977 | |
1978 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
1979 | |
1980 | nfsstats.rpccnt[NFSPROC_RMDIR13]++; |
1981 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + |
1982 | NFSX_UNSIGNED4 + nfsm_rndup(cnp->cn_namelen)(((cnp->cn_namelen)+3)&(~0x3))); |
1983 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
1984 | nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN)if ((cnp->cn_namelen) > (255)) { m_freem(info.nmi_mreq) ; error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb , (cnp->cn_nameptr), (cnp->cn_namelen)); |
1985 | |
1986 | info.nmi_procp = cnp->cn_proc; |
1987 | info.nmi_cred = cnp->cn_cred; |
1988 | error = nfs_request(dvp, NFSPROC_RMDIR13, &info); |
1989 | if (info.nmi_v3) |
1990 | nfsm_wcc_data(dvp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(dvp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(dvp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(dvp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((dvp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((dvp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
1991 | m_freem(info.nmi_mrep); |
1992 | |
1993 | nfsmout: |
1994 | pool_put(&namei_pool, cnp->cn_pnbuf); |
1995 | VTONFS(dvp)((struct nfsnode *)(dvp)->v_data)->n_flag |= NMODIFIED0x0004; |
1996 | if (!wccflag) |
1997 | NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp))((((struct nfsnode *)(dvp)->v_data))->n_attrstamp = 0); |
1998 | |
1999 | VN_KNOTE(dvp, NOTE_WRITE|NOTE_LINK)knote_locked(&dvp->v_klist, (0x0002|0x0010)); |
2000 | VN_KNOTE(vp, NOTE_DELETE)knote_locked(&vp->v_klist, (0x0001)); |
2001 | |
2002 | cache_purge(vp); |
2003 | vput(vp); |
2004 | vput(dvp); |
2005 | /* |
2006 | * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. |
2007 | */ |
2008 | if (error == ENOENT2) |
2009 | error = 0; |
2010 | return (error); |
2011 | } |
2012 | |
2013 | |
2014 | /* |
2015 | * The readdir logic below has a big design bug. It stores the NFS cookie in |
2016 | * the returned uio->uio_offset but does not store the verifier (it cannot). |
2017 | * Instead, the code stores the verifier in the nfsnode and applies that |
2018 | * verifies to all cookies, no matter what verifier was originally with |
2019 | * the cookie. |
2020 | * |
2021 | * From a practical standpoint, this is not a problem since almost all |
2022 | * NFS servers do not change the validity of cookies across deletes |
2023 | * and inserts. |
2024 | */ |
2025 | |
2026 | struct nfs_dirent { |
2027 | u_int32_t cookie[2]; |
2028 | struct dirent dirent; |
2029 | }; |
2030 | |
2031 | #define NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)) (sizeof (struct nfs_dirent) - (MAXNAMLEN255 + 1)) |
2032 | #define NFS_DIRENT_OVERHEAD__builtin_offsetof(struct nfs_dirent, dirent) offsetof(struct nfs_dirent, dirent)__builtin_offsetof(struct nfs_dirent, dirent) |
2033 | |
2034 | /* |
2035 | * nfs readdir call |
2036 | */ |
2037 | int |
2038 | nfs_readdir(void *v) |
2039 | { |
2040 | struct vop_readdir_args *ap = v; |
2041 | struct vnode *vp = ap->a_vp; |
2042 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
2043 | struct uio *uio = ap->a_uio; |
2044 | int tresid, error = 0; |
2045 | struct vattr vattr; |
2046 | int cnt; |
2047 | u_int64_t newoff = uio->uio_offset; |
2048 | struct nfsmount *nmp = VFSTONFS(vp->v_mount)((struct nfsmount *)((vp->v_mount)->mnt_data)); |
2049 | struct uio readdir_uio; |
2050 | struct iovec readdir_iovec; |
2051 | struct proc * p = uio->uio_procp; |
2052 | int done = 0, eof = 0; |
2053 | struct ucred *cred = ap->a_cred; |
2054 | void *data; |
2055 | |
2056 | if (vp->v_type != VDIR) |
2057 | return (EPERM1); |
2058 | /* |
2059 | * First, check for hit on the EOF offset cache |
2060 | */ |
2061 | if (np->n_direofoffsetn_un2.nd_direof != 0 && |
2062 | uio->uio_offset == np->n_direofoffsetn_un2.nd_direof) { |
2063 | if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp) == 0 && |
2064 | timespeccmp(&np->n_mtime, &vattr.va_mtime, ==)(((&np->n_mtime)->tv_sec == (&vattr.va_mtime)-> tv_sec) ? ((&np->n_mtime)->tv_nsec == (&vattr.va_mtime )->tv_nsec) : ((&np->n_mtime)->tv_sec == (&vattr .va_mtime)->tv_sec))) { |
2065 | nfsstats.direofcache_hits++; |
2066 | *ap->a_eofflag = 1; |
2067 | return (0); |
2068 | } |
2069 | } |
2070 | |
2071 | if (uio->uio_resid < NFS_FABLKSIZE512) |
2072 | return (EINVAL22); |
2073 | |
2074 | tresid = uio->uio_resid; |
2075 | |
2076 | if (uio->uio_rw != UIO_READ) |
2077 | return (EINVAL22); |
2078 | |
2079 | if ((nmp->nm_flag & (NFSMNT_NFSV30x00000200 | NFSMNT_GOTFSINFO0x00100000)) == NFSMNT_NFSV30x00000200) |
2080 | (void)nfs_fsinfo(nmp, vp, cred, p); |
2081 | |
2082 | cnt = 5; |
2083 | |
2084 | /* M_ZERO to avoid leaking kernel data in dirent padding */ |
2085 | data = malloc(NFS_DIRBLKSIZ1024, M_TEMP127, M_WAITOK0x0001|M_ZERO0x0008); |
2086 | do { |
2087 | struct nfs_dirent *ndp = data; |
2088 | |
2089 | readdir_iovec.iov_len = NFS_DIRBLKSIZ1024; |
2090 | readdir_iovec.iov_base = data; |
2091 | readdir_uio.uio_offset = newoff; |
2092 | readdir_uio.uio_iov = &readdir_iovec; |
2093 | readdir_uio.uio_iovcnt = 1; |
2094 | readdir_uio.uio_segflg = UIO_SYSSPACE; |
2095 | readdir_uio.uio_rw = UIO_READ; |
2096 | readdir_uio.uio_resid = NFS_DIRBLKSIZ1024; |
2097 | readdir_uio.uio_procp = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc; |
2098 | |
2099 | if (nmp->nm_flag & NFSMNT_RDIRPLUS0x00010000) { |
2100 | error = nfs_readdirplusrpc(vp, &readdir_uio, cred, |
2101 | &eof, p); |
2102 | if (error == NFSERR_NOTSUPP10004) |
2103 | nmp->nm_flag &= ~NFSMNT_RDIRPLUS0x00010000; |
2104 | } |
2105 | if ((nmp->nm_flag & NFSMNT_RDIRPLUS0x00010000) == 0) |
2106 | error = nfs_readdirrpc(vp, &readdir_uio, cred, &eof); |
2107 | |
2108 | if (error == NFSERR_BAD_COOKIE10003) |
2109 | error = EINVAL22; |
2110 | |
2111 | while (error == 0 && |
2112 | ndp < (struct nfs_dirent *)readdir_iovec.iov_base) { |
2113 | struct dirent *dp = &ndp->dirent; |
2114 | int reclen = dp->d_reclen; |
2115 | |
2116 | dp->d_reclen -= NFS_DIRENT_OVERHEAD__builtin_offsetof(struct nfs_dirent, dirent); |
2117 | dp->d_off = fxdr_hyper(&ndp->cookie[0])((((u_quad_t)(__uint32_t)(__builtin_constant_p(((u_int32_t *) (&ndp->cookie[0]))[0]) ? (__uint32_t)(((__uint32_t)((( u_int32_t *)(&ndp->cookie[0]))[0]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[0 ]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(& ndp->cookie[0]))[0]) & 0xff0000) >> 8 | ((__uint32_t )(((u_int32_t *)(&ndp->cookie[0]))[0]) & 0xff000000 ) >> 24) : __swap32md(((u_int32_t *)(&ndp->cookie [0]))[0]))) << 32) | (u_quad_t)((__uint32_t)(__builtin_constant_p (((u_int32_t *)(&ndp->cookie[0]))[1]) ? (__uint32_t)(( (__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[1]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&ndp-> cookie[0]))[1]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[1]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[1]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *)(&ndp ->cookie[0]))[1])))); |
2118 | |
2119 | if (uio->uio_resid < dp->d_reclen) { |
2120 | eof = 0; |
2121 | done = 1; |
2122 | break; |
2123 | } |
2124 | |
2125 | if ((error = uiomove(dp, dp->d_reclen, uio))) |
2126 | break; |
2127 | |
2128 | newoff = fxdr_hyper(&ndp->cookie[0])((((u_quad_t)(__uint32_t)(__builtin_constant_p(((u_int32_t *) (&ndp->cookie[0]))[0]) ? (__uint32_t)(((__uint32_t)((( u_int32_t *)(&ndp->cookie[0]))[0]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[0 ]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(& ndp->cookie[0]))[0]) & 0xff0000) >> 8 | ((__uint32_t )(((u_int32_t *)(&ndp->cookie[0]))[0]) & 0xff000000 ) >> 24) : __swap32md(((u_int32_t *)(&ndp->cookie [0]))[0]))) << 32) | (u_quad_t)((__uint32_t)(__builtin_constant_p (((u_int32_t *)(&ndp->cookie[0]))[1]) ? (__uint32_t)(( (__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[1]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&ndp-> cookie[0]))[1]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[1]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(&ndp->cookie[0]))[1]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *)(&ndp ->cookie[0]))[1])))); |
2129 | |
2130 | ndp = (struct nfs_dirent *)((u_int8_t *)ndp + reclen); |
2131 | } |
2132 | } while (!error && !done && !eof && cnt--); |
2133 | |
2134 | free(data, M_TEMP127, NFS_DIRBLKSIZ1024); |
2135 | data = NULL((void *)0); |
2136 | |
2137 | uio->uio_offset = newoff; |
2138 | |
2139 | if (!error && (eof || uio->uio_resid == tresid)) { |
2140 | nfsstats.direofcache_misses++; |
2141 | *ap->a_eofflag = 1; |
2142 | return (0); |
2143 | } |
2144 | |
2145 | *ap->a_eofflag = 0; |
2146 | return (error); |
2147 | } |
2148 | |
2149 | |
2150 | /* |
2151 | * The function below stuff the cookies in after the name |
2152 | */ |
2153 | |
2154 | /* |
2155 | * Readdir rpc call. |
2156 | */ |
2157 | int |
2158 | nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, |
2159 | int *end_of_directory) |
2160 | { |
2161 | int len, left; |
2162 | struct nfs_dirent *ndp = NULL((void *)0); |
2163 | struct dirent *dp = NULL((void *)0); |
2164 | struct nfsm_info info; |
2165 | u_int32_t *tl; |
2166 | caddr_t cp; |
2167 | int32_t t1; |
2168 | caddr_t cp2; |
2169 | nfsuint64 cookie; |
2170 | struct nfsmount *nmp = VFSTONFS(vp->v_mount)((struct nfsmount *)((vp->v_mount)->mnt_data)); |
2171 | struct nfsnode *dnp = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
2172 | u_quad_t fileno; |
2173 | int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; |
2174 | int attrflag; |
2175 | |
2176 | info.nmi_v3 = NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200); |
2177 | |
2178 | #ifdef DIAGNOSTIC1 |
2179 | if (uiop->uio_iovcnt != 1 || |
2180 | (uiop->uio_resid & (NFS_DIRBLKSIZ1024 - 1))) |
2181 | panic("nfs readdirrpc bad uio"); |
2182 | #endif |
2183 | |
2184 | txdr_hyper(uiop->uio_offset, &cookie.nfsuquad[0])do { ((u_int32_t *)(&cookie.nfsuquad[0]))[0] = (__uint32_t )(__builtin_constant_p((u_int32_t)((uiop->uio_offset) >> 32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((uiop->uio_offset ) >> 32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t )((uiop->uio_offset) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset) >> 32 )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)((uiop ->uio_offset) >> 32)) & 0xff000000) >> 24) : __swap32md((u_int32_t)((uiop->uio_offset) >> 32)) ); ((u_int32_t *)(&cookie.nfsuquad[0]))[1] = (__uint32_t) (__builtin_constant_p((u_int32_t)((uiop->uio_offset) & 0xffffffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((uiop-> uio_offset) & 0xffffffff)) & 0xff) << 24 | ((__uint32_t )((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff00 ) << 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t )((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff000000 ) >> 24) : __swap32md((u_int32_t)((uiop->uio_offset) & 0xffffffff))); } while (0); |
2185 | |
2186 | /* |
2187 | * Loop around doing readdir rpc's of size nm_readdirsize |
2188 | * truncated to a multiple of NFS_READDIRBLKSIZ. |
2189 | * The stopping criteria is EOF or buffer full. |
2190 | */ |
2191 | while (more_dirs && bigenough) { |
2192 | nfsstats.rpccnt[NFSPROC_READDIR16]++; |
2193 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) |
2194 | + NFSX_READDIR(info.nmi_v3)((info.nmi_v3) ? (5 * 4) : (2 * 4))); |
2195 | nfsm_fhtom(&info, vp, info.nmi_v3); |
2196 | if (info.nmi_v3) { |
2197 | tl = nfsm_build(&info.nmi_mb, 5 * NFSX_UNSIGNED4); |
2198 | *tl++ = cookie.nfsuquad[0]; |
2199 | *tl++ = cookie.nfsuquad[1]; |
2200 | if (cookie.nfsuquad[0] == 0 && |
2201 | cookie.nfsuquad[1] == 0) { |
2202 | *tl++ = 0; |
2203 | *tl++ = 0; |
2204 | } else { |
2205 | *tl++ = dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[0]; |
2206 | *tl++ = dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[1]; |
2207 | } |
2208 | } else { |
2209 | tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4); |
2210 | *tl++ = cookie.nfsuquad[1]; |
2211 | } |
2212 | *tl = txdr_unsigned(nmp->nm_readdirsize)((__uint32_t)(__builtin_constant_p((int32_t)(nmp->nm_readdirsize )) ? (__uint32_t)(((__uint32_t)((int32_t)(nmp->nm_readdirsize )) & 0xff) << 24 | ((__uint32_t)((int32_t)(nmp-> nm_readdirsize)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(nmp->nm_readdirsize)) & 0xff0000) >> 8 | ((__uint32_t )((int32_t)(nmp->nm_readdirsize)) & 0xff000000) >> 24) : __swap32md((int32_t)(nmp->nm_readdirsize)))); |
2213 | |
2214 | info.nmi_procp = uiop->uio_procp; |
2215 | info.nmi_cred = cred; |
2216 | error = nfs_request(vp, NFSPROC_READDIR16, &info); |
2217 | if (info.nmi_v3) |
2218 | nfsm_postop_attr(vp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (vp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (vp) = ttvp; } } }; |
2219 | |
2220 | if (error) { |
2221 | m_freem(info.nmi_mrep); |
2222 | goto nfsmout; |
2223 | } |
2224 | |
2225 | if (info.nmi_v3) { |
2226 | nfsm_dissect(tl, u_int32_t *,{ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (2 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } } |
2227 | 2 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (2 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2228 | dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[0] = *tl++; |
2229 | dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[1] = *tl; |
2230 | } |
2231 | |
2232 | nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2233 | more_dirs = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2234 | |
2235 | /* loop thru the dir entries, doctoring them to dirent form */ |
2236 | while (more_dirs && bigenough) { |
2237 | if (info.nmi_v3) { |
2238 | nfsm_dissect(tl, u_int32_t *,{ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (3 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (3 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (3 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } } |
2239 | 3 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (3 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (3 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (3 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2240 | fileno = fxdr_hyper(tl)((((u_quad_t)(__uint32_t)(__builtin_constant_p(((u_int32_t *) (tl))[0]) ? (__uint32_t)(((__uint32_t)(((u_int32_t *)(tl))[0] ) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(tl)) [0]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)( tl))[0]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(tl))[0]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *)(tl))[0]))) << 32) | (u_quad_t)((__uint32_t)(__builtin_constant_p (((u_int32_t *)(tl))[1]) ? (__uint32_t)(((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *)(tl))[1])))); |
2241 | len = fxdr_unsigned(int, *(tl + 2))((int)(__uint32_t)(__builtin_constant_p((int32_t)(*(tl + 2))) ? (__uint32_t)(((__uint32_t)((int32_t)(*(tl + 2))) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*(tl + 2))) & 0xff00 ) << 8 | ((__uint32_t)((int32_t)(*(tl + 2))) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*(tl + 2))) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*(tl + 2))))); |
2242 | } else { |
2243 | nfsm_dissect(tl, u_int32_t *,{ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (2 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } } |
2244 | 2 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (2 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2245 | fileno = fxdr_unsigned(u_quad_t, *tl++)((u_quad_t)(__uint32_t)(__builtin_constant_p((int32_t)(*tl++) ) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl++)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl++)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl++)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl++)) & 0xff000000) >> 24) : __swap32md((int32_t)(*tl++)))); |
2246 | len = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2247 | } |
2248 | if (len <= 0 || len > NFS_MAXNAMLEN255) { |
2249 | error = EBADRPC72; |
2250 | m_freem(info.nmi_mrep); |
2251 | goto nfsmout; |
2252 | } |
2253 | tlen = DIRENT_RECSIZE(len)((__builtin_offsetof(struct dirent, d_name) + (len) + 1 + 7) & ~ 7) + NFS_DIRENT_OVERHEAD__builtin_offsetof(struct nfs_dirent, dirent); |
2254 | left = NFS_READDIRBLKSIZ512 - blksiz; |
2255 | if (tlen > left) { |
2256 | dp->d_reclen += left; |
2257 | uiop->uio_iov->iov_base += left; |
2258 | uiop->uio_iov->iov_len -= left; |
2259 | uiop->uio_resid -= left; |
2260 | blksiz = 0; |
2261 | } |
2262 | if (tlen > uiop->uio_resid) |
2263 | bigenough = 0; |
2264 | if (bigenough) { |
2265 | ndp = (struct nfs_dirent *) |
2266 | uiop->uio_iov->iov_base; |
2267 | dp = &ndp->dirent; |
2268 | dp->d_fileno = fileno; |
2269 | dp->d_namlen = len; |
2270 | dp->d_reclen = tlen; |
2271 | dp->d_type = DT_UNKNOWN0; |
2272 | blksiz += tlen; |
2273 | if (blksiz == NFS_READDIRBLKSIZ512) |
2274 | blksiz = 0; |
2275 | uiop->uio_resid -= NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)); |
2276 | uiop->uio_iov->iov_base = |
2277 | (char *)uiop->uio_iov->iov_base + |
2278 | NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)); |
2279 | uiop->uio_iov->iov_len -= NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)); |
2280 | nfsm_mtouio(uiop, len)if ((len) > 0 && (t1 = nfsm_mbuftouio(&info.nmi_md , (uiop), (len), &info.nmi_dpos)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; }; |
2281 | cp = uiop->uio_iov->iov_base; |
2282 | tlen -= NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)) + len; |
2283 | *cp = '\0'; /* null terminate */ |
2284 | uiop->uio_iov->iov_base += tlen; |
2285 | uiop->uio_iov->iov_len -= tlen; |
2286 | uiop->uio_resid -= tlen; |
2287 | } else |
2288 | nfsm_adv(nfsm_rndup(len)){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ((((len)+3)& (~0x3)))) { info.nmi_dpos += ((((len)+3)&(~0x3))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos, (((( len)+3)&(~0x3))), t1)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } }; |
2289 | if (info.nmi_v3) { |
2290 | nfsm_dissect(tl, u_int32_t *,{ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (3 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (3 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (3 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } } |
2291 | 3 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (3 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (3 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (3 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2292 | } else { |
2293 | nfsm_dissect(tl, u_int32_t *,{ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (2 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } } |
2294 | 2 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (2 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (2 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (2 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2295 | } |
2296 | if (bigenough) { |
2297 | if (info.nmi_v3) { |
2298 | ndp->cookie[0] = cookie.nfsuquad[0] = |
2299 | *tl++; |
2300 | } else |
2301 | ndp->cookie[0] = 0; |
2302 | |
2303 | ndp->cookie[1] = cookie.nfsuquad[1] = *tl++; |
2304 | } else if (info.nmi_v3) |
2305 | tl += 2; |
2306 | else |
2307 | tl++; |
2308 | more_dirs = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2309 | } |
2310 | /* |
2311 | * If at end of rpc data, get the eof boolean |
2312 | */ |
2313 | if (!more_dirs) { |
2314 | nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2315 | more_dirs = (fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))) == 0); |
2316 | } |
2317 | m_freem(info.nmi_mrep); |
2318 | } |
2319 | /* |
2320 | * Fill last record, iff any, out to a multiple of NFS_READDIRBLKSIZ |
2321 | * by increasing d_reclen for the last record. |
2322 | */ |
2323 | if (blksiz > 0) { |
2324 | left = NFS_READDIRBLKSIZ512 - blksiz; |
2325 | dp->d_reclen += left; |
2326 | uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + |
2327 | left; |
2328 | uiop->uio_iov->iov_len -= left; |
2329 | uiop->uio_resid -= left; |
2330 | } |
2331 | |
2332 | /* |
2333 | * We are now either at the end of the directory or have filled the |
2334 | * block. |
2335 | */ |
2336 | if (bigenough) { |
2337 | dnp->n_direofoffsetn_un2.nd_direof = fxdr_hyper(&cookie.nfsuquad[0])((((u_quad_t)(__uint32_t)(__builtin_constant_p(((u_int32_t *) (&cookie.nfsuquad[0]))[0]) ? (__uint32_t)(((__uint32_t)(( (u_int32_t *)(&cookie.nfsuquad[0]))[0]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&cookie.nfsuquad[0]))[ 0]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(& cookie.nfsuquad[0]))[0]) & 0xff0000) >> 8 | ((__uint32_t )(((u_int32_t *)(&cookie.nfsuquad[0]))[0]) & 0xff000000 ) >> 24) : __swap32md(((u_int32_t *)(&cookie.nfsuquad [0]))[0]))) << 32) | (u_quad_t)((__uint32_t)(__builtin_constant_p (((u_int32_t *)(&cookie.nfsuquad[0]))[1]) ? (__uint32_t)( ((__uint32_t)(((u_int32_t *)(&cookie.nfsuquad[0]))[1]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&cookie .nfsuquad[0]))[1]) & 0xff00) << 8 | ((__uint32_t)(( (u_int32_t *)(&cookie.nfsuquad[0]))[1]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(&cookie.nfsuquad[0]))[1 ]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *) (&cookie.nfsuquad[0]))[1])))); |
2338 | if (end_of_directory) *end_of_directory = 1; |
2339 | } else { |
2340 | if (uiop->uio_resid > 0) |
2341 | printf("EEK! readdirrpc resid > 0\n"); |
2342 | } |
2343 | |
2344 | nfsmout: |
2345 | return (error); |
2346 | } |
2347 | |
2348 | /* |
2349 | * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc(). |
2350 | */ |
2351 | int |
2352 | nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, |
2353 | int *end_of_directory, struct proc *p) |
2354 | { |
2355 | int len, left; |
2356 | struct nfs_dirent *ndirp = NULL((void *)0); |
2357 | struct dirent *dp = NULL((void *)0); |
2358 | struct nfsm_info info; |
2359 | u_int32_t *tl; |
2360 | caddr_t cp; |
2361 | int32_t t1; |
2362 | struct vnode *newvp; |
2363 | caddr_t cp2, dpossav1, dpossav2; |
2364 | struct mbuf *mdsav1, *mdsav2; |
2365 | struct nameidata nami, *ndp = &nami; |
2366 | struct componentname *cnp = &ndp->ni_cnd; |
2367 | nfsuint64 cookie; |
2368 | struct nfsmount *nmp = VFSTONFS(vp->v_mount)((struct nfsmount *)((vp->v_mount)->mnt_data)); |
2369 | struct nfsnode *dnp = VTONFS(vp)((struct nfsnode *)(vp)->v_data), *np; |
2370 | nfsfh_t *fhp; |
2371 | u_quad_t fileno; |
2372 | int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i; |
2373 | int attrflag, fhsize; |
2374 | |
2375 | #ifdef DIAGNOSTIC1 |
2376 | if (uiop->uio_iovcnt != 1 || |
2377 | (uiop->uio_resid & (NFS_DIRBLKSIZ1024 - 1))) |
2378 | panic("nfs readdirplusrpc bad uio"); |
2379 | #endif |
2380 | NDINIT(ndp, 0, 0, UIO_SYSSPACE, NULL, p)ndinitat(ndp, 0, 0, UIO_SYSSPACE, -100, ((void *)0), p); |
2381 | ndp->ni_dvp = vp; |
2382 | newvp = NULLVP((struct vnode *)((void *)0)); |
2383 | |
2384 | txdr_hyper(uiop->uio_offset, &cookie.nfsuquad[0])do { ((u_int32_t *)(&cookie.nfsuquad[0]))[0] = (__uint32_t )(__builtin_constant_p((u_int32_t)((uiop->uio_offset) >> 32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((uiop->uio_offset ) >> 32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t )((uiop->uio_offset) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset) >> 32 )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)((uiop ->uio_offset) >> 32)) & 0xff000000) >> 24) : __swap32md((u_int32_t)((uiop->uio_offset) >> 32)) ); ((u_int32_t *)(&cookie.nfsuquad[0]))[1] = (__uint32_t) (__builtin_constant_p((u_int32_t)((uiop->uio_offset) & 0xffffffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((uiop-> uio_offset) & 0xffffffff)) & 0xff) << 24 | ((__uint32_t )((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff00 ) << 8 | ((__uint32_t)((u_int32_t)((uiop->uio_offset ) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t )((u_int32_t)((uiop->uio_offset) & 0xffffffff)) & 0xff000000 ) >> 24) : __swap32md((u_int32_t)((uiop->uio_offset) & 0xffffffff))); } while (0); |
2385 | |
2386 | /* |
2387 | * Loop around doing readdir rpc's of size nm_readdirsize |
2388 | * truncated to a multiple of NFS_READDIRBLKSIZ. |
2389 | * The stopping criteria is EOF or buffer full. |
2390 | */ |
2391 | while (more_dirs && bigenough) { |
2392 | nfsstats.rpccnt[NFSPROC_READDIRPLUS17]++; |
2393 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1)((1) ? (64 + 4) : 32) + 6 * NFSX_UNSIGNED4); |
2394 | nfsm_fhtom(&info, vp, 1); |
2395 | tl = nfsm_build(&info.nmi_mb, 6 * NFSX_UNSIGNED4); |
2396 | *tl++ = cookie.nfsuquad[0]; |
2397 | *tl++ = cookie.nfsuquad[1]; |
2398 | if (cookie.nfsuquad[0] == 0 && |
2399 | cookie.nfsuquad[1] == 0) { |
2400 | *tl++ = 0; |
2401 | *tl++ = 0; |
2402 | } else { |
2403 | *tl++ = dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[0]; |
2404 | *tl++ = dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[1]; |
2405 | } |
2406 | *tl++ = txdr_unsigned(nmp->nm_readdirsize)((__uint32_t)(__builtin_constant_p((int32_t)(nmp->nm_readdirsize )) ? (__uint32_t)(((__uint32_t)((int32_t)(nmp->nm_readdirsize )) & 0xff) << 24 | ((__uint32_t)((int32_t)(nmp-> nm_readdirsize)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(nmp->nm_readdirsize)) & 0xff0000) >> 8 | ((__uint32_t )((int32_t)(nmp->nm_readdirsize)) & 0xff000000) >> 24) : __swap32md((int32_t)(nmp->nm_readdirsize)))); |
2407 | *tl = txdr_unsigned(nmp->nm_rsize)((__uint32_t)(__builtin_constant_p((int32_t)(nmp->nm_rsize )) ? (__uint32_t)(((__uint32_t)((int32_t)(nmp->nm_rsize)) & 0xff) << 24 | ((__uint32_t)((int32_t)(nmp->nm_rsize )) & 0xff00) << 8 | ((__uint32_t)((int32_t)(nmp-> nm_rsize)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t )(nmp->nm_rsize)) & 0xff000000) >> 24) : __swap32md ((int32_t)(nmp->nm_rsize)))); |
2408 | |
2409 | info.nmi_procp = uiop->uio_procp; |
2410 | info.nmi_cred = cred; |
2411 | error = nfs_request(vp, NFSPROC_READDIRPLUS17, &info); |
2412 | nfsm_postop_attr(vp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (vp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (vp) = ttvp; } } }; |
2413 | if (error) { |
2414 | m_freem(info.nmi_mrep); |
2415 | goto nfsmout; |
2416 | } |
2417 | |
2418 | nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (3 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (3 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (3 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2419 | dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[0] = *tl++; |
2420 | dnp->n_cookieverfn_un1.nd_cookieverf.nfsuquad[1] = *tl++; |
2421 | more_dirs = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2422 | |
2423 | /* loop thru the dir entries, doctoring them to 4bsd form */ |
2424 | while (more_dirs && bigenough) { |
2425 | nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (3 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (3 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (3 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2426 | fileno = fxdr_hyper(tl)((((u_quad_t)(__uint32_t)(__builtin_constant_p(((u_int32_t *) (tl))[0]) ? (__uint32_t)(((__uint32_t)(((u_int32_t *)(tl))[0] ) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(tl)) [0]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)( tl))[0]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(tl))[0]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *)(tl))[0]))) << 32) | (u_quad_t)((__uint32_t)(__builtin_constant_p (((u_int32_t *)(tl))[1]) ? (__uint32_t)(((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(tl))[1]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *)(tl))[1])))); |
2427 | len = fxdr_unsigned(int, *(tl + 2))((int)(__uint32_t)(__builtin_constant_p((int32_t)(*(tl + 2))) ? (__uint32_t)(((__uint32_t)((int32_t)(*(tl + 2))) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*(tl + 2))) & 0xff00 ) << 8 | ((__uint32_t)((int32_t)(*(tl + 2))) & 0xff0000 ) >> 8 | ((__uint32_t)((int32_t)(*(tl + 2))) & 0xff000000 ) >> 24) : __swap32md((int32_t)(*(tl + 2))))); |
2428 | if (len <= 0 || len > NFS_MAXNAMLEN255) { |
2429 | error = EBADRPC72; |
2430 | m_freem(info.nmi_mrep); |
2431 | goto nfsmout; |
2432 | } |
2433 | tlen = DIRENT_RECSIZE(len)((__builtin_offsetof(struct dirent, d_name) + (len) + 1 + 7) & ~ 7) + NFS_DIRENT_OVERHEAD__builtin_offsetof(struct nfs_dirent, dirent); |
2434 | left = NFS_READDIRBLKSIZ512 - blksiz; |
2435 | if (tlen > left) { |
2436 | dp->d_reclen += left; |
2437 | uiop->uio_iov->iov_base = |
2438 | (char *)uiop->uio_iov->iov_base + left; |
2439 | uiop->uio_iov->iov_len -= left; |
2440 | uiop->uio_resid -= left; |
2441 | blksiz = 0; |
2442 | } |
2443 | if (tlen > uiop->uio_resid) |
2444 | bigenough = 0; |
2445 | if (bigenough) { |
2446 | ndirp = (struct nfs_dirent *) |
2447 | uiop->uio_iov->iov_base; |
2448 | dp = &ndirp->dirent; |
2449 | dp->d_fileno = fileno; |
2450 | dp->d_namlen = len; |
2451 | dp->d_reclen = tlen; |
2452 | dp->d_type = DT_UNKNOWN0; |
2453 | blksiz += tlen; |
2454 | if (blksiz == NFS_READDIRBLKSIZ512) |
2455 | blksiz = 0; |
2456 | uiop->uio_resid -= NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)); |
2457 | uiop->uio_iov->iov_base = |
2458 | (char *)uiop->uio_iov->iov_base + |
2459 | NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)); |
2460 | uiop->uio_iov->iov_len -= NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)); |
2461 | cnp->cn_nameptr = uiop->uio_iov->iov_base; |
2462 | cnp->cn_namelen = len; |
2463 | nfsm_mtouio(uiop, len)if ((len) > 0 && (t1 = nfsm_mbuftouio(&info.nmi_md , (uiop), (len), &info.nmi_dpos)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; }; |
2464 | cp = uiop->uio_iov->iov_base; |
2465 | tlen -= NFS_DIRHDSIZ(sizeof (struct nfs_dirent) - (255 + 1)) + len; |
2466 | *cp = '\0'; |
2467 | uiop->uio_iov->iov_base += tlen; |
2468 | uiop->uio_iov->iov_len -= tlen; |
2469 | uiop->uio_resid -= tlen; |
2470 | } else |
2471 | nfsm_adv(nfsm_rndup(len)){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ((((len)+3)& (~0x3)))) { info.nmi_dpos += ((((len)+3)&(~0x3))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos, (((( len)+3)&(~0x3))), t1)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } }; |
2472 | nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (3 * 4)) { (tl ) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (3 * 4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (3 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2473 | if (bigenough) { |
2474 | ndirp->cookie[0] = cookie.nfsuquad[0] = *tl++; |
2475 | ndirp->cookie[1] = cookie.nfsuquad[1] = *tl++; |
2476 | } else |
2477 | tl += 2; |
2478 | |
2479 | /* |
2480 | * Since the attributes are before the file handle |
2481 | * (sigh), we must skip over the attributes and then |
2482 | * come back and get them. |
2483 | */ |
2484 | attrflag = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2485 | if (attrflag) { |
2486 | dpossav1 = info.nmi_dpos; |
2487 | mdsav1 = info.nmi_md; |
2488 | nfsm_adv(NFSX_V3FATTR){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (84)) { info. nmi_dpos += (84); } else if ((t1 = nfs_adv(&info.nmi_md, & info.nmi_dpos, (84), t1)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } }; |
2489 | nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2490 | doit = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2491 | if (doit) { |
2492 | nfsm_getfh(fhp, fhsize, 1){ if (1) { { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data) ) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info .nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (((fhsize) = ((int)(__uint32_t)(__builtin_constant_p(( int32_t)(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00 ) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(*tl))))) <= 0 || (fhsize) > 64) { m_freem(info.nmi_mrep); error = 72; goto nfsmout; } } else (fhsize) = 32; { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data )) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ((((fhsize)+3)&(~0x3)))) { ((fhp)) = (nfsfh_t *)(info.nmi_dpos ); info.nmi_dpos += ((((fhsize)+3)&(~0x3))); } else if (( t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, ((((fhsize )+3)&(~0x3))), t1, &cp2)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } else { ((fhp)) = (nfsfh_t *) cp2; } }; }; |
2493 | if (NFS_CMPFH(dnp, fhp, fhsize)((dnp)->n_fhsize == (fhsize) && !bcmp((caddr_t)(dnp )->n_fhp, (caddr_t)(fhp), (fhsize)))) { |
2494 | vref(vp); |
2495 | newvp = vp; |
2496 | np = dnp; |
2497 | } else { |
2498 | error = nfs_nget(vp->v_mount, |
2499 | fhp, fhsize, &np); |
2500 | if (error) |
2501 | doit = 0; |
2502 | else |
2503 | newvp = NFSTOV(np)((np)->n_vnode); |
2504 | } |
2505 | } |
2506 | if (doit && bigenough) { |
2507 | dpossav2 = info.nmi_dpos; |
2508 | info.nmi_dpos = dpossav1; |
2509 | mdsav2 = info.nmi_md; |
2510 | info.nmi_md = mdsav1; |
2511 | nfsm_loadattr(newvp, NULL){ struct vnode *ttvp = (newvp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (newvp ) = ttvp; }; |
2512 | info.nmi_dpos = dpossav2; |
2513 | info.nmi_md = mdsav2; |
2514 | dp->d_type = IFTODT(((((vttoif_tab[(int)(np->n_vattr.va_type)])) & 0170000 ) >> 12) |
2515 | VTTOIF(np->n_vattr.va_type))((((vttoif_tab[(int)(np->n_vattr.va_type)])) & 0170000 ) >> 12); |
2516 | if (cnp->cn_namelen <= |
2517 | NAMECACHE_MAXLEN31) { |
2518 | ndp->ni_vp = newvp; |
2519 | cache_purge(ndp->ni_dvp); |
2520 | nfs_cache_enter(ndp->ni_dvp, |
2521 | ndp->ni_vp, cnp); |
2522 | } |
2523 | } |
2524 | } else { |
2525 | /* Just skip over the file handle */ |
2526 | nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2527 | i = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2528 | if (i > 0) |
2529 | nfsm_adv(nfsm_rndup(i)){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ((((i)+3)& (~0x3)))) { info.nmi_dpos += ((((i)+3)&(~0x3))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos, ((((i)+ 3)&(~0x3))), t1)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } }; |
2530 | } |
2531 | if (newvp != NULLVP((struct vnode *)((void *)0))) { |
2532 | if (newvp == vp) |
2533 | vrele(newvp); |
2534 | else |
2535 | vput(newvp); |
2536 | newvp = NULLVP((struct vnode *)((void *)0)); |
2537 | } |
2538 | nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2539 | more_dirs = fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))); |
2540 | } |
2541 | /* |
2542 | * If at end of rpc data, get the eof boolean |
2543 | */ |
2544 | if (!more_dirs) { |
2545 | nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2546 | more_dirs = (fxdr_unsigned(int, *tl)((int)(__uint32_t)(__builtin_constant_p((int32_t)(*tl)) ? (__uint32_t )(((__uint32_t)((int32_t)(*tl)) & 0xff) << 24 | ((__uint32_t )((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( *tl)) & 0xff000000) >> 24) : __swap32md((int32_t)(* tl)))) == 0); |
2547 | } |
2548 | m_freem(info.nmi_mrep); |
2549 | } |
2550 | /* |
2551 | * Fill last record, iff any, out to a multiple of NFS_READDIRBLKSIZ |
2552 | * by increasing d_reclen for the last record. |
2553 | */ |
2554 | if (blksiz > 0) { |
2555 | left = NFS_READDIRBLKSIZ512 - blksiz; |
2556 | dp->d_reclen += left; |
2557 | uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + |
2558 | left; |
2559 | uiop->uio_iov->iov_len -= left; |
2560 | uiop->uio_resid -= left; |
2561 | } |
2562 | |
2563 | /* |
2564 | * We are now either at the end of the directory or have filled the |
2565 | * block. |
2566 | */ |
2567 | if (bigenough) { |
2568 | dnp->n_direofoffsetn_un2.nd_direof = fxdr_hyper(&cookie.nfsuquad[0])((((u_quad_t)(__uint32_t)(__builtin_constant_p(((u_int32_t *) (&cookie.nfsuquad[0]))[0]) ? (__uint32_t)(((__uint32_t)(( (u_int32_t *)(&cookie.nfsuquad[0]))[0]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&cookie.nfsuquad[0]))[ 0]) & 0xff00) << 8 | ((__uint32_t)(((u_int32_t *)(& cookie.nfsuquad[0]))[0]) & 0xff0000) >> 8 | ((__uint32_t )(((u_int32_t *)(&cookie.nfsuquad[0]))[0]) & 0xff000000 ) >> 24) : __swap32md(((u_int32_t *)(&cookie.nfsuquad [0]))[0]))) << 32) | (u_quad_t)((__uint32_t)(__builtin_constant_p (((u_int32_t *)(&cookie.nfsuquad[0]))[1]) ? (__uint32_t)( ((__uint32_t)(((u_int32_t *)(&cookie.nfsuquad[0]))[1]) & 0xff) << 24 | ((__uint32_t)(((u_int32_t *)(&cookie .nfsuquad[0]))[1]) & 0xff00) << 8 | ((__uint32_t)(( (u_int32_t *)(&cookie.nfsuquad[0]))[1]) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t *)(&cookie.nfsuquad[0]))[1 ]) & 0xff000000) >> 24) : __swap32md(((u_int32_t *) (&cookie.nfsuquad[0]))[1])))); |
2569 | if (end_of_directory) *end_of_directory = 1; |
2570 | } else { |
2571 | if (uiop->uio_resid > 0) |
2572 | printf("EEK! readdirplusrpc resid > 0\n"); |
2573 | } |
2574 | |
2575 | nfsmout: |
2576 | if (newvp != NULLVP((struct vnode *)((void *)0))) { |
2577 | if (newvp == vp) |
2578 | vrele(newvp); |
2579 | else |
2580 | vput(newvp); |
2581 | } |
2582 | return (error); |
2583 | } |
2584 | |
2585 | /* |
2586 | * Silly rename. To make the NFS filesystem that is stateless look a little |
2587 | * more like the "ufs" a remove of an active vnode is translated to a rename |
2588 | * to a funny looking filename that is removed by nfs_inactive on the |
2589 | * nfsnode. There is the potential for another process on a different client |
2590 | * to create the same funny name between the nfs_lookitup() fails and the |
2591 | * nfs_rename() completes, but... |
2592 | */ |
2593 | int |
2594 | nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) |
2595 | { |
2596 | struct sillyrename *sp; |
2597 | struct nfsnode *np; |
2598 | int error; |
2599 | |
2600 | cache_purge(dvp); |
2601 | np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
2602 | sp = malloc(sizeof(*sp), M_NFSREQ22, M_WAITOK0x0001); |
2603 | sp->s_cred = crdup(cnp->cn_cred); |
2604 | sp->s_dvp = dvp; |
2605 | vref(dvp); |
2606 | |
2607 | if (vp->v_type == VDIR) { |
2608 | #ifdef DIAGNOSTIC1 |
2609 | printf("nfs: sillyrename dir\n"); |
2610 | #endif |
2611 | error = EINVAL22; |
2612 | goto bad; |
2613 | } |
2614 | |
2615 | /* Try lookitups until we get one that isn't there */ |
2616 | while (1) { |
2617 | /* Fudge together a funny name */ |
2618 | u_int32_t rnd[2]; |
2619 | |
2620 | arc4random_buf(&rnd, sizeof rnd); |
2621 | sp->s_namlen = snprintf(sp->s_name, sizeof sp->s_name, |
2622 | ".nfs%08X%08X", rnd[0], rnd[1]); |
2623 | if (sp->s_namlen > sizeof sp->s_name) |
2624 | sp->s_namlen = strlen(sp->s_name); |
2625 | |
2626 | if (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, |
2627 | cnp->cn_proc, NULL((void *)0))) |
2628 | break; |
2629 | } |
2630 | |
2631 | error = nfs_renameit(dvp, cnp, sp); |
2632 | if (error) |
2633 | goto bad; |
2634 | error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, |
Value stored to 'error' is never read | |
2635 | cnp->cn_proc, &np); |
2636 | np->n_sillyrename = sp; |
2637 | return (0); |
2638 | bad: |
2639 | vrele(sp->s_dvp); |
2640 | crfree(sp->s_cred); |
2641 | free(sp, M_NFSREQ22, sizeof(*sp)); |
2642 | return (error); |
2643 | } |
2644 | |
2645 | /* |
2646 | * Look up a file name and optionally either update the file handle or |
2647 | * allocate an nfsnode, depending on the value of npp. |
2648 | * npp == NULL --> just do the lookup |
2649 | * *npp == NULL --> allocate a new nfsnode and make sure attributes are |
2650 | * handled too |
2651 | * *npp != NULL --> update the file handle in the vnode |
2652 | */ |
2653 | int |
2654 | nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred, |
2655 | struct proc *procp, struct nfsnode **npp) |
2656 | { |
2657 | struct nfsm_info info; |
2658 | u_int32_t *tl; |
2659 | int32_t t1; |
2660 | struct vnode *newvp = NULL((void *)0); |
2661 | struct nfsnode *np, *dnp = VTONFS(dvp)((struct nfsnode *)(dvp)->v_data); |
2662 | caddr_t cp2; |
2663 | int error = 0, fhlen, attrflag = 0; |
2664 | nfsfh_t *nfhp; |
2665 | |
2666 | info.nmi_v3 = NFS_ISV3(dvp)(((struct nfsmount *)(((dvp)->v_mount)->mnt_data))-> nm_flag & 0x00000200); |
2667 | |
2668 | nfsstats.rpccnt[NFSPROC_LOOKUP3]++; |
2669 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)((info.nmi_v3) ? (64 + 4) : 32) + NFSX_UNSIGNED4 + |
2670 | nfsm_rndup(len)(((len)+3)&(~0x3))); |
2671 | nfsm_fhtom(&info, dvp, info.nmi_v3); |
2672 | nfsm_strtom(name, len, NFS_MAXNAMLEN)if ((len) > (255)) { m_freem(info.nmi_mreq); error = 63; goto nfsmout; } nfsm_strtombuf(&info.nmi_mb, (name), (len)); |
2673 | |
2674 | info.nmi_procp = procp; |
2675 | info.nmi_cred = cred; |
2676 | error = nfs_request(dvp, NFSPROC_LOOKUP3, &info); |
2677 | if (error && !info.nmi_v3) { |
2678 | m_freem(info.nmi_mrep); |
2679 | goto nfsmout; |
2680 | } |
2681 | |
2682 | if (npp && !error) { |
2683 | nfsm_getfh(nfhp, fhlen, info.nmi_v3){ if (info.nmi_v3) { { t1 = ((caddr_t)((info.nmi_md)->m_hdr .mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info .nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info .nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (((fhlen) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) <= 0 || (fhlen) > 64) { m_freem(info.nmi_mrep); error = 72; goto nfsmout; } } else (fhlen) = 32; { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data )) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= ((((fhlen)+3)&(~0x3)))) { ((nfhp)) = (nfsfh_t *)(info.nmi_dpos ); info.nmi_dpos += ((((fhlen)+3)&(~0x3))); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, ((((fhlen )+3)&(~0x3))), t1, &cp2)) != 0) { error = t1; m_freem (info.nmi_mrep); goto nfsmout; } else { ((nfhp)) = (nfsfh_t * )cp2; } }; }; |
2684 | if (*npp) { |
2685 | np = *npp; |
2686 | np->n_fhp = &np->n_fh; |
2687 | bcopy(nfhp, np->n_fhp, fhlen); |
2688 | np->n_fhsize = fhlen; |
2689 | newvp = NFSTOV(np)((np)->n_vnode); |
2690 | } else if (NFS_CMPFH(dnp, nfhp, fhlen)((dnp)->n_fhsize == (fhlen) && !bcmp((caddr_t)(dnp )->n_fhp, (caddr_t)(nfhp), (fhlen)))) { |
2691 | vref(dvp); |
2692 | newvp = dvp; |
2693 | np = dnp; |
2694 | } else { |
2695 | error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np); |
2696 | if (error) { |
2697 | m_freem(info.nmi_mrep); |
2698 | return (error); |
2699 | } |
2700 | newvp = NFSTOV(np)((np)->n_vnode); |
2701 | } |
2702 | if (info.nmi_v3) { |
2703 | nfsm_postop_attr(newvp, attrflag){ if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = (newvp ); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (attrflag) = ((int)(__uint32_t)(__builtin_constant_p((int32_t )(*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (attrflag) = 0; m_freem(info.nmi_mrep) ; goto nfsmout; } (newvp) = ttvp; } } }; |
2704 | if (!attrflag && *npp == NULL((void *)0)) { |
2705 | m_freem(info.nmi_mrep); |
2706 | if (newvp == dvp) |
2707 | vrele(newvp); |
2708 | else |
2709 | vput(newvp); |
2710 | return (ENOENT2); |
2711 | } |
2712 | } else |
2713 | nfsm_loadattr(newvp, NULL){ struct vnode *ttvp = (newvp); if ((t1 = nfs_loadattrcache(& ttvp, &info.nmi_md, &info.nmi_dpos, (((void *)0)))) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } (newvp ) = ttvp; }; |
2714 | } |
2715 | m_freem(info.nmi_mrep); |
2716 | nfsmout: |
2717 | if (npp && *npp == NULL((void *)0)) { |
2718 | if (error) { |
2719 | if (newvp == dvp) |
2720 | vrele(newvp); |
2721 | else |
2722 | vput(newvp); |
2723 | } else |
2724 | *npp = np; |
2725 | } |
2726 | return (error); |
2727 | } |
2728 | |
2729 | /* |
2730 | * Nfs Version 3 commit rpc |
2731 | */ |
2732 | int |
2733 | nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp) |
2734 | { |
2735 | struct nfsm_info info; |
2736 | u_int32_t *tl; |
2737 | int32_t t1; |
2738 | struct nfsmount *nmp = VFSTONFS(vp->v_mount)((struct nfsmount *)((vp->v_mount)->mnt_data)); |
2739 | caddr_t cp2; |
2740 | int error = 0, wccflag = NFSV3_WCCRATTR0; |
2741 | |
2742 | if ((nmp->nm_flag & NFSMNT_HASWRITEVERF0x00040000) == 0) |
2743 | return (0); |
2744 | nfsstats.rpccnt[NFSPROC_COMMIT21]++; |
2745 | info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1)((1) ? (64 + 4) : 32)); |
2746 | nfsm_fhtom(&info, vp, 1); |
2747 | |
2748 | tl = nfsm_build(&info.nmi_mb, 3 * NFSX_UNSIGNED4); |
2749 | txdr_hyper(offset, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p ((u_int32_t)((offset) >> 32)) ? (__uint32_t)(((__uint32_t )((u_int32_t)((offset) >> 32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((offset) >> 32)) & 0xff00 ) << 8 | ((__uint32_t)((u_int32_t)((offset) >> 32 )) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)((offset ) >> 32)) & 0xff000000) >> 24) : __swap32md(( u_int32_t)((offset) >> 32))); ((u_int32_t *)(tl))[1] = ( __uint32_t)(__builtin_constant_p((u_int32_t)((offset) & 0xffffffff )) ? (__uint32_t)(((__uint32_t)((u_int32_t)((offset) & 0xffffffff )) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((offset ) & 0xffffffff)) & 0xff00) << 8 | ((__uint32_t) ((u_int32_t)((offset) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)((offset) & 0xffffffff)) & 0xff000000) >> 24) : __swap32md((u_int32_t)((offset) & 0xffffffff))); } while (0); |
2750 | tl += 2; |
2751 | *tl = txdr_unsigned(cnt)((__uint32_t)(__builtin_constant_p((int32_t)(cnt)) ? (__uint32_t )(((__uint32_t)((int32_t)(cnt)) & 0xff) << 24 | ((__uint32_t )((int32_t)(cnt)) & 0xff00) << 8 | ((__uint32_t)((int32_t )(cnt)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)( cnt)) & 0xff000000) >> 24) : __swap32md((int32_t)(cnt )))); |
2752 | |
2753 | info.nmi_procp = procp; |
2754 | info.nmi_cred = VTONFS(vp)((struct nfsnode *)(vp)->v_data)->n_wcred; |
2755 | error = nfs_request(vp, NFSPROC_COMMIT21, &info); |
2756 | nfsm_wcc_data(vp, wccflag)do { if (info.nmi_mrep != ((void *)0)) { struct timespec _mtime ; int ttattrf, ttretf = 0; { t1 = ((caddr_t)((info.nmi_md)-> m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info .nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md , &info.nmi_dpos, (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (*tl == nfs_true) { { t1 = ((caddr_t)((info.nmi_md )->m_hdr.mh_data)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos ; if (t1 >= (6 * 4)) { (tl) = (u_int32_t *)(info.nmi_dpos) ; info.nmi_dpos += (6 * 4); } else if ((t1 = nfsm_disct(& info.nmi_md, &info.nmi_dpos, (6 * 4), t1, &cp2)) != 0 ) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; do { (&_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) ? (__uint32_t)(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff) << 24 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff00 ) << 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_sec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_sec )); (&_mtime)->tv_nsec = (__uint32_t)(__builtin_constant_p (((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) ? (__uint32_t )(((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec ) & 0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t )(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec) & 0xff0000 ) >> 8 | ((__uint32_t)(((struct nfsv3_time *)(tl + 2))-> nfsv3_nsec) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time *)(tl + 2))->nfsv3_nsec)); } while (0); if (wccflag ) { ttretf = (((&((struct nfsnode *)(vp)->v_data)-> n_mtime)->tv_sec == (&_mtime)->tv_sec) ? ((&((struct nfsnode *)(vp)->v_data)->n_mtime)->tv_nsec != (& _mtime)->tv_nsec) : ((&((struct nfsnode *)(vp)->v_data )->n_mtime)->tv_sec != (&_mtime)->tv_sec)); } } { if (info.nmi_mrep != ((void *)0)) { struct vnode *ttvp = ((vp )); { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info .nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (4)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos , (4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep ); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; if (( (ttattrf) = ((int)(__uint32_t)(__builtin_constant_p((int32_t) (*tl)) ? (__uint32_t)(((__uint32_t)((int32_t)(*tl)) & 0xff ) << 24 | ((__uint32_t)((int32_t)(*tl)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(*tl)) & 0xff000000) >> 24 ) : __swap32md((int32_t)(*tl))))) != 0) { if ((t1 = nfs_loadattrcache (&ttvp, &info.nmi_md, &info.nmi_dpos, ((void *)0) )) != 0) { error = t1; (ttattrf) = 0; m_freem(info.nmi_mrep); goto nfsmout; } ((vp)) = ttvp; } } }; if (wccflag) { (wccflag ) = ttretf; } else { (wccflag) = ttattrf; } } } while (0); |
2757 | |
2758 | if (!error) { |
2759 | nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md ->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (8)) { (tl) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (8); } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos, (8), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; |
2760 | if (bcmp(nmp->nm_verf, tl, |
2761 | NFSX_V3WRITEVERF8)) { |
2762 | bcopy(tl, nmp->nm_verf, |
2763 | NFSX_V3WRITEVERF8); |
2764 | error = NFSERR_STALEWRITEVERF30001; |
2765 | } |
2766 | } |
2767 | m_freem(info.nmi_mrep); |
2768 | |
2769 | nfsmout: |
2770 | return (error); |
2771 | } |
2772 | |
2773 | /* |
2774 | * Kludge City.. |
2775 | * - make nfs_bmap() essentially a no-op that does no translation |
2776 | * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc |
2777 | * (Maybe I could use the process's page mapping, but I was concerned that |
2778 | * Kernel Write might not be enabled and also figured copyout() would do |
2779 | * a lot more work than bcopy() and also it currently happens in the |
2780 | * context of the swapper process (2). |
2781 | */ |
2782 | int |
2783 | nfs_bmap(void *v) |
2784 | { |
2785 | struct vop_bmap_args *ap = v; |
2786 | struct vnode *vp = ap->a_vp; |
2787 | |
2788 | if (ap->a_vpp != NULL((void *)0)) |
2789 | *ap->a_vpp = vp; |
2790 | if (ap->a_bnp != NULL((void *)0)) |
2791 | *ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize)((vp->v_mount->mnt_stat.f_iosize) >> 9); |
2792 | return (0); |
2793 | } |
2794 | |
2795 | /* |
2796 | * Strategy routine. |
2797 | * For async requests when nfsiod(s) are running, queue the request by |
2798 | * calling nfs_asyncio(), otherwise just all nfs_doio() to do the |
2799 | * request. |
2800 | */ |
2801 | int |
2802 | nfs_strategy(void *v) |
2803 | { |
2804 | struct vop_strategy_args *ap = v; |
2805 | struct buf *bp = ap->a_bp; |
2806 | struct proc *p; |
2807 | int error = 0; |
2808 | |
2809 | if ((bp->b_flags & (B_PHYS0x00002000|B_ASYNC0x00000004)) == (B_PHYS0x00002000|B_ASYNC0x00000004)) |
2810 | panic("nfs physio/async"); |
2811 | if (bp->b_flags & B_ASYNC0x00000004) |
2812 | p = NULL((void *)0); |
2813 | else |
2814 | p = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc; /* XXX */ |
2815 | /* |
2816 | * If the op is asynchronous and an i/o daemon is waiting |
2817 | * queue the request, wake it up and wait for completion |
2818 | * otherwise just do it ourselves. |
2819 | */ |
2820 | if ((bp->b_flags & B_ASYNC0x00000004) == 0 || nfs_asyncio(bp, 0)) |
2821 | error = nfs_doio(bp, p); |
2822 | return (error); |
2823 | } |
2824 | |
2825 | /* |
2826 | * fsync vnode op. Just call nfs_flush() with commit == 1. |
2827 | */ |
2828 | int |
2829 | nfs_fsync(void *v) |
2830 | { |
2831 | struct vop_fsync_args *ap = v; |
2832 | |
2833 | return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_p, 1)); |
2834 | } |
2835 | |
2836 | /* |
2837 | * Flush all the blocks associated with a vnode. |
2838 | * Walk through the buffer pool and push any dirty pages |
2839 | * associated with the vnode. |
2840 | */ |
2841 | int |
2842 | nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct proc *p, |
2843 | int commit) |
2844 | { |
2845 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
2846 | struct buf *bp; |
2847 | int i; |
2848 | struct buf *nbp; |
2849 | struct nfsmount *nmp = VFSTONFS(vp->v_mount)((struct nfsmount *)((vp->v_mount)->mnt_data)); |
2850 | uint64_t slptimeo = INFSLP0xffffffffffffffffULL; |
2851 | int s, error = 0, slpflag = 0, retv, bvecpos; |
2852 | int dirty, passone = 1; |
2853 | u_quad_t off = (u_quad_t)-1, endoff = 0, toff; |
2854 | #ifndef NFS_COMMITBVECSIZ20 |
2855 | #define NFS_COMMITBVECSIZ20 20 |
2856 | #endif |
2857 | struct buf *bvec[NFS_COMMITBVECSIZ20]; |
2858 | |
2859 | if (nmp->nm_flag & NFSMNT_INT0x00000040) |
2860 | slpflag = PCATCH0x100; |
2861 | if (!commit) |
2862 | passone = 0; |
2863 | /* |
2864 | * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the |
2865 | * server, but nas not been committed to stable storage on the server |
2866 | * yet. On the first pass, the byte range is worked out and the commit |
2867 | * rpc is done. On the second pass, nfs_writebp() is called to do the |
2868 | * job. |
2869 | */ |
2870 | again: |
2871 | bvecpos = 0; |
2872 | if (NFS_ISV3(vp)(((struct nfsmount *)(((vp)->v_mount)->mnt_data))->nm_flag & 0x00000200) && commit) { |
2873 | s = splbio()splraise(0x3); |
2874 | LIST_FOREACH_SAFE(bp, &vp->v_dirtyblkhd, b_vnbufs, nbp)for ((bp) = ((&vp->v_dirtyblkhd)->lh_first); (bp) && ((nbp) = ((bp)->b_vnbufs.le_next), 1); (bp) = (nbp)) { |
2875 | if (bvecpos >= NFS_COMMITBVECSIZ20) |
2876 | break; |
2877 | if ((bp->b_flags & (B_BUSY0x00000010 | B_DELWRI0x00000080 | B_NEEDCOMMIT0x00000002)) |
2878 | != (B_DELWRI0x00000080 | B_NEEDCOMMIT0x00000002)) |
2879 | continue; |
2880 | bremfreebufcache_take(bp); |
2881 | bp->b_flags |= B_WRITEINPROG0x00020000; |
2882 | buf_acquire(bp); |
2883 | |
2884 | /* |
2885 | * A list of these buffers is kept so that the |
2886 | * second loop knows which buffers have actually |
2887 | * been committed. This is necessary, since there |
2888 | * may be a race between the commit rpc and new |
2889 | * uncommitted writes on the file. |
2890 | */ |
2891 | bvec[bvecpos++] = bp; |
2892 | toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE(1 << 9) + |
2893 | bp->b_dirtyoff; |
2894 | if (toff < off) |
2895 | off = toff; |
2896 | toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff); |
2897 | if (toff > endoff) |
2898 | endoff = toff; |
2899 | } |
2900 | splx(s)spllower(s); |
2901 | } |
2902 | if (bvecpos > 0) { |
2903 | /* |
2904 | * Commit data on the server, as required. |
2905 | */ |
2906 | bcstats.pendingwrites++; |
2907 | bcstats.numwrites++; |
2908 | retv = nfs_commit(vp, off, (int)(endoff - off), p); |
2909 | if (retv == NFSERR_STALEWRITEVERF30001) |
2910 | nfs_clearcommit(vp->v_mount); |
2911 | /* |
2912 | * Now, either mark the blocks I/O done or mark the |
2913 | * blocks dirty, depending on whether the commit |
2914 | * succeeded. |
2915 | */ |
2916 | for (i = 0; i < bvecpos; i++) { |
2917 | bp = bvec[i]; |
2918 | bp->b_flags &= ~(B_NEEDCOMMIT0x00000002 | B_WRITEINPROG0x00020000); |
2919 | if (retv) { |
2920 | if (i == 0) |
2921 | bcstats.pendingwrites--; |
2922 | brelse(bp); |
2923 | } else { |
2924 | if (i > 0) |
2925 | bcstats.pendingwrites++; |
2926 | s = splbio()splraise(0x3); |
2927 | buf_undirty(bp); |
2928 | vp->v_numoutput++; |
2929 | bp->b_flags |= B_ASYNC0x00000004; |
2930 | bp->b_flags &= ~(B_READ0x00008000|B_DONE0x00000100|B_ERROR0x00000400); |
2931 | bp->b_dirtyoff = bp->b_dirtyend = 0; |
2932 | biodone(bp); |
2933 | splx(s)spllower(s); |
2934 | } |
2935 | } |
2936 | } |
2937 | |
2938 | /* |
2939 | * Start/do any write(s) that are required. |
2940 | */ |
2941 | loop: |
2942 | s = splbio()splraise(0x3); |
2943 | LIST_FOREACH_SAFE(bp, &vp->v_dirtyblkhd, b_vnbufs, nbp)for ((bp) = ((&vp->v_dirtyblkhd)->lh_first); (bp) && ((nbp) = ((bp)->b_vnbufs.le_next), 1); (bp) = (nbp)) { |
2944 | if (bp->b_flags & B_BUSY0x00000010) { |
2945 | if (waitfor != MNT_WAIT1 || passone) |
2946 | continue; |
2947 | bp->b_flags |= B_WANTED0x00010000; |
2948 | error = tsleep_nsec(bp, slpflag | (PRIBIO16 + 1), |
2949 | "nfsfsync", slptimeo); |
2950 | splx(s)spllower(s); |
2951 | if (error) { |
2952 | if (nfs_sigintr(nmp, NULL((void *)0), p)) |
2953 | return (EINTR4); |
2954 | if (slpflag == PCATCH0x100) { |
2955 | slpflag = 0; |
2956 | slptimeo = SEC_TO_NSEC(2); |
2957 | } |
2958 | } |
2959 | goto loop; |
2960 | } |
2961 | if ((bp->b_flags & B_DELWRI0x00000080) == 0) |
2962 | panic("nfs_fsync: not dirty"); |
2963 | if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT0x00000002)) |
2964 | continue; |
2965 | bremfreebufcache_take(bp); |
2966 | if (passone || !commit) { |
2967 | bp->b_flags |= B_ASYNC0x00000004; |
2968 | } else { |
2969 | bp->b_flags |= (B_ASYNC0x00000004|B_WRITEINPROG0x00020000|B_NEEDCOMMIT0x00000002); |
2970 | } |
2971 | buf_acquire(bp); |
2972 | splx(s)spllower(s); |
2973 | VOP_BWRITE(bp); |
2974 | goto loop; |
2975 | } |
2976 | splx(s)spllower(s); |
2977 | if (passone) { |
2978 | passone = 0; |
2979 | goto again; |
2980 | } |
2981 | if (waitfor == MNT_WAIT1) { |
2982 | loop2: |
2983 | s = splbio()splraise(0x3); |
2984 | error = vwaitforio(vp, slpflag, "nfs_fsync", slptimeo); |
2985 | if (error) { |
2986 | splx(s)spllower(s); |
2987 | if (nfs_sigintr(nmp, NULL((void *)0), p)) |
2988 | return (EINTR4); |
2989 | if (slpflag == PCATCH0x100) { |
2990 | slpflag = 0; |
2991 | slptimeo = SEC_TO_NSEC(2); |
2992 | } |
2993 | goto loop2; |
2994 | } |
2995 | dirty = (!LIST_EMPTY(&vp->v_dirtyblkhd)(((&vp->v_dirtyblkhd)->lh_first) == ((void *)0)) && commit); |
2996 | splx(s)spllower(s); |
2997 | if (dirty) { |
2998 | #if 0 |
2999 | vprint("nfs_fsync: dirty", vp); |
3000 | #endif |
3001 | goto loop; |
3002 | } |
3003 | } |
3004 | if (np->n_flag & NWRITEERR0x0008) { |
3005 | error = np->n_error; |
3006 | np->n_flag &= ~NWRITEERR0x0008; |
3007 | } |
3008 | return (error); |
3009 | } |
3010 | |
3011 | /* |
3012 | * Return POSIX pathconf information applicable to nfs. |
3013 | * Fake it. For v3 we could ask the server, but such code |
3014 | * hasn't been written yet. |
3015 | */ |
3016 | int |
3017 | nfs_pathconf(void *v) |
3018 | { |
3019 | struct vop_pathconf_args *ap = v; |
3020 | struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount)((struct nfsmount *)((ap->a_vp->v_mount)->mnt_data)); |
3021 | int error = 0; |
3022 | |
3023 | switch (ap->a_name) { |
3024 | case _PC_LINK_MAX1: |
3025 | *ap->a_retval = LINK_MAX32767; |
3026 | break; |
3027 | case _PC_NAME_MAX4: |
3028 | *ap->a_retval = NAME_MAX255; |
3029 | break; |
3030 | case _PC_CHOWN_RESTRICTED7: |
3031 | *ap->a_retval = 1; |
3032 | break; |
3033 | case _PC_NO_TRUNC8: |
3034 | *ap->a_retval = 1; |
3035 | break; |
3036 | case _PC_ALLOC_SIZE_MIN11: |
3037 | *ap->a_retval = NFS_FABLKSIZE512; |
3038 | break; |
3039 | case _PC_FILESIZEBITS13: |
3040 | *ap->a_retval = 64; |
3041 | break; |
3042 | case _PC_REC_INCR_XFER_SIZE15: |
3043 | *ap->a_retval = min(nmp->nm_rsize, nmp->nm_wsize); |
3044 | break; |
3045 | case _PC_REC_MAX_XFER_SIZE16: |
3046 | *ap->a_retval = -1; /* means ``unlimited'' */ |
3047 | break; |
3048 | case _PC_REC_MIN_XFER_SIZE17: |
3049 | *ap->a_retval = min(nmp->nm_rsize, nmp->nm_wsize); |
3050 | break; |
3051 | case _PC_REC_XFER_ALIGN18: |
3052 | *ap->a_retval = PAGE_SIZE(1 << 12); |
3053 | break; |
3054 | case _PC_SYMLINK_MAX19: |
3055 | *ap->a_retval = MAXPATHLEN1024; |
3056 | break; |
3057 | case _PC_2_SYMLINKS10: |
3058 | *ap->a_retval = 1; |
3059 | break; |
3060 | case _PC_TIMESTAMP_RESOLUTION21: |
3061 | *ap->a_retval = NFS_ISV3(ap->a_vp)(((struct nfsmount *)(((ap->a_vp)->v_mount)->mnt_data ))->nm_flag & 0x00000200) ? 1 : 1000; |
3062 | break; |
3063 | default: |
3064 | error = EINVAL22; |
3065 | break; |
3066 | } |
3067 | |
3068 | return (error); |
3069 | } |
3070 | |
3071 | /* |
3072 | * NFS advisory byte-level locks. |
3073 | */ |
3074 | int |
3075 | nfs_advlock(void *v) |
3076 | { |
3077 | struct vop_advlock_args *ap = v; |
3078 | struct nfsnode *np = VTONFS(ap->a_vp)((struct nfsnode *)(ap->a_vp)->v_data); |
3079 | |
3080 | return (lf_advlock(&np->n_lockf, np->n_size, ap->a_id, ap->a_op, |
3081 | ap->a_fl, ap->a_flags)); |
3082 | } |
3083 | |
3084 | /* |
3085 | * Print out the contents of an nfsnode. |
3086 | */ |
3087 | int |
3088 | nfs_print(void *v) |
3089 | { |
3090 | struct vop_print_args *ap = v; |
3091 | struct vnode *vp = ap->a_vp; |
3092 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
3093 | |
3094 | printf("tag VT_NFS, fileid %lld fsid 0x%lx", |
3095 | np->n_vattr.va_fileid, np->n_vattr.va_fsid); |
3096 | #ifdef FIFO1 |
3097 | if (vp->v_type == VFIFO) |
3098 | fifo_printinfo(vp); |
3099 | #endif |
3100 | printf("\n"); |
3101 | return (0); |
3102 | } |
3103 | |
3104 | /* |
3105 | * Just call nfs_writebp() with the force argument set to 1. |
3106 | */ |
3107 | int |
3108 | nfs_bwrite(void *v) |
3109 | { |
3110 | struct vop_bwrite_args *ap = v; |
3111 | |
3112 | return (nfs_writebp(ap->a_bp, 1)); |
3113 | } |
3114 | |
3115 | /* |
3116 | * This is a clone of vop_generic_bwrite(), except that B_WRITEINPROG isn't set unless |
3117 | * the force flag is one and it also handles the B_NEEDCOMMIT flag. |
3118 | */ |
3119 | int |
3120 | nfs_writebp(struct buf *bp, int force) |
3121 | { |
3122 | int oldflags = bp->b_flags, retv = 1; |
3123 | struct proc *p = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc; /* XXX */ |
3124 | off_t off; |
3125 | size_t cnt; |
3126 | int s; |
3127 | struct vnode *vp; |
3128 | struct nfsnode *np; |
3129 | |
3130 | if(!(bp->b_flags & B_BUSY0x00000010)) |
3131 | panic("bwrite: buffer is not busy???"); |
3132 | |
3133 | vp = bp->b_vp; |
3134 | np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
3135 | |
3136 | bp->b_flags &= ~(B_READ0x00008000|B_DONE0x00000100|B_ERROR0x00000400); |
3137 | |
3138 | s = splbio()splraise(0x3); |
3139 | buf_undirty(bp); |
3140 | |
3141 | if ((oldflags & B_ASYNC0x00000004) && !(oldflags & B_DELWRI0x00000080) && p) |
3142 | ++p->p_ru.ru_oublock; |
3143 | |
3144 | bp->b_vp->v_numoutput++; |
3145 | splx(s)spllower(s); |
3146 | |
3147 | /* |
3148 | * If B_NEEDCOMMIT is set, a commit rpc may do the trick. If not |
3149 | * an actual write will have to be scheduled via. VOP_STRATEGY(). |
3150 | * If B_WRITEINPROG is already set, then push it with a write anyhow. |
3151 | */ |
3152 | if ((oldflags & (B_NEEDCOMMIT0x00000002 | B_WRITEINPROG0x00020000)) == B_NEEDCOMMIT0x00000002) { |
3153 | off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE(1 << 9) + bp->b_dirtyoff; |
3154 | cnt = bp->b_dirtyend - bp->b_dirtyoff; |
3155 | |
3156 | rw_enter_write(&np->n_commitlock); |
3157 | if (!(bp->b_flags & B_NEEDCOMMIT0x00000002)) { |
3158 | rw_exit_write(&np->n_commitlock); |
3159 | return (0); |
3160 | } |
3161 | |
3162 | /* |
3163 | * If it's already been committed by somebody else, |
3164 | * bail. |
3165 | */ |
3166 | if (!nfs_in_committed_range(vp, bp)) { |
3167 | int pushedrange = 0; |
3168 | /* |
3169 | * Since we're going to do this, push as much |
3170 | * as we can. |
3171 | */ |
3172 | |
3173 | if (nfs_in_tobecommitted_range(vp, bp)) { |
3174 | pushedrange = 1; |
3175 | off = np->n_pushlo; |
3176 | cnt = np->n_pushhi - np->n_pushlo; |
3177 | } |
3178 | |
3179 | bp->b_flags |= B_WRITEINPROG0x00020000; |
3180 | bcstats.pendingwrites++; |
3181 | bcstats.numwrites++; |
3182 | retv = nfs_commit(bp->b_vp, off, cnt, curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc); |
3183 | bp->b_flags &= ~B_WRITEINPROG0x00020000; |
3184 | |
3185 | if (retv == 0) { |
3186 | if (pushedrange) |
3187 | nfs_merge_commit_ranges(vp); |
3188 | else |
3189 | nfs_add_committed_range(vp, bp); |
3190 | } else |
3191 | bcstats.pendingwrites--; |
3192 | } else |
3193 | retv = 0; /* It has already been committed. */ |
3194 | |
3195 | rw_exit_write(&np->n_commitlock); |
3196 | if (!retv) { |
3197 | bp->b_dirtyoff = bp->b_dirtyend = 0; |
3198 | bp->b_flags &= ~B_NEEDCOMMIT0x00000002; |
3199 | s = splbio()splraise(0x3); |
3200 | biodone(bp); |
3201 | splx(s)spllower(s); |
3202 | } else if (retv == NFSERR_STALEWRITEVERF30001) |
3203 | nfs_clearcommit(bp->b_vp->v_mount); |
3204 | } |
3205 | if (retv) { |
3206 | s = splbio()splraise(0x3); |
3207 | buf_flip_dma(bp); |
3208 | if (force) |
3209 | bp->b_flags |= B_WRITEINPROG0x00020000; |
3210 | splx(s)spllower(s); |
3211 | VOP_STRATEGY(bp->b_vp, bp); |
3212 | } |
3213 | |
3214 | if( (oldflags & B_ASYNC0x00000004) == 0) { |
3215 | int rtval; |
3216 | |
3217 | bp->b_flags |= B_RAW0x00004000; |
3218 | rtval = biowait(bp); |
3219 | if (!(oldflags & B_DELWRI0x00000080) && p) { |
3220 | ++p->p_ru.ru_oublock; |
3221 | } |
3222 | brelse(bp); |
3223 | return (rtval); |
3224 | } |
3225 | |
3226 | return (0); |
3227 | } |
3228 | |
3229 | /* |
3230 | * nfs special file access vnode op. |
3231 | * Essentially just get vattr and then imitate iaccess() since the device is |
3232 | * local to the client. |
3233 | */ |
3234 | int |
3235 | nfsspec_access(void *v) |
3236 | { |
3237 | struct vop_access_args *ap = v; |
3238 | struct vattr va; |
3239 | struct vnode *vp = ap->a_vp; |
3240 | int error; |
3241 | |
3242 | /* |
3243 | * Disallow write attempts on filesystems mounted read-only; |
3244 | * unless the file is a socket, fifo, or a block or character |
3245 | * device resident on the filesystem. |
3246 | */ |
3247 | if ((ap->a_mode & VWRITE00200) && (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001)) { |
3248 | switch (vp->v_type) { |
3249 | case VREG: |
3250 | case VDIR: |
3251 | case VLNK: |
3252 | return (EROFS30); |
3253 | default: |
3254 | break; |
3255 | } |
3256 | } |
3257 | |
3258 | error = VOP_GETATTR(vp, &va, ap->a_cred, ap->a_p); |
3259 | if (error) |
3260 | return (error); |
3261 | |
3262 | return (vaccess(vp->v_type, va.va_mode, va.va_uid, va.va_gid, |
3263 | ap->a_mode, ap->a_cred)); |
3264 | } |
3265 | |
3266 | /* |
3267 | * Read wrapper for special devices. |
3268 | */ |
3269 | int |
3270 | nfsspec_read(void *v) |
3271 | { |
3272 | struct vop_read_args *ap = v; |
3273 | struct nfsnode *np = VTONFS(ap->a_vp)((struct nfsnode *)(ap->a_vp)->v_data); |
3274 | |
3275 | /* |
3276 | * Set access flag. |
3277 | */ |
3278 | np->n_flag |= NACC0x0100; |
3279 | getnanotime(&np->n_atimn_un1.nf_atim); |
3280 | return (spec_read(ap)); |
3281 | } |
3282 | |
3283 | /* |
3284 | * Write wrapper for special devices. |
3285 | */ |
3286 | int |
3287 | nfsspec_write(void *v) |
3288 | { |
3289 | struct vop_write_args *ap = v; |
3290 | struct nfsnode *np = VTONFS(ap->a_vp)((struct nfsnode *)(ap->a_vp)->v_data); |
3291 | |
3292 | /* |
3293 | * Set update flag. |
3294 | */ |
3295 | np->n_flag |= NUPD0x0200; |
3296 | getnanotime(&np->n_mtimn_un2.nf_mtim); |
3297 | return (spec_write(ap)); |
3298 | } |
3299 | |
3300 | /* |
3301 | * Close wrapper for special devices. |
3302 | * |
3303 | * Update the times on the nfsnode then do device close. |
3304 | */ |
3305 | int |
3306 | nfsspec_close(void *v) |
3307 | { |
3308 | struct vop_close_args *ap = v; |
3309 | struct vnode *vp = ap->a_vp; |
3310 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
3311 | struct vattr vattr; |
3312 | |
3313 | if (np->n_flag & (NACC0x0100 | NUPD0x0200)) { |
3314 | np->n_flag |= NCHG0x0400; |
3315 | if (vp->v_usecount == 1 && |
3316 | (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001) == 0) { |
3317 | VATTR_NULL(&vattr)vattr_null(&vattr); |
3318 | if (np->n_flag & NACC0x0100) |
3319 | vattr.va_atime = np->n_atimn_un1.nf_atim; |
3320 | if (np->n_flag & NUPD0x0200) |
3321 | vattr.va_mtime = np->n_mtimn_un2.nf_mtim; |
3322 | (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); |
3323 | } |
3324 | } |
3325 | return (spec_close(ap)); |
3326 | } |
3327 | |
3328 | #ifdef FIFO1 |
3329 | /* |
3330 | * Read wrapper for fifos. |
3331 | */ |
3332 | int |
3333 | nfsfifo_read(void *v) |
3334 | { |
3335 | struct vop_read_args *ap = v; |
3336 | struct nfsnode *np = VTONFS(ap->a_vp)((struct nfsnode *)(ap->a_vp)->v_data); |
3337 | |
3338 | /* |
3339 | * Set access flag. |
3340 | */ |
3341 | np->n_flag |= NACC0x0100; |
3342 | getnanotime(&np->n_atimn_un1.nf_atim); |
3343 | return (fifo_read(ap)); |
3344 | } |
3345 | |
3346 | /* |
3347 | * Write wrapper for fifos. |
3348 | */ |
3349 | int |
3350 | nfsfifo_write(void *v) |
3351 | { |
3352 | struct vop_write_args *ap = v; |
3353 | struct nfsnode *np = VTONFS(ap->a_vp)((struct nfsnode *)(ap->a_vp)->v_data); |
3354 | |
3355 | /* |
3356 | * Set update flag. |
3357 | */ |
3358 | np->n_flag |= NUPD0x0200; |
3359 | getnanotime(&np->n_mtimn_un2.nf_mtim); |
3360 | return (fifo_write(ap)); |
3361 | } |
3362 | |
3363 | /* |
3364 | * Close wrapper for fifos. |
3365 | * |
3366 | * Update the times on the nfsnode then do fifo close. |
3367 | */ |
3368 | int |
3369 | nfsfifo_close(void *v) |
3370 | { |
3371 | struct vop_close_args *ap = v; |
3372 | struct vnode *vp = ap->a_vp; |
3373 | struct nfsnode *np = VTONFS(vp)((struct nfsnode *)(vp)->v_data); |
3374 | struct vattr vattr; |
3375 | |
3376 | if (np->n_flag & (NACC0x0100 | NUPD0x0200)) { |
3377 | if (np->n_flag & NACC0x0100) { |
3378 | getnanotime(&np->n_atimn_un1.nf_atim); |
3379 | } |
3380 | if (np->n_flag & NUPD0x0200) { |
3381 | getnanotime(&np->n_mtimn_un2.nf_mtim); |
3382 | } |
3383 | np->n_flag |= NCHG0x0400; |
3384 | if (vp->v_usecount == 1 && |
3385 | (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001) == 0) { |
3386 | VATTR_NULL(&vattr)vattr_null(&vattr); |
3387 | if (np->n_flag & NACC0x0100) |
3388 | vattr.va_atime = np->n_atimn_un1.nf_atim; |
3389 | if (np->n_flag & NUPD0x0200) |
3390 | vattr.va_mtime = np->n_mtimn_un2.nf_mtim; |
3391 | (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); |
3392 | } |
3393 | } |
3394 | return (fifo_close(ap)); |
3395 | } |
3396 | |
3397 | int |
3398 | nfsfifo_reclaim(void *v) |
3399 | { |
3400 | fifo_reclaim(v); |
3401 | return (nfs_reclaim(v)); |
3402 | } |
3403 | #endif /* ! FIFO */ |