Bug Summary

File:nfs/nfs_serv.c
Warning:line 1534, column 6
Branch condition evaluates to a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name nfs_serv.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -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 -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/lib/clang/13.0.0 -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/swsmu -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/powerplay -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/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 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 -D CONFIG_DRM_AMD_DC_DCN3_0 -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 -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 /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/nfs/nfs_serv.c
1/* $OpenBSD: nfs_serv.c,v 1.120 2021/03/11 13:31:35 jsg Exp $ */
2/* $NetBSD: nfs_serv.c,v 1.34 1997/05/12 23:37:12 fvdl 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_serv.c 8.7 (Berkeley) 5/14/95
36 */
37
38/*
39 * nfs version 2 and 3 server calls to vnode ops
40 * - these routines generally have 3 phases
41 * 1 - break down and validate rpc request in mbuf list
42 * 2 - do the vnode ops for the request
43 * (surprisingly ?? many are very similar to syscalls in vfs_syscalls.c)
44 * 3 - build the rpc reply in an mbuf list
45 * nb:
46 * - do not mix the phases, since the nfsm_?? macros can return failures
47 * on a bad rpc or similar and do not do any vrele() or vput()'s
48 *
49 * - the nfsm_reply() macro generates an nfs rpc reply with the nfs
50 * error number iff error != 0 whereas
51 * returning an error from the server function implies a fatal error
52 * such as a badly constructed rpc request that should be dropped without
53 * a reply.
54 * For Version 3, nfsm_reply() does not return for the error case, since
55 * most version 3 rpcs return more than the status for error cases.
56 */
57
58#include <sys/param.h>
59#include <sys/systm.h>
60#include <sys/proc.h>
61#include <sys/namei.h>
62#include <sys/vnode.h>
63#include <sys/lock.h>
64#include <sys/mount.h>
65#include <sys/socket.h>
66#include <sys/socketvar.h>
67#include <sys/mbuf.h>
68#include <sys/dirent.h>
69#include <sys/stat.h>
70#include <sys/kernel.h>
71#include <sys/pool.h>
72#include <sys/queue.h>
73#include <sys/unistd.h>
74
75#include <ufs/ufs/dir.h>
76
77#include <nfs/nfsproto.h>
78#include <nfs/nfs.h>
79#include <nfs/xdr_subs.h>
80#include <nfs/nfsm_subs.h>
81#include <nfs/nfs_var.h>
82
83/* Global vars */
84extern u_int32_t nfs_xdrneg1;
85extern u_int32_t nfs_false, nfs_true;
86extern enum vtype nv3tov_type[8];
87extern struct nfsstats nfsstats;
88extern nfstype nfsv2_type[9];
89extern nfstype nfsv3_type[9];
90
91int nfsrv_access(struct vnode *, int, struct ucred *, int, struct proc *, int);
92
93/*
94 * nfs v3 access service
95 */
96int
97nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
98 struct proc *procp, struct mbuf **mrq)
99{
100 struct mbuf *nam = nfsd->nd_nam;
101 struct nfsm_info info;
102 struct ucred *cred = &nfsd->nd_cr;
103 struct vnode *vp;
104 nfsfh_t nfh;
105 fhandle_t *fhp;
106 u_int32_t *tl;
107 int32_t t1;
108 int error = 0, rdonly, getret;
109 char *cp2;
110 struct vattr va;
111 u_long testmode, nfsmode;
112
113 info.nmi_mreq = NULL((void *)0);
114 info.nmi_mrep = nfsd->nd_mrep;
115 info.nmi_md = nfsd->nd_md;
116 info.nmi_dpos = nfsd->nd_dpos;
117
118 fhp = &nfh.fh_generic;
119 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
120 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; } }
;
121 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
122 if (error) {
123 nfsm_reply(NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((4)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
124 nfsm_srvpostop_attr(nfsd, 1, NULL((void *)0), &info);
125 error = 0;
126 goto nfsmout;
127 }
128 nfsmode = 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))))
;
129 if ((nfsmode & NFSV3ACCESS_READ0x01) &&
130 nfsrv_access(vp, VREAD00400, cred, rdonly, procp, 0))
131 nfsmode &= ~NFSV3ACCESS_READ0x01;
132 if (vp->v_type == VDIR)
133 testmode = (NFSV3ACCESS_MODIFY0x04 | NFSV3ACCESS_EXTEND0x08 |
134 NFSV3ACCESS_DELETE0x10);
135 else
136 testmode = (NFSV3ACCESS_MODIFY0x04 | NFSV3ACCESS_EXTEND0x08);
137 if ((nfsmode & testmode) &&
138 nfsrv_access(vp, VWRITE00200, cred, rdonly, procp, 0))
139 nfsmode &= ~testmode;
140 if (vp->v_type == VDIR)
141 testmode = NFSV3ACCESS_LOOKUP0x02;
142 else
143 testmode = NFSV3ACCESS_EXECUTE0x20;
144 if ((nfsmode & testmode) &&
145 nfsrv_access(vp, VEXEC00100, cred, rdonly, procp, 0))
146 nfsmode &= ~testmode;
147 getret = VOP_GETATTR(vp, &va, cred, procp);
148 vput(vp);
149 nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
1) ? (84 + 4) : 0) + 4), nfsd, slp, error, &info.nmi_mreq
, &info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem
(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
150 nfsm_srvpostop_attr(nfsd, getret, &va, &info);
151 tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4);
152 *tl = txdr_unsigned(nfsmode)((__uint32_t)(__builtin_constant_p((int32_t)(nfsmode)) ? (__uint32_t
)(((__uint32_t)((int32_t)(nfsmode)) & 0xff) << 24 |
((__uint32_t)((int32_t)(nfsmode)) & 0xff00) << 8 |
((__uint32_t)((int32_t)(nfsmode)) & 0xff0000) >> 8
| ((__uint32_t)((int32_t)(nfsmode)) & 0xff000000) >>
24) : __swap32md((int32_t)(nfsmode))))
;
153nfsmout:
154 return(error);
155}
156
157/*
158 * nfs getattr service
159 */
160int
161nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
162 struct proc *procp, struct mbuf **mrq)
163{
164 struct mbuf *nam = nfsd->nd_nam;
165 struct nfsm_info info;
166 struct ucred *cred = &nfsd->nd_cr;
167 struct nfs_fattr *fp;
168 struct vattr va;
169 struct vnode *vp;
170 nfsfh_t nfh;
171 fhandle_t *fhp;
172 u_int32_t *tl;
173 int32_t t1;
174 int error = 0, rdonly;
175 char *cp2;
176
177 info.nmi_mreq = NULL((void *)0);
178 info.nmi_mrep = nfsd->nd_mrep;
179 info.nmi_md = nfsd->nd_md;
180 info.nmi_dpos = nfsd->nd_dpos;
181 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
182
183 fhp = &nfh.fh_generic;
184 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
185 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
186 if (error) {
187 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
188 error = 0;
189 goto nfsmout;
190 }
191 error = VOP_GETATTR(vp, &va, cred, procp);
192 vput(vp);
193 nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
nfsd->nd_flag & 0x08) ? 84 : 68)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
194 if (error) {
195 error = 0;
196 goto nfsmout;
197 }
198 fp = nfsm_build(&info.nmi_mb, NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)((nfsd->nd_flag & 0x08) ? 84 : 68));
199 nfsm_srvfattr(nfsd, &va, fp);
200nfsmout:
201 return(error);
202}
203
204/*
205 * nfs setattr service
206 */
207int
208nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
209 struct proc *procp, struct mbuf **mrq)
210{
211 struct mbuf *nam = nfsd->nd_nam;
212 struct nfsm_info info;
213 struct ucred *cred = &nfsd->nd_cr;
214 struct vattr va, preat;
215 struct nfsv2_sattr *sp;
216 struct nfs_fattr *fp;
217 struct vnode *vp;
218 nfsfh_t nfh;
219 fhandle_t *fhp;
220 u_int32_t *tl;
221 int32_t t1;
222 int error = 0, rdonly, preat_ret = 1, postat_ret = 1;
223 int gcheck = 0;
224 char *cp2;
225 struct timespec guard;
226
227 info.nmi_mreq = NULL((void *)0);
228 info.nmi_mrep = nfsd->nd_mrep;
229 info.nmi_md = nfsd->nd_md;
230 info.nmi_dpos = nfsd->nd_dpos;
231 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
232
233 fhp = &nfh.fh_generic;
234 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
235 VATTR_NULL(&va)vattr_null(&va);
236 if (info.nmi_v3) {
237 va.va_vaflags |= VA_UTIMES_NULL0x01;
238 error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep, &info.nmi_dpos);
239 if (error)
240 goto nfsmout;
241 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; } }
;
242 gcheck = 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))))
;
243 if (gcheck) {
244 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; } }
;
245 fxdr_nfsv3time(tl, &guard)do { (&guard)->tv_sec = (__uint32_t)(__builtin_constant_p
(((struct nfsv3_time *)(tl))->nfsv3_sec) ? (__uint32_t)(((
__uint32_t)(((struct nfsv3_time *)(tl))->nfsv3_sec) & 0xff
) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl))->
nfsv3_sec) & 0xff00) << 8 | ((__uint32_t)(((struct nfsv3_time
*)(tl))->nfsv3_sec) & 0xff0000) >> 8 | ((__uint32_t
)(((struct nfsv3_time *)(tl))->nfsv3_sec) & 0xff000000
) >> 24) : __swap32md(((struct nfsv3_time *)(tl))->nfsv3_sec
)); (&guard)->tv_nsec = (__uint32_t)(__builtin_constant_p
(((struct nfsv3_time *)(tl))->nfsv3_nsec) ? (__uint32_t)((
(__uint32_t)(((struct nfsv3_time *)(tl))->nfsv3_nsec) &
0xff) << 24 | ((__uint32_t)(((struct nfsv3_time *)(tl)
)->nfsv3_nsec) & 0xff00) << 8 | ((__uint32_t)(((
struct nfsv3_time *)(tl))->nfsv3_nsec) & 0xff0000) >>
8 | ((__uint32_t)(((struct nfsv3_time *)(tl))->nfsv3_nsec
) & 0xff000000) >> 24) : __swap32md(((struct nfsv3_time
*)(tl))->nfsv3_nsec)); } while (0)
;
246 }
247 } else {
248 nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md
->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32)) { (sp) =
(struct nfsv2_sattr *)(info.nmi_dpos); info.nmi_dpos += (32)
; } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos
, (32), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep
); goto nfsmout; } else { (sp) = (struct nfsv2_sattr *)cp2; }
}
;
249 /*
250 * Nah nah nah nah na nah
251 * There is a bug in the Sun client that puts 0xffff in the mode
252 * field of sattr when it should put in 0xffffffff. The u_short
253 * doesn't sign extend.
254 * --> check the low order 2 bytes for 0xffff
255 */
256 if ((fxdr_unsigned(int, sp->sa_mode)((int)(__uint32_t)(__builtin_constant_p((int32_t)(sp->sa_mode
)) ? (__uint32_t)(((__uint32_t)((int32_t)(sp->sa_mode)) &
0xff) << 24 | ((__uint32_t)((int32_t)(sp->sa_mode))
& 0xff00) << 8 | ((__uint32_t)((int32_t)(sp->sa_mode
)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(sp->
sa_mode)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sp->sa_mode))))
& 0xffff) != 0xffff)
257 va.va_mode = nfstov_mode(sp->sa_mode)(((u_int16_t)(__uint32_t)(__builtin_constant_p((int32_t)((sp->
sa_mode))) ? (__uint32_t)(((__uint32_t)((int32_t)((sp->sa_mode
))) & 0xff) << 24 | ((__uint32_t)((int32_t)((sp->
sa_mode))) & 0xff00) << 8 | ((__uint32_t)((int32_t)
((sp->sa_mode))) & 0xff0000) >> 8 | ((__uint32_t
)((int32_t)((sp->sa_mode))) & 0xff000000) >> 24)
: __swap32md((int32_t)((sp->sa_mode)))))&07777)
;
258 if (sp->sa_uid != nfs_xdrneg1)
259 va.va_uid = fxdr_unsigned(uid_t, sp->sa_uid)((uid_t)(__uint32_t)(__builtin_constant_p((int32_t)(sp->sa_uid
)) ? (__uint32_t)(((__uint32_t)((int32_t)(sp->sa_uid)) &
0xff) << 24 | ((__uint32_t)((int32_t)(sp->sa_uid)) &
0xff00) << 8 | ((__uint32_t)((int32_t)(sp->sa_uid))
& 0xff0000) >> 8 | ((__uint32_t)((int32_t)(sp->
sa_uid)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sp->sa_uid))))
;
260 if (sp->sa_gid != nfs_xdrneg1)
261 va.va_gid = fxdr_unsigned(gid_t, sp->sa_gid)((gid_t)(__uint32_t)(__builtin_constant_p((int32_t)(sp->sa_gid
)) ? (__uint32_t)(((__uint32_t)((int32_t)(sp->sa_gid)) &
0xff) << 24 | ((__uint32_t)((int32_t)(sp->sa_gid)) &
0xff00) << 8 | ((__uint32_t)((int32_t)(sp->sa_gid))
& 0xff0000) >> 8 | ((__uint32_t)((int32_t)(sp->
sa_gid)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sp->sa_gid))))
;
262 if (sp->sa_size != nfs_xdrneg1)
263 va.va_size = fxdr_unsigned(u_quad_t, sp->sa_size)((u_quad_t)(__uint32_t)(__builtin_constant_p((int32_t)(sp->
sa_size)) ? (__uint32_t)(((__uint32_t)((int32_t)(sp->sa_size
)) & 0xff) << 24 | ((__uint32_t)((int32_t)(sp->sa_size
)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(sp->
sa_size)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t
)(sp->sa_size)) & 0xff000000) >> 24) : __swap32md
((int32_t)(sp->sa_size))))
;
264 if (sp->sa_atime.nfsv2_sec != nfs_xdrneg1) {
265#ifdef notyet
266 fxdr_nfsv2time(&sp->sa_atime, &va.va_atime)do { (&va.va_atime)->tv_sec = (__uint32_t)(__builtin_constant_p
(((struct nfsv2_time *)(&sp->sa_atime))->nfsv2_sec)
? (__uint32_t)(((__uint32_t)(((struct nfsv2_time *)(&sp->
sa_atime))->nfsv2_sec) & 0xff) << 24 | ((__uint32_t
)(((struct nfsv2_time *)(&sp->sa_atime))->nfsv2_sec
) & 0xff00) << 8 | ((__uint32_t)(((struct nfsv2_time
*)(&sp->sa_atime))->nfsv2_sec) & 0xff0000) >>
8 | ((__uint32_t)(((struct nfsv2_time *)(&sp->sa_atime
))->nfsv2_sec) & 0xff000000) >> 24) : __swap32md
(((struct nfsv2_time *)(&sp->sa_atime))->nfsv2_sec)
); if (((struct nfsv2_time *)(&sp->sa_atime))->nfsv2_usec
!= 0xffffffff) (&va.va_atime)->tv_nsec = 1000 * (__uint32_t
)(__builtin_constant_p(((struct nfsv2_time *)(&sp->sa_atime
))->nfsv2_usec) ? (__uint32_t)(((__uint32_t)(((struct nfsv2_time
*)(&sp->sa_atime))->nfsv2_usec) & 0xff) <<
24 | ((__uint32_t)(((struct nfsv2_time *)(&sp->sa_atime
))->nfsv2_usec) & 0xff00) << 8 | ((__uint32_t)((
(struct nfsv2_time *)(&sp->sa_atime))->nfsv2_usec) &
0xff0000) >> 8 | ((__uint32_t)(((struct nfsv2_time *)(
&sp->sa_atime))->nfsv2_usec) & 0xff000000) >>
24) : __swap32md(((struct nfsv2_time *)(&sp->sa_atime
))->nfsv2_usec)); else (&va.va_atime)->tv_nsec = 0;
} while (0)
;
267#else
268 va.va_atime.tv_sec =
269 fxdr_unsigned(u_int32_t,sp->sa_atime.nfsv2_sec)((u_int32_t)(__uint32_t)(__builtin_constant_p((int32_t)(sp->
sa_atime.nfsv2_sec)) ? (__uint32_t)(((__uint32_t)((int32_t)(sp
->sa_atime.nfsv2_sec)) & 0xff) << 24 | ((__uint32_t
)((int32_t)(sp->sa_atime.nfsv2_sec)) & 0xff00) <<
8 | ((__uint32_t)((int32_t)(sp->sa_atime.nfsv2_sec)) &
0xff0000) >> 8 | ((__uint32_t)((int32_t)(sp->sa_atime
.nfsv2_sec)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sp->sa_atime.nfsv2_sec))))
;
270 va.va_atime.tv_nsec = 0;
271#endif
272 }
273 if (sp->sa_mtime.nfsv2_sec != nfs_xdrneg1)
274 fxdr_nfsv2time(&sp->sa_mtime, &va.va_mtime)do { (&va.va_mtime)->tv_sec = (__uint32_t)(__builtin_constant_p
(((struct nfsv2_time *)(&sp->sa_mtime))->nfsv2_sec)
? (__uint32_t)(((__uint32_t)(((struct nfsv2_time *)(&sp->
sa_mtime))->nfsv2_sec) & 0xff) << 24 | ((__uint32_t
)(((struct nfsv2_time *)(&sp->sa_mtime))->nfsv2_sec
) & 0xff00) << 8 | ((__uint32_t)(((struct nfsv2_time
*)(&sp->sa_mtime))->nfsv2_sec) & 0xff0000) >>
8 | ((__uint32_t)(((struct nfsv2_time *)(&sp->sa_mtime
))->nfsv2_sec) & 0xff000000) >> 24) : __swap32md
(((struct nfsv2_time *)(&sp->sa_mtime))->nfsv2_sec)
); if (((struct nfsv2_time *)(&sp->sa_mtime))->nfsv2_usec
!= 0xffffffff) (&va.va_mtime)->tv_nsec = 1000 * (__uint32_t
)(__builtin_constant_p(((struct nfsv2_time *)(&sp->sa_mtime
))->nfsv2_usec) ? (__uint32_t)(((__uint32_t)(((struct nfsv2_time
*)(&sp->sa_mtime))->nfsv2_usec) & 0xff) <<
24 | ((__uint32_t)(((struct nfsv2_time *)(&sp->sa_mtime
))->nfsv2_usec) & 0xff00) << 8 | ((__uint32_t)((
(struct nfsv2_time *)(&sp->sa_mtime))->nfsv2_usec) &
0xff0000) >> 8 | ((__uint32_t)(((struct nfsv2_time *)(
&sp->sa_mtime))->nfsv2_usec) & 0xff000000) >>
24) : __swap32md(((struct nfsv2_time *)(&sp->sa_mtime
))->nfsv2_usec)); else (&va.va_mtime)->tv_nsec = 0;
} while (0)
;
275
276 }
277
278 /*
279 * Now that we have all the fields, lets do it.
280 */
281 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
282 if (error) {
283 nfsm_reply(2 * NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((2 *
4), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb);
if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
284 nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va, &info);
285 error = 0;
286 goto nfsmout;
287 }
288 if (info.nmi_v3) {
289 error = preat_ret = VOP_GETATTR(vp, &preat, cred, procp);
290 if (!error && gcheck &&
291 (preat.va_ctime.tv_sec != guard.tv_sec ||
292 preat.va_ctime.tv_nsec != guard.tv_nsec))
293 error = NFSERR_NOT_SYNC10002;
294 if (error) {
295 vput(vp);
296 nfsm_reply(NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
297 nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va,
298 &info);
299 error = 0;
300 goto nfsmout;
301 }
302 }
303
304 /*
305 * If the size is being changed write access is required, otherwise
306 * just check for a read only file system.
307 */
308 if (va.va_size == ((u_quad_t)((quad_t) -1))) {
309 if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001)) {
310 error = EROFS30;
311 goto out;
312 }
313 } else {
314 if (vp->v_type == VDIR) {
315 error = EISDIR21;
316 goto out;
317 } else if ((error = nfsrv_access(vp, VWRITE00200, cred, rdonly,
318 procp, 1)) != 0)
319 goto out;
320 }
321 error = VOP_SETATTR(vp, &va, cred, procp);
322 postat_ret = VOP_GETATTR(vp, &va, cred, procp);
323 if (!error)
324 error = postat_ret;
325out:
326 vput(vp);
327 nfsm_reply(NFSX_WCCORFATTR(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? ((84 + 4) + 8 * 4) : 68)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
328 if (info.nmi_v3) {
329 nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va,
330 &info);
331 error = 0;
332 goto nfsmout;
333 } else {
334 fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR68);
335 nfsm_srvfattr(nfsd, &va, fp);
336 }
337nfsmout:
338 return(error);
339}
340
341/*
342 * nfs lookup rpc
343 */
344int
345nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
346 struct proc *procp, struct mbuf **mrq)
347{
348 struct mbuf *nam = nfsd->nd_nam;
349 struct ucred *cred = &nfsd->nd_cr;
350 struct nfs_fattr *fp;
351 struct nameidata nd;
352 struct vnode *vp, *dirp;
353 struct nfsm_info info;
354 nfsfh_t nfh;
355 fhandle_t *fhp;
356 u_int32_t *tl;
357 int32_t t1;
358 int error = 0, len, dirattr_ret = 1;
359 int v3 = (nfsd->nd_flag & ND_NFSV30x08);
360 char *cp2;
361 struct vattr va, dirattr;
362
363 info.nmi_mrep = nfsd->nd_mrep;
364 info.nmi_mreq = NULL((void *)0);
365 info.nmi_md = nfsd->nd_md;
366 info.nmi_dpos = nfsd->nd_dpos;
367 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
368
369 fhp = &nfh.fh_generic;
370 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
371 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
372
373 NDINIT(&nd, LOOKUP, LOCKLEAF | SAVESTART, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 0, 0x0004 | 0x001000, UIO_SYSSPACE, -100, (
(void *)0), procp)
;
374 nd.ni_cnd.cn_cred = cred;
375 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md, &info.nmi_dpos, &dirp, procp);
376 if (dirp) {
377 if (info.nmi_v3)
378 dirattr_ret = VOP_GETATTR(dirp, &dirattr, cred,
379 procp);
380 vrele(dirp);
381 }
382 if (error) {
383 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0)), nfsd, slp, error, &info.nmi_mreq
, &info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem
(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
384 nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
385 return (0);
386 }
387 vrele(nd.ni_startdir);
388 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
389 vp = nd.ni_vp;
390 memset(fhp, 0, sizeof(nfh))__builtin_memset((fhp), (0), (sizeof(nfh)));
391 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
392 error = VFS_VPTOFH(vp, &fhp->fh_fid)(*(vp)->v_mount->mnt_op->vfs_vptofh)(vp, &fhp->
fh_fid)
;
393 if (!error)
394 error = VOP_GETATTR(vp, &va, cred, procp);
395 vput(vp);
396 nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? (
84 + 4) : 68) + ((info.nmi_v3) ? (84 + 4) : 0)), nfsd, slp, error
, &info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep !=
((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void
*)0); } *mrq = info.nmi_mreq; if (error && (!(nfsd->
nd_flag & 0x08) || error == 72)) return(0); }
397 + NFSX_POSTOPATTR(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? (
84 + 4) : 68) + ((info.nmi_v3) ? (84 + 4) : 0)), nfsd, slp, error
, &info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep !=
((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void
*)0); } *mrq = info.nmi_mreq; if (error && (!(nfsd->
nd_flag & 0x08) || error == 72)) return(0); }
;
398 if (error) {
399 nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
400 error = 0;
401 goto nfsmout;
402 }
403 nfsm_srvfhtom(&info.nmi_mb, fhp, info.nmi_v3);
404 if (v3) {
405 nfsm_srvpostop_attr(nfsd, 0, &va, &info);
406 nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
407 } else {
408 fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR68);
409 nfsm_srvfattr(nfsd, &va, fp);
410 }
411nfsmout:
412 return(error);
413}
414
415/*
416 * nfs readlink service
417 */
418int
419nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
420 struct proc *procp, struct mbuf **mrq)
421{
422 struct mbuf *nam = nfsd->nd_nam;
423 struct ucred *cred = &nfsd->nd_cr;
424 struct iovec iov;
425 struct mbuf *mp = NULL((void *)0);
426 struct nfsm_info info;
427 u_int32_t *tl;
428 int32_t t1;
429 int error = 0, rdonly, tlen, len = 0, getret;
430 char *cp2;
431 struct vnode *vp;
432 struct vattr attr;
433 nfsfh_t nfh;
434 fhandle_t *fhp;
435 struct uio uio;
436
437 info.nmi_mreq = NULL((void *)0);
438 info.nmi_mrep = nfsd->nd_mrep;
439 info.nmi_md = nfsd->nd_md;
440 info.nmi_dpos = nfsd->nd_dpos;
441 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
442
443 memset(&uio, 0, sizeof(uio))__builtin_memset((&uio), (0), (sizeof(uio)));
444
445 fhp = &nfh.fh_generic;
446 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
447 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
448 if (error) {
449 nfsm_reply(2 * NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((2 *
4), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb);
if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
450 nfsm_srvpostop_attr(nfsd, 1, NULL((void *)0), &info);
451 error = 0;
452 goto nfsmout;
453 }
454 if (vp->v_type != VLNK) {
455 if (info.nmi_v3)
456 error = EINVAL22;
457 else
458 error = ENXIO6;
459 goto out;
460 }
461
462 MGET(mp, M_WAIT, MT_DATA)mp = m_get((0x0001), (1));
463 MCLGET(mp, M_WAIT)(void) m_clget((mp), (0x0001), (1 << 11)); /* MLEN < NFS_MAXPATHLEN < MCLBYTES */
464 mp->m_lenm_hdr.mh_len = NFS_MAXPATHLEN1024;
465 len = NFS_MAXPATHLEN1024;
466 iov.iov_base = mtod(mp, caddr_t)((caddr_t)((mp)->m_hdr.mh_data));
467 iov.iov_len = mp->m_lenm_hdr.mh_len;
468
469 uio.uio_iov = &iov;
470 uio.uio_iovcnt = 1;
471 uio.uio_offset = 0;
472 uio.uio_resid = NFS_MAXPATHLEN1024;
473 uio.uio_rw = UIO_READ;
474 uio.uio_segflg = UIO_SYSSPACE;
475 uio.uio_procp = NULL((void *)0);
476
477 error = VOP_READLINK(vp, &uio, cred);
478out:
479 getret = VOP_GETATTR(vp, &attr, cred, procp);
480 vput(vp);
481 if (error)
482 m_freem(mp);
483 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + 4), nfsd, slp, error, &info
.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void *)0
)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *
mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
484 if (info.nmi_v3) {
485 nfsm_srvpostop_attr(nfsd, getret, &attr, &info);
486 if (error) {
487 error = 0;
488 goto nfsmout;
489 }
490 }
491 if (uio.uio_resid > 0) {
492 len -= uio.uio_resid;
493 tlen = nfsm_rndup(len)(((len)+3)&(~0x3));
494 nfsm_adj(mp, NFS_MAXPATHLEN1024-tlen, tlen-len);
495 }
496 tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4);
497 *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
))))
;
498 info.nmi_mb->m_nextm_hdr.mh_next = mp;
499
500nfsmout:
501 return (error);
502}
503
504/*
505 * nfs read service
506 */
507int
508nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
509 struct proc *procp, struct mbuf **mrq)
510{
511 struct mbuf *nam = nfsd->nd_nam;
512 struct ucred *cred = &nfsd->nd_cr;
513 struct mbuf *m;
514 struct nfs_fattr *fp;
515 struct nfsm_info info;
516 u_int32_t *tl;
517 int32_t t1;
518 int i, reqlen;
519 int error = 0, rdonly, cnt, len, left, siz, tlen, getret = 1;
520 char *cp2;
521 struct mbuf *m2;
522 struct vnode *vp;
523 nfsfh_t nfh;
524 fhandle_t *fhp;
525 struct uio io, *uiop = &io;
526 struct vattr va;
527 off_t off;
528
529 info.nmi_mreq = NULL((void *)0);
530 info.nmi_mrep = nfsd->nd_mrep;
531 info.nmi_md = nfsd->nd_md;
532 info.nmi_dpos = nfsd->nd_dpos;
533 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
534
535 fhp = &nfh.fh_generic;
536 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
537 if (info.nmi_v3) {
538 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; } }
;
539 off = 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]))))
;
540 } else {
541 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; } }
;
542 off = (off_t)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))))
;
543 }
544
545 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; } }
;
546 reqlen = fxdr_unsigned(int32_t, *tl)((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))))
;
547 if (reqlen > (NFS_SRVMAXDATA(nfsd)(((nfsd)->nd_flag & 0x08) ? (((nfsd)->nd_nam2) ? 32768
: (64 * 1024)) : 8192)
) || reqlen <= 0) {
548 error = EBADRPC72;
549 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
550 }
551
552 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
553 if (error)
554 goto bad;
555
556 if (vp->v_type != VREG) {
557 if (info.nmi_v3)
558 error = EINVAL22;
559 else
560 error = (vp->v_type == VDIR) ? EISDIR21 : EACCES13;
561 }
562 if (!error) {
563 if ((error = nfsrv_access(vp, VREAD00400, cred, rdonly, procp, 1)) != 0)
564 error = nfsrv_access(vp, VEXEC00100, cred, rdonly, procp, 1);
565 }
566 getret = VOP_GETATTR(vp, &va, cred, procp);
567 if (!error)
568 error = getret;
569 if (error)
570 goto vbad;
571
572 if (off >= va.va_size)
573 cnt = 0;
574 else if ((off + reqlen) > va.va_size)
575 cnt = va.va_size - off;
576 else
577 cnt = reqlen;
578 nfsm_reply(NFSX_POSTOPORFATTR(info.nmi_v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 68) + 3 * 4 +(((cnt)+3)&(~0x3))
), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
579 if (info.nmi_v3) {
580 tl = nfsm_build(&info.nmi_mb, NFSX_V3FATTR84 + 4 * NFSX_UNSIGNED4);
581 *tl++ = nfs_true;
582 fp = (struct nfs_fattr *)tl;
583 tl += (NFSX_V3FATTR84 / sizeof (u_int32_t));
584 } else {
585 tl = nfsm_build(&info.nmi_mb, NFSX_V2FATTR68 + NFSX_UNSIGNED4);
586 fp = (struct nfs_fattr *)tl;
587 tl += (NFSX_V2FATTR68 / sizeof (u_int32_t));
588 }
589 len = left = nfsm_rndup (cnt)(((cnt)+3)&(~0x3));
590 if (cnt > 0) {
591 struct iovec *iv, *iv2;
592 size_t ivlen;
593 /*
594 * Generate the mbuf list with the uio_iov ref. to it.
595 */
596 i = 0;
597 m = m2 = info.nmi_mb;
598 while (left > 0) {
599 siz = min(m_trailingspace(m), left);
600 if (siz > 0) {
601 left -= siz;
602 i++;
603 }
604 if (left > 0) {
605 MGET(m, M_WAIT, MT_DATA)m = m_get((0x0001), (1));
606 if (left >= MINCLSIZE(((256 - sizeof(struct m_hdr)) - sizeof(struct pkthdr)) + (256
- sizeof(struct m_hdr)) + 1)
)
607 MCLGET(m, M_WAIT)(void) m_clget((m), (0x0001), (1 << 11));
608 m->m_lenm_hdr.mh_len = 0;
609 m2->m_nextm_hdr.mh_next = m;
610 m2 = m;
611 }
612 }
613 iv = mallocarray(i, sizeof(*iv), M_TEMP127, M_WAITOK0x0001);
614 ivlen = i * sizeof(*iv);
615 uiop->uio_iov = iv2 = iv;
616 m = info.nmi_mb;
617 left = len;
618 i = 0;
619 while (left > 0) {
620 if (m == NULL((void *)0))
621 panic("nfsrv_read iov");
622 siz = min(m_trailingspace(m), left);
623 if (siz > 0) {
624 iv->iov_base = mtod(m, caddr_t)((caddr_t)((m)->m_hdr.mh_data)) + m->m_lenm_hdr.mh_len;
625 iv->iov_len = siz;
626 m->m_lenm_hdr.mh_len += siz;
627 left -= siz;
628 iv++;
629 i++;
630 }
631 m = m->m_nextm_hdr.mh_next;
632 }
633 uiop->uio_iovcnt = i;
634 uiop->uio_offset = off;
635 uiop->uio_resid = len;
636 uiop->uio_rw = UIO_READ;
637 uiop->uio_segflg = UIO_SYSSPACE;
638 error = VOP_READ(vp, uiop, IO_NODELOCKED0x08, cred);
639 off = uiop->uio_offset;
640 free(iv2, M_TEMP127, ivlen);
641 if (error || (getret = VOP_GETATTR(vp, &va, cred, procp)) != 0){
642 if (!error)
643 error = getret;
644 m_freem(info.nmi_mreq);
645 goto vbad;
646 }
647 } else
648 uiop->uio_resid = 0;
649 vput(vp);
650 nfsm_srvfattr(nfsd, &va, fp);
651 tlen = len - uiop->uio_resid;
652 cnt = cnt < tlen ? cnt : tlen;
653 tlen = nfsm_rndup (cnt)(((cnt)+3)&(~0x3));
654 if (len != tlen || tlen != cnt)
655 nfsm_adj(info.nmi_mb, len - tlen, tlen - cnt);
656 if (info.nmi_v3) {
657 *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
))))
;
658 if (len < reqlen)
659 *tl++ = nfs_true;
660 else
661 *tl++ = nfs_false;
662 }
663 *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
))))
;
664nfsmout:
665 return(error);
666
667vbad:
668 vput(vp);
669bad:
670 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
671 nfsm_srvpostop_attr(nfsd, getret, &va, &info);
672 return (0);
673}
674
675/*
676 * nfs write service
677 */
678int
679nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
680 struct proc *procp, struct mbuf **mrq)
681{
682 struct mbuf *nam = nfsd->nd_nam;
683 struct ucred *cred = &nfsd->nd_cr;
684 struct nfsm_info info;
685 int i, cnt;
686 struct mbuf *mp;
687 struct nfs_fattr *fp;
688 struct timeval boottime;
689 struct vattr va, forat;
690 u_int32_t *tl;
691 int32_t t1;
692 int error = 0, rdonly, len, forat_ret = 1;
693 int ioflags, aftat_ret = 1, retlen, zeroing, adjust;
694 int stable = NFSV3WRITE_FILESYNC2;
695 char *cp2;
696 struct vnode *vp;
697 nfsfh_t nfh;
698 fhandle_t *fhp;
699 struct uio io, *uiop = &io;
700 off_t off;
701
702 info.nmi_mreq = NULL((void *)0);
703 info.nmi_mrep = nfsd->nd_mrep;
704 info.nmi_md = nfsd->nd_md;
705 info.nmi_dpos = nfsd->nd_dpos;
706 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
707
708 if (info.nmi_mrep == NULL((void *)0)) {
709 *mrq = NULL((void *)0);
710 return (0);
711 }
712 fhp = &nfh.fh_generic;
713 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
714 if (info.nmi_v3) {
715 nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md
->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (5 * 4)) { (tl
) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (5 * 4); }
else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos
, (5 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep
); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }
;
716 off = 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]))))
;
717 tl += 3;
718 stable = 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++))))
;
719 } else {
720 nfsm_dissect(tl, u_int32_t *, 4 * 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 * 4)) { (tl
) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (4 * 4); }
else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos
, (4 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep
); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }
;
721 off = (off_t)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))))
;
722 tl += 2;
723 }
724 retlen = len = fxdr_unsigned(int32_t, *tl)((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))))
;
725 cnt = i = 0;
726
727 /*
728 * For NFS Version 2, it is not obvious what a write of zero length
729 * should do, but I might as well be consistent with Version 3,
730 * which is to return ok so long as there are no permission problems.
731 */
732 if (len > 0) {
733 zeroing = 1;
734 mp = info.nmi_mrep;
735 while (mp) {
736 if (mp == info.nmi_md) {
737 zeroing = 0;
738 adjust = info.nmi_dpos - mtod(mp, caddr_t)((caddr_t)((mp)->m_hdr.mh_data));
739 mp->m_lenm_hdr.mh_len -= adjust;
740 if (mp->m_lenm_hdr.mh_len > 0 && adjust > 0)
741 mp->m_datam_hdr.mh_data += adjust;
742 }
743 if (zeroing)
744 mp->m_lenm_hdr.mh_len = 0;
745 else if (mp->m_lenm_hdr.mh_len > 0) {
746 i += mp->m_lenm_hdr.mh_len;
747 if (i > len) {
748 mp->m_lenm_hdr.mh_len -= (i - len);
749 zeroing = 1;
750 }
751 if (mp->m_lenm_hdr.mh_len > 0)
752 cnt++;
753 }
754 mp = mp->m_nextm_hdr.mh_next;
755 }
756 }
757 if (len > NFS_MAXDATA(64 * 1024) || len < 0 || i < len) {
758 error = EIO5;
759 goto bad;
760 }
761 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
762 if (error)
763 goto bad;
764 if (info.nmi_v3)
765 forat_ret = VOP_GETATTR(vp, &forat, cred, procp);
766 if (vp->v_type != VREG) {
767 if (info.nmi_v3)
768 error = EINVAL22;
769 else
770 error = (vp->v_type == VDIR) ? EISDIR21 : EACCES13;
771 goto vbad;
772 }
773 error = nfsrv_access(vp, VWRITE00200, cred, rdonly, procp, 1);
774 if (error)
775 goto vbad;
776
777 if (len > 0) {
778 struct iovec *iv, *ivp;
779 size_t ivlen;
780
781 ivp = mallocarray(cnt, sizeof(*ivp), M_TEMP127, M_WAITOK0x0001);
782 ivlen = cnt * sizeof(*ivp);
783 uiop->uio_iov = iv = ivp;
784 uiop->uio_iovcnt = cnt;
785 mp = info.nmi_mrep;
786 while (mp) {
787 if (mp->m_lenm_hdr.mh_len > 0) {
788 ivp->iov_base = mtod(mp, caddr_t)((caddr_t)((mp)->m_hdr.mh_data));
789 ivp->iov_len = mp->m_lenm_hdr.mh_len;
790 ivp++;
791 }
792 mp = mp->m_nextm_hdr.mh_next;
793 }
794
795 if (stable == NFSV3WRITE_UNSTABLE0)
796 ioflags = IO_NODELOCKED0x08;
797 else if (stable == NFSV3WRITE_DATASYNC1)
798 ioflags = (IO_SYNC0x04 | IO_NODELOCKED0x08);
799 else
800 ioflags = (IO_SYNC0x04 | IO_NODELOCKED0x08);
801 uiop->uio_resid = len;
802 uiop->uio_rw = UIO_WRITE;
803 uiop->uio_segflg = UIO_SYSSPACE;
804 uiop->uio_procp = NULL((void *)0);
805 uiop->uio_offset = off;
806 error = VOP_WRITE(vp, uiop, ioflags, cred);
807 nfsstats.srvvop_writes++;
808 free(iv, M_TEMP127, ivlen);
809 }
810 aftat_ret = VOP_GETATTR(vp, &va, cred, procp);
811 vput(vp);
812 if (!error)
813 error = aftat_ret;
814 nfsm_reply(NFSX_PREOPATTR(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) +{ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (7 * 4) : 0) + ((info.nmi_v3) ? (84 + 4) : 68)
+ 2 * 4 + ((info.nmi_v3) ? 8 : 0)), nfsd, slp, error, &info
.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void *)0
)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *
mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
815 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (7 * 4) : 0) + ((info.nmi_v3) ? (84 + 4) : 68)
+ 2 * 4 + ((info.nmi_v3) ? 8 : 0)), nfsd, slp, error, &info
.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void *)0
)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *
mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
816 if (info.nmi_v3) {
817 nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info);
818 if (error) {
819 error = 0;
820 goto nfsmout;
821 }
822 tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED4);
823 *tl++ = txdr_unsigned(retlen)((__uint32_t)(__builtin_constant_p((int32_t)(retlen)) ? (__uint32_t
)(((__uint32_t)((int32_t)(retlen)) & 0xff) << 24 | (
(__uint32_t)((int32_t)(retlen)) & 0xff00) << 8 | ((
__uint32_t)((int32_t)(retlen)) & 0xff0000) >> 8 | (
(__uint32_t)((int32_t)(retlen)) & 0xff000000) >> 24
) : __swap32md((int32_t)(retlen))))
;
824 if (stable == NFSV3WRITE_UNSTABLE0)
825 *tl++ = txdr_unsigned(stable)((__uint32_t)(__builtin_constant_p((int32_t)(stable)) ? (__uint32_t
)(((__uint32_t)((int32_t)(stable)) & 0xff) << 24 | (
(__uint32_t)((int32_t)(stable)) & 0xff00) << 8 | ((
__uint32_t)((int32_t)(stable)) & 0xff0000) >> 8 | (
(__uint32_t)((int32_t)(stable)) & 0xff000000) >> 24
) : __swap32md((int32_t)(stable))))
;
826 else
827 *tl++ = txdr_unsigned(NFSV3WRITE_FILESYNC)((__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))))
;
828 /*
829 * Actually, there is no need to txdr these fields,
830 * but it may make the values more human readable,
831 * for debugging purposes.
832 */
833 microboottime(&boottime);
834 *tl++ = txdr_unsigned(boottime.tv_sec)((__uint32_t)(__builtin_constant_p((int32_t)(boottime.tv_sec)
) ? (__uint32_t)(((__uint32_t)((int32_t)(boottime.tv_sec)) &
0xff) << 24 | ((__uint32_t)((int32_t)(boottime.tv_sec)
) & 0xff00) << 8 | ((__uint32_t)((int32_t)(boottime
.tv_sec)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t
)(boottime.tv_sec)) & 0xff000000) >> 24) : __swap32md
((int32_t)(boottime.tv_sec))))
;
835 *tl = txdr_unsigned(boottime.tv_usec)((__uint32_t)(__builtin_constant_p((int32_t)(boottime.tv_usec
)) ? (__uint32_t)(((__uint32_t)((int32_t)(boottime.tv_usec)) &
0xff) << 24 | ((__uint32_t)((int32_t)(boottime.tv_usec
)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(boottime
.tv_usec)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t
)(boottime.tv_usec)) & 0xff000000) >> 24) : __swap32md
((int32_t)(boottime.tv_usec))))
;
836 } else {
837 fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR68);
838 nfsm_srvfattr(nfsd, &va, fp);
839 }
840nfsmout:
841 return(error);
842
843vbad:
844 vput(vp);
845bad:
846 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
847 nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info);
848 return (0);
849}
850
851/*
852 * nfs create service
853 * now does a truncate to 0 length via. setattr if it already exists
854 */
855int
856nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
857 struct proc *procp, struct mbuf **mrq)
858{
859 struct mbuf *nam = nfsd->nd_nam;
860 struct ucred *cred = &nfsd->nd_cr;
861 struct nfs_fattr *fp;
862 struct vattr va, dirfor, diraft;
863 struct nfsv2_sattr *sp;
864 struct nfsm_info info;
865 u_int32_t *tl;
866 struct nameidata nd;
867 caddr_t cp;
868 int32_t t1;
869 int error = 0, len, tsize, dirfor_ret = 1, diraft_ret = 1;
870 dev_t rdev = 0;
871 int how, exclusive_flag = 0;
872 char *cp2;
873 struct vnode *vp = NULL((void *)0), *dirp = NULL((void *)0);
874 nfsfh_t nfh;
875 fhandle_t *fhp;
876 u_quad_t tempsize;
877 u_char cverf[NFSX_V3CREATEVERF8];
878
879 info.nmi_mreq = NULL((void *)0);
880 info.nmi_mrep = nfsd->nd_mrep;
881 info.nmi_md = nfsd->nd_md;
882 info.nmi_dpos = nfsd->nd_dpos;
883 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
884
885 fhp = &nfh.fh_generic;
886 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
887 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
888
889 NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE,ndinitat(&nd, 1, 0x0008 | 0x0004 | 0x001000, UIO_SYSSPACE
, -100, ((void *)0), procp)
890 NULL, procp)ndinitat(&nd, 1, 0x0008 | 0x0004 | 0x001000, UIO_SYSSPACE
, -100, ((void *)0), procp)
;
891 nd.ni_cnd.cn_cred = cred;
892 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
893 &info.nmi_dpos, &dirp, procp);
894 if (dirp) {
895 if (info.nmi_v3)
896 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
897 else {
898 vrele(dirp);
899 dirp = NULL((void *)0);
900 }
901 }
902 if (error) {
903 nfsm_reply(NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
904 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
905 &info);
906 if (dirp)
907 vrele(dirp);
908 return (0);
909 }
910
911 VATTR_NULL(&va)vattr_null(&va);
912 if (info.nmi_v3) {
913 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; } }
;
914 how = 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))))
;
915 switch (how) {
916 case NFSV3CREATE_GUARDED1:
917 if (nd.ni_vp) {
918 error = EEXIST17;
919 break;
920 }
921 case NFSV3CREATE_UNCHECKED0:
922 error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
923 &info.nmi_dpos);
924 if (error)
925 goto nfsmout;
926 break;
927 case NFSV3CREATE_EXCLUSIVE2:
928 nfsm_dissect(cp, caddr_t, NFSX_V3CREATEVERF){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md
->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (8)) { (cp) =
(caddr_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 { (cp) = (caddr_t)cp2; } }
;
929 bcopy(cp, cverf, NFSX_V3CREATEVERF8);
930 exclusive_flag = 1;
931 if (nd.ni_vp == NULL((void *)0))
932 va.va_mode = 0;
933 break;
934 };
935 va.va_type = VREG;
936 } else {
937 nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md
->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32)) { (sp) =
(struct nfsv2_sattr *)(info.nmi_dpos); info.nmi_dpos += (32)
; } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos
, (32), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep
); goto nfsmout; } else { (sp) = (struct nfsv2_sattr *)cp2; }
}
;
938 va.va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode))(iftovt_tab[((((u_int32_t)(__uint32_t)(__builtin_constant_p((
int32_t)(sp->sa_mode)) ? (__uint32_t)(((__uint32_t)((int32_t
)(sp->sa_mode)) & 0xff) << 24 | ((__uint32_t)((int32_t
)(sp->sa_mode)) & 0xff00) << 8 | ((__uint32_t)((
int32_t)(sp->sa_mode)) & 0xff0000) >> 8 | ((__uint32_t
)((int32_t)(sp->sa_mode)) & 0xff000000) >> 24) :
__swap32md((int32_t)(sp->sa_mode))))) & 0170000) >>
12])
;
939 if (va.va_type == VNON)
940 va.va_type = VREG;
941 va.va_mode = nfstov_mode(sp->sa_mode)(((u_int16_t)(__uint32_t)(__builtin_constant_p((int32_t)((sp->
sa_mode))) ? (__uint32_t)(((__uint32_t)((int32_t)((sp->sa_mode
))) & 0xff) << 24 | ((__uint32_t)((int32_t)((sp->
sa_mode))) & 0xff00) << 8 | ((__uint32_t)((int32_t)
((sp->sa_mode))) & 0xff0000) >> 8 | ((__uint32_t
)((int32_t)((sp->sa_mode))) & 0xff000000) >> 24)
: __swap32md((int32_t)((sp->sa_mode)))))&07777)
;
942 switch (va.va_type) {
943 case VREG:
944 tsize = fxdr_unsigned(int32_t, sp->sa_size)((int32_t)(__uint32_t)(__builtin_constant_p((int32_t)(sp->
sa_size)) ? (__uint32_t)(((__uint32_t)((int32_t)(sp->sa_size
)) & 0xff) << 24 | ((__uint32_t)((int32_t)(sp->sa_size
)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(sp->
sa_size)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t
)(sp->sa_size)) & 0xff000000) >> 24) : __swap32md
((int32_t)(sp->sa_size))))
;
945 if (tsize != -1)
946 va.va_size = (u_quad_t)tsize;
947 break;
948 case VCHR:
949 case VBLK:
950 case VFIFO:
951 rdev = (dev_t)fxdr_unsigned(int32_t, sp->sa_size)((int32_t)(__uint32_t)(__builtin_constant_p((int32_t)(sp->
sa_size)) ? (__uint32_t)(((__uint32_t)((int32_t)(sp->sa_size
)) & 0xff) << 24 | ((__uint32_t)((int32_t)(sp->sa_size
)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(sp->
sa_size)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t
)(sp->sa_size)) & 0xff000000) >> 24) : __swap32md
((int32_t)(sp->sa_size))))
;
952 break;
953 default:
954 break;
955 };
956 }
957
958 /*
959 * Iff doesn't exist, create it
960 * otherwise just truncate to 0 length
961 * should I set the mode too ??
962 */
963 if (nd.ni_vp == NULL((void *)0)) {
964 if (va.va_type == VREG || va.va_type == VSOCK) {
965 vrele(nd.ni_startdir);
966 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd,
967 &va);
968 vput(nd.ni_dvp);
969 if (!error) {
970 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
971 if (exclusive_flag) {
972 exclusive_flag = 0;
973 VATTR_NULL(&va)vattr_null(&va);
974 bcopy(cverf, (caddr_t)&va.va_atime,
975 NFSX_V3CREATEVERF8);
976 error = VOP_SETATTR(nd.ni_vp, &va, cred,
977 procp);
978 }
979 }
980 } else if (va.va_type == VCHR || va.va_type == VBLK ||
981 va.va_type == VFIFO) {
982 if (va.va_type == VCHR && rdev == 0xffffffff)
983 va.va_type = VFIFO;
984 if (va.va_type != VFIFO &&
985 (error = suser_ucred(cred))) {
986 vrele(nd.ni_startdir);
987 if (nd.ni_cnd.cn_flags & HASBUF0x000400) {
988 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
989 nd.ni_cnd.cn_flags &= ~HASBUF0x000400;
990 }
991 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
992 vput(nd.ni_dvp);
993 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
994 error = 0;
995 goto nfsmout;
996 } else
997 va.va_rdev = (dev_t)rdev;
998 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd,
999 &va);
1000 vput(nd.ni_dvp);
1001 if (error) {
1002 vrele(nd.ni_startdir);
1003 if (nd.ni_cnd.cn_flags & HASBUF0x000400) {
1004 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1005 nd.ni_cnd.cn_flags &= ~HASBUF0x000400;
1006 }
1007 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
1008 error = 0;
1009 goto nfsmout;
1010 }
1011 nd.ni_cnd.cn_nameiop = LOOKUP0;
1012 nd.ni_cnd.cn_flags &= ~(LOCKPARENT0x0008 | SAVESTART0x001000);
1013 nd.ni_cnd.cn_proc = procp;
1014 nd.ni_cnd.cn_cred = cred;
1015 if ((error = vfs_lookup(&nd)) != 0) {
1016 if (nd.ni_cnd.cn_flags & HASBUF0x000400) {
1017 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1018 nd.ni_cnd.cn_flags &= ~HASBUF0x000400;
1019 }
1020 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
1021 error = 0;
1022 goto nfsmout;
1023 }
1024
1025 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1026 if (nd.ni_cnd.cn_flags & ISSYMLINK0x010000) {
1027 vrele(nd.ni_dvp);
1028 vput(nd.ni_vp);
1029 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1030 error = EINVAL22;
1031 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
1032 error = 0;
1033 goto nfsmout;
1034 }
1035 } else {
1036 vrele(nd.ni_startdir);
1037 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1038 nd.ni_cnd.cn_flags &= ~HASBUF0x000400;
1039 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1040 vput(nd.ni_dvp);
1041 error = ENXIO6;
1042 }
1043 vp = nd.ni_vp;
1044 } else {
1045 vrele(nd.ni_startdir);
1046 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1047 nd.ni_cnd.cn_flags &= ~HASBUF0x000400;
1048 vp = nd.ni_vp;
1049 if (nd.ni_dvp == vp)
1050 vrele(nd.ni_dvp);
1051 else
1052 vput(nd.ni_dvp);
1053 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1054 if (va.va_size != -1) {
1055 error = nfsrv_access(vp, VWRITE00200, cred,
1056 (nd.ni_cnd.cn_flags & RDONLY0x000200), procp, 0);
1057 if (!error) {
1058 tempsize = va.va_size;
1059 VATTR_NULL(&va)vattr_null(&va);
1060 va.va_size = tempsize;
1061 error = VOP_SETATTR(vp, &va, cred,
1062 procp);
1063 }
1064 if (error)
1065 vput(vp);
1066 }
1067 }
1068 if (!error) {
1069 memset(fhp, 0, sizeof(nfh))__builtin_memset((fhp), (0), (sizeof(nfh)));
1070 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
1071 error = VFS_VPTOFH(vp, &fhp->fh_fid)(*(vp)->v_mount->mnt_op->vfs_vptofh)(vp, &fhp->
fh_fid)
;
1072 if (!error)
1073 error = VOP_GETATTR(vp, &va, cred, procp);
1074 vput(vp);
1075 }
1076 if (info.nmi_v3) {
1077 if (exclusive_flag && !error &&
1078 bcmp(cverf, (caddr_t)&va.va_atime, NFSX_V3CREATEVERF8))
1079 error = EEXIST17;
1080 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1081 vrele(dirp);
1082 }
1083 nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_FATTR(info.nmi_v3){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? 84
: 68) + ((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep
!= ((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((
void *)0); } *mrq = info.nmi_mreq; if (error && (!(nfsd
->nd_flag & 0x08) || error == 72)) return(0); }
1084 + NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? 84
: 68) + ((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep
!= ((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((
void *)0); } *mrq = info.nmi_mreq; if (error && (!(nfsd
->nd_flag & 0x08) || error == 72)) return(0); }
;
1085 if (info.nmi_v3) {
1086 if (!error) {
1087 nfsm_srvpostop_fh(fhp){ tl = nfsm_build(&info.nmi_mb, 2 * 4 + (sizeof (fhandle_t
))); *tl++ = nfs_true; *tl++ = ((__uint32_t)(__builtin_constant_p
((int32_t)((sizeof (fhandle_t)))) ? (__uint32_t)(((__uint32_t
)((int32_t)((sizeof (fhandle_t)))) & 0xff) << 24 | (
(__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff00) <<
8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff0000
) >> 8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t))))
& 0xff000000) >> 24) : __swap32md((int32_t)((sizeof
(fhandle_t)))))); bcopy((fhp), tl, (sizeof (fhandle_t))); }
;
1088 nfsm_srvpostop_attr(nfsd, 0, &va, &info);
1089 }
1090 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1091 &info);
1092 } else {
1093 nfsm_srvfhtom(&info.nmi_mb, fhp, info.nmi_v3);
1094 fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR68);
1095 nfsm_srvfattr(nfsd, &va, fp);
1096 }
1097 return (0);
1098nfsmout:
1099 if (dirp)
1100 vrele(dirp);
1101 if (nd.ni_cnd.cn_nameiop != LOOKUP0) {
1102 vrele(nd.ni_startdir);
1103 if (nd.ni_cnd.cn_flags & HASBUF0x000400) {
1104 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1105 nd.ni_cnd.cn_flags &= ~HASBUF0x000400;
1106 }
1107 }
1108 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1109 if (nd.ni_dvp == nd.ni_vp)
1110 vrele(nd.ni_dvp);
1111 else
1112 vput(nd.ni_dvp);
1113 if (nd.ni_vp)
1114 vput(nd.ni_vp);
1115 return (error);
1116}
1117
1118/*
1119 * nfs v3 mknod service
1120 */
1121int
1122nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1123 struct proc *procp, struct mbuf **mrq)
1124{
1125 struct mbuf *nam = nfsd->nd_nam;
1126 struct ucred *cred = &nfsd->nd_cr;
1127 struct vattr va, dirfor, diraft;
1128 struct nfsm_info info;
1129 u_int32_t *tl;
1130 struct nameidata nd;
1131 int32_t t1;
1132 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1133 u_int32_t major, minor;
1134 enum vtype vtyp;
1135 char *cp2;
1136 struct vnode *vp, *dirp = NULL((void *)0);
1137 nfsfh_t nfh;
1138 fhandle_t *fhp;
1139
1140 info.nmi_mreq = NULL((void *)0);
1141 info.nmi_mrep = nfsd->nd_mrep;
1142 info.nmi_md = nfsd->nd_md;
1143 info.nmi_dpos = nfsd->nd_dpos;
1144 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1145
1146 fhp = &nfh.fh_generic;
1147 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1148 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
1149
1150 NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE,ndinitat(&nd, 1, 0x0008 | 0x0004 | 0x001000, UIO_SYSSPACE
, -100, ((void *)0), procp)
1151 NULL, procp)ndinitat(&nd, 1, 0x0008 | 0x0004 | 0x001000, UIO_SYSSPACE
, -100, ((void *)0), procp)
;
1152 nd.ni_cnd.cn_cred = cred;
1153 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md, &info.nmi_dpos, &dirp, procp);
1154 if (dirp)
1155 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
1156 if (error) {
1157 nfsm_reply(NFSX_WCCDATA(1)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
1) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &info.nmi_mreq
, &info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem
(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
1158 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1159 &info);
1160 if (dirp)
1161 vrele(dirp);
1162 return (0);
1163 }
1164
1165 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; } }
;
1166 vtyp = nfsv3tov_type(*tl)nv3tov_type[((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)))))&0x7]
;
1167 if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
1168 vrele(nd.ni_startdir);
1169 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1170 error = NFSERR_BADTYPE10007;
1171 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1172 if (nd.ni_dvp == nd.ni_vp)
1173 vrele(nd.ni_dvp);
1174 else
1175 vput(nd.ni_dvp);
1176 if (nd.ni_vp)
1177 vput(nd.ni_vp);
1178 goto out;
1179 }
1180 VATTR_NULL(&va)vattr_null(&va);
1181 error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep, &info.nmi_dpos);
1182 if (error)
1183 goto nfsmout;
1184 if (vtyp == VCHR || vtyp == VBLK) {
1185 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; } }
;
1186 major = 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++))))
;
1187 minor = 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))))
;
1188 va.va_rdev = makedev(major, minor)((dev_t)((((major) & 0xff) << 8) | ((minor) & 0xff
) | (((minor) & 0xffff00) << 8)))
;
1189 }
1190
1191 /*
1192 * Iff doesn't exist, create it.
1193 */
1194 if (nd.ni_vp) {
1195 vrele(nd.ni_startdir);
1196 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1197 error = EEXIST17;
1198 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1199 if (nd.ni_dvp == nd.ni_vp)
1200 vrele(nd.ni_dvp);
1201 else
1202 vput(nd.ni_dvp);
1203 vput(nd.ni_vp);
1204 goto out;
1205 }
1206 va.va_type = vtyp;
1207 if (vtyp == VSOCK) {
1208 vrele(nd.ni_startdir);
1209 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va);
1210 vput(nd.ni_dvp);
1211 if (!error)
1212 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1213 } else {
1214 if (va.va_type != VFIFO &&
1215 (error = suser_ucred(cred))) {
1216 vrele(nd.ni_startdir);
1217 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1218 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1219 vput(nd.ni_dvp);
1220 goto out;
1221 }
1222 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va);
1223 vput(nd.ni_dvp);
1224 if (error) {
1225 vrele(nd.ni_startdir);
1226 goto out;
1227 }
1228 nd.ni_cnd.cn_nameiop = LOOKUP0;
1229 nd.ni_cnd.cn_flags &= ~(LOCKPARENT0x0008 | SAVESTART0x001000);
1230 nd.ni_cnd.cn_proc = procp;
1231 nd.ni_cnd.cn_cred = procp->p_ucred;
1232 error = vfs_lookup(&nd);
1233 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1234 if (error)
1235 goto out;
1236 if (nd.ni_cnd.cn_flags & ISSYMLINK0x010000) {
1237 vrele(nd.ni_dvp);
1238 vput(nd.ni_vp);
1239 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1240 error = EINVAL22;
1241 }
1242 }
1243out:
1244 vp = nd.ni_vp;
1245 if (!error) {
1246 memset(fhp, 0, sizeof(nfh))__builtin_memset((fhp), (0), (sizeof(nfh)));
1247 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
1248 error = VFS_VPTOFH(vp, &fhp->fh_fid)(*(vp)->v_mount->mnt_op->vfs_vptofh)(vp, &fhp->
fh_fid)
;
1249 if (!error)
1250 error = VOP_GETATTR(vp, &va, cred, procp);
1251 vput(vp);
1252 }
1253 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1254 vrele(dirp);
1255 nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
1) ? (sizeof (fhandle_t)) : 32) + ((1) ? (84 + 4) : 0) + ((1)
? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &info.nmi_mreq
, &info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem
(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
1256 if (!error) {
1257 nfsm_srvpostop_fh(fhp){ tl = nfsm_build(&info.nmi_mb, 2 * 4 + (sizeof (fhandle_t
))); *tl++ = nfs_true; *tl++ = ((__uint32_t)(__builtin_constant_p
((int32_t)((sizeof (fhandle_t)))) ? (__uint32_t)(((__uint32_t
)((int32_t)((sizeof (fhandle_t)))) & 0xff) << 24 | (
(__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff00) <<
8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff0000
) >> 8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t))))
& 0xff000000) >> 24) : __swap32md((int32_t)((sizeof
(fhandle_t)))))); bcopy((fhp), tl, (sizeof (fhandle_t))); }
;
1258 nfsm_srvpostop_attr(nfsd, 0, &va, &info);
1259 }
1260 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info);
1261 return (0);
1262nfsmout:
1263 if (dirp)
1264 vrele(dirp);
1265 if (nd.ni_cnd.cn_nameiop) {
1266 vrele(nd.ni_startdir);
1267 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1268 }
1269 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1270 if (nd.ni_dvp == nd.ni_vp)
1271 vrele(nd.ni_dvp);
1272 else
1273 vput(nd.ni_dvp);
1274 if (nd.ni_vp)
1275 vput(nd.ni_vp);
1276 return (error);
1277}
1278
1279/*
1280 * nfs remove service
1281 */
1282int
1283nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1284 struct proc *procp, struct mbuf **mrq)
1285{
1286 struct mbuf *nam = nfsd->nd_nam;
1287 struct ucred *cred = &nfsd->nd_cr;
1288 struct nameidata nd;
1289 struct nfsm_info info;
1290 u_int32_t *tl;
1291 int32_t t1;
1292 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1293 char *cp2;
1294 struct vnode *vp, *dirp;
1295 struct vattr dirfor, diraft;
1296 nfsfh_t nfh;
1297 fhandle_t *fhp;
1298
1299 info.nmi_mreq = NULL((void *)0);
1300 info.nmi_mrep = nfsd->nd_mrep;
1301 info.nmi_md = nfsd->nd_md;
1302 info.nmi_dpos = nfsd->nd_dpos;
1303 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1304
1305 vp = NULL((void *)0);
1306
1307 fhp = &nfh.fh_generic;
1308 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1309 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
1310
1311 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 2, 0x0008 | 0x0004, UIO_SYSSPACE, -100, ((void
*)0), procp)
;
1312 nd.ni_cnd.cn_cred = cred;
1313 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md, &info.nmi_dpos, &dirp, procp);
1314 if (dirp) {
1315 if (info.nmi_v3)
1316 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
1317 else {
1318 vrele(dirp);
1319 dirp = NULL((void *)0);
1320 }
1321 }
1322
1323 if (!error) {
1324 vp = nd.ni_vp;
1325 if (vp->v_type == VDIR &&
1326 (error = suser_ucred(cred)) != 0)
1327 goto out;
1328 /*
1329 * The root of a mounted filesystem cannot be deleted.
1330 */
1331 if (vp->v_flag & VROOT0x0001) {
1332 error = EBUSY16;
1333 goto out;
1334 }
1335 if (vp->v_flag & VTEXT0x0002)
1336 uvm_vnp_uncache(vp);
1337out:
1338 if (!error) {
1339 error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
1340 } else {
1341 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1342 if (nd.ni_dvp == vp)
1343 vrele(nd.ni_dvp);
1344 else
1345 vput(nd.ni_dvp);
1346 vput(vp);
1347 }
1348 }
1349 if (dirp && info.nmi_v3) {
1350 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1351 vrele(dirp);
1352 }
1353 nfsm_reply(NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
1354 if (info.nmi_v3) {
1355 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1356 &info);
1357 return (0);
1358 }
1359
1360nfsmout:
1361 return(error);
1362}
1363
1364/*
1365 * nfs rename service
1366 */
1367int
1368nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1369 struct proc *procp, struct mbuf **mrq)
1370{
1371 struct mbuf *nam = nfsd->nd_nam;
1372 struct ucred *cred = &nfsd->nd_cr;
1373 struct nfsm_info info;
1374 u_int32_t *tl;
1375 int32_t t1;
1376 int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
1377 int tdirfor_ret = 1, tdiraft_ret = 1;
1378 char *cp2;
1379 struct nameidata fromnd, tond;
1380 struct vnode *fvp = NULL((void *)0), *tvp, *tdvp, *fdirp = NULL((void *)0);
1381 struct vnode *tdirp = NULL((void *)0);
1382 struct vattr fdirfor, fdiraft, tdirfor, tdiraft;
1383 nfsfh_t fnfh, tnfh;
1384 fhandle_t *ffhp, *tfhp;
1385 uid_t saved_uid;
1386
1387 info.nmi_mreq = NULL((void *)0);
1388 info.nmi_mrep = nfsd->nd_mrep;
1389 info.nmi_md = nfsd->nd_md;
1390 info.nmi_dpos = nfsd->nd_dpos;
1391 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1392
1393 ffhp = &fnfh.fh_generic;
1394 tfhp = &tnfh.fh_generic;
1395 nfsm_srvmtofh(ffhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (ffhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1
Assuming the condition is false
2
Taking false branch
3
Assuming the condition is false
4
Taking false branch
5
Assuming the condition is true
6
Taking true branch
7
Control jumps to line 1530
1396 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
1397
1398 /*
1399 * Remember our original uid so that we can reset cr_uid before
1400 * the second nfs_namei() call, in case it is remapped.
1401 */
1402 saved_uid = cred->cr_uid;
1403
1404 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_SYSSPACE, NULL,ndinitat(&fromnd, 2, 0x0010 | 0x001000, UIO_SYSSPACE, -100
, ((void *)0), procp)
1405 procp)ndinitat(&fromnd, 2, 0x0010 | 0x001000, UIO_SYSSPACE, -100
, ((void *)0), procp)
;
1406 fromnd.ni_cnd.cn_cred = cred;
1407 error = nfs_namei(&fromnd, ffhp, len, slp, nam, &info.nmi_md,
1408 &info.nmi_dpos, &fdirp, procp);
1409 if (fdirp) {
1410 if (info.nmi_v3)
1411 fdirfor_ret = VOP_GETATTR(fdirp, &fdirfor, cred,
1412 procp);
1413 else {
1414 vrele(fdirp);
1415 fdirp = NULL((void *)0);
1416 }
1417 }
1418 if (error) {
1419 nfsm_reply(2 * NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((2 *
((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error,
&info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != (
(void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *
)0); } *mrq = info.nmi_mreq; if (error && (!(nfsd->
nd_flag & 0x08) || error == 72)) return(0); }
;
1420 nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft,
1421 &info);
1422 nfsm_srvwcc(nfsd, tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft,
1423 &info);
1424 if (fdirp)
1425 vrele(fdirp);
1426 return (0);
1427 }
1428
1429 fvp = fromnd.ni_vp;
1430 nfsm_srvmtofh(tfhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (tfhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1431 nfsm_strsiz(len2, NFS_MAXNAMLEN){ { 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 (((
len2) = ((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 || (len2) > (255)
) { m_freem(info.nmi_mrep); error = 72; goto nfsmout; } }
;
1432 cred->cr_uid = saved_uid;
1433
1434 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF| NOCACHE | SAVESTART,ndinitat(&tond, 3, 0x0008 | 0x0004| 0x0020 | 0x001000, UIO_SYSSPACE
, -100, ((void *)0), procp)
1435 UIO_SYSSPACE, NULL, procp)ndinitat(&tond, 3, 0x0008 | 0x0004| 0x0020 | 0x001000, UIO_SYSSPACE
, -100, ((void *)0), procp)
;
1436 tond.ni_cnd.cn_cred = cred;
1437 error = nfs_namei(&tond, tfhp, len2, slp, nam, &info.nmi_md,
1438 &info.nmi_dpos, &tdirp, procp);
1439 if (tdirp) {
1440 if (info.nmi_v3)
1441 tdirfor_ret = VOP_GETATTR(tdirp, &tdirfor, cred,
1442 procp);
1443 else {
1444 vrele(tdirp);
1445 tdirp = NULL((void *)0);
1446 }
1447 }
1448 if (error) {
1449 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1450 vrele(fromnd.ni_dvp);
1451 vrele(fvp);
1452 goto out1;
1453 }
1454 tdvp = tond.ni_dvp;
1455 tvp = tond.ni_vp;
1456 if (tvp != NULL((void *)0)) {
1457 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
1458 error = info.nmi_v3 ? EEXIST17 : EISDIR21;
1459 goto out;
1460 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
1461 error = info.nmi_v3 ? EEXIST17 : ENOTDIR20;
1462 goto out;
1463 }
1464 if (tvp->v_type == VDIR && tvp->v_mountedherev_un.vu_mountedhere) {
1465 error = info.nmi_v3 ? EXDEV18 : ENOTEMPTY66;
1466 goto out;
1467 }
1468 }
1469 if (fvp->v_type == VDIR && fvp->v_mountedherev_un.vu_mountedhere) {
1470 error = info.nmi_v3 ? EXDEV18 : ENOTEMPTY66;
1471 goto out;
1472 }
1473 if (fvp->v_mount != tdvp->v_mount) {
1474 error = info.nmi_v3 ? EXDEV18 : ENOTEMPTY66;
1475 goto out;
1476 }
1477 if (fvp == tdvp)
1478 error = info.nmi_v3 ? EINVAL22 : ENOTEMPTY66;
1479 /*
1480 * If source is the same as the destination (that is the
1481 * same vnode with the same name in the same directory),
1482 * then there is nothing to do.
1483 */
1484 if (fvp == tvp && fromnd.ni_dvp == tdvp &&
1485 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
1486 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
1487 fromnd.ni_cnd.cn_namelen))
1488 error = -1;
1489out:
1490 if (!error) {
1491 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
1492 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
1493 } else {
1494 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
1495 if (tdvp == tvp)
1496 vrele(tdvp);
1497 else
1498 vput(tdvp);
1499 if (tvp)
1500 vput(tvp);
1501 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1502 vrele(fromnd.ni_dvp);
1503 vrele(fvp);
1504 if (error == -1)
1505 error = 0;
1506 }
1507 vrele(tond.ni_startdir);
1508 pool_put(&namei_pool, tond.ni_cnd.cn_pnbuf);
1509out1:
1510 if (fdirp) {
1511 fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred, procp);
1512 vrele(fdirp);
1513 }
1514 if (tdirp) {
1515 tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred, procp);
1516 vrele(tdirp);
1517 }
1518 vrele(fromnd.ni_startdir);
1519 pool_put(&namei_pool, fromnd.ni_cnd.cn_pnbuf);
1520 nfsm_reply(2 * NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((2 *
((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error,
&info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != (
(void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *
)0); } *mrq = info.nmi_mreq; if (error && (!(nfsd->
nd_flag & 0x08) || error == 72)) return(0); }
;
1521 if (info.nmi_v3) {
1522 nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft,
1523 &info);
1524 nfsm_srvwcc(nfsd, tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft,
1525 &info);
1526 }
1527 return (0);
1528
1529nfsmout:
1530 if (fdirp
7.1
'fdirp' is null
)
8
Taking false branch
1531 vrele(fdirp);
1532 if (tdirp
8.1
'tdirp' is null
)
9
Taking false branch
1533 vrele(tdirp);
1534 if (tond.ni_cnd.cn_nameiop) {
10
Branch condition evaluates to a garbage value
1535 vrele(tond.ni_startdir);
1536 pool_put(&namei_pool, tond.ni_cnd.cn_pnbuf);
1537 }
1538 if (fromnd.ni_cnd.cn_nameiop) {
1539 if (fromnd.ni_startdir)
1540 vrele(fromnd.ni_startdir);
1541 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1542
1543 /*
1544 * XXX: Workaround the fact that fromnd.ni_dvp can point
1545 * to the same vnode as fdirp.
1546 */
1547 if (fromnd.ni_dvp != NULL((void *)0) && fromnd.ni_dvp != fdirp)
1548 vrele(fromnd.ni_dvp);
1549 if (fvp)
1550 vrele(fvp);
1551 }
1552 return (error);
1553}
1554
1555/*
1556 * nfs link service
1557 */
1558int
1559nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1560 struct proc *procp, struct mbuf **mrq)
1561{
1562 struct mbuf *nam = nfsd->nd_nam;
1563 struct nfsm_info info;
1564 struct ucred *cred = &nfsd->nd_cr;
1565 struct nameidata nd;
1566 u_int32_t *tl;
1567 int32_t t1;
1568 int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
1569 int getret = 1;
1570 char *cp2;
1571 struct vnode *vp, *xp, *dirp = NULL((void *)0);
1572 struct vattr dirfor, diraft, at;
1573 nfsfh_t nfh, dnfh;
1574 fhandle_t *fhp, *dfhp;
1575
1576 info.nmi_mreq = NULL((void *)0);
1577 info.nmi_mrep = nfsd->nd_mrep;
1578 info.nmi_md = nfsd->nd_md;
1579 info.nmi_dpos = nfsd->nd_dpos;
1580 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1581
1582 fhp = &nfh.fh_generic;
1583 dfhp = &dnfh.fh_generic;
1584 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1585 nfsm_srvmtofh(dfhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (dfhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1586 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
1587
1588 error = nfsrv_fhtovp(fhp, 0, &vp, cred, slp, nam, &rdonly);
1589 if (error) {
1590 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) +{ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + ((info.nmi_v3) ? ((84 + 4) + 8
* 4) : 0)), nfsd, slp, error, &info.nmi_mreq, &info.
nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep
); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }
1591 NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + ((info.nmi_v3) ? ((84 + 4) + 8
* 4) : 0)), nfsd, slp, error, &info.nmi_mreq, &info.
nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep
); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }
;
1592 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
1593 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1594 &info);
1595 error = 0;
1596 goto nfsmout;
1597 }
1598 if (vp->v_type == VDIR && (error = suser_ucred(cred)) != 0)
1599 goto out1;
1600
1601 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 1, 0x0008, UIO_SYSSPACE, -100, ((void *)0),
procp)
;
1602 nd.ni_cnd.cn_cred = cred;
1603 error = nfs_namei(&nd, dfhp, len, slp, nam, &info.nmi_md,
1604 &info.nmi_dpos, &dirp, procp);
1605 if (dirp) {
1606 if (info.nmi_v3)
1607 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
1608 procp);
1609 else {
1610 vrele(dirp);
1611 dirp = NULL((void *)0);
1612 }
1613 }
1614 if (error)
1615 goto out1;
1616 xp = nd.ni_vp;
1617 if (xp != NULL((void *)0)) {
1618 error = EEXIST17;
1619 goto out;
1620 }
1621 xp = nd.ni_dvp;
1622 if (vp->v_mount != xp->v_mount)
1623 error = EXDEV18;
1624out:
1625 if (!error) {
1626 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1627 } else {
1628 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1629 if (nd.ni_dvp == nd.ni_vp)
1630 vrele(nd.ni_dvp);
1631 else
1632 vput(nd.ni_dvp);
1633 if (nd.ni_vp)
1634 vrele(nd.ni_vp);
1635 }
1636out1:
1637 if (info.nmi_v3)
1638 getret = VOP_GETATTR(vp, &at, cred, procp);
1639 if (dirp) {
1640 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1641 vrele(dirp);
1642 }
1643 vrele(vp);
1644 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + ((info.nmi_v3) ? ((84 + 4) + 8
* 4) : 0)), nfsd, slp, error, &info.nmi_mreq, &info.
nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep
); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }
;
1645 if (info.nmi_v3) {
1646 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
1647 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1648 &info);
1649 error = 0;
1650 }
1651nfsmout:
1652 return(error);
1653}
1654
1655/*
1656 * nfs symbolic link service
1657 */
1658int
1659nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1660 struct proc *procp, struct mbuf **mrq)
1661{
1662 struct mbuf *nam = nfsd->nd_nam;
1663 struct ucred *cred = &nfsd->nd_cr;
1664 struct vattr va, dirfor, diraft;
1665 struct nameidata nd;
1666 struct nfsm_info info;
1667 u_int32_t *tl;
1668 int32_t t1;
1669 struct nfsv2_sattr *sp;
1670 char *pathcp = NULL((void *)0), *cp2;
1671 struct uio io;
1672 struct iovec iv;
1673 int error = 0, len, pathlen, len2, dirfor_ret = 1, diraft_ret = 1;
1674 struct vnode *dirp = NULL((void *)0);
1675 nfsfh_t nfh;
1676 fhandle_t *fhp;
1677
1678 info.nmi_mreq = NULL((void *)0);
1679 info.nmi_mrep = nfsd->nd_mrep;
1680 info.nmi_md = nfsd->nd_md;
1681 info.nmi_dpos = nfsd->nd_dpos;
1682 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1683
1684 fhp = &nfh.fh_generic;
1685 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1686 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
1687
1688 NDINIT(&nd, CREATE, LOCKPARENT | SAVESTART, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 1, 0x0008 | 0x001000, UIO_SYSSPACE, -100, (
(void *)0), procp)
;
1689 nd.ni_cnd.cn_cred = cred;
1690 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
1691 &info.nmi_dpos, &dirp, procp);
1692 if (dirp) {
1693 if (info.nmi_v3)
1694 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
1695 procp);
1696 else {
1697 vrele(dirp);
1698 dirp = NULL((void *)0);
1699 }
1700 }
1701 if (error)
1702 goto out;
1703 VATTR_NULL(&va)vattr_null(&va);
1704 if (info.nmi_v3) {
1705 error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
1706 &info.nmi_dpos);
1707 if (error)
1708 goto nfsmout;
1709 }
1710 nfsm_strsiz(len2, 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 (((
len2) = ((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 || (len2) > (1024
)) { m_freem(info.nmi_mrep); error = 72; goto nfsmout; } }
;
1711 pathlen = len2 + 1;
1712 pathcp = malloc(pathlen, M_TEMP127, M_WAITOK0x0001);
1713 iv.iov_base = pathcp;
1714 iv.iov_len = len2;
1715 io.uio_resid = len2;
1716 io.uio_offset = 0;
1717 io.uio_iov = &iv;
1718 io.uio_iovcnt = 1;
1719 io.uio_segflg = UIO_SYSSPACE;
1720 io.uio_rw = UIO_READ;
1721 io.uio_procp = NULL((void *)0);
1722 nfsm_mtouio(&io, len2)if ((len2) > 0 && (t1 = nfsm_mbuftouio(&info.nmi_md
, (&io), (len2), &info.nmi_dpos)) != 0) { error = t1;
m_freem(info.nmi_mrep); goto nfsmout; }
;
1723 if (!info.nmi_v3) {
1724 nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md
->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32)) { (sp) =
(struct nfsv2_sattr *)(info.nmi_dpos); info.nmi_dpos += (32)
; } else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos
, (32), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep
); goto nfsmout; } else { (sp) = (struct nfsv2_sattr *)cp2; }
}
;
1725 va.va_mode = nfstov_mode(sp->sa_mode)(((u_int16_t)(__uint32_t)(__builtin_constant_p((int32_t)((sp->
sa_mode))) ? (__uint32_t)(((__uint32_t)((int32_t)((sp->sa_mode
))) & 0xff) << 24 | ((__uint32_t)((int32_t)((sp->
sa_mode))) & 0xff00) << 8 | ((__uint32_t)((int32_t)
((sp->sa_mode))) & 0xff0000) >> 8 | ((__uint32_t
)((int32_t)((sp->sa_mode))) & 0xff000000) >> 24)
: __swap32md((int32_t)((sp->sa_mode)))))&07777)
;
1726 }
1727 *(pathcp + len2) = '\0';
1728 if (nd.ni_vp) {
1729 vrele(nd.ni_startdir);
1730 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1731 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1732 if (nd.ni_dvp == nd.ni_vp)
1733 vrele(nd.ni_dvp);
1734 else
1735 vput(nd.ni_dvp);
1736 vrele(nd.ni_vp);
1737 error = EEXIST17;
1738 goto out;
1739 }
1740 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va, pathcp);
1741 if (error)
1742 vrele(nd.ni_startdir);
1743 else {
1744 if (info.nmi_v3) {
1745 nd.ni_cnd.cn_nameiop = LOOKUP0;
1746 nd.ni_cnd.cn_flags &= ~(LOCKPARENT0x0008 | SAVESTART0x001000 |
1747 FOLLOW0x0040);
1748 nd.ni_cnd.cn_flags |= (NOFOLLOW0x0000 | LOCKLEAF0x0004);
1749 nd.ni_cnd.cn_proc = procp;
1750 nd.ni_cnd.cn_cred = cred;
1751 error = vfs_lookup(&nd);
1752 if (!error) {
1753 memset(fhp, 0, sizeof(nfh))__builtin_memset((fhp), (0), (sizeof(nfh)));
1754 fhp->fh_fsid =
1755 nd.ni_vp->v_mount->mnt_stat.f_fsid;
1756 error = VFS_VPTOFH(nd.ni_vp, &fhp->fh_fid)(*(nd.ni_vp)->v_mount->mnt_op->vfs_vptofh)(nd.ni_vp,
&fhp->fh_fid)
;
1757 if (!error)
1758 error = VOP_GETATTR(nd.ni_vp, &va, cred,
1759 procp);
1760 vput(nd.ni_vp);
1761 }
1762 } else
1763 vrele(nd.ni_startdir);
1764 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1765 }
1766out:
1767 if (pathcp)
1768 free(pathcp, M_TEMP127, pathlen);
1769 if (dirp) {
1770 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1771 vrele(dirp);
1772 }
1773 nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPATTR(info.nmi_v3){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? (
84 + 4) : 0) + ((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd
, slp, error, &info.nmi_mreq, &info.nmi_mb); if (info
.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep
= ((void *)0); } *mrq = info.nmi_mreq; if (error && (
!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
1774 + NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? (
84 + 4) : 0) + ((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd
, slp, error, &info.nmi_mreq, &info.nmi_mb); if (info
.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep
= ((void *)0); } *mrq = info.nmi_mreq; if (error && (
!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
1775 if (info.nmi_v3) {
1776 if (!error) {
1777 nfsm_srvpostop_fh(fhp){ tl = nfsm_build(&info.nmi_mb, 2 * 4 + (sizeof (fhandle_t
))); *tl++ = nfs_true; *tl++ = ((__uint32_t)(__builtin_constant_p
((int32_t)((sizeof (fhandle_t)))) ? (__uint32_t)(((__uint32_t
)((int32_t)((sizeof (fhandle_t)))) & 0xff) << 24 | (
(__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff00) <<
8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff0000
) >> 8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t))))
& 0xff000000) >> 24) : __swap32md((int32_t)((sizeof
(fhandle_t)))))); bcopy((fhp), tl, (sizeof (fhandle_t))); }
;
1778 nfsm_srvpostop_attr(nfsd, 0, &va, &info);
1779 }
1780 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1781 &info);
1782 }
1783 return (0);
1784nfsmout:
1785 if (nd.ni_cnd.cn_nameiop) {
1786 vrele(nd.ni_startdir);
1787 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1788 }
1789 if (dirp)
1790 vrele(dirp);
1791 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1792 if (nd.ni_dvp == nd.ni_vp)
1793 vrele(nd.ni_dvp);
1794 else
1795 vput(nd.ni_dvp);
1796 if (nd.ni_vp)
1797 vrele(nd.ni_vp);
1798 if (pathcp)
1799 free(pathcp, M_TEMP127, pathlen);
1800 return (error);
1801}
1802
1803/*
1804 * nfs mkdir service
1805 */
1806int
1807nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1808 struct proc *procp, struct mbuf **mrq)
1809{
1810 struct mbuf *nam = nfsd->nd_nam;
1811 struct ucred *cred = &nfsd->nd_cr;
1812 struct vattr va, dirfor, diraft;
1813 struct nfs_fattr *fp;
1814 struct nameidata nd;
1815 struct nfsm_info info;
1816 u_int32_t *tl;
1817 int32_t t1;
1818 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1819 char *cp2;
1820 struct vnode *vp, *dirp = NULL((void *)0);
1821 nfsfh_t nfh;
1822 fhandle_t *fhp;
1823
1824 info.nmi_mreq = NULL((void *)0);
1825 info.nmi_mrep = nfsd->nd_mrep;
1826 info.nmi_md = nfsd->nd_md;
1827 info.nmi_dpos = nfsd->nd_dpos;
1828 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1829
1830 fhp = &nfh.fh_generic;
1831 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1832 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
1833
1834 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 1, 0x0008, UIO_SYSSPACE, -100, ((void *)0),
procp)
;
1835 nd.ni_cnd.cn_cred = cred;
1836 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
1837 &info.nmi_dpos, &dirp, procp);
1838 if (dirp) {
1839 if (info.nmi_v3)
1840 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
1841 else {
1842 vrele(dirp);
1843 dirp = NULL((void *)0);
1844 }
1845 }
1846 if (error) {
1847 nfsm_reply(NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
1848 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1849 &info);
1850 if (dirp)
1851 vrele(dirp);
1852 return (0);
1853 }
1854
1855 VATTR_NULL(&va)vattr_null(&va);
1856 if (info.nmi_v3) {
1857 error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
1858 &info.nmi_dpos);
1859 if (error)
1860 goto nfsmout;
1861 } else {
1862 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; } }
;
1863 va.va_mode = nfstov_mode(*tl++)(((u_int16_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++)))))&07777)
;
1864 }
1865 va.va_type = VDIR;
1866 vp = nd.ni_vp;
1867 if (vp != NULL((void *)0)) {
1868 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1869 if (nd.ni_dvp == vp)
1870 vrele(nd.ni_dvp);
1871 else
1872 vput(nd.ni_dvp);
1873 vrele(vp);
1874 error = EEXIST17;
1875 goto out;
1876 }
1877 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va);
1878 if (!error) {
1879 vp = nd.ni_vp;
1880 memset(fhp, 0, sizeof(nfh))__builtin_memset((fhp), (0), (sizeof(nfh)));
1881 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
1882 error = VFS_VPTOFH(vp, &fhp->fh_fid)(*(vp)->v_mount->mnt_op->vfs_vptofh)(vp, &fhp->
fh_fid)
;
1883 if (!error)
1884 error = VOP_GETATTR(vp, &va, cred, procp);
1885 vput(vp);
1886 }
1887out:
1888 if (dirp) {
1889 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1890 vrele(dirp);
1891 }
1892 nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPATTR(info.nmi_v3) +{ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? (
84 + 4) : 0) + ((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd
, slp, error, &info.nmi_mreq, &info.nmi_mb); if (info
.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep
= ((void *)0); } *mrq = info.nmi_mreq; if (error && (
!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
1893 NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (sizeof (fhandle_t)) : 32) + ((info.nmi_v3) ? (
84 + 4) : 0) + ((info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd
, slp, error, &info.nmi_mreq, &info.nmi_mb); if (info
.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep
= ((void *)0); } *mrq = info.nmi_mreq; if (error && (
!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
1894 if (info.nmi_v3) {
1895 if (!error) {
1896 nfsm_srvpostop_fh(fhp){ tl = nfsm_build(&info.nmi_mb, 2 * 4 + (sizeof (fhandle_t
))); *tl++ = nfs_true; *tl++ = ((__uint32_t)(__builtin_constant_p
((int32_t)((sizeof (fhandle_t)))) ? (__uint32_t)(((__uint32_t
)((int32_t)((sizeof (fhandle_t)))) & 0xff) << 24 | (
(__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff00) <<
8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t)))) & 0xff0000
) >> 8 | ((__uint32_t)((int32_t)((sizeof (fhandle_t))))
& 0xff000000) >> 24) : __swap32md((int32_t)((sizeof
(fhandle_t)))))); bcopy((fhp), tl, (sizeof (fhandle_t))); }
;
1897 nfsm_srvpostop_attr(nfsd, 0, &va, &info);
1898 }
1899 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1900 &info);
1901 } else {
1902 nfsm_srvfhtom(&info.nmi_mb, fhp, info.nmi_v3);
1903 fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR68);
1904 nfsm_srvfattr(nfsd, &va, fp);
1905 }
1906 return (0);
1907nfsmout:
1908 if (dirp)
1909 vrele(dirp);
1910 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1911 if (nd.ni_dvp == nd.ni_vp)
1912 vrele(nd.ni_dvp);
1913 else
1914 vput(nd.ni_dvp);
1915 if (nd.ni_vp)
1916 vrele(nd.ni_vp);
1917 return (error);
1918}
1919
1920/*
1921 * nfs rmdir service
1922 */
1923int
1924nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1925 struct proc *procp, struct mbuf **mrq)
1926{
1927 struct mbuf *nam = nfsd->nd_nam;
1928 struct ucred *cred = &nfsd->nd_cr;
1929 struct nfsm_info info;
1930 u_int32_t *tl;
1931 int32_t t1;
1932 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1933 char *cp2;
1934 struct vnode *vp, *dirp = NULL((void *)0);
1935 struct vattr dirfor, diraft;
1936 nfsfh_t nfh;
1937 fhandle_t *fhp;
1938 struct nameidata nd;
1939
1940 info.nmi_mreq = NULL((void *)0);
1941 info.nmi_mrep = nfsd->nd_mrep;
1942 info.nmi_md = nfsd->nd_md;
1943 info.nmi_dpos = nfsd->nd_dpos;
1944 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1945
1946 fhp = &nfh.fh_generic;
1947 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
1948 nfsm_srvnamesiz(len){ { 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))))) > 255) error = 63; if ((
len) <= 0) error = 72; if (error) { nfsd->nd_repstat = error
; if (error && !(nfsd->nd_flag & 0x08)) (void)
nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, &info
.nmi_mb); else (void) nfs_rephead((0), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }; }
;
1949
1950 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 2, 0x0008 | 0x0004, UIO_SYSSPACE, -100, ((void
*)0), procp)
;
1951 nd.ni_cnd.cn_cred = cred;
1952 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
1953 &info.nmi_dpos, &dirp, procp);
1954 if (dirp) {
1955 if (info.nmi_v3)
1956 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
1957 procp);
1958 else {
1959 vrele(dirp);
1960 dirp = NULL((void *)0);
1961 }
1962 }
1963 if (error) {
1964 nfsm_reply(NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
1965 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1966 &info);
1967 if (dirp)
1968 vrele(dirp);
1969 return (0);
1970 }
1971 vp = nd.ni_vp;
1972 if (vp->v_type != VDIR) {
1973 error = ENOTDIR20;
1974 goto out;
1975 }
1976 /*
1977 * No rmdir "." please.
1978 */
1979 if (nd.ni_dvp == vp) {
1980 error = EINVAL22;
1981 goto out;
1982 }
1983 /*
1984 * A mounted on directory cannot be deleted.
1985 */
1986 if (vp->v_mountedherev_un.vu_mountedhere != NULL((void *)0)) {
1987 error = EBUSY16;
1988 goto out;
1989 }
1990 /*
1991 * The root of a mounted filesystem cannot be deleted.
1992 */
1993 if (vp->v_flag & VROOT0x0001)
1994 error = EBUSY16;
1995out:
1996 if (!error) {
1997 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
1998 } else {
1999 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
2000 if (nd.ni_dvp == nd.ni_vp)
2001 vrele(nd.ni_dvp);
2002 else
2003 vput(nd.ni_dvp);
2004 vput(vp);
2005 }
2006 if (dirp) {
2007 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
2008 vrele(dirp);
2009 }
2010 nfsm_reply(NFSX_WCCDATA(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? ((84 + 4) + 8 * 4) : 0)), nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); if (info.nmi_mrep != ((void
*)0)) { m_freem(info.nmi_mrep); info.nmi_mrep = ((void *)0);
} *mrq = info.nmi_mreq; if (error && (!(nfsd->nd_flag
& 0x08) || error == 72)) return(0); }
;
2011 if (info.nmi_v3) {
2012 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
2013 &info);
2014 error = 0;
2015 }
2016nfsmout:
2017 return(error);
2018}
2019
2020/*
2021 * nfs readdir service
2022 * - mallocs what it thinks is enough to read
2023 * count rounded up to a multiple of NFS_DIRBLKSIZ <= NFS_MAXREADDIR
2024 * - calls VOP_READDIR()
2025 * - loops around building the reply
2026 * if the output generated exceeds count break out of loop
2027 * - it only knows that it has encountered eof when the VOP_READDIR()
2028 * reads nothing
2029 * - as such one readdir rpc will return eof false although you are there
2030 * and then the next will return eof
2031 * - it trims out records with d_fileno == 0
2032 * this doesn't matter for Unix clients, but they might confuse clients
2033 * for other os'.
2034 * NB: It is tempting to set eof to true if the VOP_READDIR() reads less
2035 * than requested, but this may not apply to all filesystems. For
2036 * example, client NFS does not { although it is never remote mounted
2037 * anyhow }
2038 * The alternate call nfsrv_readdirplus() does lookups as well.
2039 * PS: The NFS protocol spec. does not clarify what the "count" byte
2040 * argument is a count of.. just name strings and file id's or the
2041 * entire reply rpc or ...
2042 * I tried just file name and id sizes and it confused the Sun client,
2043 * so I am using the full rpc size now. The "paranoia.." comment refers
2044 * to including the status longwords that are not a part of the dir.
2045 * "entry" structures, but are in the rpc.
2046 */
2047struct flrep {
2048 nfsuint64 fl_off;
2049 u_int32_t fl_postopok;
2050 u_int32_t fl_fattr[NFSX_V3FATTR84 / sizeof (u_int32_t)];
2051 u_int32_t fl_fhok;
2052 u_int32_t fl_fhsize;
2053 u_int32_t fl_nfh[NFSX_V3FH(sizeof (fhandle_t)) / sizeof (u_int32_t)];
2054};
2055
2056int
2057nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2058 struct proc *procp, struct mbuf **mrq)
2059{
2060 struct mbuf *nam = nfsd->nd_nam;
2061 struct ucred *cred = &nfsd->nd_cr;
2062 struct dirent *dp;
2063 struct nfsm_info info;
2064 u_int32_t *tl;
2065 int32_t t1;
2066 char *cpos, *cend, *cp2, *rbuf;
2067 struct vnode *vp;
2068 struct vattr at;
2069 nfsfh_t nfh;
2070 fhandle_t *fhp;
2071 struct uio io;
2072 struct iovec iv;
2073 int len, nlen, pad, xfer, error = 0, getret = 1;
2074 int siz, cnt, fullsiz, eofflag, rdonly;
2075 u_quad_t off, toff, verf;
2076
2077 info.nmi_mreq = NULL((void *)0);
2078 info.nmi_mrep = nfsd->nd_mrep;
2079 info.nmi_md = nfsd->nd_md;
2080 info.nmi_dpos = nfsd->nd_dpos;
2081 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2082
2083 fhp = &nfh.fh_generic;
2084 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
2085 if (info.nmi_v3) {
2086 nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED){ t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info.nmi_md
->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (5 * 4)) { (tl
) = (u_int32_t *)(info.nmi_dpos); info.nmi_dpos += (5 * 4); }
else if ((t1 = nfsm_disct(&info.nmi_md, &info.nmi_dpos
, (5 * 4), t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep
); goto nfsmout; } else { (tl) = (u_int32_t *)cp2; } }
;
2087 toff = 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]))))
;
2088 tl += 2;
2089 verf = 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]))))
;
2090 tl += 2;
2091 } else {
2092 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; } }
;
2093 toff = 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++))))
;
2094 }
2095 off = toff;
2096 cnt = 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))))
;
2097 xfer = NFS_SRVMAXDATA(nfsd)(((nfsd)->nd_flag & 0x08) ? (((nfsd)->nd_nam2) ? 32768
: (64 * 1024)) : 8192)
;
2098 if (cnt > xfer || cnt < 0)
2099 cnt = xfer;
2100 siz = ((cnt + DIRBLKSIZ(1 << 9) - 1) & ~(DIRBLKSIZ(1 << 9) - 1));
2101 if (siz > xfer)
2102 siz = xfer;
2103 fullsiz = siz;
2104 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2105 if (error) {
2106 nfsm_reply(NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((4)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2107 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2108 error = 0;
2109 goto nfsmout;
2110 }
2111 if (info.nmi_v3)
2112 error = getret = VOP_GETATTR(vp, &at, cred, procp);
2113 if (!error)
2114 error = nfsrv_access(vp, VEXEC00100, cred, rdonly, procp, 0);
2115 if (error) {
2116 vput(vp);
2117 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0)), nfsd, slp, error, &info.nmi_mreq
, &info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem
(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
2118 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2119 error = 0;
2120 goto nfsmout;
2121 }
2122 VOP_UNLOCK(vp);
2123 rbuf = malloc(fullsiz, M_TEMP127, M_WAITOK0x0001);
2124again:
2125 iv.iov_base = rbuf;
2126 iv.iov_len = fullsiz;
2127 io.uio_iov = &iv;
2128 io.uio_iovcnt = 1;
2129 io.uio_offset = (off_t)off;
2130 io.uio_resid = fullsiz;
2131 io.uio_segflg = UIO_SYSSPACE;
2132 io.uio_rw = UIO_READ;
2133 io.uio_procp = NULL((void *)0);
2134 eofflag = 0;
2135
2136 vn_lock(vp, LK_EXCLUSIVE0x0001UL | LK_RETRY0x2000UL);
2137 error = VOP_READDIR(vp, &io, cred, &eofflag);
2138
2139 off = (off_t)io.uio_offset;
2140 if (info.nmi_v3) {
2141 getret = VOP_GETATTR(vp, &at, cred, procp);
2142 if (!error)
2143 error = getret;
2144 }
2145
2146 VOP_UNLOCK(vp);
2147 if (error) {
2148 vrele(vp);
2149 free(rbuf, M_TEMP127, fullsiz);
2150 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0)), nfsd, slp, error, &info.nmi_mreq
, &info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem
(info.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
2151 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2152 error = 0;
2153 goto nfsmout;
2154 }
2155 if (io.uio_resid) {
2156 siz -= io.uio_resid;
2157
2158 /*
2159 * If nothing read, return eof
2160 * rpc reply
2161 */
2162 if (siz == 0) {
2163 vrele(vp);
2164 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_COOKIEVERF(info.nmi_v3) +{ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + ((info.nmi_v3) ? 8 : 0) + 2 * 4
), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
2165 2 * NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + ((info.nmi_v3) ? 8 : 0) + 2 * 4
), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2166 if (info.nmi_v3) {
2167 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2168 tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED4);
2169 txdr_hyper(at.va_filerev, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((at.va_filerev) >> 32)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) >> 32)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) >> 32))
& 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) >> 32)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)((at.va_filerev) >> 32)) & 0xff000000) >> 24
) : __swap32md((u_int32_t)((at.va_filerev) >> 32))); ((
u_int32_t *)(tl))[1] = (__uint32_t)(__builtin_constant_p((u_int32_t
)((at.va_filerev) & 0xffffffff)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) & 0xffffffff
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)((at.va_filerev) &
0xffffffff))); } while (0)
;
2170 tl += 2;
2171 } else
2172 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2173 *tl++ = nfs_false;
2174 *tl = nfs_true;
2175 free(rbuf, M_TEMP127, fullsiz);
2176 error = 0;
2177 goto nfsmout;
2178 }
2179 }
2180
2181 /*
2182 * Check for degenerate cases of nothing useful read.
2183 * If so go try again
2184 */
2185 cpos = rbuf;
2186 cend = rbuf + siz;
2187 dp = (struct dirent *)cpos;
2188
2189 while (cpos < cend && dp->d_fileno == 0) {
2190 cpos += dp->d_reclen;
2191 dp = (struct dirent *)cpos;
2192 }
2193 if (cpos >= cend) {
2194 toff = off;
2195 siz = fullsiz;
2196 goto again;
2197 }
2198
2199 len = 3 * NFSX_UNSIGNED4; /* paranoia, probably can be 0 */
2200 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_COOKIEVERF(info.nmi_v3) + siz){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + ((info.nmi_v3) ? 8 : 0) + siz)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2201 if (info.nmi_v3) {
2202 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2203 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2204 txdr_hyper(at.va_filerev, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((at.va_filerev) >> 32)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) >> 32)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) >> 32))
& 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) >> 32)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)((at.va_filerev) >> 32)) & 0xff000000) >> 24
) : __swap32md((u_int32_t)((at.va_filerev) >> 32))); ((
u_int32_t *)(tl))[1] = (__uint32_t)(__builtin_constant_p((u_int32_t
)((at.va_filerev) & 0xffffffff)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) & 0xffffffff
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)((at.va_filerev) &
0xffffffff))); } while (0)
;
2205 }
2206
2207 /* Loop through the records and build reply */
2208 while (cpos < cend) {
2209 if (dp->d_fileno != 0) {
2210 nlen = dp->d_namlen;
2211 pad = nfsm_padlen(nlen)((((nlen)+3)&(~0x3)) - (nlen));
2212 len += (4 * NFSX_UNSIGNED4 + nlen + pad);
2213 if (info.nmi_v3)
2214 len += 2 * NFSX_UNSIGNED4;
2215 if (len > cnt) {
2216 eofflag = 0;
2217 break;
2218 }
2219 /*
2220 * Build the directory record xdr from
2221 * the dirent entry.
2222 */
2223 tl = nfsm_build(&info.nmi_mb,
2224 (info.nmi_v3 ? 3 : 2) * NFSX_UNSIGNED4);
2225 *tl++ = nfs_true;
2226 if (info.nmi_v3)
2227 txdr_hyper(dp->d_fileno, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((dp->d_fileno) >> 32)) ? (__uint32_t)((
(__uint32_t)((u_int32_t)((dp->d_fileno) >> 32)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)((dp->d_fileno
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((dp->d_fileno) >> 32)) & 0xff0000) >> 8 |
((__uint32_t)((u_int32_t)((dp->d_fileno) >> 32)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((dp->d_fileno
) >> 32))); ((u_int32_t *)(tl))[1] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((dp->d_fileno) & 0xffffffff)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)((dp->d_fileno) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((dp->
d_fileno) & 0xffffffff)) & 0xff00) << 8 | ((__uint32_t
)((u_int32_t)((dp->d_fileno) & 0xffffffff)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)((dp->d_fileno) &
0xffffffff)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)((dp->d_fileno) & 0xffffffff))); } while (0)
;
2228 else
2229 *tl = txdr_unsigned((u_int32_t)dp->d_fileno)((__uint32_t)(__builtin_constant_p((int32_t)((u_int32_t)dp->
d_fileno)) ? (__uint32_t)(((__uint32_t)((int32_t)((u_int32_t)
dp->d_fileno)) & 0xff) << 24 | ((__uint32_t)((int32_t
)((u_int32_t)dp->d_fileno)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)((u_int32_t)dp->d_fileno)) & 0xff0000) >>
8 | ((__uint32_t)((int32_t)((u_int32_t)dp->d_fileno)) &
0xff000000) >> 24) : __swap32md((int32_t)((u_int32_t)dp
->d_fileno))))
;
2230
2231 /* And copy the name */
2232 nfsm_strtombuf(&info.nmi_mb, dp->d_name, nlen);
2233
2234 /* Finish off the record */
2235 if (info.nmi_v3) {
2236 tl = nfsm_build(&info.nmi_mb, 2*NFSX_UNSIGNED4);
2237 txdr_hyper(dp->d_off, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((dp->d_off) >> 32)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((dp->d_off) >> 32)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((dp->d_off) >> 32)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)((dp->d_off
) >> 32)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)((dp->d_off) >> 32)) & 0xff000000) >> 24)
: __swap32md((u_int32_t)((dp->d_off) >> 32))); ((u_int32_t
*)(tl))[1] = (__uint32_t)(__builtin_constant_p((u_int32_t)((
dp->d_off) & 0xffffffff)) ? (__uint32_t)(((__uint32_t)
((u_int32_t)((dp->d_off) & 0xffffffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((dp->d_off) & 0xffffffff
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)((dp->
d_off) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((dp->d_off) & 0xffffffff)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)((dp->d_off) & 0xffffffff
))); } while (0)
;
2238 } else {
2239 tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4);
2240 *tl = txdr_unsigned((u_int32_t)dp->d_off)((__uint32_t)(__builtin_constant_p((int32_t)((u_int32_t)dp->
d_off)) ? (__uint32_t)(((__uint32_t)((int32_t)((u_int32_t)dp->
d_off)) & 0xff) << 24 | ((__uint32_t)((int32_t)((u_int32_t
)dp->d_off)) & 0xff00) << 8 | ((__uint32_t)((int32_t
)((u_int32_t)dp->d_off)) & 0xff0000) >> 8 | ((__uint32_t
)((int32_t)((u_int32_t)dp->d_off)) & 0xff000000) >>
24) : __swap32md((int32_t)((u_int32_t)dp->d_off))))
;
2241 }
2242 }
2243 cpos += dp->d_reclen;
2244 dp = (struct dirent *)cpos;
2245 }
2246 vrele(vp);
2247 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2248 *tl++ = nfs_false;
2249 if (eofflag)
2250 *tl = nfs_true;
2251 else
2252 *tl = nfs_false;
2253 free(rbuf, M_TEMP127, fullsiz);
2254nfsmout:
2255 return(error);
2256}
2257
2258int
2259nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2260 struct proc *procp, struct mbuf **mrq)
2261{
2262 struct mbuf *nam = nfsd->nd_nam;
2263 struct ucred *cred = &nfsd->nd_cr;
2264 struct dirent *dp;
2265 struct nfsm_info info;
2266 u_int32_t *tl;
2267 int32_t t1;
2268 char *cpos, *cend, *cp2, *rbuf;
2269 struct vnode *vp, *nvp;
2270 struct flrep fl;
2271 nfsfh_t nfh;
2272 fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh;
2273 struct uio io;
2274 struct iovec iv;
2275 struct vattr va, at, *vap = &va;
2276 struct nfs_fattr *fp;
2277 int len, nlen, pad, xfer, error = 0, getret = 1;
2278 int siz, cnt, fullsiz, eofflag, rdonly, dirlen;
2279 u_quad_t off, toff, verf;
2280
2281 info.nmi_mreq = NULL((void *)0);
2282 info.nmi_mrep = nfsd->nd_mrep;
2283 info.nmi_md = nfsd->nd_md;
2284 info.nmi_dpos = nfsd->nd_dpos;
2285 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2286
2287 fhp = &nfh.fh_generic;
2288 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
2289 nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED){ 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; } }
;
2290 off = toff = 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]))))
;
2291 tl += 2;
2292 verf = 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]))))
;
2293 tl += 2;
2294 siz = 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++))))
;
2295 cnt = 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))))
;
2296 xfer = NFS_SRVMAXDATA(nfsd)(((nfsd)->nd_flag & 0x08) ? (((nfsd)->nd_nam2) ? 32768
: (64 * 1024)) : 8192)
;
2297 if (cnt > xfer || cnt < 0)
2298 cnt = xfer;
2299 siz = ((siz + DIRBLKSIZ(1 << 9) - 1) & ~(DIRBLKSIZ(1 << 9) - 1));
2300 if (siz > xfer)
2301 siz = xfer;
2302 fullsiz = siz;
2303 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2304 if (error) {
2305 nfsm_reply(NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((4)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2306 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2307 error = 0;
2308 goto nfsmout;
2309 }
2310 error = getret = VOP_GETATTR(vp, &at, cred, procp);
2311 if (!error)
2312 error = nfsrv_access(vp, VEXEC00100, cred, rdonly, procp, 0);
2313 if (error) {
2314 vput(vp);
2315 nfsm_reply(NFSX_V3POSTOPATTR){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead(((84
+ 4)), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb
); if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep)
; info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }
;
2316 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2317 error = 0;
2318 goto nfsmout;
2319 }
2320 VOP_UNLOCK(vp);
2321
2322 rbuf = malloc(fullsiz, M_TEMP127, M_WAITOK0x0001);
2323again:
2324 iv.iov_base = rbuf;
2325 iv.iov_len = fullsiz;
2326 io.uio_iov = &iv;
2327 io.uio_iovcnt = 1;
2328 io.uio_offset = (off_t)off;
2329 io.uio_resid = fullsiz;
2330 io.uio_segflg = UIO_SYSSPACE;
2331 io.uio_rw = UIO_READ;
2332 io.uio_procp = NULL((void *)0);
2333 eofflag = 0;
2334
2335 vn_lock(vp, LK_EXCLUSIVE0x0001UL | LK_RETRY0x2000UL);
2336 error = VOP_READDIR(vp, &io, cred, &eofflag);
2337
2338 off = (u_quad_t)io.uio_offset;
2339 getret = VOP_GETATTR(vp, &at, cred, procp);
2340
2341 VOP_UNLOCK(vp);
2342
2343 if (!error)
2344 error = getret;
2345 if (error) {
2346 vrele(vp);
2347 free(rbuf, M_TEMP127, fullsiz);
2348 nfsm_reply(NFSX_V3POSTOPATTR){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead(((84
+ 4)), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb
); if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep)
; info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }
;
2349 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2350 error = 0;
2351 goto nfsmout;
2352 }
2353 if (io.uio_resid) {
2354 siz -= io.uio_resid;
2355
2356 /*
2357 * If nothing read, return eof
2358 * rpc reply
2359 */
2360 if (siz == 0) {
2361 vrele(vp);
2362 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +{ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead(((84
+ 4) + 8 + 2 * 4), nfsd, slp, error, &info.nmi_mreq, &
info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info
.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
2363 2 * NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead(((84
+ 4) + 8 + 2 * 4), nfsd, slp, error, &info.nmi_mreq, &
info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info
.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
2364 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2365 tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED4);
2366 txdr_hyper(at.va_filerev, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((at.va_filerev) >> 32)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) >> 32)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) >> 32))
& 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) >> 32)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)((at.va_filerev) >> 32)) & 0xff000000) >> 24
) : __swap32md((u_int32_t)((at.va_filerev) >> 32))); ((
u_int32_t *)(tl))[1] = (__uint32_t)(__builtin_constant_p((u_int32_t
)((at.va_filerev) & 0xffffffff)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) & 0xffffffff
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)((at.va_filerev) &
0xffffffff))); } while (0)
;
2367 tl += 2;
2368 *tl++ = nfs_false;
2369 *tl = nfs_true;
2370 free(rbuf, M_TEMP127, fullsiz);
2371 error = 0;
2372 goto nfsmout;
2373 }
2374 }
2375
2376 /*
2377 * Check for degenerate cases of nothing useful read.
2378 * If so go try again
2379 */
2380 cpos = rbuf;
2381 cend = rbuf + siz;
2382 dp = (struct dirent *)cpos;
2383
2384 while (cpos < cend && dp->d_fileno == 0) {
2385 cpos += dp->d_reclen;
2386 dp = (struct dirent *)cpos;
2387 }
2388 if (cpos >= cend) {
2389 toff = off;
2390 siz = fullsiz;
2391 goto again;
2392 }
2393
2394 /*
2395 * struct READDIRPLUS3resok {
2396 * postop_attr dir_attributes;
2397 * cookieverf3 cookieverf;
2398 * dirlistplus3 reply;
2399 * }
2400 *
2401 * struct dirlistplus3 {
2402 * entryplus3 *entries;
2403 * bool eof;
2404 * }
2405 */
2406 dirlen = len = NFSX_V3POSTOPATTR(84 + 4) + NFSX_V3COOKIEVERF8 + 2 * NFSX_UNSIGNED4;
2407 nfsm_reply(cnt){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((cnt
), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2408 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2409 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2410 txdr_hyper(at.va_filerev, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((at.va_filerev) >> 32)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) >> 32)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) >> 32))
& 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) >> 32)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)((at.va_filerev) >> 32)) & 0xff000000) >> 24
) : __swap32md((u_int32_t)((at.va_filerev) >> 32))); ((
u_int32_t *)(tl))[1] = (__uint32_t)(__builtin_constant_p((u_int32_t
)((at.va_filerev) & 0xffffffff)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((at.va_filerev) & 0xffffffff
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)((at.va_filerev
) & 0xffffffff)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((at.va_filerev) & 0xffffffff)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)((at.va_filerev) &
0xffffffff))); } while (0)
;
2411
2412 /* Loop through the records and build reply */
2413 while (cpos < cend) {
2414 if (dp->d_fileno != 0) {
2415 nlen = dp->d_namlen;
2416 pad = nfsm_padlen(nlen)((((nlen)+3)&(~0x3)) - (nlen));
2417
2418 /*
2419 * For readdir_and_lookup get the vnode using
2420 * the file number.
2421 */
2422 if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp)(*(vp->v_mount)->mnt_op->vfs_vget)(vp->v_mount, dp
->d_fileno, &nvp)
)
2423 goto invalid;
2424 memset(nfhp, 0, NFSX_V3FH)__builtin_memset((nfhp), (0), ((sizeof (fhandle_t))));
2425 nfhp->fh_fsid =
2426 nvp->v_mount->mnt_stat.f_fsid;
2427 if (VFS_VPTOFH(nvp, &nfhp->fh_fid)(*(nvp)->v_mount->mnt_op->vfs_vptofh)(nvp, &nfhp
->fh_fid)
) {
2428 vput(nvp);
2429 goto invalid;
2430 }
2431 if (VOP_GETATTR(nvp, vap, cred, procp)) {
2432 vput(nvp);
2433 goto invalid;
2434 }
2435 vput(nvp);
2436
2437 /*
2438 * If either the dircount or maxcount will be
2439 * exceeded, get out now. Both of these lengths
2440 * are calculated conservatively, including all
2441 * XDR overheads.
2442 *
2443 * Each entry:
2444 * 2 * NFSX_UNSIGNED for fileid3
2445 * 1 * NFSX_UNSIGNED for length of name
2446 * nlen + pad == space the name takes up
2447 * 2 * NFSX_UNSIGNED for the cookie
2448 * 1 * NFSX_UNSIGNED to indicate if file handle present
2449 * 1 * NFSX_UNSIGNED for the file handle length
2450 * NFSX_V3FH == space our file handle takes up
2451 * NFSX_V3POSTOPATTR == space the attributes take up
2452 * 1 * NFSX_UNSIGNED for next pointer
2453 */
2454 len += (8 * NFSX_UNSIGNED4 + nlen + pad + NFSX_V3FH(sizeof (fhandle_t)) +
2455 NFSX_V3POSTOPATTR(84 + 4));
2456 dirlen += (6 * NFSX_UNSIGNED4 + nlen + pad);
2457 if (len > cnt || dirlen > fullsiz) {
2458 eofflag = 0;
2459 break;
2460 }
2461
2462 tl = nfsm_build(&info.nmi_mb, 3 * NFSX_UNSIGNED4);
2463 *tl++ = nfs_true;
2464 txdr_hyper(dp->d_fileno, tl)do { ((u_int32_t *)(tl))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((dp->d_fileno) >> 32)) ? (__uint32_t)((
(__uint32_t)((u_int32_t)((dp->d_fileno) >> 32)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)((dp->d_fileno
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((dp->d_fileno) >> 32)) & 0xff0000) >> 8 |
((__uint32_t)((u_int32_t)((dp->d_fileno) >> 32)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((dp->d_fileno
) >> 32))); ((u_int32_t *)(tl))[1] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((dp->d_fileno) & 0xffffffff)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)((dp->d_fileno) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((dp->
d_fileno) & 0xffffffff)) & 0xff00) << 8 | ((__uint32_t
)((u_int32_t)((dp->d_fileno) & 0xffffffff)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)((dp->d_fileno) &
0xffffffff)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)((dp->d_fileno) & 0xffffffff))); } while (0)
;
2465
2466 /* And copy the name */
2467 nfsm_strtombuf(&info.nmi_mb, dp->d_name, nlen);
2468
2469 /*
2470 * Build the directory record xdr from
2471 * the dirent entry.
2472 */
2473 fp = (struct nfs_fattr *)&fl.fl_fattr;
2474 nfsm_srvfattr(nfsd, vap, fp);
2475 fl.fl_fhsize = txdr_unsigned(NFSX_V3FH)((__uint32_t)(__builtin_constant_p((int32_t)((sizeof (fhandle_t
)))) ? (__uint32_t)(((__uint32_t)((int32_t)((sizeof (fhandle_t
)))) & 0xff) << 24 | ((__uint32_t)((int32_t)((sizeof
(fhandle_t)))) & 0xff00) << 8 | ((__uint32_t)((int32_t
)((sizeof (fhandle_t)))) & 0xff0000) >> 8 | ((__uint32_t
)((int32_t)((sizeof (fhandle_t)))) & 0xff000000) >>
24) : __swap32md((int32_t)((sizeof (fhandle_t))))))
;
2476 fl.fl_fhok = nfs_true;
2477 fl.fl_postopok = nfs_true;
2478 txdr_hyper(dp->d_off, fl.fl_off.nfsuquad)do { ((u_int32_t *)(fl.fl_off.nfsuquad))[0] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((dp->d_off) >> 32)) ? (__uint32_t)(((__uint32_t
)((u_int32_t)((dp->d_off) >> 32)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)((dp->d_off) >> 32)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)((dp->d_off
) >> 32)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)((dp->d_off) >> 32)) & 0xff000000) >> 24)
: __swap32md((u_int32_t)((dp->d_off) >> 32))); ((u_int32_t
*)(fl.fl_off.nfsuquad))[1] = (__uint32_t)(__builtin_constant_p
((u_int32_t)((dp->d_off) & 0xffffffff)) ? (__uint32_t)
(((__uint32_t)((u_int32_t)((dp->d_off) & 0xffffffff)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)((dp->d_off)
& 0xffffffff)) & 0xff00) << 8 | ((__uint32_t)(
(u_int32_t)((dp->d_off) & 0xffffffff)) & 0xff0000)
>> 8 | ((__uint32_t)((u_int32_t)((dp->d_off) & 0xffffffff
)) & 0xff000000) >> 24) : __swap32md((u_int32_t)((dp
->d_off) & 0xffffffff))); } while (0)
;
2479
2480 /* Now copy the flrep structure out. */
2481 nfsm_buftombuf(&info.nmi_mb, &fl, sizeof(struct flrep));
2482 }
2483invalid:
2484 cpos += dp->d_reclen;
2485 dp = (struct dirent *)cpos;
2486 }
2487 vrele(vp);
2488 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2489 *tl++ = nfs_false;
2490 if (eofflag)
2491 *tl = nfs_true;
2492 else
2493 *tl = nfs_false;
2494 free(rbuf, M_TEMP127, fullsiz);
2495nfsmout:
2496 return(error);
2497}
2498
2499/*
2500 * nfs commit service
2501 */
2502int
2503nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2504 struct proc *procp, struct mbuf **mrq)
2505{
2506 struct mbuf *nam = nfsd->nd_nam;
2507 struct ucred *cred = &nfsd->nd_cr;
2508 struct vattr bfor, aft;
2509 struct vnode *vp;
2510 struct nfsm_info info;
2511 struct timeval boottime;
2512 nfsfh_t nfh;
2513 fhandle_t *fhp;
2514 u_int32_t *tl;
2515 int32_t t1;
2516 int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt;
2517 char *cp2;
2518 u_quad_t off;
2519
2520 info.nmi_mreq = NULL((void *)0);
2521 info.nmi_mrep = nfsd->nd_mrep;
2522 info.nmi_md = nfsd->nd_md;
2523 info.nmi_dpos = nfsd->nd_dpos;
2524 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2525
2526 fhp = &nfh.fh_generic;
2527 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
2528 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; } }
;
2529
2530 /*
2531 * XXX At this time VOP_FSYNC() does not accept offset and byte
2532 * count parameters, so these arguments are useless (someday maybe).
2533 */
2534 off = 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]))))
;
2535 tl += 2;
2536 cnt = 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))))
;
2537 if (cnt < 0)
2538 cnt = 0;
2539 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2540 if (error) {
2541 nfsm_reply(2 * NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((2 *
4), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb);
if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2542 nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
2543 error = 0;
2544 goto nfsmout;
2545 }
2546 for_ret = VOP_GETATTR(vp, &bfor, cred, procp);
2547 error = VOP_FSYNC(vp, cred, MNT_WAIT1, procp);
2548 aft_ret = VOP_GETATTR(vp, &aft, cred, procp);
2549 vput(vp);
2550 nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
84 + 4) + 8 * 4) + 8), nfsd, slp, error, &info.nmi_mreq, &
info.nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info
.nmi_mrep); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq
; if (error && (!(nfsd->nd_flag & 0x08) || error
== 72)) return(0); }
;
2551 nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
2552 if (!error) {
2553 tl = nfsm_build(&info.nmi_mb, NFSX_V3WRITEVERF8);
2554 microboottime(&boottime);
2555 *tl++ = txdr_unsigned(boottime.tv_sec)((__uint32_t)(__builtin_constant_p((int32_t)(boottime.tv_sec)
) ? (__uint32_t)(((__uint32_t)((int32_t)(boottime.tv_sec)) &
0xff) << 24 | ((__uint32_t)((int32_t)(boottime.tv_sec)
) & 0xff00) << 8 | ((__uint32_t)((int32_t)(boottime
.tv_sec)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t
)(boottime.tv_sec)) & 0xff000000) >> 24) : __swap32md
((int32_t)(boottime.tv_sec))))
;
2556 *tl = txdr_unsigned(boottime.tv_usec)((__uint32_t)(__builtin_constant_p((int32_t)(boottime.tv_usec
)) ? (__uint32_t)(((__uint32_t)((int32_t)(boottime.tv_usec)) &
0xff) << 24 | ((__uint32_t)((int32_t)(boottime.tv_usec
)) & 0xff00) << 8 | ((__uint32_t)((int32_t)(boottime
.tv_usec)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t
)(boottime.tv_usec)) & 0xff000000) >> 24) : __swap32md
((int32_t)(boottime.tv_usec))))
;
2557 } else
2558 error = 0;
2559nfsmout:
2560 return(error);
2561}
2562
2563/*
2564 * nfs statfs service
2565 */
2566int
2567nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2568 struct proc *procp, struct mbuf **mrq)
2569{
2570 struct mbuf *nam = nfsd->nd_nam;
2571 struct ucred *cred = &nfsd->nd_cr;
2572 struct statfs *sf;
2573 struct nfs_statfs *sfp;
2574 struct nfsm_info info;
2575 u_int32_t *tl;
2576 int32_t t1;
2577 int error = 0, rdonly, getret = 1;
2578 char *cp2;
2579 struct vnode *vp;
2580 struct vattr at;
2581 nfsfh_t nfh;
2582 fhandle_t *fhp;
2583 struct statfs statfs;
2584 u_quad_t tval;
2585
2586 info.nmi_mreq = NULL((void *)0);
2587 info.nmi_mrep = nfsd->nd_mrep;
2588 info.nmi_md = nfsd->nd_md;
2589 info.nmi_dpos = nfsd->nd_dpos;
2590 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2591
2592 fhp = &nfh.fh_generic;
2593 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
2594 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2595 if (error) {
2596 nfsm_reply(NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((4)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2597 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2598 error = 0;
2599 goto nfsmout;
2600 }
2601 sf = &statfs;
2602 error = VFS_STATFS(vp->v_mount, sf, procp)(*(vp->v_mount)->mnt_op->vfs_statfs)(vp->v_mount,
sf, procp)
;
2603 getret = VOP_GETATTR(vp, &at, cred, procp);
2604 vput(vp);
2605 nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_STATFS(info.nmi_v3)){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((((
info.nmi_v3) ? (84 + 4) : 0) + ((info.nmi_v3) ? 52 : 20)), nfsd
, slp, error, &info.nmi_mreq, &info.nmi_mb); if (info
.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info.nmi_mrep
= ((void *)0); } *mrq = info.nmi_mreq; if (error && (
!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2606 if (info.nmi_v3)
2607 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2608 if (error) {
2609 error = 0;
2610 goto nfsmout;
2611 }
2612 sfp = nfsm_build(&info.nmi_mb, NFSX_STATFS(info.nmi_v3)((info.nmi_v3) ? 52 : 20));
2613 if (info.nmi_v3) {
2614 tval = (u_quad_t)sf->f_blocks;
2615 tval *= (u_quad_t)sf->f_bsize;
2616 txdr_hyper(tval, &sfp->sf_tbytes)do { ((u_int32_t *)(&sfp->sf_un.sf_nfsv3.nfsv3sf_tbytes
))[0] = (__uint32_t)(__builtin_constant_p((u_int32_t)((tval) >>
32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((tval) >>
32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((tval) >> 32)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((tval) >> 32)) & 0xff000000) >>
24) : __swap32md((u_int32_t)((tval) >> 32))); ((u_int32_t
*)(&sfp->sf_un.sf_nfsv3.nfsv3sf_tbytes))[1] = (__uint32_t
)(__builtin_constant_p((u_int32_t)((tval) & 0xffffffff)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)((tval) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval)
& 0xffffffff)) & 0xff00) << 8 | ((__uint32_t)(
(u_int32_t)((tval) & 0xffffffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)((tval) & 0xffffffff)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((tval) &
0xffffffff))); } while (0)
;
2617 tval = (u_quad_t)sf->f_bfree;
2618 tval *= (u_quad_t)sf->f_bsize;
2619 txdr_hyper(tval, &sfp->sf_fbytes)do { ((u_int32_t *)(&sfp->sf_un.sf_nfsv3.nfsv3sf_fbytes
))[0] = (__uint32_t)(__builtin_constant_p((u_int32_t)((tval) >>
32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((tval) >>
32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((tval) >> 32)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((tval) >> 32)) & 0xff000000) >>
24) : __swap32md((u_int32_t)((tval) >> 32))); ((u_int32_t
*)(&sfp->sf_un.sf_nfsv3.nfsv3sf_fbytes))[1] = (__uint32_t
)(__builtin_constant_p((u_int32_t)((tval) & 0xffffffff)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)((tval) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval)
& 0xffffffff)) & 0xff00) << 8 | ((__uint32_t)(
(u_int32_t)((tval) & 0xffffffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)((tval) & 0xffffffff)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((tval) &
0xffffffff))); } while (0)
;
2620 tval = (u_quad_t)sf->f_bavail;
2621 tval *= (u_quad_t)sf->f_bsize;
2622 txdr_hyper(tval, &sfp->sf_abytes)do { ((u_int32_t *)(&sfp->sf_un.sf_nfsv3.nfsv3sf_abytes
))[0] = (__uint32_t)(__builtin_constant_p((u_int32_t)((tval) >>
32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((tval) >>
32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((tval) >> 32)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((tval) >> 32)) & 0xff000000) >>
24) : __swap32md((u_int32_t)((tval) >> 32))); ((u_int32_t
*)(&sfp->sf_un.sf_nfsv3.nfsv3sf_abytes))[1] = (__uint32_t
)(__builtin_constant_p((u_int32_t)((tval) & 0xffffffff)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)((tval) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval)
& 0xffffffff)) & 0xff00) << 8 | ((__uint32_t)(
(u_int32_t)((tval) & 0xffffffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)((tval) & 0xffffffff)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((tval) &
0xffffffff))); } while (0)
;
2623 tval = (u_quad_t)sf->f_files;
2624 txdr_hyper(tval, &sfp->sf_tfiles)do { ((u_int32_t *)(&sfp->sf_un.sf_nfsv3.nfsv3sf_tfiles
))[0] = (__uint32_t)(__builtin_constant_p((u_int32_t)((tval) >>
32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((tval) >>
32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((tval) >> 32)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((tval) >> 32)) & 0xff000000) >>
24) : __swap32md((u_int32_t)((tval) >> 32))); ((u_int32_t
*)(&sfp->sf_un.sf_nfsv3.nfsv3sf_tfiles))[1] = (__uint32_t
)(__builtin_constant_p((u_int32_t)((tval) & 0xffffffff)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)((tval) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval)
& 0xffffffff)) & 0xff00) << 8 | ((__uint32_t)(
(u_int32_t)((tval) & 0xffffffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)((tval) & 0xffffffff)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((tval) &
0xffffffff))); } while (0)
;
2625 tval = (u_quad_t)sf->f_ffree;
2626 txdr_hyper(tval, &sfp->sf_ffiles)do { ((u_int32_t *)(&sfp->sf_un.sf_nfsv3.nfsv3sf_ffiles
))[0] = (__uint32_t)(__builtin_constant_p((u_int32_t)((tval) >>
32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((tval) >>
32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((tval) >> 32)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((tval) >> 32)) & 0xff000000) >>
24) : __swap32md((u_int32_t)((tval) >> 32))); ((u_int32_t
*)(&sfp->sf_un.sf_nfsv3.nfsv3sf_ffiles))[1] = (__uint32_t
)(__builtin_constant_p((u_int32_t)((tval) & 0xffffffff)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)((tval) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval)
& 0xffffffff)) & 0xff00) << 8 | ((__uint32_t)(
(u_int32_t)((tval) & 0xffffffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)((tval) & 0xffffffff)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((tval) &
0xffffffff))); } while (0)
;
2627 txdr_hyper(tval, &sfp->sf_afiles)do { ((u_int32_t *)(&sfp->sf_un.sf_nfsv3.nfsv3sf_afiles
))[0] = (__uint32_t)(__builtin_constant_p((u_int32_t)((tval) >>
32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)((tval) >>
32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval
) >> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)((tval) >> 32)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)((tval) >> 32)) & 0xff000000) >>
24) : __swap32md((u_int32_t)((tval) >> 32))); ((u_int32_t
*)(&sfp->sf_un.sf_nfsv3.nfsv3sf_afiles))[1] = (__uint32_t
)(__builtin_constant_p((u_int32_t)((tval) & 0xffffffff)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)((tval) & 0xffffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)((tval)
& 0xffffffff)) & 0xff00) << 8 | ((__uint32_t)(
(u_int32_t)((tval) & 0xffffffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)((tval) & 0xffffffff)) &
0xff000000) >> 24) : __swap32md((u_int32_t)((tval) &
0xffffffff))); } while (0)
;
2628 sfp->sf_invarsecsf_un.sf_nfsv3.nfsv3sf_invarsec = 0;
2629 } else {
2630 sfp->sf_tsizesf_un.sf_nfsv2.nfsv2sf_tsize = txdr_unsigned(NFS_MAXDGRAMDATA)((__uint32_t)(__builtin_constant_p((int32_t)(32768)) ? (__uint32_t
)(((__uint32_t)((int32_t)(32768)) & 0xff) << 24 | (
(__uint32_t)((int32_t)(32768)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)(32768)) & 0xff0000) >> 8 | ((__uint32_t
)((int32_t)(32768)) & 0xff000000) >> 24) : __swap32md
((int32_t)(32768))))
;
2631 sfp->sf_bsizesf_un.sf_nfsv2.nfsv2sf_bsize = txdr_unsigned(sf->f_bsize)((__uint32_t)(__builtin_constant_p((int32_t)(sf->f_bsize))
? (__uint32_t)(((__uint32_t)((int32_t)(sf->f_bsize)) &
0xff) << 24 | ((__uint32_t)((int32_t)(sf->f_bsize))
& 0xff00) << 8 | ((__uint32_t)((int32_t)(sf->f_bsize
)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(sf->
f_bsize)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sf->f_bsize))))
;
2632 sfp->sf_blockssf_un.sf_nfsv2.nfsv2sf_blocks = txdr_unsigned(sf->f_blocks)((__uint32_t)(__builtin_constant_p((int32_t)(sf->f_blocks)
) ? (__uint32_t)(((__uint32_t)((int32_t)(sf->f_blocks)) &
0xff) << 24 | ((__uint32_t)((int32_t)(sf->f_blocks)
) & 0xff00) << 8 | ((__uint32_t)((int32_t)(sf->f_blocks
)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(sf->
f_blocks)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sf->f_blocks))))
;
2633 sfp->sf_bfreesf_un.sf_nfsv2.nfsv2sf_bfree = txdr_unsigned(sf->f_bfree)((__uint32_t)(__builtin_constant_p((int32_t)(sf->f_bfree))
? (__uint32_t)(((__uint32_t)((int32_t)(sf->f_bfree)) &
0xff) << 24 | ((__uint32_t)((int32_t)(sf->f_bfree))
& 0xff00) << 8 | ((__uint32_t)((int32_t)(sf->f_bfree
)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(sf->
f_bfree)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sf->f_bfree))))
;
2634 sfp->sf_bavailsf_un.sf_nfsv2.nfsv2sf_bavail = txdr_unsigned(sf->f_bavail)((__uint32_t)(__builtin_constant_p((int32_t)(sf->f_bavail)
) ? (__uint32_t)(((__uint32_t)((int32_t)(sf->f_bavail)) &
0xff) << 24 | ((__uint32_t)((int32_t)(sf->f_bavail)
) & 0xff00) << 8 | ((__uint32_t)((int32_t)(sf->f_bavail
)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(sf->
f_bavail)) & 0xff000000) >> 24) : __swap32md((int32_t
)(sf->f_bavail))))
;
2635 }
2636nfsmout:
2637 return(error);
2638}
2639
2640/*
2641 * nfs fsinfo service
2642 */
2643int
2644nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2645 struct proc *procp, struct mbuf **mrq)
2646{
2647 struct mbuf *nam = nfsd->nd_nam;
2648 struct ucred *cred = &nfsd->nd_cr;
2649 struct nfsm_info info;
2650 u_int32_t *tl;
2651 struct nfsv3_fsinfo *sip;
2652 int32_t t1;
2653 int error = 0, rdonly, getret = 1, pref;
2654 char *cp2;
2655 struct vnode *vp;
2656 struct vattr at;
2657 nfsfh_t nfh;
2658 fhandle_t *fhp;
2659
2660 info.nmi_mreq = NULL((void *)0);
2661 info.nmi_mrep = nfsd->nd_mrep;
2662 info.nmi_md = nfsd->nd_md;
2663 info.nmi_dpos = nfsd->nd_dpos;
2664 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2665
2666 fhp = &nfh.fh_generic;
2667 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
2668 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2669 if (error) {
2670 nfsm_reply(NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((4)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2671 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2672 error = 0;
2673 goto nfsmout;
2674 }
2675 getret = VOP_GETATTR(vp, &at, cred, procp);
2676 vput(vp);
2677 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead(((84
+ 4) + 48), nfsd, slp, error, &info.nmi_mreq, &info.
nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep
); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }
;
2678 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2679 sip = nfsm_build(&info.nmi_mb, NFSX_V3FSINFO48);
2680
2681 /*
2682 * XXX
2683 * There should be file system VFS OP(s) to get this information.
2684 * For now, assume ufs.
2685 */
2686 if (slp->ns_so->so_type == SOCK_DGRAM2)
2687 pref = NFS_MAXDGRAMDATA32768;
2688 else
2689 pref = NFS_MAXDATA(64 * 1024);
2690 sip->fs_rtmax = txdr_unsigned(NFS_MAXDATA)((__uint32_t)(__builtin_constant_p((int32_t)((64 * 1024))) ? (
__uint32_t)(((__uint32_t)((int32_t)((64 * 1024))) & 0xff)
<< 24 | ((__uint32_t)((int32_t)((64 * 1024))) & 0xff00
) << 8 | ((__uint32_t)((int32_t)((64 * 1024))) & 0xff0000
) >> 8 | ((__uint32_t)((int32_t)((64 * 1024))) & 0xff000000
) >> 24) : __swap32md((int32_t)((64 * 1024)))))
;
2691 sip->fs_rtpref = txdr_unsigned(pref)((__uint32_t)(__builtin_constant_p((int32_t)(pref)) ? (__uint32_t
)(((__uint32_t)((int32_t)(pref)) & 0xff) << 24 | ((
__uint32_t)((int32_t)(pref)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)(pref)) & 0xff0000) >> 8 | ((__uint32_t)
((int32_t)(pref)) & 0xff000000) >> 24) : __swap32md
((int32_t)(pref))))
;
2692 sip->fs_rtmult = txdr_unsigned(NFS_FABLKSIZE)((__uint32_t)(__builtin_constant_p((int32_t)(512)) ? (__uint32_t
)(((__uint32_t)((int32_t)(512)) & 0xff) << 24 | ((__uint32_t
)((int32_t)(512)) & 0xff00) << 8 | ((__uint32_t)((int32_t
)(512)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(
512)) & 0xff000000) >> 24) : __swap32md((int32_t)(512
))))
;
2693 sip->fs_wtmax = txdr_unsigned(NFS_MAXDATA)((__uint32_t)(__builtin_constant_p((int32_t)((64 * 1024))) ? (
__uint32_t)(((__uint32_t)((int32_t)((64 * 1024))) & 0xff)
<< 24 | ((__uint32_t)((int32_t)((64 * 1024))) & 0xff00
) << 8 | ((__uint32_t)((int32_t)((64 * 1024))) & 0xff0000
) >> 8 | ((__uint32_t)((int32_t)((64 * 1024))) & 0xff000000
) >> 24) : __swap32md((int32_t)((64 * 1024)))))
;
2694 sip->fs_wtpref = txdr_unsigned(pref)((__uint32_t)(__builtin_constant_p((int32_t)(pref)) ? (__uint32_t
)(((__uint32_t)((int32_t)(pref)) & 0xff) << 24 | ((
__uint32_t)((int32_t)(pref)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)(pref)) & 0xff0000) >> 8 | ((__uint32_t)
((int32_t)(pref)) & 0xff000000) >> 24) : __swap32md
((int32_t)(pref))))
;
2695 sip->fs_wtmult = txdr_unsigned(NFS_FABLKSIZE)((__uint32_t)(__builtin_constant_p((int32_t)(512)) ? (__uint32_t
)(((__uint32_t)((int32_t)(512)) & 0xff) << 24 | ((__uint32_t
)((int32_t)(512)) & 0xff00) << 8 | ((__uint32_t)((int32_t
)(512)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(
512)) & 0xff000000) >> 24) : __swap32md((int32_t)(512
))))
;
2696 sip->fs_dtpref = txdr_unsigned(pref)((__uint32_t)(__builtin_constant_p((int32_t)(pref)) ? (__uint32_t
)(((__uint32_t)((int32_t)(pref)) & 0xff) << 24 | ((
__uint32_t)((int32_t)(pref)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)(pref)) & 0xff0000) >> 8 | ((__uint32_t)
((int32_t)(pref)) & 0xff000000) >> 24) : __swap32md
((int32_t)(pref))))
;
2697 sip->fs_maxfilesize.nfsuquad[0] = 0xffffffff;
2698 sip->fs_maxfilesize.nfsuquad[1] = 0xffffffff;
2699 sip->fs_timedelta.nfsv3_sec = 0;
2700 sip->fs_timedelta.nfsv3_nsec = txdr_unsigned(1)((__uint32_t)(__builtin_constant_p((int32_t)(1)) ? (__uint32_t
)(((__uint32_t)((int32_t)(1)) & 0xff) << 24 | ((__uint32_t
)((int32_t)(1)) & 0xff00) << 8 | ((__uint32_t)((int32_t
)(1)) & 0xff0000) >> 8 | ((__uint32_t)((int32_t)(1)
) & 0xff000000) >> 24) : __swap32md((int32_t)(1))))
;
2701 sip->fs_properties = txdr_unsigned(NFSV3FSINFO_LINK |((__uint32_t)(__builtin_constant_p((int32_t)(0x01 | 0x02 | 0x08
| 0x10)) ? (__uint32_t)(((__uint32_t)((int32_t)(0x01 | 0x02 |
0x08 | 0x10)) & 0xff) << 24 | ((__uint32_t)((int32_t
)(0x01 | 0x02 | 0x08 | 0x10)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)(0x01 | 0x02 | 0x08 | 0x10)) & 0xff0000) >>
8 | ((__uint32_t)((int32_t)(0x01 | 0x02 | 0x08 | 0x10)) &
0xff000000) >> 24) : __swap32md((int32_t)(0x01 | 0x02 |
0x08 | 0x10))))
2702 NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS |((__uint32_t)(__builtin_constant_p((int32_t)(0x01 | 0x02 | 0x08
| 0x10)) ? (__uint32_t)(((__uint32_t)((int32_t)(0x01 | 0x02 |
0x08 | 0x10)) & 0xff) << 24 | ((__uint32_t)((int32_t
)(0x01 | 0x02 | 0x08 | 0x10)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)(0x01 | 0x02 | 0x08 | 0x10)) & 0xff0000) >>
8 | ((__uint32_t)((int32_t)(0x01 | 0x02 | 0x08 | 0x10)) &
0xff000000) >> 24) : __swap32md((int32_t)(0x01 | 0x02 |
0x08 | 0x10))))
2703 NFSV3FSINFO_CANSETTIME)((__uint32_t)(__builtin_constant_p((int32_t)(0x01 | 0x02 | 0x08
| 0x10)) ? (__uint32_t)(((__uint32_t)((int32_t)(0x01 | 0x02 |
0x08 | 0x10)) & 0xff) << 24 | ((__uint32_t)((int32_t
)(0x01 | 0x02 | 0x08 | 0x10)) & 0xff00) << 8 | ((__uint32_t
)((int32_t)(0x01 | 0x02 | 0x08 | 0x10)) & 0xff0000) >>
8 | ((__uint32_t)((int32_t)(0x01 | 0x02 | 0x08 | 0x10)) &
0xff000000) >> 24) : __swap32md((int32_t)(0x01 | 0x02 |
0x08 | 0x10))))
;
2704nfsmout:
2705 return(error);
2706}
2707
2708/*
2709 * nfs pathconf service
2710 */
2711int
2712nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2713 struct proc *procp, struct mbuf **mrq)
2714{
2715 struct mbuf *nam = nfsd->nd_nam;
2716 struct ucred *cred = &nfsd->nd_cr;
2717 struct nfsm_info info;
2718 u_int32_t *tl;
2719 struct nfsv3_pathconf *pc;
2720 int32_t t1;
2721 int error = 0, rdonly, getret = 1;
2722 register_t linkmax, namemax, chownres, notrunc;
2723 char *cp2;
2724 struct vnode *vp;
2725 struct vattr at;
2726 nfsfh_t nfh;
2727 fhandle_t *fhp;
2728
2729 info.nmi_mreq = NULL((void *)0);
2730 info.nmi_mrep = nfsd->nd_mrep;
2731 info.nmi_md = nfsd->nd_md;
2732 info.nmi_dpos = nfsd->nd_dpos;
2733 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2734
2735 fhp = &nfh.fh_generic;
2736 nfsm_srvmtofh(fhp){ if (nfsd->nd_flag & 0x08) { { 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 (((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)))) != (sizeof (fhandle_t
))) { error = 72; { nfsd->nd_repstat = error; if (error &&
!(nfsd->nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp
, error, &info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead
((0), nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb)
; if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep);
info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }; } } { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data
)) + info.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >=
((sizeof (fhandle_t)))) { (tl) = (u_int32_t *)(info.nmi_dpos
); info.nmi_dpos += ((sizeof (fhandle_t))); } else if ((t1 = nfsm_disct
(&info.nmi_md, &info.nmi_dpos, ((sizeof (fhandle_t)))
, t1, &cp2)) != 0) { error = t1; m_freem(info.nmi_mrep); goto
nfsmout; } else { (tl) = (u_int32_t *)cp2; } }; bcopy(tl, (fhp
), (sizeof (fhandle_t))); if ((nfsd->nd_flag & 0x08) ==
0) { t1 = ((caddr_t)((info.nmi_md)->m_hdr.mh_data)) + info
.nmi_md->m_hdr.mh_len - info.nmi_dpos; if (t1 >= (32 - (
sizeof (fhandle_t)))) { info.nmi_dpos += (32 - (sizeof (fhandle_t
))); } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos
, (32 - (sizeof (fhandle_t))), t1)) != 0) { error = t1; m_freem
(info.nmi_mrep); goto nfsmout; } }; }
;
2737 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2738 if (error) {
2739 nfsm_reply(NFSX_UNSIGNED){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((4)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2740 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2741 error = 0;
2742 goto nfsmout;
2743 }
2744 error = VOP_PATHCONF(vp, _PC_LINK_MAX1, &linkmax);
2745 if (!error)
2746 error = VOP_PATHCONF(vp, _PC_NAME_MAX4, &namemax);
2747 if (!error)
2748 error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED7, &chownres);
2749 if (!error)
2750 error = VOP_PATHCONF(vp, _PC_NO_TRUNC8, &notrunc);
2751 getret = VOP_GETATTR(vp, &at, cred, procp);
2752 vput(vp);
2753 nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead(((84
+ 4) + 24), nfsd, slp, error, &info.nmi_mreq, &info.
nmi_mb); if (info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep
); info.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error
&& (!(nfsd->nd_flag & 0x08) || error == 72)) return
(0); }
;
2754 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2755 if (error) {
2756 error = 0;
2757 goto nfsmout;
2758 }
2759 pc = nfsm_build(&info.nmi_mb, NFSX_V3PATHCONF24);
2760
2761 pc->pc_linkmax = txdr_unsigned(linkmax)((__uint32_t)(__builtin_constant_p((int32_t)(linkmax)) ? (__uint32_t
)(((__uint32_t)((int32_t)(linkmax)) & 0xff) << 24 |
((__uint32_t)((int32_t)(linkmax)) & 0xff00) << 8 |
((__uint32_t)((int32_t)(linkmax)) & 0xff0000) >> 8
| ((__uint32_t)((int32_t)(linkmax)) & 0xff000000) >>
24) : __swap32md((int32_t)(linkmax))))
;
2762 pc->pc_namemax = txdr_unsigned(namemax)((__uint32_t)(__builtin_constant_p((int32_t)(namemax)) ? (__uint32_t
)(((__uint32_t)((int32_t)(namemax)) & 0xff) << 24 |
((__uint32_t)((int32_t)(namemax)) & 0xff00) << 8 |
((__uint32_t)((int32_t)(namemax)) & 0xff0000) >> 8
| ((__uint32_t)((int32_t)(namemax)) & 0xff000000) >>
24) : __swap32md((int32_t)(namemax))))
;
2763 pc->pc_notrunc = txdr_unsigned(notrunc)((__uint32_t)(__builtin_constant_p((int32_t)(notrunc)) ? (__uint32_t
)(((__uint32_t)((int32_t)(notrunc)) & 0xff) << 24 |
((__uint32_t)((int32_t)(notrunc)) & 0xff00) << 8 |
((__uint32_t)((int32_t)(notrunc)) & 0xff0000) >> 8
| ((__uint32_t)((int32_t)(notrunc)) & 0xff000000) >>
24) : __swap32md((int32_t)(notrunc))))
;
2764 pc->pc_chownrestricted = txdr_unsigned(chownres)((__uint32_t)(__builtin_constant_p((int32_t)(chownres)) ? (__uint32_t
)(((__uint32_t)((int32_t)(chownres)) & 0xff) << 24 |
((__uint32_t)((int32_t)(chownres)) & 0xff00) << 8 |
((__uint32_t)((int32_t)(chownres)) & 0xff0000) >> 8
| ((__uint32_t)((int32_t)(chownres)) & 0xff000000) >>
24) : __swap32md((int32_t)(chownres))))
;
2765
2766 /*
2767 * These should probably be supported by VOP_PATHCONF(), but
2768 * until msdosfs is exportable (why would you want to?), the
2769 * Unix defaults should be ok.
2770 */
2771 pc->pc_caseinsensitive = nfs_false;
2772 pc->pc_casepreserving = nfs_true;
2773nfsmout:
2774 return(error);
2775}
2776
2777/*
2778 * Null operation, used by clients to ping server
2779 */
2780/* ARGSUSED */
2781int
2782nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2783 struct proc *procp, struct mbuf **mrq)
2784{
2785 struct nfsm_info info;
2786 int error = NFSERR_RETVOID0x20000000;
2787
2788 info.nmi_mreq = NULL((void *)0);
2789 info.nmi_mrep = nfsd->nd_mrep;
2790 info.nmi_md = nfsd->nd_md;
2791 info.nmi_dpos = nfsd->nd_dpos;
2792 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2793
2794 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2795 return (0);
2796}
2797
2798/*
2799 * No operation, used for obsolete procedures
2800 */
2801/* ARGSUSED */
2802int
2803nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2804 struct proc *procp, struct mbuf **mrq)
2805{
2806 struct nfsm_info info;
2807 int error;
2808
2809 info.nmi_mreq = NULL((void *)0);
2810 info.nmi_mrep = nfsd->nd_mrep;
2811 info.nmi_md = nfsd->nd_md;
2812 info.nmi_dpos = nfsd->nd_dpos;
2813 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2814
2815 if (nfsd->nd_repstat)
2816 error = nfsd->nd_repstat;
2817 else
2818 error = EPROCUNAVAIL76;
2819 nfsm_reply(0){ nfsd->nd_repstat = error; if (error && !(nfsd->
nd_flag & 0x08)) (void) nfs_rephead(0, nfsd, slp, error, &
info.nmi_mreq, &info.nmi_mb); else (void) nfs_rephead((0)
, nfsd, slp, error, &info.nmi_mreq, &info.nmi_mb); if
(info.nmi_mrep != ((void *)0)) { m_freem(info.nmi_mrep); info
.nmi_mrep = ((void *)0); } *mrq = info.nmi_mreq; if (error &&
(!(nfsd->nd_flag & 0x08) || error == 72)) return(0); }
;
2820 return (0);
2821}
2822
2823/*
2824 * Perform access checking for vnodes obtained from file handles that would
2825 * refer to files already opened by a Unix client.
2826 * You cannot just use vn_writechk() and VOP_ACCESS() for two reasons:
2827 * 1 - You must check for exported rdonly as well as MNT_RDONLY for the
2828 * write case
2829 * 2 - The owner is to be given access irrespective of mode bits for some
2830 * operations, so that processes that chmod after opening a file don't
2831 * break. I don't like this because it opens a security hole, but since
2832 * the nfs server opens a security hole the size of a barn door anyhow,
2833 * what the heck. A notable exception to this rule is when VOP_ACCESS()
2834 * returns EPERM (e.g. when a file is immutable) which is always an
2835 * error.
2836 */
2837int
2838nfsrv_access(struct vnode *vp, int flags, struct ucred *cred, int rdonly,
2839 struct proc *p, int override)
2840{
2841 struct vattr vattr;
2842 int error;
2843
2844 if (flags & VWRITE00200) {
2845 /* Just vn_writechk() changed to check rdonly */
2846 /*
2847 * Disallow write attempts on read-only file systems;
2848 * unless the file is a socket or a block or character
2849 * device resident on the file system.
2850 */
2851 if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001)) {
2852 switch (vp->v_type) {
2853 case VREG:
2854 case VDIR:
2855 case VLNK:
2856 return (EROFS30);
2857 default:
2858 break;
2859 }
2860 }
2861 /*
2862 * If there's shared text associated with
2863 * the inode, try to free it up once. If
2864 * we fail, we can't allow writing.
2865 */
2866 if ((vp->v_flag & VTEXT0x0002) && !uvm_vnp_uncache(vp))
2867 return (ETXTBSY26);
2868 }
2869 error = VOP_ACCESS(vp, flags, cred, p);
2870 /*
2871 * Allow certain operations for the owner (reads and writes
2872 * on files that are already open).
2873 */
2874 if (override && error == EACCES13 &&
2875 VOP_GETATTR(vp, &vattr, cred, p) == 0 &&
2876 cred->cr_uid == vattr.va_uid)
2877 error = 0;
2878 return error;
2879}