Bug Summary

File:nfs/nfs_serv.c
Warning:line 2392, column 3
Value stored to 'toff' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nfs_serv.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/nfs/nfs_serv.c
1/* $OpenBSD: nfs_serv.c,v 1.122 2023/03/08 04:43:09 guenther 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; } }; }
;
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 if (tvp) {
1492 (void)uvm_vnp_uncache(tvp);
1493 }
1494 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
1495 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
1496 } else {
1497 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
1498 if (tdvp == tvp)
1499 vrele(tdvp);
1500 else
1501 vput(tdvp);
1502 if (tvp)
1503 vput(tvp);
1504 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1505 vrele(fromnd.ni_dvp);
1506 vrele(fvp);
1507 if (error == -1)
1508 error = 0;
1509 }
1510 vrele(tond.ni_startdir);
1511 pool_put(&namei_pool, tond.ni_cnd.cn_pnbuf);
1512out1:
1513 if (fdirp) {
1514 fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred, procp);
1515 vrele(fdirp);
1516 }
1517 if (tdirp) {
1518 tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred, procp);
1519 vrele(tdirp);
1520 }
1521 vrele(fromnd.ni_startdir);
1522 pool_put(&namei_pool, fromnd.ni_cnd.cn_pnbuf);
1523 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); }
;
1524 if (info.nmi_v3) {
1525 nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft,
1526 &info);
1527 nfsm_srvwcc(nfsd, tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft,
1528 &info);
1529 }
1530 return (0);
1531
1532nfsmout:
1533 if (fdirp)
1534 vrele(fdirp);
1535 if (tdirp)
1536 vrele(tdirp);
1537 if (tond.ni_cnd.cn_nameiop) {
1538 vrele(tond.ni_startdir);
1539 pool_put(&namei_pool, tond.ni_cnd.cn_pnbuf);
1540 }
1541 if (fromnd.ni_cnd.cn_nameiop) {
1542 if (fromnd.ni_startdir)
1543 vrele(fromnd.ni_startdir);
1544 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1545
1546 /*
1547 * XXX: Workaround the fact that fromnd.ni_dvp can point
1548 * to the same vnode as fdirp.
1549 */
1550 if (fromnd.ni_dvp != NULL((void *)0) && fromnd.ni_dvp != fdirp)
1551 vrele(fromnd.ni_dvp);
1552 if (fvp)
1553 vrele(fvp);
1554 }
1555 return (error);
1556}
1557
1558/*
1559 * nfs link service
1560 */
1561int
1562nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1563 struct proc *procp, struct mbuf **mrq)
1564{
1565 struct mbuf *nam = nfsd->nd_nam;
1566 struct nfsm_info info;
1567 struct ucred *cred = &nfsd->nd_cr;
1568 struct nameidata nd;
1569 u_int32_t *tl;
1570 int32_t t1;
1571 int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
1572 int getret = 1;
1573 char *cp2;
1574 struct vnode *vp, *xp, *dirp = NULL((void *)0);
1575 struct vattr dirfor, diraft, at;
1576 nfsfh_t nfh, dnfh;
1577 fhandle_t *fhp, *dfhp;
1578
1579 info.nmi_mreq = NULL((void *)0);
1580 info.nmi_mrep = nfsd->nd_mrep;
1581 info.nmi_md = nfsd->nd_md;
1582 info.nmi_dpos = nfsd->nd_dpos;
1583 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1584
1585 fhp = &nfh.fh_generic;
1586 dfhp = &dnfh.fh_generic;
1587 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; } }; }
;
1588 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; } }; }
;
1589 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); }; }
;
1590
1591 error = nfsrv_fhtovp(fhp, 0, &vp, cred, slp, nam, &rdonly);
1592 if (error) {
1593 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); }
1594 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); }
;
1595 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
1596 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1597 &info);
1598 error = 0;
1599 goto nfsmout;
1600 }
1601 if (vp->v_type == VDIR && (error = suser_ucred(cred)) != 0)
1602 goto out1;
1603
1604 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 1, 0x0008, UIO_SYSSPACE, -100, ((void *)0),
procp)
;
1605 nd.ni_cnd.cn_cred = cred;
1606 error = nfs_namei(&nd, dfhp, len, slp, nam, &info.nmi_md,
1607 &info.nmi_dpos, &dirp, procp);
1608 if (dirp) {
1609 if (info.nmi_v3)
1610 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
1611 procp);
1612 else {
1613 vrele(dirp);
1614 dirp = NULL((void *)0);
1615 }
1616 }
1617 if (error)
1618 goto out1;
1619 xp = nd.ni_vp;
1620 if (xp != NULL((void *)0)) {
1621 error = EEXIST17;
1622 goto out;
1623 }
1624 xp = nd.ni_dvp;
1625 if (vp->v_mount != xp->v_mount)
1626 error = EXDEV18;
1627out:
1628 if (!error) {
1629 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1630 } else {
1631 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1632 if (nd.ni_dvp == nd.ni_vp)
1633 vrele(nd.ni_dvp);
1634 else
1635 vput(nd.ni_dvp);
1636 if (nd.ni_vp)
1637 vrele(nd.ni_vp);
1638 }
1639out1:
1640 if (info.nmi_v3)
1641 getret = VOP_GETATTR(vp, &at, cred, procp);
1642 if (dirp) {
1643 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1644 vrele(dirp);
1645 }
1646 vrele(vp);
1647 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); }
;
1648 if (info.nmi_v3) {
1649 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
1650 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1651 &info);
1652 error = 0;
1653 }
1654nfsmout:
1655 return(error);
1656}
1657
1658/*
1659 * nfs symbolic link service
1660 */
1661int
1662nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1663 struct proc *procp, struct mbuf **mrq)
1664{
1665 struct mbuf *nam = nfsd->nd_nam;
1666 struct ucred *cred = &nfsd->nd_cr;
1667 struct vattr va, dirfor, diraft;
1668 struct nameidata nd;
1669 struct nfsm_info info;
1670 u_int32_t *tl;
1671 int32_t t1;
1672 struct nfsv2_sattr *sp;
1673 char *pathcp = NULL((void *)0), *cp2;
1674 struct uio io;
1675 struct iovec iv;
1676 int error = 0, len, pathlen, len2, dirfor_ret = 1, diraft_ret = 1;
1677 struct vnode *dirp = NULL((void *)0);
1678 nfsfh_t nfh;
1679 fhandle_t *fhp;
1680
1681 info.nmi_mreq = NULL((void *)0);
1682 info.nmi_mrep = nfsd->nd_mrep;
1683 info.nmi_md = nfsd->nd_md;
1684 info.nmi_dpos = nfsd->nd_dpos;
1685 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1686
1687 fhp = &nfh.fh_generic;
1688 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; } }; }
;
1689 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); }; }
;
1690
1691 NDINIT(&nd, CREATE, LOCKPARENT | SAVESTART, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 1, 0x0008 | 0x001000, UIO_SYSSPACE, -100, (
(void *)0), procp)
;
1692 nd.ni_cnd.cn_cred = cred;
1693 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
1694 &info.nmi_dpos, &dirp, procp);
1695 if (dirp) {
1696 if (info.nmi_v3)
1697 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
1698 procp);
1699 else {
1700 vrele(dirp);
1701 dirp = NULL((void *)0);
1702 }
1703 }
1704 if (error)
1705 goto out;
1706 VATTR_NULL(&va)vattr_null(&va);
1707 if (info.nmi_v3) {
1708 error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
1709 &info.nmi_dpos);
1710 if (error)
1711 goto nfsmout;
1712 }
1713 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; } }
;
1714 pathlen = len2 + 1;
1715 pathcp = malloc(pathlen, M_TEMP127, M_WAITOK0x0001);
1716 iv.iov_base = pathcp;
1717 iv.iov_len = len2;
1718 io.uio_resid = len2;
1719 io.uio_offset = 0;
1720 io.uio_iov = &iv;
1721 io.uio_iovcnt = 1;
1722 io.uio_segflg = UIO_SYSSPACE;
1723 io.uio_rw = UIO_READ;
1724 io.uio_procp = NULL((void *)0);
1725 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; }
;
1726 if (!info.nmi_v3) {
1727 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; }
}
;
1728 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)
;
1729 }
1730 *(pathcp + len2) = '\0';
1731 if (nd.ni_vp) {
1732 vrele(nd.ni_startdir);
1733 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1734 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1735 if (nd.ni_dvp == nd.ni_vp)
1736 vrele(nd.ni_dvp);
1737 else
1738 vput(nd.ni_dvp);
1739 vrele(nd.ni_vp);
1740 error = EEXIST17;
1741 goto out;
1742 }
1743 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va, pathcp);
1744 if (error)
1745 vrele(nd.ni_startdir);
1746 else {
1747 if (info.nmi_v3) {
1748 nd.ni_cnd.cn_nameiop = LOOKUP0;
1749 nd.ni_cnd.cn_flags &= ~(LOCKPARENT0x0008 | SAVESTART0x001000 |
1750 FOLLOW0x0040);
1751 nd.ni_cnd.cn_flags |= (NOFOLLOW0x0000 | LOCKLEAF0x0004);
1752 nd.ni_cnd.cn_proc = procp;
1753 nd.ni_cnd.cn_cred = cred;
1754 error = vfs_lookup(&nd);
1755 if (!error) {
1756 memset(fhp, 0, sizeof(nfh))__builtin_memset((fhp), (0), (sizeof(nfh)));
1757 fhp->fh_fsid =
1758 nd.ni_vp->v_mount->mnt_stat.f_fsid;
1759 error = VFS_VPTOFH(nd.ni_vp, &fhp->fh_fid)(*(nd.ni_vp)->v_mount->mnt_op->vfs_vptofh)(nd.ni_vp,
&fhp->fh_fid)
;
1760 if (!error)
1761 error = VOP_GETATTR(nd.ni_vp, &va, cred,
1762 procp);
1763 vput(nd.ni_vp);
1764 }
1765 } else
1766 vrele(nd.ni_startdir);
1767 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1768 }
1769out:
1770 if (pathcp)
1771 free(pathcp, M_TEMP127, pathlen);
1772 if (dirp) {
1773 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1774 vrele(dirp);
1775 }
1776 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); }
1777 + 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); }
;
1778 if (info.nmi_v3) {
1779 if (!error) {
1780 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))); }
;
1781 nfsm_srvpostop_attr(nfsd, 0, &va, &info);
1782 }
1783 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1784 &info);
1785 }
1786 return (0);
1787nfsmout:
1788 if (nd.ni_cnd.cn_nameiop) {
1789 vrele(nd.ni_startdir);
1790 pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
1791 }
1792 if (dirp)
1793 vrele(dirp);
1794 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1795 if (nd.ni_dvp == nd.ni_vp)
1796 vrele(nd.ni_dvp);
1797 else
1798 vput(nd.ni_dvp);
1799 if (nd.ni_vp)
1800 vrele(nd.ni_vp);
1801 if (pathcp)
1802 free(pathcp, M_TEMP127, pathlen);
1803 return (error);
1804}
1805
1806/*
1807 * nfs mkdir service
1808 */
1809int
1810nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1811 struct proc *procp, struct mbuf **mrq)
1812{
1813 struct mbuf *nam = nfsd->nd_nam;
1814 struct ucred *cred = &nfsd->nd_cr;
1815 struct vattr va, dirfor, diraft;
1816 struct nfs_fattr *fp;
1817 struct nameidata nd;
1818 struct nfsm_info info;
1819 u_int32_t *tl;
1820 int32_t t1;
1821 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1822 char *cp2;
1823 struct vnode *vp, *dirp = NULL((void *)0);
1824 nfsfh_t nfh;
1825 fhandle_t *fhp;
1826
1827 info.nmi_mreq = NULL((void *)0);
1828 info.nmi_mrep = nfsd->nd_mrep;
1829 info.nmi_md = nfsd->nd_md;
1830 info.nmi_dpos = nfsd->nd_dpos;
1831 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1832
1833 fhp = &nfh.fh_generic;
1834 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; } }; }
;
1835 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); }; }
;
1836
1837 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 1, 0x0008, UIO_SYSSPACE, -100, ((void *)0),
procp)
;
1838 nd.ni_cnd.cn_cred = cred;
1839 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
1840 &info.nmi_dpos, &dirp, procp);
1841 if (dirp) {
1842 if (info.nmi_v3)
1843 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
1844 else {
1845 vrele(dirp);
1846 dirp = NULL((void *)0);
1847 }
1848 }
1849 if (error) {
1850 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); }
;
1851 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1852 &info);
1853 if (dirp)
1854 vrele(dirp);
1855 return (0);
1856 }
1857
1858 VATTR_NULL(&va)vattr_null(&va);
1859 if (info.nmi_v3) {
1860 error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
1861 &info.nmi_dpos);
1862 if (error)
1863 goto nfsmout;
1864 } else {
1865 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; } }
;
1866 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)
;
1867 }
1868 va.va_type = VDIR;
1869 vp = nd.ni_vp;
1870 if (vp != NULL((void *)0)) {
1871 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1872 if (nd.ni_dvp == vp)
1873 vrele(nd.ni_dvp);
1874 else
1875 vput(nd.ni_dvp);
1876 vrele(vp);
1877 error = EEXIST17;
1878 goto out;
1879 }
1880 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va);
1881 if (!error) {
1882 vp = nd.ni_vp;
1883 memset(fhp, 0, sizeof(nfh))__builtin_memset((fhp), (0), (sizeof(nfh)));
1884 fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
1885 error = VFS_VPTOFH(vp, &fhp->fh_fid)(*(vp)->v_mount->mnt_op->vfs_vptofh)(vp, &fhp->
fh_fid)
;
1886 if (!error)
1887 error = VOP_GETATTR(vp, &va, cred, procp);
1888 vput(vp);
1889 }
1890out:
1891 if (dirp) {
1892 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
1893 vrele(dirp);
1894 }
1895 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); }
1896 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); }
;
1897 if (info.nmi_v3) {
1898 if (!error) {
1899 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))); }
;
1900 nfsm_srvpostop_attr(nfsd, 0, &va, &info);
1901 }
1902 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1903 &info);
1904 } else {
1905 nfsm_srvfhtom(&info.nmi_mb, fhp, info.nmi_v3);
1906 fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR68);
1907 nfsm_srvfattr(nfsd, &va, fp);
1908 }
1909 return (0);
1910nfsmout:
1911 if (dirp)
1912 vrele(dirp);
1913 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1914 if (nd.ni_dvp == nd.ni_vp)
1915 vrele(nd.ni_dvp);
1916 else
1917 vput(nd.ni_dvp);
1918 if (nd.ni_vp)
1919 vrele(nd.ni_vp);
1920 return (error);
1921}
1922
1923/*
1924 * nfs rmdir service
1925 */
1926int
1927nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
1928 struct proc *procp, struct mbuf **mrq)
1929{
1930 struct mbuf *nam = nfsd->nd_nam;
1931 struct ucred *cred = &nfsd->nd_cr;
1932 struct nfsm_info info;
1933 u_int32_t *tl;
1934 int32_t t1;
1935 int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
1936 char *cp2;
1937 struct vnode *vp, *dirp = NULL((void *)0);
1938 struct vattr dirfor, diraft;
1939 nfsfh_t nfh;
1940 fhandle_t *fhp;
1941 struct nameidata nd;
1942
1943 info.nmi_mreq = NULL((void *)0);
1944 info.nmi_mrep = nfsd->nd_mrep;
1945 info.nmi_md = nfsd->nd_md;
1946 info.nmi_dpos = nfsd->nd_dpos;
1947 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
1948
1949 fhp = &nfh.fh_generic;
1950 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; } }; }
;
1951 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); }; }
;
1952
1953 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp)ndinitat(&nd, 2, 0x0008 | 0x0004, UIO_SYSSPACE, -100, ((void
*)0), procp)
;
1954 nd.ni_cnd.cn_cred = cred;
1955 error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
1956 &info.nmi_dpos, &dirp, procp);
1957 if (dirp) {
1958 if (info.nmi_v3)
1959 dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
1960 procp);
1961 else {
1962 vrele(dirp);
1963 dirp = NULL((void *)0);
1964 }
1965 }
1966 if (error) {
1967 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); }
;
1968 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
1969 &info);
1970 if (dirp)
1971 vrele(dirp);
1972 return (0);
1973 }
1974 vp = nd.ni_vp;
1975 if (vp->v_type != VDIR) {
1976 error = ENOTDIR20;
1977 goto out;
1978 }
1979 /*
1980 * No rmdir "." please.
1981 */
1982 if (nd.ni_dvp == vp) {
1983 error = EINVAL22;
1984 goto out;
1985 }
1986 /*
1987 * A mounted on directory cannot be deleted.
1988 */
1989 if (vp->v_mountedherev_un.vu_mountedhere != NULL((void *)0)) {
1990 error = EBUSY16;
1991 goto out;
1992 }
1993 /*
1994 * The root of a mounted filesystem cannot be deleted.
1995 */
1996 if (vp->v_flag & VROOT0x0001)
1997 error = EBUSY16;
1998out:
1999 if (!error) {
2000 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
2001 } else {
2002 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
2003 if (nd.ni_dvp == nd.ni_vp)
2004 vrele(nd.ni_dvp);
2005 else
2006 vput(nd.ni_dvp);
2007 vput(vp);
2008 }
2009 if (dirp) {
2010 diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
2011 vrele(dirp);
2012 }
2013 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); }
;
2014 if (info.nmi_v3) {
2015 nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
2016 &info);
2017 error = 0;
2018 }
2019nfsmout:
2020 return(error);
2021}
2022
2023/*
2024 * nfs readdir service
2025 * - mallocs what it thinks is enough to read
2026 * count rounded up to a multiple of NFS_DIRBLKSIZ <= NFS_MAXREADDIR
2027 * - calls VOP_READDIR()
2028 * - loops around building the reply
2029 * if the output generated exceeds count break out of loop
2030 * - it only knows that it has encountered eof when the VOP_READDIR()
2031 * reads nothing
2032 * - as such one readdir rpc will return eof false although you are there
2033 * and then the next will return eof
2034 * - it trims out records with d_fileno == 0
2035 * this doesn't matter for Unix clients, but they might confuse clients
2036 * for other os'.
2037 * NB: It is tempting to set eof to true if the VOP_READDIR() reads less
2038 * than requested, but this may not apply to all filesystems. For
2039 * example, client NFS does not { although it is never remote mounted
2040 * anyhow }
2041 * The alternate call nfsrv_readdirplus() does lookups as well.
2042 * PS: The NFS protocol spec. does not clarify what the "count" byte
2043 * argument is a count of.. just name strings and file id's or the
2044 * entire reply rpc or ...
2045 * I tried just file name and id sizes and it confused the Sun client,
2046 * so I am using the full rpc size now. The "paranoia.." comment refers
2047 * to including the status longwords that are not a part of the dir.
2048 * "entry" structures, but are in the rpc.
2049 */
2050struct flrep {
2051 nfsuint64 fl_off;
2052 u_int32_t fl_postopok;
2053 u_int32_t fl_fattr[NFSX_V3FATTR84 / sizeof (u_int32_t)];
2054 u_int32_t fl_fhok;
2055 u_int32_t fl_fhsize;
2056 u_int32_t fl_nfh[NFSX_V3FH(sizeof (fhandle_t)) / sizeof (u_int32_t)];
2057};
2058
2059int
2060nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2061 struct proc *procp, struct mbuf **mrq)
2062{
2063 struct mbuf *nam = nfsd->nd_nam;
2064 struct ucred *cred = &nfsd->nd_cr;
2065 struct dirent *dp;
2066 struct nfsm_info info;
2067 u_int32_t *tl;
2068 int32_t t1;
2069 char *cpos, *cend, *cp2, *rbuf;
2070 struct vnode *vp;
2071 struct vattr at;
2072 nfsfh_t nfh;
2073 fhandle_t *fhp;
2074 struct uio io;
2075 struct iovec iv;
2076 int len, nlen, pad, xfer, error = 0, getret = 1;
2077 int siz, cnt, fullsiz, eofflag, rdonly;
2078 u_quad_t off, toff, verf;
2079
2080 info.nmi_mreq = NULL((void *)0);
2081 info.nmi_mrep = nfsd->nd_mrep;
2082 info.nmi_md = nfsd->nd_md;
2083 info.nmi_dpos = nfsd->nd_dpos;
2084 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2085
2086 fhp = &nfh.fh_generic;
2087 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; } }; }
;
2088 if (info.nmi_v3) {
2089 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; } }
;
2090 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]))))
;
2091 tl += 2;
2092 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]))))
;
2093 tl += 2;
2094 } else {
2095 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; } }
;
2096 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++))))
;
2097 }
2098 off = toff;
2099 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))))
;
2100 xfer = NFS_SRVMAXDATA(nfsd)(((nfsd)->nd_flag & 0x08) ? (((nfsd)->nd_nam2) ? 32768
: (64 * 1024)) : 8192)
;
2101 if (cnt > xfer || cnt < 0)
2102 cnt = xfer;
2103 siz = ((cnt + DIRBLKSIZ(1 << 9) - 1) & ~(DIRBLKSIZ(1 << 9) - 1));
2104 if (siz > xfer)
2105 siz = xfer;
2106 fullsiz = siz;
2107 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2108 if (error) {
2109 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); }
;
2110 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2111 error = 0;
2112 goto nfsmout;
2113 }
2114 if (info.nmi_v3)
2115 error = getret = VOP_GETATTR(vp, &at, cred, procp);
2116 if (!error)
2117 error = nfsrv_access(vp, VEXEC00100, cred, rdonly, procp, 0);
2118 if (error) {
2119 vput(vp);
2120 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); }
;
2121 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2122 error = 0;
2123 goto nfsmout;
2124 }
2125 VOP_UNLOCK(vp);
2126 rbuf = malloc(fullsiz, M_TEMP127, M_WAITOK0x0001);
2127again:
2128 iv.iov_base = rbuf;
2129 iv.iov_len = fullsiz;
2130 io.uio_iov = &iv;
2131 io.uio_iovcnt = 1;
2132 io.uio_offset = (off_t)off;
2133 io.uio_resid = fullsiz;
2134 io.uio_segflg = UIO_SYSSPACE;
2135 io.uio_rw = UIO_READ;
2136 io.uio_procp = NULL((void *)0);
2137 eofflag = 0;
2138
2139 vn_lock(vp, LK_EXCLUSIVE0x0001UL | LK_RETRY0x2000UL);
2140 error = VOP_READDIR(vp, &io, cred, &eofflag);
2141
2142 off = (off_t)io.uio_offset;
2143 if (info.nmi_v3) {
2144 getret = VOP_GETATTR(vp, &at, cred, procp);
2145 if (!error)
2146 error = getret;
2147 }
2148
2149 VOP_UNLOCK(vp);
2150 if (error) {
2151 vrele(vp);
2152 free(rbuf, M_TEMP127, fullsiz);
2153 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); }
;
2154 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2155 error = 0;
2156 goto nfsmout;
2157 }
2158 if (io.uio_resid) {
2159 siz -= io.uio_resid;
2160
2161 /*
2162 * If nothing read, return eof
2163 * rpc reply
2164 */
2165 if (siz == 0) {
2166 vrele(vp);
2167 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); }
2168 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); }
;
2169 if (info.nmi_v3) {
2170 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2171 tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED4);
2172 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)
;
2173 tl += 2;
2174 } else
2175 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2176 *tl++ = nfs_false;
2177 *tl = nfs_true;
2178 free(rbuf, M_TEMP127, fullsiz);
2179 error = 0;
2180 goto nfsmout;
2181 }
2182 }
2183
2184 /*
2185 * Check for degenerate cases of nothing useful read.
2186 * If so go try again
2187 */
2188 cpos = rbuf;
2189 cend = rbuf + siz;
2190 dp = (struct dirent *)cpos;
2191
2192 while (cpos < cend && dp->d_fileno == 0) {
2193 cpos += dp->d_reclen;
2194 dp = (struct dirent *)cpos;
2195 }
2196 if (cpos >= cend) {
2197 toff = off;
2198 siz = fullsiz;
2199 goto again;
2200 }
2201
2202 len = 3 * NFSX_UNSIGNED4; /* paranoia, probably can be 0 */
2203 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); }
;
2204 if (info.nmi_v3) {
2205 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2206 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2207 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)
;
2208 }
2209
2210 /* Loop through the records and build reply */
2211 while (cpos < cend) {
2212 if (dp->d_fileno != 0) {
2213 nlen = dp->d_namlen;
2214 pad = nfsm_padlen(nlen)((((nlen)+3)&(~0x3)) - (nlen));
2215 len += (4 * NFSX_UNSIGNED4 + nlen + pad);
2216 if (info.nmi_v3)
2217 len += 2 * NFSX_UNSIGNED4;
2218 if (len > cnt) {
2219 eofflag = 0;
2220 break;
2221 }
2222 /*
2223 * Build the directory record xdr from
2224 * the dirent entry.
2225 */
2226 tl = nfsm_build(&info.nmi_mb,
2227 (info.nmi_v3 ? 3 : 2) * NFSX_UNSIGNED4);
2228 *tl++ = nfs_true;
2229 if (info.nmi_v3)
2230 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)
;
2231 else
2232 *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))))
;
2233
2234 /* And copy the name */
2235 nfsm_strtombuf(&info.nmi_mb, dp->d_name, nlen);
2236
2237 /* Finish off the record */
2238 if (info.nmi_v3) {
2239 tl = nfsm_build(&info.nmi_mb, 2*NFSX_UNSIGNED4);
2240 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)
;
2241 } else {
2242 tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED4);
2243 *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))))
;
2244 }
2245 }
2246 cpos += dp->d_reclen;
2247 dp = (struct dirent *)cpos;
2248 }
2249 vrele(vp);
2250 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2251 *tl++ = nfs_false;
2252 if (eofflag)
2253 *tl = nfs_true;
2254 else
2255 *tl = nfs_false;
2256 free(rbuf, M_TEMP127, fullsiz);
2257nfsmout:
2258 return(error);
2259}
2260
2261int
2262nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2263 struct proc *procp, struct mbuf **mrq)
2264{
2265 struct mbuf *nam = nfsd->nd_nam;
2266 struct ucred *cred = &nfsd->nd_cr;
2267 struct dirent *dp;
2268 struct nfsm_info info;
2269 u_int32_t *tl;
2270 int32_t t1;
2271 char *cpos, *cend, *cp2, *rbuf;
2272 struct vnode *vp, *nvp;
2273 struct flrep fl;
2274 nfsfh_t nfh;
2275 fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh;
2276 struct uio io;
2277 struct iovec iv;
2278 struct vattr va, at, *vap = &va;
2279 struct nfs_fattr *fp;
2280 int len, nlen, pad, xfer, error = 0, getret = 1;
2281 int siz, cnt, fullsiz, eofflag, rdonly, dirlen;
2282 u_quad_t off, toff, verf;
2283
2284 info.nmi_mreq = NULL((void *)0);
2285 info.nmi_mrep = nfsd->nd_mrep;
2286 info.nmi_md = nfsd->nd_md;
2287 info.nmi_dpos = nfsd->nd_dpos;
2288 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2289
2290 fhp = &nfh.fh_generic;
2291 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; } }; }
;
2292 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; } }
;
2293 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]))))
;
2294 tl += 2;
2295 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]))))
;
2296 tl += 2;
2297 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++))))
;
2298 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))))
;
2299 xfer = NFS_SRVMAXDATA(nfsd)(((nfsd)->nd_flag & 0x08) ? (((nfsd)->nd_nam2) ? 32768
: (64 * 1024)) : 8192)
;
2300 if (cnt > xfer || cnt < 0)
2301 cnt = xfer;
2302 siz = ((siz + DIRBLKSIZ(1 << 9) - 1) & ~(DIRBLKSIZ(1 << 9) - 1));
2303 if (siz > xfer)
2304 siz = xfer;
2305 fullsiz = siz;
2306 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2307 if (error) {
2308 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); }
;
2309 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2310 error = 0;
2311 goto nfsmout;
2312 }
2313 error = getret = VOP_GETATTR(vp, &at, cred, procp);
2314 if (!error)
2315 error = nfsrv_access(vp, VEXEC00100, cred, rdonly, procp, 0);
2316 if (error) {
2317 vput(vp);
2318 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); }
;
2319 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2320 error = 0;
2321 goto nfsmout;
2322 }
2323 VOP_UNLOCK(vp);
2324
2325 rbuf = malloc(fullsiz, M_TEMP127, M_WAITOK0x0001);
2326again:
2327 iv.iov_base = rbuf;
2328 iv.iov_len = fullsiz;
2329 io.uio_iov = &iv;
2330 io.uio_iovcnt = 1;
2331 io.uio_offset = (off_t)off;
2332 io.uio_resid = fullsiz;
2333 io.uio_segflg = UIO_SYSSPACE;
2334 io.uio_rw = UIO_READ;
2335 io.uio_procp = NULL((void *)0);
2336 eofflag = 0;
2337
2338 vn_lock(vp, LK_EXCLUSIVE0x0001UL | LK_RETRY0x2000UL);
2339 error = VOP_READDIR(vp, &io, cred, &eofflag);
2340
2341 off = (u_quad_t)io.uio_offset;
2342 getret = VOP_GETATTR(vp, &at, cred, procp);
2343
2344 VOP_UNLOCK(vp);
2345
2346 if (!error)
2347 error = getret;
2348 if (error) {
2349 vrele(vp);
2350 free(rbuf, M_TEMP127, fullsiz);
2351 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); }
;
2352 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2353 error = 0;
2354 goto nfsmout;
2355 }
2356 if (io.uio_resid) {
2357 siz -= io.uio_resid;
2358
2359 /*
2360 * If nothing read, return eof
2361 * rpc reply
2362 */
2363 if (siz == 0) {
2364 vrele(vp);
2365 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); }
2366 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); }
;
2367 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2368 tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED4);
2369 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)
;
2370 tl += 2;
2371 *tl++ = nfs_false;
2372 *tl = nfs_true;
2373 free(rbuf, M_TEMP127, fullsiz);
2374 error = 0;
2375 goto nfsmout;
2376 }
2377 }
2378
2379 /*
2380 * Check for degenerate cases of nothing useful read.
2381 * If so go try again
2382 */
2383 cpos = rbuf;
2384 cend = rbuf + siz;
2385 dp = (struct dirent *)cpos;
2386
2387 while (cpos < cend && dp->d_fileno == 0) {
2388 cpos += dp->d_reclen;
2389 dp = (struct dirent *)cpos;
2390 }
2391 if (cpos >= cend) {
2392 toff = off;
Value stored to 'toff' is never read
2393 siz = fullsiz;
2394 goto again;
2395 }
2396
2397 /*
2398 * struct READDIRPLUS3resok {
2399 * postop_attr dir_attributes;
2400 * cookieverf3 cookieverf;
2401 * dirlistplus3 reply;
2402 * }
2403 *
2404 * struct dirlistplus3 {
2405 * entryplus3 *entries;
2406 * bool eof;
2407 * }
2408 */
2409 dirlen = len = NFSX_V3POSTOPATTR(84 + 4) + NFSX_V3COOKIEVERF8 + 2 * NFSX_UNSIGNED4;
2410 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); }
;
2411 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2412 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2413 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)
;
2414
2415 /* Loop through the records and build reply */
2416 while (cpos < cend) {
2417 if (dp->d_fileno != 0) {
2418 nlen = dp->d_namlen;
2419 pad = nfsm_padlen(nlen)((((nlen)+3)&(~0x3)) - (nlen));
2420
2421 /*
2422 * For readdir_and_lookup get the vnode using
2423 * the file number.
2424 */
2425 if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp)(*(vp->v_mount)->mnt_op->vfs_vget)(vp->v_mount, dp
->d_fileno, &nvp)
)
2426 goto invalid;
2427 memset(nfhp, 0, NFSX_V3FH)__builtin_memset((nfhp), (0), ((sizeof (fhandle_t))));
2428 nfhp->fh_fsid =
2429 nvp->v_mount->mnt_stat.f_fsid;
2430 if (VFS_VPTOFH(nvp, &nfhp->fh_fid)(*(nvp)->v_mount->mnt_op->vfs_vptofh)(nvp, &nfhp
->fh_fid)
) {
2431 vput(nvp);
2432 goto invalid;
2433 }
2434 if (VOP_GETATTR(nvp, vap, cred, procp)) {
2435 vput(nvp);
2436 goto invalid;
2437 }
2438 vput(nvp);
2439
2440 /*
2441 * If either the dircount or maxcount will be
2442 * exceeded, get out now. Both of these lengths
2443 * are calculated conservatively, including all
2444 * XDR overheads.
2445 *
2446 * Each entry:
2447 * 2 * NFSX_UNSIGNED for fileid3
2448 * 1 * NFSX_UNSIGNED for length of name
2449 * nlen + pad == space the name takes up
2450 * 2 * NFSX_UNSIGNED for the cookie
2451 * 1 * NFSX_UNSIGNED to indicate if file handle present
2452 * 1 * NFSX_UNSIGNED for the file handle length
2453 * NFSX_V3FH == space our file handle takes up
2454 * NFSX_V3POSTOPATTR == space the attributes take up
2455 * 1 * NFSX_UNSIGNED for next pointer
2456 */
2457 len += (8 * NFSX_UNSIGNED4 + nlen + pad + NFSX_V3FH(sizeof (fhandle_t)) +
2458 NFSX_V3POSTOPATTR(84 + 4));
2459 dirlen += (6 * NFSX_UNSIGNED4 + nlen + pad);
2460 if (len > cnt || dirlen > fullsiz) {
2461 eofflag = 0;
2462 break;
2463 }
2464
2465 tl = nfsm_build(&info.nmi_mb, 3 * NFSX_UNSIGNED4);
2466 *tl++ = nfs_true;
2467 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)
;
2468
2469 /* And copy the name */
2470 nfsm_strtombuf(&info.nmi_mb, dp->d_name, nlen);
2471
2472 /*
2473 * Build the directory record xdr from
2474 * the dirent entry.
2475 */
2476 fp = (struct nfs_fattr *)&fl.fl_fattr;
2477 nfsm_srvfattr(nfsd, vap, fp);
2478 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))))))
;
2479 fl.fl_fhok = nfs_true;
2480 fl.fl_postopok = nfs_true;
2481 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)
;
2482
2483 /* Now copy the flrep structure out. */
2484 nfsm_buftombuf(&info.nmi_mb, &fl, sizeof(struct flrep));
2485 }
2486invalid:
2487 cpos += dp->d_reclen;
2488 dp = (struct dirent *)cpos;
2489 }
2490 vrele(vp);
2491 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED4);
2492 *tl++ = nfs_false;
2493 if (eofflag)
2494 *tl = nfs_true;
2495 else
2496 *tl = nfs_false;
2497 free(rbuf, M_TEMP127, fullsiz);
2498nfsmout:
2499 return(error);
2500}
2501
2502/*
2503 * nfs commit service
2504 */
2505int
2506nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2507 struct proc *procp, struct mbuf **mrq)
2508{
2509 struct mbuf *nam = nfsd->nd_nam;
2510 struct ucred *cred = &nfsd->nd_cr;
2511 struct vattr bfor, aft;
2512 struct vnode *vp;
2513 struct nfsm_info info;
2514 struct timeval boottime;
2515 nfsfh_t nfh;
2516 fhandle_t *fhp;
2517 u_int32_t *tl;
2518 int32_t t1;
2519 int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt;
2520 char *cp2;
2521 u_quad_t off;
2522
2523 info.nmi_mreq = NULL((void *)0);
2524 info.nmi_mrep = nfsd->nd_mrep;
2525 info.nmi_md = nfsd->nd_md;
2526 info.nmi_dpos = nfsd->nd_dpos;
2527 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2528
2529 fhp = &nfh.fh_generic;
2530 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; } }; }
;
2531 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; } }
;
2532
2533 /*
2534 * XXX At this time VOP_FSYNC() does not accept offset and byte
2535 * count parameters, so these arguments are useless (someday maybe).
2536 */
2537 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]))))
;
2538 tl += 2;
2539 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))))
;
2540 if (cnt < 0)
2541 cnt = 0;
2542 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2543 if (error) {
2544 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); }
;
2545 nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
2546 error = 0;
2547 goto nfsmout;
2548 }
2549 for_ret = VOP_GETATTR(vp, &bfor, cred, procp);
2550 error = VOP_FSYNC(vp, cred, MNT_WAIT1, procp);
2551 aft_ret = VOP_GETATTR(vp, &aft, cred, procp);
2552 vput(vp);
2553 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); }
;
2554 nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
2555 if (!error) {
2556 tl = nfsm_build(&info.nmi_mb, NFSX_V3WRITEVERF8);
2557 microboottime(&boottime);
2558 *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))))
;
2559 *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))))
;
2560 } else
2561 error = 0;
2562nfsmout:
2563 return(error);
2564}
2565
2566/*
2567 * nfs statfs service
2568 */
2569int
2570nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2571 struct proc *procp, struct mbuf **mrq)
2572{
2573 struct mbuf *nam = nfsd->nd_nam;
2574 struct ucred *cred = &nfsd->nd_cr;
2575 struct statfs *sf;
2576 struct nfs_statfs *sfp;
2577 struct nfsm_info info;
2578 u_int32_t *tl;
2579 int32_t t1;
2580 int error = 0, rdonly, getret = 1;
2581 char *cp2;
2582 struct vnode *vp;
2583 struct vattr at;
2584 nfsfh_t nfh;
2585 fhandle_t *fhp;
2586 struct statfs statfs;
2587 u_quad_t tval;
2588
2589 info.nmi_mreq = NULL((void *)0);
2590 info.nmi_mrep = nfsd->nd_mrep;
2591 info.nmi_md = nfsd->nd_md;
2592 info.nmi_dpos = nfsd->nd_dpos;
2593 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2594
2595 fhp = &nfh.fh_generic;
2596 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; } }; }
;
2597 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2598 if (error) {
2599 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); }
;
2600 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2601 error = 0;
2602 goto nfsmout;
2603 }
2604 sf = &statfs;
2605 error = VFS_STATFS(vp->v_mount, sf, procp)(*(vp->v_mount)->mnt_op->vfs_statfs)(vp->v_mount,
sf, procp)
;
2606 getret = VOP_GETATTR(vp, &at, cred, procp);
2607 vput(vp);
2608 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); }
;
2609 if (info.nmi_v3)
2610 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2611 if (error) {
2612 error = 0;
2613 goto nfsmout;
2614 }
2615 sfp = nfsm_build(&info.nmi_mb, NFSX_STATFS(info.nmi_v3)((info.nmi_v3) ? 52 : 20));
2616 if (info.nmi_v3) {
2617 tval = (u_quad_t)sf->f_blocks;
2618 tval *= (u_quad_t)sf->f_bsize;
2619 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)
;
2620 tval = (u_quad_t)sf->f_bfree;
2621 tval *= (u_quad_t)sf->f_bsize;
2622 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)
;
2623 tval = (u_quad_t)sf->f_bavail;
2624 tval *= (u_quad_t)sf->f_bsize;
2625 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)
;
2626 tval = (u_quad_t)sf->f_files;
2627 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)
;
2628 tval = (u_quad_t)sf->f_ffree;
2629 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)
;
2630 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)
;
2631 sfp->sf_invarsecsf_un.sf_nfsv3.nfsv3sf_invarsec = 0;
2632 } else {
2633 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))))
;
2634 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))))
;
2635 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))))
;
2636 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))))
;
2637 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))))
;
2638 }
2639nfsmout:
2640 return(error);
2641}
2642
2643/*
2644 * nfs fsinfo service
2645 */
2646int
2647nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2648 struct proc *procp, struct mbuf **mrq)
2649{
2650 struct mbuf *nam = nfsd->nd_nam;
2651 struct ucred *cred = &nfsd->nd_cr;
2652 struct nfsm_info info;
2653 u_int32_t *tl;
2654 struct nfsv3_fsinfo *sip;
2655 int32_t t1;
2656 int error = 0, rdonly, getret = 1, pref;
2657 char *cp2;
2658 struct vnode *vp;
2659 struct vattr at;
2660 nfsfh_t nfh;
2661 fhandle_t *fhp;
2662
2663 info.nmi_mreq = NULL((void *)0);
2664 info.nmi_mrep = nfsd->nd_mrep;
2665 info.nmi_md = nfsd->nd_md;
2666 info.nmi_dpos = nfsd->nd_dpos;
2667 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2668
2669 fhp = &nfh.fh_generic;
2670 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; } }; }
;
2671 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2672 if (error) {
2673 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); }
;
2674 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2675 error = 0;
2676 goto nfsmout;
2677 }
2678 getret = VOP_GETATTR(vp, &at, cred, procp);
2679 vput(vp);
2680 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); }
;
2681 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2682 sip = nfsm_build(&info.nmi_mb, NFSX_V3FSINFO48);
2683
2684 /*
2685 * XXX
2686 * There should be file system VFS OP(s) to get this information.
2687 * For now, assume ufs.
2688 */
2689 if (slp->ns_so->so_type == SOCK_DGRAM2)
2690 pref = NFS_MAXDGRAMDATA32768;
2691 else
2692 pref = NFS_MAXDATA(64 * 1024);
2693 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)))))
;
2694 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))))
;
2695 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
))))
;
2696 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)))))
;
2697 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))))
;
2698 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
))))
;
2699 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))))
;
2700 sip->fs_maxfilesize.nfsuquad[0] = 0xffffffff;
2701 sip->fs_maxfilesize.nfsuquad[1] = 0xffffffff;
2702 sip->fs_timedelta.nfsv3_sec = 0;
2703 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))))
;
2704 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))))
2705 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))))
2706 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))))
;
2707nfsmout:
2708 return(error);
2709}
2710
2711/*
2712 * nfs pathconf service
2713 */
2714int
2715nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2716 struct proc *procp, struct mbuf **mrq)
2717{
2718 struct mbuf *nam = nfsd->nd_nam;
2719 struct ucred *cred = &nfsd->nd_cr;
2720 struct nfsm_info info;
2721 u_int32_t *tl;
2722 struct nfsv3_pathconf *pc;
2723 int32_t t1;
2724 int error = 0, rdonly, getret = 1;
2725 register_t linkmax, namemax, chownres, notrunc;
2726 char *cp2;
2727 struct vnode *vp;
2728 struct vattr at;
2729 nfsfh_t nfh;
2730 fhandle_t *fhp;
2731
2732 info.nmi_mreq = NULL((void *)0);
2733 info.nmi_mrep = nfsd->nd_mrep;
2734 info.nmi_md = nfsd->nd_md;
2735 info.nmi_dpos = nfsd->nd_dpos;
2736 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2737
2738 fhp = &nfh.fh_generic;
2739 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; } }; }
;
2740 error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
2741 if (error) {
2742 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); }
;
2743 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2744 error = 0;
2745 goto nfsmout;
2746 }
2747 error = VOP_PATHCONF(vp, _PC_LINK_MAX1, &linkmax);
2748 if (!error)
2749 error = VOP_PATHCONF(vp, _PC_NAME_MAX4, &namemax);
2750 if (!error)
2751 error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED7, &chownres);
2752 if (!error)
2753 error = VOP_PATHCONF(vp, _PC_NO_TRUNC8, &notrunc);
2754 getret = VOP_GETATTR(vp, &at, cred, procp);
2755 vput(vp);
2756 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); }
;
2757 nfsm_srvpostop_attr(nfsd, getret, &at, &info);
2758 if (error) {
2759 error = 0;
2760 goto nfsmout;
2761 }
2762 pc = nfsm_build(&info.nmi_mb, NFSX_V3PATHCONF24);
2763
2764 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))))
;
2765 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))))
;
2766 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))))
;
2767 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))))
;
2768
2769 /*
2770 * These should probably be supported by VOP_PATHCONF(), but
2771 * until msdosfs is exportable (why would you want to?), the
2772 * Unix defaults should be ok.
2773 */
2774 pc->pc_caseinsensitive = nfs_false;
2775 pc->pc_casepreserving = nfs_true;
2776nfsmout:
2777 return(error);
2778}
2779
2780/*
2781 * Null operation, used by clients to ping server
2782 */
2783int
2784nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2785 struct proc *procp, struct mbuf **mrq)
2786{
2787 struct nfsm_info info;
2788 int error = NFSERR_RETVOID0x20000000;
2789
2790 info.nmi_mreq = NULL((void *)0);
2791 info.nmi_mrep = nfsd->nd_mrep;
2792 info.nmi_md = nfsd->nd_md;
2793 info.nmi_dpos = nfsd->nd_dpos;
2794 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2795
2796 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); }
;
2797 return (0);
2798}
2799
2800/*
2801 * No operation, used for obsolete procedures
2802 */
2803int
2804nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
2805 struct proc *procp, struct mbuf **mrq)
2806{
2807 struct nfsm_info info;
2808 int error;
2809
2810 info.nmi_mreq = NULL((void *)0);
2811 info.nmi_mrep = nfsd->nd_mrep;
2812 info.nmi_md = nfsd->nd_md;
2813 info.nmi_dpos = nfsd->nd_dpos;
2814 info.nmi_v3 = (nfsd->nd_flag & ND_NFSV30x08);
2815
2816 if (nfsd->nd_repstat)
2817 error = nfsd->nd_repstat;
2818 else
2819 error = EPROCUNAVAIL76;
2820 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); }
;
2821 return (0);
2822}
2823
2824/*
2825 * Perform access checking for vnodes obtained from file handles that would
2826 * refer to files already opened by a Unix client.
2827 * You cannot just use vn_writechk() and VOP_ACCESS() for two reasons:
2828 * 1 - You must check for exported rdonly as well as MNT_RDONLY for the
2829 * write case
2830 * 2 - The owner is to be given access irrespective of mode bits for some
2831 * operations, so that processes that chmod after opening a file don't
2832 * break. I don't like this because it opens a security hole, but since
2833 * the nfs server opens a security hole the size of a barn door anyhow,
2834 * what the heck. A notable exception to this rule is when VOP_ACCESS()
2835 * returns EPERM (e.g. when a file is immutable) which is always an
2836 * error.
2837 */
2838int
2839nfsrv_access(struct vnode *vp, int flags, struct ucred *cred, int rdonly,
2840 struct proc *p, int override)
2841{
2842 struct vattr vattr;
2843 int error;
2844
2845 if (flags & VWRITE00200) {
2846 /* Just vn_writechk() changed to check rdonly */
2847 /*
2848 * Disallow write attempts on read-only file systems;
2849 * unless the file is a socket or a block or character
2850 * device resident on the file system.
2851 */
2852 if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY0x00000001)) {
2853 switch (vp->v_type) {
2854 case VREG:
2855 case VDIR:
2856 case VLNK:
2857 return (EROFS30);
2858 default:
2859 break;
2860 }
2861 }
2862 /*
2863 * If there's shared text associated with
2864 * the inode, try to free it up once. If
2865 * we fail, we can't allow writing.
2866 */
2867 if ((vp->v_flag & VTEXT0x0002) && !uvm_vnp_uncache(vp))
2868 return (ETXTBSY26);
2869 }
2870 error = VOP_ACCESS(vp, flags, cred, p);
2871 /*
2872 * Allow certain operations for the owner (reads and writes
2873 * on files that are already open).
2874 */
2875 if (override && error == EACCES13 &&
2876 VOP_GETATTR(vp, &vattr, cred, p) == 0 &&
2877 cred->cr_uid == vattr.va_uid)
2878 error = 0;
2879 return error;
2880}