Bug Summary

File:nfs/nfs_vnops.c
Warning:line 1740, column 3
Assigned value is garbage or undefined

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nfs_vnops.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/nfs/nfs_vnops.c
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
79int nfs_access(void *);
80int nfs_advlock(void *);
81int nfs_bmap(void *);
82int nfs_bwrite(void *);
83int nfs_close(void *);
84int nfs_commit(struct vnode *, u_quad_t, int, struct proc *);
85int nfs_create(void *);
86int nfs_flush(struct vnode *, struct ucred *, int, struct proc *, int);
87int nfs_fsync(void *);
88int nfs_getattr(void *);
89int nfs_getreq(struct nfsrv_descript *, struct nfsd *, int);
90int nfs_islocked(void *);
91int nfs_link(void *);
92int nfs_lock(void *);
93int nfs_lookitup(struct vnode *, char *, int, struct ucred *, struct proc *,
94 struct nfsnode **);
95int nfs_lookup(void *);
96int nfs_mkdir(void *);
97int nfs_mknod(void *);
98int nfs_mknodrpc(struct vnode *, struct vnode **, struct componentname *,
99 struct vattr *);
100int nfs_null(struct vnode *, struct ucred *, struct proc *);
101int nfs_open(void *);
102int nfs_pathconf(void *);
103int nfs_print(void *);
104int nfs_read(void *);
105int nfs_readdir(void *);
106int nfs_readdirplusrpc(struct vnode *, struct uio *, struct ucred *, int *,
107 struct proc *);
108int nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *, int *);
109int nfs_remove(void *);
110int nfs_removerpc(struct vnode *, char *, int, struct ucred *, struct proc *);
111int nfs_rename(void *);
112int nfs_renameit(struct vnode *, struct componentname *, struct sillyrename *);
113int nfs_renamerpc(struct vnode *, char *, int, struct vnode *, char *, int,
114 struct ucred *, struct proc *);
115int nfs_rmdir(void *);
116int nfs_setattr(void *);
117int nfs_setattrrpc(struct vnode *, struct vattr *, struct ucred *,
118 struct proc *);
119int nfs_sillyrename(struct vnode *, struct vnode *,
120 struct componentname *);
121int nfs_strategy(void *);
122int nfs_symlink(void *);
123int nfs_unlock(void *);
124
125void nfs_cache_enter(struct vnode *, struct vnode *, struct componentname *);
126
127int nfsfifo_close(void *);
128int nfsfifo_read(void *);
129int nfsfifo_reclaim(void *);
130int nfsfifo_write(void *);
131
132int nfsspec_access(void *);
133int nfsspec_close(void *);
134int nfsspec_read(void *);
135int nfsspec_write(void *);
136
137/* Global vfs data structures for nfs. */
138const 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. */
176const 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
216const 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 */
259extern u_int32_t nfs_true, nfs_false;
260extern u_int32_t nfs_xdrneg1;
261extern struct nfsstats nfsstats;
262extern nfstype nfsv3_type[9];
263int nfs_numasync = 0;
264
265void
266nfs_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 */
285int
286nfs_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 */
303int
304nfs_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 }
427nfsmout:
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 */
438int
439nfs_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 */
532int
533nfs_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 */
560int
561nfs_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);
592nfsmout:
593 return (error);
594}
595
596/*
597 * nfs setattr call.
598 */
599int
600nfs_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 */
684int
685nfs_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);
735nfsmout:
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 */
744int
745nfs_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 }
850dorpc:
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
973nfsmout:
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 */
1009int
1010nfs_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 */
1023int
1024nfs_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 */
1037int
1038nfs_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 */
1049int
1050nfs_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 */
1062int
1063nfs_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 */
1074int
1075nfs_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
1102nfsmout:
1103 return (error);
1104}
1105
1106/*
1107 * nfs read rpc call
1108 * Ditto above
1109 */
1110int
1111nfs_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
1172nfsmout:
1173 return (error);
1174}
1175
1176/*
1177 * nfs write call
1178 */
1179int
1180nfs_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 }
1288nfsmout:
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 */
1300int
1301nfs_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
1367nfsmout:
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 */
1387int
1388nfs_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
1403int
1404nfs_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
1431again:
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
1475nfsmout:
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 */
1517int
1518nfs_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 */
1581int
1582nfs_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 */
1601int
1602nfs_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
1626nfsmout:
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 */
1636int
1637nfs_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 }
1683out:
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 */
1703int
1704nfs_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 */
1714int
1715nfs_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) +
1
Assuming field 'nmi_v3' is 0
2
'?' condition is false
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))
;
3
Assuming 'fnamelen' is <= 255
4
Taking false branch
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))
;
5
Assuming 'tnamelen' is <= 255
6
Taking false branch
1734
1735 info.nmi_procp = proc;
1736 info.nmi_cred = cred;
1737 error = nfs_request(fdvp, NFSPROC_RENAME14, &info);
1738 if (info.nmi_v3) {
7
Assuming field 'nmi_v3' is not equal to 0
8
Taking true branch
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)
;
9
Assuming field 'nmi_mrep' is not equal to null
10
Taking true branch
11
Assuming 't1' is >= 4
12
Taking true branch
13
Assuming the condition is false
14
Taking false branch
15
Taking true branch
16
Assuming 't1' is >= 4
17
Taking true branch
18
'?' condition is false
19
Assuming the condition is false
20
Taking false branch
21
Taking false branch
22
Loop condition is false. Exiting loop
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)
;
23
Taking true branch
24
'ttattrf' declared without an initial value
25
Assuming 't1' is < 4
26
Taking false branch
27
Assuming the condition is false
28
Taking false branch
29
Assuming the condition is false
30
Taking false branch
31
Assuming field 'nmi_mrep' is equal to null
32
Taking false branch
33
Taking false branch
34
Assigned value is garbage or undefined
1741 }
1742 m_freem(info.nmi_mrep);
1743
1744nfsmout:
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 */
1757int
1758nfs_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);
1806nfsmout:
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 */
1824int
1825nfs_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
1871nfsmout:
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 */
1886int
1887nfs_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
1934nfsmout:
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 */
1965int
1966nfs_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
1993nfsmout:
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
2026struct 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 */
2037int
2038nfs_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 */
2157int
2158nfs_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
2344nfsmout:
2345 return (error);
2346}
2347
2348/*
2349 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
2350 */
2351int
2352nfs_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
2575nfsmout:
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 */
2593int
2594nfs_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,
2635 cnp->cn_proc, &np);
2636 np->n_sillyrename = sp;
2637 return (0);
2638bad:
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 */
2653int
2654nfs_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);
2716nfsmout:
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 */
2732int
2733nfs_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
2769nfsmout:
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 */
2782int
2783nfs_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 */
2801int
2802nfs_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 */
2828int
2829nfs_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 */
2841int
2842nfs_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 */
2870again:
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 */
2941loop:
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 */
3016int
3017nfs_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 */
3074int
3075nfs_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 */
3087int
3088nfs_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 */
3107int
3108nfs_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 */
3119int
3120nfs_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 */
3234int
3235nfsspec_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 */
3269int
3270nfsspec_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 */
3286int
3287nfsspec_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 */
3305int
3306nfsspec_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 */
3332int
3333nfsfifo_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 */
3349int
3350nfsfifo_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 */
3368int
3369nfsfifo_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
3397int
3398nfsfifo_reclaim(void *v)
3399{
3400 fifo_reclaim(v);
3401 return (nfs_reclaim(v));
3402}
3403#endif /* ! FIFO */