nfs_vnops.c revision 1.288 1 /* $NetBSD: nfs_vnops.c,v 1.288 2010/12/14 16:25:18 cegger Exp $ */
2
3 /*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)nfs_vnops.c 8.19 (Berkeley) 7/31/95
35 */
36
37 /*
38 * vnode op calls for Sun NFS version 2 and 3
39 */
40
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.288 2010/12/14 16:25:18 cegger Exp $");
43
44 #ifdef _KERNEL_OPT
45 #include "opt_nfs.h"
46 #include "opt_uvmhist.h"
47 #endif
48
49 #include <sys/param.h>
50 #include <sys/proc.h>
51 #include <sys/kernel.h>
52 #include <sys/systm.h>
53 #include <sys/resourcevar.h>
54 #include <sys/mount.h>
55 #include <sys/buf.h>
56 #include <sys/condvar.h>
57 #include <sys/disk.h>
58 #include <sys/malloc.h>
59 #include <sys/kmem.h>
60 #include <sys/mbuf.h>
61 #include <sys/mutex.h>
62 #include <sys/namei.h>
63 #include <sys/vnode.h>
64 #include <sys/dirent.h>
65 #include <sys/fcntl.h>
66 #include <sys/hash.h>
67 #include <sys/lockf.h>
68 #include <sys/stat.h>
69 #include <sys/unistd.h>
70 #include <sys/kauth.h>
71
72 #include <uvm/uvm_extern.h>
73 #include <uvm/uvm.h>
74
75 #include <miscfs/fifofs/fifo.h>
76 #include <miscfs/genfs/genfs.h>
77 #include <miscfs/genfs/genfs_node.h>
78 #include <miscfs/specfs/specdev.h>
79
80 #include <nfs/rpcv2.h>
81 #include <nfs/nfsproto.h>
82 #include <nfs/nfs.h>
83 #include <nfs/nfsnode.h>
84 #include <nfs/nfsmount.h>
85 #include <nfs/xdr_subs.h>
86 #include <nfs/nfsm_subs.h>
87 #include <nfs/nfs_var.h>
88
89 #include <net/if.h>
90 #include <netinet/in.h>
91 #include <netinet/in_var.h>
92
93 /*
94 * Global vfs data structures for nfs
95 */
96 int (**nfsv2_vnodeop_p)(void *);
97 const struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = {
98 { &vop_default_desc, vn_default_error },
99 { &vop_lookup_desc, nfs_lookup }, /* lookup */
100 { &vop_create_desc, nfs_create }, /* create */
101 { &vop_mknod_desc, nfs_mknod }, /* mknod */
102 { &vop_open_desc, nfs_open }, /* open */
103 { &vop_close_desc, nfs_close }, /* close */
104 { &vop_access_desc, nfs_access }, /* access */
105 { &vop_getattr_desc, nfs_getattr }, /* getattr */
106 { &vop_setattr_desc, nfs_setattr }, /* setattr */
107 { &vop_read_desc, nfs_read }, /* read */
108 { &vop_write_desc, nfs_write }, /* write */
109 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */
110 { &vop_ioctl_desc, nfs_ioctl }, /* ioctl */
111 { &vop_poll_desc, nfs_poll }, /* poll */
112 { &vop_kqfilter_desc, nfs_kqfilter }, /* kqfilter */
113 { &vop_revoke_desc, nfs_revoke }, /* revoke */
114 { &vop_mmap_desc, nfs_mmap }, /* mmap */
115 { &vop_fsync_desc, nfs_fsync }, /* fsync */
116 { &vop_seek_desc, nfs_seek }, /* seek */
117 { &vop_remove_desc, nfs_remove }, /* remove */
118 { &vop_link_desc, nfs_link }, /* link */
119 { &vop_rename_desc, nfs_rename }, /* rename */
120 { &vop_mkdir_desc, nfs_mkdir }, /* mkdir */
121 { &vop_rmdir_desc, nfs_rmdir }, /* rmdir */
122 { &vop_symlink_desc, nfs_symlink }, /* symlink */
123 { &vop_readdir_desc, nfs_readdir }, /* readdir */
124 { &vop_readlink_desc, nfs_readlink }, /* readlink */
125 { &vop_abortop_desc, nfs_abortop }, /* abortop */
126 { &vop_inactive_desc, nfs_inactive }, /* inactive */
127 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */
128 { &vop_lock_desc, nfs_lock }, /* lock */
129 { &vop_unlock_desc, nfs_unlock }, /* unlock */
130 { &vop_bmap_desc, nfs_bmap }, /* bmap */
131 { &vop_strategy_desc, nfs_strategy }, /* strategy */
132 { &vop_print_desc, nfs_print }, /* print */
133 { &vop_islocked_desc, nfs_islocked }, /* islocked */
134 { &vop_pathconf_desc, nfs_pathconf }, /* pathconf */
135 { &vop_advlock_desc, nfs_advlock }, /* advlock */
136 { &vop_bwrite_desc, genfs_badop }, /* bwrite */
137 { &vop_getpages_desc, nfs_getpages }, /* getpages */
138 { &vop_putpages_desc, genfs_putpages }, /* putpages */
139 { NULL, NULL }
140 };
141 const struct vnodeopv_desc nfsv2_vnodeop_opv_desc =
142 { &nfsv2_vnodeop_p, nfsv2_vnodeop_entries };
143
144 /*
145 * Special device vnode ops
146 */
147 int (**spec_nfsv2nodeop_p)(void *);
148 const struct vnodeopv_entry_desc spec_nfsv2nodeop_entries[] = {
149 { &vop_default_desc, vn_default_error },
150 { &vop_lookup_desc, spec_lookup }, /* lookup */
151 { &vop_create_desc, spec_create }, /* create */
152 { &vop_mknod_desc, spec_mknod }, /* mknod */
153 { &vop_open_desc, spec_open }, /* open */
154 { &vop_close_desc, nfsspec_close }, /* close */
155 { &vop_access_desc, nfsspec_access }, /* access */
156 { &vop_getattr_desc, nfs_getattr }, /* getattr */
157 { &vop_setattr_desc, nfs_setattr }, /* setattr */
158 { &vop_read_desc, nfsspec_read }, /* read */
159 { &vop_write_desc, nfsspec_write }, /* write */
160 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */
161 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */
162 { &vop_poll_desc, spec_poll }, /* poll */
163 { &vop_kqfilter_desc, spec_kqfilter }, /* kqfilter */
164 { &vop_revoke_desc, spec_revoke }, /* revoke */
165 { &vop_mmap_desc, spec_mmap }, /* mmap */
166 { &vop_fsync_desc, spec_fsync }, /* fsync */
167 { &vop_seek_desc, spec_seek }, /* seek */
168 { &vop_remove_desc, spec_remove }, /* remove */
169 { &vop_link_desc, spec_link }, /* link */
170 { &vop_rename_desc, spec_rename }, /* rename */
171 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */
172 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */
173 { &vop_symlink_desc, spec_symlink }, /* symlink */
174 { &vop_readdir_desc, spec_readdir }, /* readdir */
175 { &vop_readlink_desc, spec_readlink }, /* readlink */
176 { &vop_abortop_desc, spec_abortop }, /* abortop */
177 { &vop_inactive_desc, nfs_inactive }, /* inactive */
178 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */
179 { &vop_lock_desc, nfs_lock }, /* lock */
180 { &vop_unlock_desc, nfs_unlock }, /* unlock */
181 { &vop_bmap_desc, spec_bmap }, /* bmap */
182 { &vop_strategy_desc, spec_strategy }, /* strategy */
183 { &vop_print_desc, nfs_print }, /* print */
184 { &vop_islocked_desc, nfs_islocked }, /* islocked */
185 { &vop_pathconf_desc, spec_pathconf }, /* pathconf */
186 { &vop_advlock_desc, spec_advlock }, /* advlock */
187 { &vop_bwrite_desc, spec_bwrite }, /* bwrite */
188 { &vop_getpages_desc, spec_getpages }, /* getpages */
189 { &vop_putpages_desc, spec_putpages }, /* putpages */
190 { NULL, NULL }
191 };
192 const struct vnodeopv_desc spec_nfsv2nodeop_opv_desc =
193 { &spec_nfsv2nodeop_p, spec_nfsv2nodeop_entries };
194
195 int (**fifo_nfsv2nodeop_p)(void *);
196 const struct vnodeopv_entry_desc fifo_nfsv2nodeop_entries[] = {
197 { &vop_default_desc, vn_default_error },
198 { &vop_lookup_desc, vn_fifo_bypass }, /* lookup */
199 { &vop_create_desc, vn_fifo_bypass }, /* create */
200 { &vop_mknod_desc, vn_fifo_bypass }, /* mknod */
201 { &vop_open_desc, vn_fifo_bypass }, /* open */
202 { &vop_close_desc, nfsfifo_close }, /* close */
203 { &vop_access_desc, nfsspec_access }, /* access */
204 { &vop_getattr_desc, nfs_getattr }, /* getattr */
205 { &vop_setattr_desc, nfs_setattr }, /* setattr */
206 { &vop_read_desc, nfsfifo_read }, /* read */
207 { &vop_write_desc, nfsfifo_write }, /* write */
208 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */
209 { &vop_ioctl_desc, vn_fifo_bypass }, /* ioctl */
210 { &vop_poll_desc, vn_fifo_bypass }, /* poll */
211 { &vop_kqfilter_desc, vn_fifo_bypass }, /* kqfilter */
212 { &vop_revoke_desc, vn_fifo_bypass }, /* revoke */
213 { &vop_mmap_desc, vn_fifo_bypass }, /* mmap */
214 { &vop_fsync_desc, nfs_fsync }, /* fsync */
215 { &vop_seek_desc, vn_fifo_bypass }, /* seek */
216 { &vop_remove_desc, vn_fifo_bypass }, /* remove */
217 { &vop_link_desc, vn_fifo_bypass }, /* link */
218 { &vop_rename_desc, vn_fifo_bypass }, /* rename */
219 { &vop_mkdir_desc, vn_fifo_bypass }, /* mkdir */
220 { &vop_rmdir_desc, vn_fifo_bypass }, /* rmdir */
221 { &vop_symlink_desc, vn_fifo_bypass }, /* symlink */
222 { &vop_readdir_desc, vn_fifo_bypass }, /* readdir */
223 { &vop_readlink_desc, vn_fifo_bypass }, /* readlink */
224 { &vop_abortop_desc, vn_fifo_bypass }, /* abortop */
225 { &vop_inactive_desc, nfs_inactive }, /* inactive */
226 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */
227 { &vop_lock_desc, nfs_lock }, /* lock */
228 { &vop_unlock_desc, nfs_unlock }, /* unlock */
229 { &vop_bmap_desc, vn_fifo_bypass }, /* bmap */
230 { &vop_strategy_desc, genfs_badop }, /* strategy */
231 { &vop_print_desc, nfs_print }, /* print */
232 { &vop_islocked_desc, nfs_islocked }, /* islocked */
233 { &vop_pathconf_desc, vn_fifo_bypass }, /* pathconf */
234 { &vop_advlock_desc, vn_fifo_bypass }, /* advlock */
235 { &vop_bwrite_desc, genfs_badop }, /* bwrite */
236 { &vop_putpages_desc, vn_fifo_bypass }, /* putpages */
237 { NULL, NULL }
238 };
239 const struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc =
240 { &fifo_nfsv2nodeop_p, fifo_nfsv2nodeop_entries };
241
242 static int nfs_linkrpc(struct vnode *, struct vnode *, const char *,
243 size_t, kauth_cred_t, struct lwp *);
244 static void nfs_writerpc_extfree(struct mbuf *, void *, size_t, void *);
245
246 /*
247 * Global variables
248 */
249 extern u_int32_t nfs_true, nfs_false;
250 extern u_int32_t nfs_xdrneg1;
251 extern const nfstype nfsv3_type[9];
252
253 int nfs_numasync = 0;
254 #define DIRHDSIZ _DIRENT_NAMEOFF(dp)
255 #define UIO_ADVANCE(uio, siz) \
256 (void)((uio)->uio_resid -= (siz), \
257 (uio)->uio_iov->iov_base = (char *)(uio)->uio_iov->iov_base + (siz), \
258 (uio)->uio_iov->iov_len -= (siz))
259
260 static void nfs_cache_enter(struct vnode *, struct vnode *,
261 struct componentname *);
262
263 static void
264 nfs_cache_enter(struct vnode *dvp, struct vnode *vp,
265 struct componentname *cnp)
266 {
267 struct nfsnode *dnp = VTONFS(dvp);
268
269 if (vp != NULL) {
270 struct nfsnode *np = VTONFS(vp);
271
272 np->n_ctime = np->n_vattr->va_ctime.tv_sec;
273 }
274
275 if (!timespecisset(&dnp->n_nctime))
276 dnp->n_nctime = dnp->n_vattr->va_mtime;
277
278 cache_enter(dvp, vp, cnp);
279 }
280
281 /*
282 * nfs null call from vfs.
283 */
284 int
285 nfs_null(struct vnode *vp, kauth_cred_t cred, struct lwp *l)
286 {
287 char *bpos, *dpos;
288 int error = 0;
289 struct mbuf *mreq, *mrep, *md, *mb;
290 struct nfsnode *np = VTONFS(vp);
291
292 nfsm_reqhead(np, NFSPROC_NULL, 0);
293 nfsm_request(np, NFSPROC_NULL, l, cred);
294 nfsm_reqdone;
295 return (error);
296 }
297
298 /*
299 * nfs access vnode op.
300 * For nfs version 2, just return ok. File accesses may fail later.
301 * For nfs version 3, use the access rpc to check accessibility. If file modes
302 * are changed on the server, accesses might still fail later.
303 */
304 int
305 nfs_access(void *v)
306 {
307 struct vop_access_args /* {
308 struct vnode *a_vp;
309 int a_mode;
310 kauth_cred_t a_cred;
311 } */ *ap = v;
312 struct vnode *vp = ap->a_vp;
313 #ifndef NFS_V2_ONLY
314 u_int32_t *tl;
315 char *cp;
316 int32_t t1, t2;
317 char *bpos, *dpos, *cp2;
318 int error = 0, attrflag;
319 struct mbuf *mreq, *mrep, *md, *mb;
320 u_int32_t mode, rmode;
321 const int v3 = NFS_ISV3(vp);
322 #endif
323 int cachevalid;
324 struct nfsnode *np = VTONFS(vp);
325 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
326
327 cachevalid = (np->n_accstamp != -1 &&
328 (time_uptime - np->n_accstamp) < nfs_attrtimeo(nmp, np) &&
329 np->n_accuid == kauth_cred_geteuid(ap->a_cred));
330
331 /*
332 * Check access cache first. If this request has been made for this
333 * uid shortly before, use the cached result.
334 */
335 if (cachevalid) {
336 if (!np->n_accerror) {
337 if ((np->n_accmode & ap->a_mode) == ap->a_mode)
338 return np->n_accerror;
339 } else if ((np->n_accmode & ap->a_mode) == np->n_accmode)
340 return np->n_accerror;
341 }
342
343 #ifndef NFS_V2_ONLY
344 /*
345 * For nfs v3, do an access rpc, otherwise you are stuck emulating
346 * ufs_access() locally using the vattr. This may not be correct,
347 * since the server may apply other access criteria such as
348 * client uid-->server uid mapping that we do not know about, but
349 * this is better than just returning anything that is lying about
350 * in the cache.
351 */
352 if (v3) {
353 nfsstats.rpccnt[NFSPROC_ACCESS]++;
354 nfsm_reqhead(np, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED);
355 nfsm_fhtom(np, v3);
356 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
357 if (ap->a_mode & VREAD)
358 mode = NFSV3ACCESS_READ;
359 else
360 mode = 0;
361 if (vp->v_type != VDIR) {
362 if (ap->a_mode & VWRITE)
363 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
364 if (ap->a_mode & VEXEC)
365 mode |= NFSV3ACCESS_EXECUTE;
366 } else {
367 if (ap->a_mode & VWRITE)
368 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
369 NFSV3ACCESS_DELETE);
370 if (ap->a_mode & VEXEC)
371 mode |= NFSV3ACCESS_LOOKUP;
372 }
373 *tl = txdr_unsigned(mode);
374 nfsm_request(np, NFSPROC_ACCESS, curlwp, ap->a_cred);
375 nfsm_postop_attr(vp, attrflag, 0);
376 if (!error) {
377 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
378 rmode = fxdr_unsigned(u_int32_t, *tl);
379 /*
380 * The NFS V3 spec does not clarify whether or not
381 * the returned access bits can be a superset of
382 * the ones requested, so...
383 */
384 if ((rmode & mode) != mode)
385 error = EACCES;
386 }
387 nfsm_reqdone;
388 } else
389 #endif
390 return (nfsspec_access(ap));
391 #ifndef NFS_V2_ONLY
392 /*
393 * Disallow write attempts on filesystems mounted read-only;
394 * unless the file is a socket, fifo, or a block or character
395 * device resident on the filesystem.
396 */
397 if (!error && (ap->a_mode & VWRITE) &&
398 (vp->v_mount->mnt_flag & MNT_RDONLY)) {
399 switch (vp->v_type) {
400 case VREG:
401 case VDIR:
402 case VLNK:
403 error = EROFS;
404 default:
405 break;
406 }
407 }
408
409 if (!error || error == EACCES) {
410 /*
411 * If we got the same result as for a previous,
412 * different request, OR it in. Don't update
413 * the timestamp in that case.
414 */
415 if (cachevalid && np->n_accstamp != -1 &&
416 error == np->n_accerror) {
417 if (!error)
418 np->n_accmode |= ap->a_mode;
419 else if ((np->n_accmode & ap->a_mode) == ap->a_mode)
420 np->n_accmode = ap->a_mode;
421 } else {
422 np->n_accstamp = time_uptime;
423 np->n_accuid = kauth_cred_geteuid(ap->a_cred);
424 np->n_accmode = ap->a_mode;
425 np->n_accerror = error;
426 }
427 }
428
429 return (error);
430 #endif
431 }
432
433 /*
434 * nfs open vnode op
435 * Check to see if the type is ok
436 * and that deletion is not in progress.
437 * For paged in text files, you will need to flush the page cache
438 * if consistency is lost.
439 */
440 /* ARGSUSED */
441 int
442 nfs_open(void *v)
443 {
444 struct vop_open_args /* {
445 struct vnode *a_vp;
446 int a_mode;
447 kauth_cred_t a_cred;
448 } */ *ap = v;
449 struct vnode *vp = ap->a_vp;
450 struct nfsnode *np = VTONFS(vp);
451 int error;
452
453 if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
454 return (EACCES);
455 }
456
457 if (ap->a_mode & FREAD) {
458 if (np->n_rcred != NULL)
459 kauth_cred_free(np->n_rcred);
460 np->n_rcred = ap->a_cred;
461 kauth_cred_hold(np->n_rcred);
462 }
463 if (ap->a_mode & FWRITE) {
464 if (np->n_wcred != NULL)
465 kauth_cred_free(np->n_wcred);
466 np->n_wcred = ap->a_cred;
467 kauth_cred_hold(np->n_wcred);
468 }
469
470 error = nfs_flushstalebuf(vp, ap->a_cred, curlwp, 0);
471 if (error)
472 return error;
473
474 NFS_INVALIDATE_ATTRCACHE(np); /* For Open/Close consistency */
475
476 return (0);
477 }
478
479 /*
480 * nfs close vnode op
481 * What an NFS client should do upon close after writing is a debatable issue.
482 * Most NFS clients push delayed writes to the server upon close, basically for
483 * two reasons:
484 * 1 - So that any write errors may be reported back to the client process
485 * doing the close system call. By far the two most likely errors are
486 * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure.
487 * 2 - To put a worst case upper bound on cache inconsistency between
488 * multiple clients for the file.
489 * There is also a consistency problem for Version 2 of the protocol w.r.t.
490 * not being able to tell if other clients are writing a file concurrently,
491 * since there is no way of knowing if the changed modify time in the reply
492 * is only due to the write for this client.
493 * (NFS Version 3 provides weak cache consistency data in the reply that
494 * should be sufficient to detect and handle this case.)
495 *
496 * The current code does the following:
497 * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers
498 * for NFS Version 3 - flush dirty buffers to the server but don't invalidate
499 * or commit them (this satisfies 1 and 2 except for the
500 * case where the server crashes after this close but
501 * before the commit RPC, which is felt to be "good
502 * enough". Changing the last argument to nfs_flush() to
503 * a 1 would force a commit operation, if it is felt a
504 * commit is necessary now.
505 */
506 /* ARGSUSED */
507 int
508 nfs_close(void *v)
509 {
510 struct vop_close_args /* {
511 struct vnodeop_desc *a_desc;
512 struct vnode *a_vp;
513 int a_fflag;
514 kauth_cred_t a_cred;
515 } */ *ap = v;
516 struct vnode *vp = ap->a_vp;
517 struct nfsnode *np = VTONFS(vp);
518 int error = 0;
519 UVMHIST_FUNC("nfs_close"); UVMHIST_CALLED(ubchist);
520
521 if (vp->v_type == VREG) {
522 if (np->n_flag & NMODIFIED) {
523 #ifndef NFS_V2_ONLY
524 if (NFS_ISV3(vp)) {
525 error = nfs_flush(vp, ap->a_cred, MNT_WAIT, curlwp, 0);
526 np->n_flag &= ~NMODIFIED;
527 } else
528 #endif
529 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, curlwp, 1);
530 NFS_INVALIDATE_ATTRCACHE(np);
531 }
532 if (np->n_flag & NWRITEERR) {
533 np->n_flag &= ~NWRITEERR;
534 error = np->n_error;
535 }
536 }
537 UVMHIST_LOG(ubchist, "returning %d", error,0,0,0);
538 return (error);
539 }
540
541 /*
542 * nfs getattr call from vfs.
543 */
544 int
545 nfs_getattr(void *v)
546 {
547 struct vop_getattr_args /* {
548 struct vnode *a_vp;
549 struct vattr *a_vap;
550 kauth_cred_t a_cred;
551 } */ *ap = v;
552 struct vnode *vp = ap->a_vp;
553 struct nfsnode *np = VTONFS(vp);
554 char *cp;
555 u_int32_t *tl;
556 int32_t t1, t2;
557 char *bpos, *dpos;
558 int error = 0;
559 struct mbuf *mreq, *mrep, *md, *mb;
560 const int v3 = NFS_ISV3(vp);
561
562 /*
563 * Update local times for special files.
564 */
565 if (np->n_flag & (NACC | NUPD))
566 np->n_flag |= NCHG;
567
568 /*
569 * if we have delayed truncation, do it now.
570 */
571 nfs_delayedtruncate(vp);
572
573 /*
574 * First look in the cache.
575 */
576 if (nfs_getattrcache(vp, ap->a_vap) == 0)
577 return (0);
578 nfsstats.rpccnt[NFSPROC_GETATTR]++;
579 nfsm_reqhead(np, NFSPROC_GETATTR, NFSX_FH(v3));
580 nfsm_fhtom(np, v3);
581 nfsm_request(np, NFSPROC_GETATTR, curlwp, ap->a_cred);
582 if (!error) {
583 nfsm_loadattr(vp, ap->a_vap, 0);
584 if (vp->v_type == VDIR &&
585 ap->a_vap->va_blocksize < NFS_DIRFRAGSIZ)
586 ap->a_vap->va_blocksize = NFS_DIRFRAGSIZ;
587 }
588 nfsm_reqdone;
589 return (error);
590 }
591
592 /*
593 * nfs setattr call.
594 */
595 int
596 nfs_setattr(void *v)
597 {
598 struct vop_setattr_args /* {
599 struct vnodeop_desc *a_desc;
600 struct vnode *a_vp;
601 struct vattr *a_vap;
602 kauth_cred_t a_cred;
603 } */ *ap = v;
604 struct vnode *vp = ap->a_vp;
605 struct nfsnode *np = VTONFS(vp);
606 struct vattr *vap = ap->a_vap;
607 int error = 0;
608 u_quad_t tsize = 0;
609
610 /*
611 * Setting of flags is not supported.
612 */
613 if (vap->va_flags != VNOVAL)
614 return (EOPNOTSUPP);
615
616 /*
617 * Disallow write attempts if the filesystem is mounted read-only.
618 */
619 if ((vap->va_uid != (uid_t)VNOVAL ||
620 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
621 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
622 (vp->v_mount->mnt_flag & MNT_RDONLY))
623 return (EROFS);
624 if (vap->va_size != VNOVAL) {
625 if (vap->va_size > VFSTONFS(vp->v_mount)->nm_maxfilesize) {
626 return EFBIG;
627 }
628 switch (vp->v_type) {
629 case VDIR:
630 return (EISDIR);
631 case VCHR:
632 case VBLK:
633 case VSOCK:
634 case VFIFO:
635 if (vap->va_mtime.tv_sec == VNOVAL &&
636 vap->va_atime.tv_sec == VNOVAL &&
637 vap->va_mode == (mode_t)VNOVAL &&
638 vap->va_uid == (uid_t)VNOVAL &&
639 vap->va_gid == (gid_t)VNOVAL)
640 return (0);
641 vap->va_size = VNOVAL;
642 break;
643 default:
644 /*
645 * Disallow write attempts if the filesystem is
646 * mounted read-only.
647 */
648 if (vp->v_mount->mnt_flag & MNT_RDONLY)
649 return (EROFS);
650 genfs_node_wrlock(vp);
651 uvm_vnp_setsize(vp, vap->va_size);
652 tsize = np->n_size;
653 np->n_size = vap->va_size;
654 if (vap->va_size == 0)
655 error = nfs_vinvalbuf(vp, 0,
656 ap->a_cred, curlwp, 1);
657 else
658 error = nfs_vinvalbuf(vp, V_SAVE,
659 ap->a_cred, curlwp, 1);
660 if (error) {
661 uvm_vnp_setsize(vp, tsize);
662 genfs_node_unlock(vp);
663 return (error);
664 }
665 np->n_vattr->va_size = vap->va_size;
666 }
667 } else {
668 /*
669 * flush files before setattr because a later write of
670 * cached data might change timestamps or reset sugid bits
671 */
672 if ((vap->va_mtime.tv_sec != VNOVAL ||
673 vap->va_atime.tv_sec != VNOVAL ||
674 vap->va_mode != VNOVAL) &&
675 vp->v_type == VREG &&
676 (error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred,
677 curlwp, 1)) == EINTR)
678 return (error);
679 }
680 error = nfs_setattrrpc(vp, vap, ap->a_cred, curlwp);
681 if (vap->va_size != VNOVAL) {
682 if (error) {
683 np->n_size = np->n_vattr->va_size = tsize;
684 uvm_vnp_setsize(vp, np->n_size);
685 }
686 genfs_node_unlock(vp);
687 }
688 VN_KNOTE(vp, NOTE_ATTRIB);
689 return (error);
690 }
691
692 /*
693 * Do an nfs setattr rpc.
694 */
695 int
696 nfs_setattrrpc(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, struct lwp *l)
697 {
698 struct nfsv2_sattr *sp;
699 char *cp;
700 int32_t t1, t2;
701 char *bpos, *dpos;
702 u_int32_t *tl;
703 int error = 0;
704 struct mbuf *mreq, *mrep, *md, *mb;
705 const int v3 = NFS_ISV3(vp);
706 struct nfsnode *np = VTONFS(vp);
707 #ifndef NFS_V2_ONLY
708 int wccflag = NFSV3_WCCRATTR;
709 char *cp2;
710 #endif
711
712 nfsstats.rpccnt[NFSPROC_SETATTR]++;
713 nfsm_reqhead(np, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3));
714 nfsm_fhtom(np, v3);
715 #ifndef NFS_V2_ONLY
716 if (v3) {
717 nfsm_v3attrbuild(vap, true);
718 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
719 *tl = nfs_false;
720 } else {
721 #endif
722 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
723 if (vap->va_mode == (mode_t)VNOVAL)
724 sp->sa_mode = nfs_xdrneg1;
725 else
726 sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode);
727 if (vap->va_uid == (uid_t)VNOVAL)
728 sp->sa_uid = nfs_xdrneg1;
729 else
730 sp->sa_uid = txdr_unsigned(vap->va_uid);
731 if (vap->va_gid == (gid_t)VNOVAL)
732 sp->sa_gid = nfs_xdrneg1;
733 else
734 sp->sa_gid = txdr_unsigned(vap->va_gid);
735 sp->sa_size = txdr_unsigned(vap->va_size);
736 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
737 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
738 #ifndef NFS_V2_ONLY
739 }
740 #endif
741 nfsm_request(np, NFSPROC_SETATTR, l, cred);
742 #ifndef NFS_V2_ONLY
743 if (v3) {
744 nfsm_wcc_data(vp, wccflag, NAC_NOTRUNC, false);
745 } else
746 #endif
747 nfsm_loadattr(vp, (struct vattr *)0, NAC_NOTRUNC);
748 nfsm_reqdone;
749 return (error);
750 }
751
752 /*
753 * nfs lookup call, one step at a time...
754 * First look in cache
755 * If not found, do the rpc.
756 */
757 int
758 nfs_lookup(void *v)
759 {
760 struct vop_lookup_args /* {
761 struct vnodeop_desc *a_desc;
762 struct vnode *a_dvp;
763 struct vnode **a_vpp;
764 struct componentname *a_cnp;
765 } */ *ap = v;
766 struct componentname *cnp = ap->a_cnp;
767 struct vnode *dvp = ap->a_dvp;
768 struct vnode **vpp = ap->a_vpp;
769 int flags;
770 struct vnode *newvp;
771 u_int32_t *tl;
772 char *cp;
773 int32_t t1, t2;
774 char *bpos, *dpos, *cp2;
775 struct mbuf *mreq, *mrep, *md, *mb;
776 long len;
777 nfsfh_t *fhp;
778 struct nfsnode *np;
779 int error = 0, attrflag, fhsize;
780 const int v3 = NFS_ISV3(dvp);
781
782 flags = cnp->cn_flags;
783
784 *vpp = NULLVP;
785 newvp = NULLVP;
786 if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
787 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
788 return (EROFS);
789 if (dvp->v_type != VDIR)
790 return (ENOTDIR);
791
792 /*
793 * RFC1813(nfsv3) 3.2 says clients should handle "." by themselves.
794 */
795 if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
796 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
797 if (error)
798 return error;
799 if (cnp->cn_nameiop == RENAME && (flags & ISLASTCN))
800 return EISDIR;
801 vref(dvp);
802 *vpp = dvp;
803 return 0;
804 }
805
806 np = VTONFS(dvp);
807
808 /*
809 * Before performing an RPC, check the name cache to see if
810 * the directory/name pair we are looking for is known already.
811 * If the directory/name pair is found in the name cache,
812 * we have to ensure the directory has not changed from
813 * the time the cache entry has been created. If it has,
814 * the cache entry has to be ignored.
815 */
816 error = cache_lookup_raw(dvp, vpp, cnp);
817 KASSERT(dvp != *vpp);
818 KASSERT((cnp->cn_flags & ISWHITEOUT) == 0);
819 if (error >= 0) {
820 struct vattr vattr;
821 int err2;
822
823 if (error && error != ENOENT) {
824 *vpp = NULLVP;
825 return error;
826 }
827
828 err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
829 if (err2 != 0) {
830 if (error == 0)
831 vrele(*vpp);
832 *vpp = NULLVP;
833 return err2;
834 }
835
836 if (VOP_GETATTR(dvp, &vattr, cnp->cn_cred)
837 || timespeccmp(&vattr.va_mtime,
838 &VTONFS(dvp)->n_nctime, !=)) {
839 if (error == 0) {
840 vrele(*vpp);
841 *vpp = NULLVP;
842 }
843 cache_purge1(dvp, NULL, PURGE_CHILDREN);
844 timespecclear(&np->n_nctime);
845 goto dorpc;
846 }
847
848 if (error == ENOENT) {
849 goto noentry;
850 }
851
852 /*
853 * investigate the vnode returned by cache_lookup_raw.
854 * if it isn't appropriate, do an rpc.
855 */
856 newvp = *vpp;
857 if ((flags & ISDOTDOT) != 0) {
858 VOP_UNLOCK(dvp);
859 }
860 error = vn_lock(newvp, LK_EXCLUSIVE);
861 if ((flags & ISDOTDOT) != 0) {
862 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
863 }
864 if (error != 0) {
865 /* newvp has been reclaimed. */
866 vrele(newvp);
867 *vpp = NULLVP;
868 goto dorpc;
869 }
870 if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred)
871 && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) {
872 nfsstats.lookupcache_hits++;
873 KASSERT(newvp->v_type != VNON);
874 return (0);
875 }
876 cache_purge1(newvp, NULL, PURGE_PARENTS);
877 vput(newvp);
878 *vpp = NULLVP;
879 }
880 dorpc:
881 #if 0
882 /*
883 * because nfsv3 has the same CREATE semantics as ours,
884 * we don't have to perform LOOKUPs beforehand.
885 *
886 * XXX ideally we can do the same for nfsv2 in the case of !O_EXCL.
887 * XXX although we have no way to know if O_EXCL is requested or not.
888 */
889
890 if (v3 && cnp->cn_nameiop == CREATE &&
891 (flags & (ISLASTCN|ISDOTDOT)) == ISLASTCN &&
892 (dvp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
893 return (EJUSTRETURN);
894 }
895 #endif /* 0 */
896
897 error = 0;
898 newvp = NULLVP;
899 nfsstats.lookupcache_misses++;
900 nfsstats.rpccnt[NFSPROC_LOOKUP]++;
901 len = cnp->cn_namelen;
902 nfsm_reqhead(np, NFSPROC_LOOKUP,
903 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
904 nfsm_fhtom(np, v3);
905 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
906 nfsm_request(np, NFSPROC_LOOKUP, curlwp, cnp->cn_cred);
907 if (error) {
908 nfsm_postop_attr(dvp, attrflag, 0);
909 m_freem(mrep);
910 goto nfsmout;
911 }
912 nfsm_getfh(fhp, fhsize, v3);
913
914 /*
915 * Handle RENAME case...
916 */
917 if (cnp->cn_nameiop == RENAME && (flags & ISLASTCN)) {
918 if (NFS_CMPFH(np, fhp, fhsize)) {
919 m_freem(mrep);
920 return (EISDIR);
921 }
922 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
923 if (error) {
924 m_freem(mrep);
925 return error;
926 }
927 newvp = NFSTOV(np);
928 #ifndef NFS_V2_ONLY
929 if (v3) {
930 nfsm_postop_attr(newvp, attrflag, 0);
931 nfsm_postop_attr(dvp, attrflag, 0);
932 } else
933 #endif
934 nfsm_loadattr(newvp, (struct vattr *)0, 0);
935 *vpp = newvp;
936 m_freem(mrep);
937 goto validate;
938 }
939
940 /*
941 * The postop attr handling is duplicated for each if case,
942 * because it should be done while dvp is locked (unlocking
943 * dvp is different for each case).
944 */
945
946 if (NFS_CMPFH(np, fhp, fhsize)) {
947 /*
948 * as we handle "." lookup locally, this should be
949 * a broken server.
950 */
951 vref(dvp);
952 newvp = dvp;
953 #ifndef NFS_V2_ONLY
954 if (v3) {
955 nfsm_postop_attr(newvp, attrflag, 0);
956 nfsm_postop_attr(dvp, attrflag, 0);
957 } else
958 #endif
959 nfsm_loadattr(newvp, (struct vattr *)0, 0);
960 } else if (flags & ISDOTDOT) {
961 /*
962 * ".." lookup
963 */
964 VOP_UNLOCK(dvp);
965 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
966 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
967 if (error) {
968 m_freem(mrep);
969 return error;
970 }
971 newvp = NFSTOV(np);
972
973 #ifndef NFS_V2_ONLY
974 if (v3) {
975 nfsm_postop_attr(newvp, attrflag, 0);
976 nfsm_postop_attr(dvp, attrflag, 0);
977 } else
978 #endif
979 nfsm_loadattr(newvp, (struct vattr *)0, 0);
980 } else {
981 /*
982 * Other lookups.
983 */
984 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
985 if (error) {
986 m_freem(mrep);
987 return error;
988 }
989 newvp = NFSTOV(np);
990 #ifndef NFS_V2_ONLY
991 if (v3) {
992 nfsm_postop_attr(newvp, attrflag, 0);
993 nfsm_postop_attr(dvp, attrflag, 0);
994 } else
995 #endif
996 nfsm_loadattr(newvp, (struct vattr *)0, 0);
997 }
998 if ((cnp->cn_flags & MAKEENTRY) &&
999 (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) {
1000 nfs_cache_enter(dvp, newvp, cnp);
1001 }
1002 *vpp = newvp;
1003 nfsm_reqdone;
1004 if (error) {
1005 /*
1006 * We get here only because of errors returned by
1007 * the RPC. Otherwise we'll have returned above
1008 * (the nfsm_* macros will jump to nfsm_reqdone
1009 * on error).
1010 */
1011 if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) &&
1012 cnp->cn_nameiop != CREATE) {
1013 nfs_cache_enter(dvp, NULL, cnp);
1014 }
1015 if (newvp != NULLVP) {
1016 if (newvp == dvp) {
1017 vrele(newvp);
1018 } else {
1019 vput(newvp);
1020 }
1021 }
1022 noentry:
1023 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
1024 (flags & ISLASTCN) && error == ENOENT) {
1025 if (dvp->v_mount->mnt_flag & MNT_RDONLY) {
1026 error = EROFS;
1027 } else {
1028 error = EJUSTRETURN;
1029 }
1030 }
1031 *vpp = NULL;
1032 return error;
1033 }
1034
1035 validate:
1036 /*
1037 * make sure we have valid type and size.
1038 */
1039
1040 newvp = *vpp;
1041 if (newvp->v_type == VNON) {
1042 struct vattr vattr; /* dummy */
1043
1044 KASSERT(VTONFS(newvp)->n_attrstamp == 0);
1045 error = VOP_GETATTR(newvp, &vattr, cnp->cn_cred);
1046 if (error) {
1047 vput(newvp);
1048 *vpp = NULL;
1049 }
1050 }
1051
1052 return error;
1053 }
1054
1055 /*
1056 * nfs read call.
1057 * Just call nfs_bioread() to do the work.
1058 */
1059 int
1060 nfs_read(void *v)
1061 {
1062 struct vop_read_args /* {
1063 struct vnode *a_vp;
1064 struct uio *a_uio;
1065 int a_ioflag;
1066 kauth_cred_t a_cred;
1067 } */ *ap = v;
1068 struct vnode *vp = ap->a_vp;
1069
1070 if (vp->v_type != VREG)
1071 return EISDIR;
1072 return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred, 0));
1073 }
1074
1075 /*
1076 * nfs readlink call
1077 */
1078 int
1079 nfs_readlink(void *v)
1080 {
1081 struct vop_readlink_args /* {
1082 struct vnode *a_vp;
1083 struct uio *a_uio;
1084 kauth_cred_t a_cred;
1085 } */ *ap = v;
1086 struct vnode *vp = ap->a_vp;
1087 struct nfsnode *np = VTONFS(vp);
1088
1089 if (vp->v_type != VLNK)
1090 return (EPERM);
1091
1092 if (np->n_rcred != NULL) {
1093 kauth_cred_free(np->n_rcred);
1094 }
1095 np->n_rcred = ap->a_cred;
1096 kauth_cred_hold(np->n_rcred);
1097
1098 return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred, 0));
1099 }
1100
1101 /*
1102 * Do a readlink rpc.
1103 * Called by nfs_doio() from below the buffer cache.
1104 */
1105 int
1106 nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
1107 {
1108 u_int32_t *tl;
1109 char *cp;
1110 int32_t t1, t2;
1111 char *bpos, *dpos, *cp2;
1112 int error = 0;
1113 uint32_t len;
1114 struct mbuf *mreq, *mrep, *md, *mb;
1115 const int v3 = NFS_ISV3(vp);
1116 struct nfsnode *np = VTONFS(vp);
1117 #ifndef NFS_V2_ONLY
1118 int attrflag;
1119 #endif
1120
1121 nfsstats.rpccnt[NFSPROC_READLINK]++;
1122 nfsm_reqhead(np, NFSPROC_READLINK, NFSX_FH(v3));
1123 nfsm_fhtom(np, v3);
1124 nfsm_request(np, NFSPROC_READLINK, curlwp, cred);
1125 #ifndef NFS_V2_ONLY
1126 if (v3)
1127 nfsm_postop_attr(vp, attrflag, 0);
1128 #endif
1129 if (!error) {
1130 #ifndef NFS_V2_ONLY
1131 if (v3) {
1132 nfsm_dissect(tl, uint32_t *, NFSX_UNSIGNED);
1133 len = fxdr_unsigned(uint32_t, *tl);
1134 if (len > MAXPATHLEN) {
1135 /*
1136 * this pathname is too long for us.
1137 */
1138 m_freem(mrep);
1139 /* Solaris returns EINVAL. should we follow? */
1140 error = ENAMETOOLONG;
1141 goto nfsmout;
1142 }
1143 } else
1144 #endif
1145 {
1146 nfsm_strsiz(len, NFS_MAXPATHLEN);
1147 }
1148 nfsm_mtouio(uiop, len);
1149 }
1150 nfsm_reqdone;
1151 return (error);
1152 }
1153
1154 /*
1155 * nfs read rpc call
1156 * Ditto above
1157 */
1158 int
1159 nfs_readrpc(struct vnode *vp, struct uio *uiop)
1160 {
1161 u_int32_t *tl;
1162 char *cp;
1163 int32_t t1, t2;
1164 char *bpos, *dpos, *cp2;
1165 struct mbuf *mreq, *mrep, *md, *mb;
1166 struct nfsmount *nmp;
1167 int error = 0, len, retlen, tsiz, eof, byte_count;
1168 const int v3 = NFS_ISV3(vp);
1169 struct nfsnode *np = VTONFS(vp);
1170 #ifndef NFS_V2_ONLY
1171 int attrflag;
1172 #endif
1173
1174 #ifndef nolint
1175 eof = 0;
1176 #endif
1177 nmp = VFSTONFS(vp->v_mount);
1178 tsiz = uiop->uio_resid;
1179 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
1180 return (EFBIG);
1181 iostat_busy(nmp->nm_stats);
1182 byte_count = 0; /* count bytes actually transferred */
1183 while (tsiz > 0) {
1184 nfsstats.rpccnt[NFSPROC_READ]++;
1185 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
1186 nfsm_reqhead(np, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3);
1187 nfsm_fhtom(np, v3);
1188 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED * 3);
1189 #ifndef NFS_V2_ONLY
1190 if (v3) {
1191 txdr_hyper(uiop->uio_offset, tl);
1192 *(tl + 2) = txdr_unsigned(len);
1193 } else
1194 #endif
1195 {
1196 *tl++ = txdr_unsigned(uiop->uio_offset);
1197 *tl++ = txdr_unsigned(len);
1198 *tl = 0;
1199 }
1200 nfsm_request(np, NFSPROC_READ, curlwp, np->n_rcred);
1201 #ifndef NFS_V2_ONLY
1202 if (v3) {
1203 nfsm_postop_attr(vp, attrflag, NAC_NOTRUNC);
1204 if (error) {
1205 m_freem(mrep);
1206 goto nfsmout;
1207 }
1208 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1209 eof = fxdr_unsigned(int, *(tl + 1));
1210 } else
1211 #endif
1212 nfsm_loadattr(vp, (struct vattr *)0, NAC_NOTRUNC);
1213 nfsm_strsiz(retlen, nmp->nm_rsize);
1214 nfsm_mtouio(uiop, retlen);
1215 m_freem(mrep);
1216 tsiz -= retlen;
1217 byte_count += retlen;
1218 #ifndef NFS_V2_ONLY
1219 if (v3) {
1220 if (eof || retlen == 0)
1221 tsiz = 0;
1222 } else
1223 #endif
1224 if (retlen < len)
1225 tsiz = 0;
1226 }
1227 nfsmout:
1228 iostat_unbusy(nmp->nm_stats, byte_count, 1);
1229 return (error);
1230 }
1231
1232 struct nfs_writerpc_context {
1233 kmutex_t nwc_lock;
1234 kcondvar_t nwc_cv;
1235 int nwc_mbufcount;
1236 };
1237
1238 /*
1239 * free mbuf used to refer protected pages while write rpc call.
1240 * called at splvm.
1241 */
1242 static void
1243 nfs_writerpc_extfree(struct mbuf *m, void *tbuf, size_t size, void *arg)
1244 {
1245 struct nfs_writerpc_context *ctx = arg;
1246
1247 KASSERT(m != NULL);
1248 KASSERT(ctx != NULL);
1249 pool_cache_put(mb_cache, m);
1250 mutex_enter(&ctx->nwc_lock);
1251 if (--ctx->nwc_mbufcount == 0) {
1252 cv_signal(&ctx->nwc_cv);
1253 }
1254 mutex_exit(&ctx->nwc_lock);
1255 }
1256
1257 /*
1258 * nfs write call
1259 */
1260 int
1261 nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, bool pageprotected, bool *stalewriteverfp)
1262 {
1263 u_int32_t *tl;
1264 char *cp;
1265 int32_t t1, t2;
1266 char *bpos, *dpos;
1267 struct mbuf *mreq, *mrep, *md, *mb;
1268 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
1269 int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR;
1270 const int v3 = NFS_ISV3(vp);
1271 int committed = NFSV3WRITE_FILESYNC;
1272 struct nfsnode *np = VTONFS(vp);
1273 struct nfs_writerpc_context ctx;
1274 int byte_count;
1275 size_t origresid;
1276 #ifndef NFS_V2_ONLY
1277 char *cp2;
1278 int rlen, commit;
1279 #endif
1280
1281 mutex_init(&ctx.nwc_lock, MUTEX_DRIVER, IPL_VM);
1282 cv_init(&ctx.nwc_cv, "nfsmblk");
1283 ctx.nwc_mbufcount = 1;
1284
1285 if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1286 panic("writerpc readonly vp %p", vp);
1287 }
1288
1289 #ifdef DIAGNOSTIC
1290 if (uiop->uio_iovcnt != 1)
1291 panic("nfs: writerpc iovcnt > 1");
1292 #endif
1293 tsiz = uiop->uio_resid;
1294 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
1295 return (EFBIG);
1296 retry:
1297 origresid = uiop->uio_resid;
1298 KASSERT(origresid == uiop->uio_iov->iov_len);
1299 iostat_busy(nmp->nm_stats);
1300 byte_count = 0; /* count of bytes actually written */
1301 while (tsiz > 0) {
1302 uint32_t datalen; /* data bytes need to be allocated in mbuf */
1303 uint32_t backup;
1304 bool stalewriteverf = false;
1305
1306 nfsstats.rpccnt[NFSPROC_WRITE]++;
1307 len = min(tsiz, nmp->nm_wsize);
1308 datalen = pageprotected ? 0 : nfsm_rndup(len);
1309 nfsm_reqhead(np, NFSPROC_WRITE,
1310 NFSX_FH(v3) + 5 * NFSX_UNSIGNED + datalen);
1311 nfsm_fhtom(np, v3);
1312 #ifndef NFS_V2_ONLY
1313 if (v3) {
1314 nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
1315 txdr_hyper(uiop->uio_offset, tl);
1316 tl += 2;
1317 *tl++ = txdr_unsigned(len);
1318 *tl++ = txdr_unsigned(*iomode);
1319 *tl = txdr_unsigned(len);
1320 } else
1321 #endif
1322 {
1323 u_int32_t x;
1324
1325 nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
1326 /* Set both "begin" and "current" to non-garbage. */
1327 x = txdr_unsigned((u_int32_t)uiop->uio_offset);
1328 *tl++ = x; /* "begin offset" */
1329 *tl++ = x; /* "current offset" */
1330 x = txdr_unsigned(len);
1331 *tl++ = x; /* total to this offset */
1332 *tl = x; /* size of this write */
1333
1334 }
1335 if (pageprotected) {
1336 /*
1337 * since we know pages can't be modified during i/o,
1338 * no need to copy them for us.
1339 */
1340 struct mbuf *m;
1341 struct iovec *iovp = uiop->uio_iov;
1342
1343 m = m_get(M_WAIT, MT_DATA);
1344 MCLAIM(m, &nfs_mowner);
1345 MEXTADD(m, iovp->iov_base, len, M_MBUF,
1346 nfs_writerpc_extfree, &ctx);
1347 m->m_flags |= M_EXT_ROMAP;
1348 m->m_len = len;
1349 mb->m_next = m;
1350 /*
1351 * no need to maintain mb and bpos here
1352 * because no one care them later.
1353 */
1354 #if 0
1355 mb = m;
1356 bpos = mtod(void *, mb) + mb->m_len;
1357 #endif
1358 UIO_ADVANCE(uiop, len);
1359 uiop->uio_offset += len;
1360 mutex_enter(&ctx.nwc_lock);
1361 ctx.nwc_mbufcount++;
1362 mutex_exit(&ctx.nwc_lock);
1363 nfs_zeropad(mb, 0, nfsm_padlen(len));
1364 } else {
1365 nfsm_uiotom(uiop, len);
1366 }
1367 nfsm_request(np, NFSPROC_WRITE, curlwp, np->n_wcred);
1368 #ifndef NFS_V2_ONLY
1369 if (v3) {
1370 wccflag = NFSV3_WCCCHK;
1371 nfsm_wcc_data(vp, wccflag, NAC_NOTRUNC, !error);
1372 if (!error) {
1373 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED
1374 + NFSX_V3WRITEVERF);
1375 rlen = fxdr_unsigned(int, *tl++);
1376 if (rlen == 0) {
1377 error = NFSERR_IO;
1378 m_freem(mrep);
1379 break;
1380 } else if (rlen < len) {
1381 backup = len - rlen;
1382 UIO_ADVANCE(uiop, -backup);
1383 uiop->uio_offset -= backup;
1384 len = rlen;
1385 }
1386 commit = fxdr_unsigned(int, *tl++);
1387
1388 /*
1389 * Return the lowest committment level
1390 * obtained by any of the RPCs.
1391 */
1392 if (committed == NFSV3WRITE_FILESYNC)
1393 committed = commit;
1394 else if (committed == NFSV3WRITE_DATASYNC &&
1395 commit == NFSV3WRITE_UNSTABLE)
1396 committed = commit;
1397 mutex_enter(&nmp->nm_lock);
1398 if ((nmp->nm_iflag & NFSMNT_HASWRITEVERF) == 0){
1399 memcpy(nmp->nm_writeverf, tl,
1400 NFSX_V3WRITEVERF);
1401 nmp->nm_iflag |= NFSMNT_HASWRITEVERF;
1402 } else if ((nmp->nm_iflag &
1403 NFSMNT_STALEWRITEVERF) ||
1404 memcmp(tl, nmp->nm_writeverf,
1405 NFSX_V3WRITEVERF)) {
1406 memcpy(nmp->nm_writeverf, tl,
1407 NFSX_V3WRITEVERF);
1408 /*
1409 * note NFSMNT_STALEWRITEVERF
1410 * if we're the first thread to
1411 * notice it.
1412 */
1413 if ((nmp->nm_iflag &
1414 NFSMNT_STALEWRITEVERF) == 0) {
1415 stalewriteverf = true;
1416 nmp->nm_iflag |=
1417 NFSMNT_STALEWRITEVERF;
1418 }
1419 }
1420 mutex_exit(&nmp->nm_lock);
1421 }
1422 } else
1423 #endif
1424 nfsm_loadattr(vp, (struct vattr *)0, NAC_NOTRUNC);
1425 if (wccflag)
1426 VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr->va_mtime;
1427 m_freem(mrep);
1428 if (error)
1429 break;
1430 tsiz -= len;
1431 byte_count += len;
1432 if (stalewriteverf) {
1433 *stalewriteverfp = true;
1434 stalewriteverf = false;
1435 if (committed == NFSV3WRITE_UNSTABLE &&
1436 len != origresid) {
1437 /*
1438 * if our write requests weren't atomic but
1439 * unstable, datas in previous iterations
1440 * might have already been lost now.
1441 * then, we should resend them to nfsd.
1442 */
1443 backup = origresid - tsiz;
1444 UIO_ADVANCE(uiop, -backup);
1445 uiop->uio_offset -= backup;
1446 tsiz = origresid;
1447 goto retry;
1448 }
1449 }
1450 }
1451 nfsmout:
1452 iostat_unbusy(nmp->nm_stats, byte_count, 0);
1453 if (pageprotected) {
1454 /*
1455 * wait until mbufs go away.
1456 * retransmitted mbufs can survive longer than rpc requests
1457 * themselves.
1458 */
1459 mutex_enter(&ctx.nwc_lock);
1460 ctx.nwc_mbufcount--;
1461 while (ctx.nwc_mbufcount > 0) {
1462 cv_wait(&ctx.nwc_cv, &ctx.nwc_lock);
1463 }
1464 mutex_exit(&ctx.nwc_lock);
1465 }
1466 mutex_destroy(&ctx.nwc_lock);
1467 cv_destroy(&ctx.nwc_cv);
1468 *iomode = committed;
1469 if (error)
1470 uiop->uio_resid = tsiz;
1471 return (error);
1472 }
1473
1474 /*
1475 * nfs mknod rpc
1476 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
1477 * mode set to specify the file type and the size field for rdev.
1478 */
1479 int
1480 nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct vattr *vap)
1481 {
1482 struct nfsv2_sattr *sp;
1483 u_int32_t *tl;
1484 char *cp;
1485 int32_t t1, t2;
1486 struct vnode *newvp = (struct vnode *)0;
1487 struct nfsnode *dnp, *np;
1488 char *cp2;
1489 char *bpos, *dpos;
1490 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0;
1491 struct mbuf *mreq, *mrep, *md, *mb;
1492 u_int32_t rdev;
1493 const int v3 = NFS_ISV3(dvp);
1494
1495 if (vap->va_type == VCHR || vap->va_type == VBLK)
1496 rdev = txdr_unsigned(vap->va_rdev);
1497 else if (vap->va_type == VFIFO || vap->va_type == VSOCK)
1498 rdev = nfs_xdrneg1;
1499 else {
1500 VOP_ABORTOP(dvp, cnp);
1501 vput(dvp);
1502 return (EOPNOTSUPP);
1503 }
1504 nfsstats.rpccnt[NFSPROC_MKNOD]++;
1505 dnp = VTONFS(dvp);
1506 nfsm_reqhead(dnp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED +
1507 + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
1508 nfsm_fhtom(dnp, v3);
1509 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1510 #ifndef NFS_V2_ONLY
1511 if (v3) {
1512 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
1513 *tl++ = vtonfsv3_type(vap->va_type);
1514 nfsm_v3attrbuild(vap, false);
1515 if (vap->va_type == VCHR || vap->va_type == VBLK) {
1516 nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1517 *tl++ = txdr_unsigned(major(vap->va_rdev));
1518 *tl = txdr_unsigned(minor(vap->va_rdev));
1519 }
1520 } else
1521 #endif
1522 {
1523 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
1524 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1525 sp->sa_uid = nfs_xdrneg1;
1526 sp->sa_gid = nfs_xdrneg1;
1527 sp->sa_size = rdev;
1528 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1529 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1530 }
1531 nfsm_request(dnp, NFSPROC_MKNOD, curlwp, cnp->cn_cred);
1532 if (!error) {
1533 nfsm_mtofh(dvp, newvp, v3, gotvp);
1534 if (!gotvp) {
1535 error = nfs_lookitup(dvp, cnp->cn_nameptr,
1536 cnp->cn_namelen, cnp->cn_cred, curlwp, &np);
1537 if (!error)
1538 newvp = NFSTOV(np);
1539 }
1540 }
1541 #ifndef NFS_V2_ONLY
1542 if (v3)
1543 nfsm_wcc_data(dvp, wccflag, 0, !error);
1544 #endif
1545 nfsm_reqdone;
1546 if (error) {
1547 if (newvp)
1548 vput(newvp);
1549 } else {
1550 if (cnp->cn_flags & MAKEENTRY)
1551 nfs_cache_enter(dvp, newvp, cnp);
1552 *vpp = newvp;
1553 }
1554 VTONFS(dvp)->n_flag |= NMODIFIED;
1555 if (!wccflag)
1556 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
1557 vput(dvp);
1558 return (error);
1559 }
1560
1561 /*
1562 * nfs mknod vop
1563 * just call nfs_mknodrpc() to do the work.
1564 */
1565 /* ARGSUSED */
1566 int
1567 nfs_mknod(void *v)
1568 {
1569 struct vop_mknod_args /* {
1570 struct vnode *a_dvp;
1571 struct vnode **a_vpp;
1572 struct componentname *a_cnp;
1573 struct vattr *a_vap;
1574 } */ *ap = v;
1575 struct vnode *dvp = ap->a_dvp;
1576 struct componentname *cnp = ap->a_cnp;
1577 int error;
1578
1579 error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, ap->a_vap);
1580 VN_KNOTE(dvp, NOTE_WRITE);
1581 if (error == 0 || error == EEXIST)
1582 cache_purge1(dvp, cnp, 0);
1583 return (error);
1584 }
1585
1586 /*
1587 * nfs file create call
1588 */
1589 int
1590 nfs_create(void *v)
1591 {
1592 struct vop_create_args /* {
1593 struct vnode *a_dvp;
1594 struct vnode **a_vpp;
1595 struct componentname *a_cnp;
1596 struct vattr *a_vap;
1597 } */ *ap = v;
1598 struct vnode *dvp = ap->a_dvp;
1599 struct vattr *vap = ap->a_vap;
1600 struct componentname *cnp = ap->a_cnp;
1601 struct nfsv2_sattr *sp;
1602 u_int32_t *tl;
1603 char *cp;
1604 int32_t t1, t2;
1605 struct nfsnode *dnp, *np = (struct nfsnode *)0;
1606 struct vnode *newvp = (struct vnode *)0;
1607 char *bpos, *dpos, *cp2;
1608 int error, wccflag = NFSV3_WCCRATTR, gotvp = 0;
1609 struct mbuf *mreq, *mrep, *md, *mb;
1610 const int v3 = NFS_ISV3(dvp);
1611 u_int32_t excl_mode = NFSV3CREATE_UNCHECKED;
1612
1613 /*
1614 * Oops, not for me..
1615 */
1616 if (vap->va_type == VSOCK)
1617 return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap));
1618
1619 KASSERT(vap->va_type == VREG);
1620
1621 #ifdef VA_EXCLUSIVE
1622 if (vap->va_vaflags & VA_EXCLUSIVE) {
1623 excl_mode = NFSV3CREATE_EXCLUSIVE;
1624 }
1625 #endif
1626 again:
1627 error = 0;
1628 nfsstats.rpccnt[NFSPROC_CREATE]++;
1629 dnp = VTONFS(dvp);
1630 nfsm_reqhead(dnp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED +
1631 nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
1632 nfsm_fhtom(dnp, v3);
1633 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1634 #ifndef NFS_V2_ONLY
1635 if (v3) {
1636 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
1637 if (excl_mode == NFSV3CREATE_EXCLUSIVE) {
1638 *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
1639 nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF);
1640 *tl++ = arc4random();
1641 *tl = arc4random();
1642 } else {
1643 *tl = txdr_unsigned(excl_mode);
1644 nfsm_v3attrbuild(vap, false);
1645 }
1646 } else
1647 #endif
1648 {
1649 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
1650 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1651 sp->sa_uid = nfs_xdrneg1;
1652 sp->sa_gid = nfs_xdrneg1;
1653 sp->sa_size = 0;
1654 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1655 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1656 }
1657 nfsm_request(dnp, NFSPROC_CREATE, curlwp, cnp->cn_cred);
1658 if (!error) {
1659 nfsm_mtofh(dvp, newvp, v3, gotvp);
1660 if (!gotvp) {
1661 error = nfs_lookitup(dvp, cnp->cn_nameptr,
1662 cnp->cn_namelen, cnp->cn_cred, curlwp, &np);
1663 if (!error)
1664 newvp = NFSTOV(np);
1665 }
1666 }
1667 #ifndef NFS_V2_ONLY
1668 if (v3)
1669 nfsm_wcc_data(dvp, wccflag, 0, !error);
1670 #endif
1671 nfsm_reqdone;
1672 if (error) {
1673 /*
1674 * nfs_request maps NFSERR_NOTSUPP to ENOTSUP.
1675 */
1676 if (v3 && error == ENOTSUP) {
1677 if (excl_mode == NFSV3CREATE_EXCLUSIVE) {
1678 excl_mode = NFSV3CREATE_GUARDED;
1679 goto again;
1680 } else if (excl_mode == NFSV3CREATE_GUARDED) {
1681 excl_mode = NFSV3CREATE_UNCHECKED;
1682 goto again;
1683 }
1684 }
1685 } else if (v3 && (excl_mode == NFSV3CREATE_EXCLUSIVE)) {
1686 struct timespec ts;
1687
1688 getnanotime(&ts);
1689
1690 /*
1691 * make sure that we'll update timestamps as
1692 * most server implementations use them to store
1693 * the create verifier.
1694 *
1695 * XXX it's better to use TOSERVER always.
1696 */
1697
1698 if (vap->va_atime.tv_sec == VNOVAL)
1699 vap->va_atime = ts;
1700 if (vap->va_mtime.tv_sec == VNOVAL)
1701 vap->va_mtime = ts;
1702
1703 error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, curlwp);
1704 }
1705 if (error == 0) {
1706 if (cnp->cn_flags & MAKEENTRY)
1707 nfs_cache_enter(dvp, newvp, cnp);
1708 else
1709 cache_purge1(dvp, cnp, 0);
1710 *ap->a_vpp = newvp;
1711 } else {
1712 if (newvp)
1713 vput(newvp);
1714 if (error == EEXIST)
1715 cache_purge1(dvp, cnp, 0);
1716 }
1717 VTONFS(dvp)->n_flag |= NMODIFIED;
1718 if (!wccflag)
1719 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
1720 VN_KNOTE(ap->a_dvp, NOTE_WRITE);
1721 vput(dvp);
1722 return (error);
1723 }
1724
1725 /*
1726 * nfs file remove call
1727 * To try and make nfs semantics closer to ufs semantics, a file that has
1728 * other processes using the vnode is renamed instead of removed and then
1729 * removed later on the last close.
1730 * - If v_usecount > 1
1731 * If a rename is not already in the works
1732 * call nfs_sillyrename() to set it up
1733 * else
1734 * do the remove rpc
1735 */
1736 int
1737 nfs_remove(void *v)
1738 {
1739 struct vop_remove_args /* {
1740 struct vnodeop_desc *a_desc;
1741 struct vnode * a_dvp;
1742 struct vnode * a_vp;
1743 struct componentname * a_cnp;
1744 } */ *ap = v;
1745 struct vnode *vp = ap->a_vp;
1746 struct vnode *dvp = ap->a_dvp;
1747 struct componentname *cnp = ap->a_cnp;
1748 struct nfsnode *np = VTONFS(vp);
1749 int error = 0;
1750 struct vattr vattr;
1751
1752 #ifndef DIAGNOSTIC
1753 if (vp->v_usecount < 1)
1754 panic("nfs_remove: bad v_usecount");
1755 #endif
1756 if (vp->v_type == VDIR)
1757 error = EPERM;
1758 else if (vp->v_usecount == 1 || (np->n_sillyrename &&
1759 VOP_GETATTR(vp, &vattr, cnp->cn_cred) == 0 &&
1760 vattr.va_nlink > 1)) {
1761 /*
1762 * Purge the name cache so that the chance of a lookup for
1763 * the name succeeding while the remove is in progress is
1764 * minimized. Without node locking it can still happen, such
1765 * that an I/O op returns ESTALE, but since you get this if
1766 * another host removes the file..
1767 */
1768 cache_purge(vp);
1769 /*
1770 * throw away biocache buffers, mainly to avoid
1771 * unnecessary delayed writes later.
1772 */
1773 error = nfs_vinvalbuf(vp, 0, cnp->cn_cred, curlwp, 1);
1774 /* Do the rpc */
1775 if (error != EINTR)
1776 error = nfs_removerpc(dvp, cnp->cn_nameptr,
1777 cnp->cn_namelen, cnp->cn_cred, curlwp);
1778 } else if (!np->n_sillyrename)
1779 error = nfs_sillyrename(dvp, vp, cnp, false);
1780 if (!error && nfs_getattrcache(vp, &vattr) == 0 &&
1781 vattr.va_nlink == 1) {
1782 np->n_flag |= NREMOVED;
1783 }
1784 NFS_INVALIDATE_ATTRCACHE(np);
1785 VN_KNOTE(vp, NOTE_DELETE);
1786 VN_KNOTE(dvp, NOTE_WRITE);
1787 if (dvp == vp)
1788 vrele(vp);
1789 else
1790 vput(vp);
1791 vput(dvp);
1792 return (error);
1793 }
1794
1795 /*
1796 * nfs file remove rpc called from nfs_inactive
1797 */
1798 int
1799 nfs_removeit(struct sillyrename *sp)
1800 {
1801
1802 return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred,
1803 (struct lwp *)0));
1804 }
1805
1806 /*
1807 * Nfs remove rpc, called from nfs_remove() and nfs_removeit().
1808 */
1809 int
1810 nfs_removerpc(struct vnode *dvp, const char *name, int namelen, kauth_cred_t cred, struct lwp *l)
1811 {
1812 u_int32_t *tl;
1813 char *cp;
1814 #ifndef NFS_V2_ONLY
1815 int32_t t1;
1816 char *cp2;
1817 #endif
1818 int32_t t2;
1819 char *bpos, *dpos;
1820 int error = 0, wccflag = NFSV3_WCCRATTR;
1821 struct mbuf *mreq, *mrep, *md, *mb;
1822 const int v3 = NFS_ISV3(dvp);
1823 int rexmit = 0;
1824 struct nfsnode *dnp = VTONFS(dvp);
1825
1826 nfsstats.rpccnt[NFSPROC_REMOVE]++;
1827 nfsm_reqhead(dnp, NFSPROC_REMOVE,
1828 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen));
1829 nfsm_fhtom(dnp, v3);
1830 nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
1831 nfsm_request1(dnp, NFSPROC_REMOVE, l, cred, &rexmit);
1832 #ifndef NFS_V2_ONLY
1833 if (v3)
1834 nfsm_wcc_data(dvp, wccflag, 0, !error);
1835 #endif
1836 nfsm_reqdone;
1837 VTONFS(dvp)->n_flag |= NMODIFIED;
1838 if (!wccflag)
1839 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
1840 /*
1841 * Kludge City: If the first reply to the remove rpc is lost..
1842 * the reply to the retransmitted request will be ENOENT
1843 * since the file was in fact removed
1844 * Therefore, we cheat and return success.
1845 */
1846 if (rexmit && error == ENOENT)
1847 error = 0;
1848 return (error);
1849 }
1850
1851 /*
1852 * nfs file rename call
1853 */
1854 int
1855 nfs_rename(void *v)
1856 {
1857 struct vop_rename_args /* {
1858 struct vnode *a_fdvp;
1859 struct vnode *a_fvp;
1860 struct componentname *a_fcnp;
1861 struct vnode *a_tdvp;
1862 struct vnode *a_tvp;
1863 struct componentname *a_tcnp;
1864 } */ *ap = v;
1865 struct vnode *fvp = ap->a_fvp;
1866 struct vnode *tvp = ap->a_tvp;
1867 struct vnode *fdvp = ap->a_fdvp;
1868 struct vnode *tdvp = ap->a_tdvp;
1869 struct componentname *tcnp = ap->a_tcnp;
1870 struct componentname *fcnp = ap->a_fcnp;
1871 int error;
1872
1873 /* Check for cross-device rename */
1874 if ((fvp->v_mount != tdvp->v_mount) ||
1875 (tvp && (fvp->v_mount != tvp->v_mount))) {
1876 error = EXDEV;
1877 goto out;
1878 }
1879
1880 /*
1881 * If the tvp exists and is in use, sillyrename it before doing the
1882 * rename of the new file over it.
1883 *
1884 * Have sillyrename use link instead of rename if possible,
1885 * so that we don't lose the file if the rename fails, and so
1886 * that there's no window when the "to" file doesn't exist.
1887 */
1888 if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename &&
1889 tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp, true)) {
1890 VN_KNOTE(tvp, NOTE_DELETE);
1891 vput(tvp);
1892 tvp = NULL;
1893 }
1894
1895 error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
1896 tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred,
1897 curlwp);
1898
1899 VN_KNOTE(fdvp, NOTE_WRITE);
1900 VN_KNOTE(tdvp, NOTE_WRITE);
1901 if (error == 0 || error == EEXIST) {
1902 if (fvp->v_type == VDIR)
1903 cache_purge(fvp);
1904 else
1905 cache_purge1(fdvp, fcnp, 0);
1906 if (tvp != NULL && tvp->v_type == VDIR)
1907 cache_purge(tvp);
1908 else
1909 cache_purge1(tdvp, tcnp, 0);
1910 }
1911 out:
1912 if (tdvp == tvp)
1913 vrele(tdvp);
1914 else
1915 vput(tdvp);
1916 if (tvp)
1917 vput(tvp);
1918 vrele(fdvp);
1919 vrele(fvp);
1920 return (error);
1921 }
1922
1923 /*
1924 * nfs file rename rpc called from nfs_remove() above
1925 */
1926 int
1927 nfs_renameit(struct vnode *sdvp, struct componentname *scnp, struct sillyrename *sp)
1928 {
1929 return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen,
1930 sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, curlwp));
1931 }
1932
1933 /*
1934 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit().
1935 */
1936 int
1937 nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen, struct vnode *tdvp, const char *tnameptr, int tnamelen, kauth_cred_t cred, struct lwp *l)
1938 {
1939 u_int32_t *tl;
1940 char *cp;
1941 #ifndef NFS_V2_ONLY
1942 int32_t t1;
1943 char *cp2;
1944 #endif
1945 int32_t t2;
1946 char *bpos, *dpos;
1947 int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
1948 struct mbuf *mreq, *mrep, *md, *mb;
1949 const int v3 = NFS_ISV3(fdvp);
1950 int rexmit = 0;
1951 struct nfsnode *fdnp = VTONFS(fdvp);
1952
1953 nfsstats.rpccnt[NFSPROC_RENAME]++;
1954 nfsm_reqhead(fdnp, NFSPROC_RENAME,
1955 (NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) +
1956 nfsm_rndup(tnamelen));
1957 nfsm_fhtom(fdnp, v3);
1958 nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN);
1959 nfsm_fhtom(VTONFS(tdvp), v3);
1960 nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN);
1961 nfsm_request1(fdnp, NFSPROC_RENAME, l, cred, &rexmit);
1962 #ifndef NFS_V2_ONLY
1963 if (v3) {
1964 nfsm_wcc_data(fdvp, fwccflag, 0, !error);
1965 nfsm_wcc_data(tdvp, twccflag, 0, !error);
1966 }
1967 #endif
1968 nfsm_reqdone;
1969 VTONFS(fdvp)->n_flag |= NMODIFIED;
1970 VTONFS(tdvp)->n_flag |= NMODIFIED;
1971 if (!fwccflag)
1972 NFS_INVALIDATE_ATTRCACHE(VTONFS(fdvp));
1973 if (!twccflag)
1974 NFS_INVALIDATE_ATTRCACHE(VTONFS(tdvp));
1975 /*
1976 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
1977 */
1978 if (rexmit && error == ENOENT)
1979 error = 0;
1980 return (error);
1981 }
1982
1983 /*
1984 * NFS link RPC, called from nfs_link.
1985 * Assumes dvp and vp locked, and leaves them that way.
1986 */
1987
1988 static int
1989 nfs_linkrpc(struct vnode *dvp, struct vnode *vp, const char *name,
1990 size_t namelen, kauth_cred_t cred, struct lwp *l)
1991 {
1992 u_int32_t *tl;
1993 char *cp;
1994 #ifndef NFS_V2_ONLY
1995 int32_t t1;
1996 char *cp2;
1997 #endif
1998 int32_t t2;
1999 char *bpos, *dpos;
2000 int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
2001 struct mbuf *mreq, *mrep, *md, *mb;
2002 const int v3 = NFS_ISV3(dvp);
2003 int rexmit = 0;
2004 struct nfsnode *np = VTONFS(vp);
2005
2006 nfsstats.rpccnt[NFSPROC_LINK]++;
2007 nfsm_reqhead(np, NFSPROC_LINK,
2008 NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(namelen));
2009 nfsm_fhtom(np, v3);
2010 nfsm_fhtom(VTONFS(dvp), v3);
2011 nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
2012 nfsm_request1(np, NFSPROC_LINK, l, cred, &rexmit);
2013 #ifndef NFS_V2_ONLY
2014 if (v3) {
2015 nfsm_postop_attr(vp, attrflag, 0);
2016 nfsm_wcc_data(dvp, wccflag, 0, !error);
2017 }
2018 #endif
2019 nfsm_reqdone;
2020
2021 VTONFS(dvp)->n_flag |= NMODIFIED;
2022 if (!attrflag)
2023 NFS_INVALIDATE_ATTRCACHE(VTONFS(vp));
2024 if (!wccflag)
2025 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
2026
2027 /*
2028 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
2029 */
2030 if (rexmit && error == EEXIST)
2031 error = 0;
2032
2033 return error;
2034 }
2035
2036 /*
2037 * nfs hard link create call
2038 */
2039 int
2040 nfs_link(void *v)
2041 {
2042 struct vop_link_args /* {
2043 struct vnode *a_dvp;
2044 struct vnode *a_vp;
2045 struct componentname *a_cnp;
2046 } */ *ap = v;
2047 struct vnode *vp = ap->a_vp;
2048 struct vnode *dvp = ap->a_dvp;
2049 struct componentname *cnp = ap->a_cnp;
2050 int error = 0;
2051
2052 if (dvp->v_mount != vp->v_mount) {
2053 VOP_ABORTOP(dvp, cnp);
2054 vput(dvp);
2055 return (EXDEV);
2056 }
2057 if (dvp != vp) {
2058 error = vn_lock(vp, LK_EXCLUSIVE);
2059 if (error != 0) {
2060 VOP_ABORTOP(dvp, cnp);
2061 vput(dvp);
2062 return error;
2063 }
2064 }
2065
2066 /*
2067 * Push all writes to the server, so that the attribute cache
2068 * doesn't get "out of sync" with the server.
2069 * XXX There should be a better way!
2070 */
2071 VOP_FSYNC(vp, cnp->cn_cred, FSYNC_WAIT, 0, 0);
2072
2073 error = nfs_linkrpc(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
2074 cnp->cn_cred, curlwp);
2075
2076 if (error == 0)
2077 cache_purge1(dvp, cnp, 0);
2078 if (dvp != vp)
2079 VOP_UNLOCK(vp);
2080 VN_KNOTE(vp, NOTE_LINK);
2081 VN_KNOTE(dvp, NOTE_WRITE);
2082 vput(dvp);
2083 return (error);
2084 }
2085
2086 /*
2087 * nfs symbolic link create call
2088 */
2089 int
2090 nfs_symlink(void *v)
2091 {
2092 struct vop_symlink_args /* {
2093 struct vnode *a_dvp;
2094 struct vnode **a_vpp;
2095 struct componentname *a_cnp;
2096 struct vattr *a_vap;
2097 char *a_target;
2098 } */ *ap = v;
2099 struct vnode *dvp = ap->a_dvp;
2100 struct vattr *vap = ap->a_vap;
2101 struct componentname *cnp = ap->a_cnp;
2102 struct nfsv2_sattr *sp;
2103 u_int32_t *tl;
2104 char *cp;
2105 int32_t t1, t2;
2106 char *bpos, *dpos, *cp2;
2107 int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
2108 struct mbuf *mreq, *mrep, *md, *mb;
2109 struct vnode *newvp = (struct vnode *)0;
2110 const int v3 = NFS_ISV3(dvp);
2111 int rexmit = 0;
2112 struct nfsnode *dnp = VTONFS(dvp);
2113
2114 *ap->a_vpp = NULL;
2115 nfsstats.rpccnt[NFSPROC_SYMLINK]++;
2116 slen = strlen(ap->a_target);
2117 nfsm_reqhead(dnp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED +
2118 nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3));
2119 nfsm_fhtom(dnp, v3);
2120 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
2121 #ifndef NFS_V2_ONlY
2122 if (v3)
2123 nfsm_v3attrbuild(vap, false);
2124 #endif
2125 nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN);
2126 #ifndef NFS_V2_ONlY
2127 if (!v3) {
2128 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
2129 sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode);
2130 sp->sa_uid = nfs_xdrneg1;
2131 sp->sa_gid = nfs_xdrneg1;
2132 sp->sa_size = nfs_xdrneg1;
2133 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
2134 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
2135 }
2136 #endif
2137 nfsm_request1(dnp, NFSPROC_SYMLINK, curlwp, cnp->cn_cred,
2138 &rexmit);
2139 #ifndef NFS_V2_ONlY
2140 if (v3) {
2141 if (!error)
2142 nfsm_mtofh(dvp, newvp, v3, gotvp);
2143 nfsm_wcc_data(dvp, wccflag, 0, !error);
2144 }
2145 #endif
2146 nfsm_reqdone;
2147 /*
2148 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
2149 */
2150 if (rexmit && error == EEXIST)
2151 error = 0;
2152 if (error == 0 || error == EEXIST)
2153 cache_purge1(dvp, cnp, 0);
2154 if (error == 0 && newvp == NULL) {
2155 struct nfsnode *np = NULL;
2156
2157 error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
2158 cnp->cn_cred, curlwp, &np);
2159 if (error == 0)
2160 newvp = NFSTOV(np);
2161 }
2162 if (error) {
2163 if (newvp != NULL)
2164 vput(newvp);
2165 } else {
2166 *ap->a_vpp = newvp;
2167 }
2168 VTONFS(dvp)->n_flag |= NMODIFIED;
2169 if (!wccflag)
2170 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
2171 VN_KNOTE(dvp, NOTE_WRITE);
2172 vput(dvp);
2173 return (error);
2174 }
2175
2176 /*
2177 * nfs make dir call
2178 */
2179 int
2180 nfs_mkdir(void *v)
2181 {
2182 struct vop_mkdir_args /* {
2183 struct vnode *a_dvp;
2184 struct vnode **a_vpp;
2185 struct componentname *a_cnp;
2186 struct vattr *a_vap;
2187 } */ *ap = v;
2188 struct vnode *dvp = ap->a_dvp;
2189 struct vattr *vap = ap->a_vap;
2190 struct componentname *cnp = ap->a_cnp;
2191 struct nfsv2_sattr *sp;
2192 u_int32_t *tl;
2193 char *cp;
2194 int32_t t1, t2;
2195 int len;
2196 struct nfsnode *dnp = VTONFS(dvp), *np = (struct nfsnode *)0;
2197 struct vnode *newvp = (struct vnode *)0;
2198 char *bpos, *dpos, *cp2;
2199 int error = 0, wccflag = NFSV3_WCCRATTR;
2200 int gotvp = 0;
2201 int rexmit = 0;
2202 struct mbuf *mreq, *mrep, *md, *mb;
2203 const int v3 = NFS_ISV3(dvp);
2204
2205 len = cnp->cn_namelen;
2206 nfsstats.rpccnt[NFSPROC_MKDIR]++;
2207 nfsm_reqhead(dnp, NFSPROC_MKDIR,
2208 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3));
2209 nfsm_fhtom(dnp, v3);
2210 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
2211 #ifndef NFS_V2_ONLY
2212 if (v3) {
2213 nfsm_v3attrbuild(vap, false);
2214 } else
2215 #endif
2216 {
2217 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
2218 sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode);
2219 sp->sa_uid = nfs_xdrneg1;
2220 sp->sa_gid = nfs_xdrneg1;
2221 sp->sa_size = nfs_xdrneg1;
2222 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
2223 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
2224 }
2225 nfsm_request1(dnp, NFSPROC_MKDIR, curlwp, cnp->cn_cred, &rexmit);
2226 if (!error)
2227 nfsm_mtofh(dvp, newvp, v3, gotvp);
2228 if (v3)
2229 nfsm_wcc_data(dvp, wccflag, 0, !error);
2230 nfsm_reqdone;
2231 VTONFS(dvp)->n_flag |= NMODIFIED;
2232 if (!wccflag)
2233 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
2234 /*
2235 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry
2236 * if we can succeed in looking up the directory.
2237 */
2238 if ((rexmit && error == EEXIST) || (!error && !gotvp)) {
2239 if (newvp) {
2240 vput(newvp);
2241 newvp = (struct vnode *)0;
2242 }
2243 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred,
2244 curlwp, &np);
2245 if (!error) {
2246 newvp = NFSTOV(np);
2247 if (newvp->v_type != VDIR || newvp == dvp)
2248 error = EEXIST;
2249 }
2250 }
2251 if (error) {
2252 if (newvp) {
2253 if (dvp != newvp)
2254 vput(newvp);
2255 else
2256 vrele(newvp);
2257 }
2258 } else {
2259 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
2260 if (cnp->cn_flags & MAKEENTRY)
2261 nfs_cache_enter(dvp, newvp, cnp);
2262 *ap->a_vpp = newvp;
2263 }
2264 vput(dvp);
2265 return (error);
2266 }
2267
2268 /*
2269 * nfs remove directory call
2270 */
2271 int
2272 nfs_rmdir(void *v)
2273 {
2274 struct vop_rmdir_args /* {
2275 struct vnode *a_dvp;
2276 struct vnode *a_vp;
2277 struct componentname *a_cnp;
2278 } */ *ap = v;
2279 struct vnode *vp = ap->a_vp;
2280 struct vnode *dvp = ap->a_dvp;
2281 struct componentname *cnp = ap->a_cnp;
2282 u_int32_t *tl;
2283 char *cp;
2284 #ifndef NFS_V2_ONLY
2285 int32_t t1;
2286 char *cp2;
2287 #endif
2288 int32_t t2;
2289 char *bpos, *dpos;
2290 int error = 0, wccflag = NFSV3_WCCRATTR;
2291 int rexmit = 0;
2292 struct mbuf *mreq, *mrep, *md, *mb;
2293 const int v3 = NFS_ISV3(dvp);
2294 struct nfsnode *dnp;
2295
2296 if (dvp == vp) {
2297 vrele(dvp);
2298 vput(dvp);
2299 return (EINVAL);
2300 }
2301 nfsstats.rpccnt[NFSPROC_RMDIR]++;
2302 dnp = VTONFS(dvp);
2303 nfsm_reqhead(dnp, NFSPROC_RMDIR,
2304 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
2305 nfsm_fhtom(dnp, v3);
2306 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
2307 nfsm_request1(dnp, NFSPROC_RMDIR, curlwp, cnp->cn_cred, &rexmit);
2308 #ifndef NFS_V2_ONLY
2309 if (v3)
2310 nfsm_wcc_data(dvp, wccflag, 0, !error);
2311 #endif
2312 nfsm_reqdone;
2313 VTONFS(dvp)->n_flag |= NMODIFIED;
2314 if (!wccflag)
2315 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp));
2316 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
2317 VN_KNOTE(vp, NOTE_DELETE);
2318 cache_purge(vp);
2319 vput(vp);
2320 vput(dvp);
2321 /*
2322 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
2323 */
2324 if (rexmit && error == ENOENT)
2325 error = 0;
2326 return (error);
2327 }
2328
2329 /*
2330 * nfs readdir call
2331 */
2332 int
2333 nfs_readdir(void *v)
2334 {
2335 struct vop_readdir_args /* {
2336 struct vnode *a_vp;
2337 struct uio *a_uio;
2338 kauth_cred_t a_cred;
2339 int *a_eofflag;
2340 off_t **a_cookies;
2341 int *a_ncookies;
2342 } */ *ap = v;
2343 struct vnode *vp = ap->a_vp;
2344 struct uio *uio = ap->a_uio;
2345 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2346 char *base = uio->uio_iov->iov_base;
2347 int tresid, error;
2348 size_t count, lost;
2349 struct dirent *dp;
2350 off_t *cookies = NULL;
2351 int ncookies = 0, nc;
2352
2353 if (vp->v_type != VDIR)
2354 return (EPERM);
2355
2356 lost = uio->uio_resid & (NFS_DIRFRAGSIZ - 1);
2357 count = uio->uio_resid - lost;
2358 if (count <= 0)
2359 return (EINVAL);
2360
2361 /*
2362 * Call nfs_bioread() to do the real work.
2363 */
2364 tresid = uio->uio_resid = count;
2365 error = nfs_bioread(vp, uio, 0, ap->a_cred,
2366 ap->a_cookies ? NFSBIO_CACHECOOKIES : 0);
2367
2368 if (!error && ap->a_cookies) {
2369 ncookies = count / 16;
2370 cookies = malloc(sizeof (off_t) * ncookies, M_TEMP, M_WAITOK);
2371 *ap->a_cookies = cookies;
2372 }
2373
2374 if (!error && uio->uio_resid == tresid) {
2375 uio->uio_resid += lost;
2376 nfsstats.direofcache_misses++;
2377 if (ap->a_cookies)
2378 *ap->a_ncookies = 0;
2379 *ap->a_eofflag = 1;
2380 return (0);
2381 }
2382
2383 if (!error && ap->a_cookies) {
2384 /*
2385 * Only the NFS server and emulations use cookies, and they
2386 * load the directory block into system space, so we can
2387 * just look at it directly.
2388 */
2389 if (!VMSPACE_IS_KERNEL_P(uio->uio_vmspace) ||
2390 uio->uio_iovcnt != 1)
2391 panic("nfs_readdir: lost in space");
2392 for (nc = 0; ncookies-- &&
2393 base < (char *)uio->uio_iov->iov_base; nc++){
2394 dp = (struct dirent *) base;
2395 if (dp->d_reclen == 0)
2396 break;
2397 if (nmp->nm_flag & NFSMNT_XLATECOOKIE)
2398 *(cookies++) = (off_t)NFS_GETCOOKIE32(dp);
2399 else
2400 *(cookies++) = NFS_GETCOOKIE(dp);
2401 base += dp->d_reclen;
2402 }
2403 uio->uio_resid +=
2404 ((char *)uio->uio_iov->iov_base - base);
2405 uio->uio_iov->iov_len +=
2406 ((char *)uio->uio_iov->iov_base - base);
2407 uio->uio_iov->iov_base = base;
2408 *ap->a_ncookies = nc;
2409 }
2410
2411 uio->uio_resid += lost;
2412 *ap->a_eofflag = 0;
2413 return (error);
2414 }
2415
2416 /*
2417 * Readdir rpc call.
2418 * Called from below the buffer cache by nfs_doio().
2419 */
2420 int
2421 nfs_readdirrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
2422 {
2423 int len, left;
2424 struct dirent *dp = NULL;
2425 u_int32_t *tl;
2426 char *cp;
2427 int32_t t1, t2;
2428 char *bpos, *dpos, *cp2;
2429 struct mbuf *mreq, *mrep, *md, *mb;
2430 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2431 struct nfsnode *dnp = VTONFS(vp);
2432 u_quad_t fileno;
2433 int error = 0, more_dirs = 1, blksiz = 0, bigenough = 1;
2434 #ifndef NFS_V2_ONLY
2435 int attrflag;
2436 #endif
2437 int nrpcs = 0, reclen;
2438 const int v3 = NFS_ISV3(vp);
2439
2440 #ifdef DIAGNOSTIC
2441 /*
2442 * Should be called from buffer cache, so only amount of
2443 * NFS_DIRBLKSIZ will be requested.
2444 */
2445 if (uiop->uio_iovcnt != 1 || uiop->uio_resid != NFS_DIRBLKSIZ)
2446 panic("nfs readdirrpc bad uio");
2447 #endif
2448
2449 /*
2450 * Loop around doing readdir rpc's of size nm_readdirsize
2451 * truncated to a multiple of NFS_DIRFRAGSIZ.
2452 * The stopping criteria is EOF or buffer full.
2453 */
2454 while (more_dirs && bigenough) {
2455 /*
2456 * Heuristic: don't bother to do another RPC to further
2457 * fill up this block if there is not much room left. (< 50%
2458 * of the readdir RPC size). This wastes some buffer space
2459 * but can save up to 50% in RPC calls.
2460 */
2461 if (nrpcs > 0 && uiop->uio_resid < (nmp->nm_readdirsize / 2)) {
2462 bigenough = 0;
2463 break;
2464 }
2465 nfsstats.rpccnt[NFSPROC_READDIR]++;
2466 nfsm_reqhead(dnp, NFSPROC_READDIR, NFSX_FH(v3) +
2467 NFSX_READDIR(v3));
2468 nfsm_fhtom(dnp, v3);
2469 #ifndef NFS_V2_ONLY
2470 if (v3) {
2471 nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
2472 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE) {
2473 txdr_swapcookie3(uiop->uio_offset, tl);
2474 } else {
2475 txdr_cookie3(uiop->uio_offset, tl);
2476 }
2477 tl += 2;
2478 *tl++ = dnp->n_cookieverf.nfsuquad[0];
2479 *tl++ = dnp->n_cookieverf.nfsuquad[1];
2480 } else
2481 #endif
2482 {
2483 nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
2484 *tl++ = txdr_unsigned(uiop->uio_offset);
2485 }
2486 *tl = txdr_unsigned(nmp->nm_readdirsize);
2487 nfsm_request(dnp, NFSPROC_READDIR, curlwp, cred);
2488 nrpcs++;
2489 #ifndef NFS_V2_ONLY
2490 if (v3) {
2491 nfsm_postop_attr(vp, attrflag, 0);
2492 if (!error) {
2493 nfsm_dissect(tl, u_int32_t *,
2494 2 * NFSX_UNSIGNED);
2495 dnp->n_cookieverf.nfsuquad[0] = *tl++;
2496 dnp->n_cookieverf.nfsuquad[1] = *tl;
2497 } else {
2498 m_freem(mrep);
2499 goto nfsmout;
2500 }
2501 }
2502 #endif
2503 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2504 more_dirs = fxdr_unsigned(int, *tl);
2505
2506 /* loop thru the dir entries, doctoring them to 4bsd form */
2507 while (more_dirs && bigenough) {
2508 #ifndef NFS_V2_ONLY
2509 if (v3) {
2510 nfsm_dissect(tl, u_int32_t *,
2511 3 * NFSX_UNSIGNED);
2512 fileno = fxdr_hyper(tl);
2513 len = fxdr_unsigned(int, *(tl + 2));
2514 } else
2515 #endif
2516 {
2517 nfsm_dissect(tl, u_int32_t *,
2518 2 * NFSX_UNSIGNED);
2519 fileno = fxdr_unsigned(u_quad_t, *tl++);
2520 len = fxdr_unsigned(int, *tl);
2521 }
2522 if (len <= 0 || len > NFS_MAXNAMLEN) {
2523 error = EBADRPC;
2524 m_freem(mrep);
2525 goto nfsmout;
2526 }
2527 /* for cookie stashing */
2528 reclen = _DIRENT_RECLEN(dp, len) + 2 * sizeof(off_t);
2529 left = NFS_DIRFRAGSIZ - blksiz;
2530 if (reclen > left) {
2531 memset(uiop->uio_iov->iov_base, 0, left);
2532 dp->d_reclen += left;
2533 UIO_ADVANCE(uiop, left);
2534 blksiz = 0;
2535 NFS_STASHCOOKIE(dp, uiop->uio_offset);
2536 }
2537 if (reclen > uiop->uio_resid)
2538 bigenough = 0;
2539 if (bigenough) {
2540 int tlen;
2541
2542 dp = (struct dirent *)uiop->uio_iov->iov_base;
2543 dp->d_fileno = fileno;
2544 dp->d_namlen = len;
2545 dp->d_reclen = reclen;
2546 dp->d_type = DT_UNKNOWN;
2547 blksiz += reclen;
2548 if (blksiz == NFS_DIRFRAGSIZ)
2549 blksiz = 0;
2550 UIO_ADVANCE(uiop, DIRHDSIZ);
2551 nfsm_mtouio(uiop, len);
2552 tlen = reclen - (DIRHDSIZ + len);
2553 (void)memset(uiop->uio_iov->iov_base, 0, tlen);
2554 UIO_ADVANCE(uiop, tlen);
2555 } else
2556 nfsm_adv(nfsm_rndup(len));
2557 #ifndef NFS_V2_ONLY
2558 if (v3) {
2559 nfsm_dissect(tl, u_int32_t *,
2560 3 * NFSX_UNSIGNED);
2561 } else
2562 #endif
2563 {
2564 nfsm_dissect(tl, u_int32_t *,
2565 2 * NFSX_UNSIGNED);
2566 }
2567 if (bigenough) {
2568 #ifndef NFS_V2_ONLY
2569 if (v3) {
2570 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE)
2571 uiop->uio_offset =
2572 fxdr_swapcookie3(tl);
2573 else
2574 uiop->uio_offset =
2575 fxdr_cookie3(tl);
2576 }
2577 else
2578 #endif
2579 {
2580 uiop->uio_offset =
2581 fxdr_unsigned(off_t, *tl);
2582 }
2583 NFS_STASHCOOKIE(dp, uiop->uio_offset);
2584 }
2585 if (v3)
2586 tl += 2;
2587 else
2588 tl++;
2589 more_dirs = fxdr_unsigned(int, *tl);
2590 }
2591 /*
2592 * If at end of rpc data, get the eof boolean
2593 */
2594 if (!more_dirs) {
2595 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2596 more_dirs = (fxdr_unsigned(int, *tl) == 0);
2597
2598 /*
2599 * kludge: if we got no entries, treat it as EOF.
2600 * some server sometimes send a reply without any
2601 * entries or EOF.
2602 * although it might mean the server has very long name,
2603 * we can't handle such entries anyway.
2604 */
2605
2606 if (uiop->uio_resid >= NFS_DIRBLKSIZ)
2607 more_dirs = 0;
2608 }
2609 m_freem(mrep);
2610 }
2611 /*
2612 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ
2613 * by increasing d_reclen for the last record.
2614 */
2615 if (blksiz > 0) {
2616 left = NFS_DIRFRAGSIZ - blksiz;
2617 memset(uiop->uio_iov->iov_base, 0, left);
2618 dp->d_reclen += left;
2619 NFS_STASHCOOKIE(dp, uiop->uio_offset);
2620 UIO_ADVANCE(uiop, left);
2621 }
2622
2623 /*
2624 * We are now either at the end of the directory or have filled the
2625 * block.
2626 */
2627 if (bigenough) {
2628 dnp->n_direofoffset = uiop->uio_offset;
2629 dnp->n_flag |= NEOFVALID;
2630 }
2631 nfsmout:
2632 return (error);
2633 }
2634
2635 #ifndef NFS_V2_ONLY
2636 /*
2637 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
2638 */
2639 int
2640 nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
2641 {
2642 int len, left;
2643 struct dirent *dp = NULL;
2644 u_int32_t *tl;
2645 char *cp;
2646 int32_t t1, t2;
2647 struct vnode *newvp;
2648 char *bpos, *dpos, *cp2;
2649 struct mbuf *mreq, *mrep, *md, *mb;
2650 struct nameidata nami, *ndp = &nami;
2651 struct componentname *cnp = &ndp->ni_cnd;
2652 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2653 struct nfsnode *dnp = VTONFS(vp), *np;
2654 nfsfh_t *fhp;
2655 u_quad_t fileno;
2656 int error = 0, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
2657 int attrflag, fhsize, nrpcs = 0, reclen;
2658 struct nfs_fattr fattr, *fp;
2659
2660 #ifdef DIAGNOSTIC
2661 if (uiop->uio_iovcnt != 1 || uiop->uio_resid != NFS_DIRBLKSIZ)
2662 panic("nfs readdirplusrpc bad uio");
2663 #endif
2664 ndp->ni_dvp = vp;
2665 newvp = NULLVP;
2666
2667 /*
2668 * Loop around doing readdir rpc's of size nm_readdirsize
2669 * truncated to a multiple of NFS_DIRFRAGSIZ.
2670 * The stopping criteria is EOF or buffer full.
2671 */
2672 while (more_dirs && bigenough) {
2673 if (nrpcs > 0 && uiop->uio_resid < (nmp->nm_readdirsize / 2)) {
2674 bigenough = 0;
2675 break;
2676 }
2677 nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
2678 nfsm_reqhead(dnp, NFSPROC_READDIRPLUS,
2679 NFSX_FH(1) + 6 * NFSX_UNSIGNED);
2680 nfsm_fhtom(dnp, 1);
2681 nfsm_build(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
2682 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE) {
2683 txdr_swapcookie3(uiop->uio_offset, tl);
2684 } else {
2685 txdr_cookie3(uiop->uio_offset, tl);
2686 }
2687 tl += 2;
2688 *tl++ = dnp->n_cookieverf.nfsuquad[0];
2689 *tl++ = dnp->n_cookieverf.nfsuquad[1];
2690 *tl++ = txdr_unsigned(nmp->nm_readdirsize);
2691 *tl = txdr_unsigned(nmp->nm_rsize);
2692 nfsm_request(dnp, NFSPROC_READDIRPLUS, curlwp, cred);
2693 nfsm_postop_attr(vp, attrflag, 0);
2694 if (error) {
2695 m_freem(mrep);
2696 goto nfsmout;
2697 }
2698 nrpcs++;
2699 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
2700 dnp->n_cookieverf.nfsuquad[0] = *tl++;
2701 dnp->n_cookieverf.nfsuquad[1] = *tl++;
2702 more_dirs = fxdr_unsigned(int, *tl);
2703
2704 /* loop thru the dir entries, doctoring them to 4bsd form */
2705 while (more_dirs && bigenough) {
2706 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
2707 fileno = fxdr_hyper(tl);
2708 len = fxdr_unsigned(int, *(tl + 2));
2709 if (len <= 0 || len > NFS_MAXNAMLEN) {
2710 error = EBADRPC;
2711 m_freem(mrep);
2712 goto nfsmout;
2713 }
2714 /* for cookie stashing */
2715 reclen = _DIRENT_RECLEN(dp, len) + 2 * sizeof(off_t);
2716 left = NFS_DIRFRAGSIZ - blksiz;
2717 if (reclen > left) {
2718 /*
2719 * DIRFRAGSIZ is aligned, no need to align
2720 * again here.
2721 */
2722 memset(uiop->uio_iov->iov_base, 0, left);
2723 dp->d_reclen += left;
2724 UIO_ADVANCE(uiop, left);
2725 NFS_STASHCOOKIE(dp, uiop->uio_offset);
2726 blksiz = 0;
2727 }
2728 if (reclen > uiop->uio_resid)
2729 bigenough = 0;
2730 if (bigenough) {
2731 int tlen;
2732
2733 dp = (struct dirent *)uiop->uio_iov->iov_base;
2734 dp->d_fileno = fileno;
2735 dp->d_namlen = len;
2736 dp->d_reclen = reclen;
2737 dp->d_type = DT_UNKNOWN;
2738 blksiz += reclen;
2739 if (blksiz == NFS_DIRFRAGSIZ)
2740 blksiz = 0;
2741 UIO_ADVANCE(uiop, DIRHDSIZ);
2742 nfsm_mtouio(uiop, len);
2743 tlen = reclen - (DIRHDSIZ + len);
2744 (void)memset(uiop->uio_iov->iov_base, 0, tlen);
2745 UIO_ADVANCE(uiop, tlen);
2746 cnp->cn_nameptr = dp->d_name;
2747 cnp->cn_namelen = dp->d_namlen;
2748 } else
2749 nfsm_adv(nfsm_rndup(len));
2750 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
2751 if (bigenough) {
2752 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE)
2753 uiop->uio_offset =
2754 fxdr_swapcookie3(tl);
2755 else
2756 uiop->uio_offset =
2757 fxdr_cookie3(tl);
2758 NFS_STASHCOOKIE(dp, uiop->uio_offset);
2759 }
2760 tl += 2;
2761
2762 /*
2763 * Since the attributes are before the file handle
2764 * (sigh), we must skip over the attributes and then
2765 * come back and get them.
2766 */
2767 attrflag = fxdr_unsigned(int, *tl);
2768 if (attrflag) {
2769 nfsm_dissect(fp, struct nfs_fattr *, NFSX_V3FATTR);
2770 memcpy(&fattr, fp, NFSX_V3FATTR);
2771 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2772 doit = fxdr_unsigned(int, *tl);
2773 if (doit) {
2774 nfsm_getfh(fhp, fhsize, 1);
2775 if (NFS_CMPFH(dnp, fhp, fhsize)) {
2776 vref(vp);
2777 newvp = vp;
2778 np = dnp;
2779 } else {
2780 error = nfs_nget1(vp->v_mount, fhp,
2781 fhsize, &np, LK_NOWAIT);
2782 if (!error)
2783 newvp = NFSTOV(np);
2784 }
2785 if (!error) {
2786 const char *xcp;
2787
2788 nfs_loadattrcache(&newvp, &fattr, 0, 0);
2789 if (bigenough) {
2790 dp->d_type =
2791 IFTODT(VTTOIF(np->n_vattr->va_type));
2792 if (cnp->cn_namelen <= NCHNAMLEN) {
2793 ndp->ni_vp = newvp;
2794 xcp = cnp->cn_nameptr +
2795 cnp->cn_namelen;
2796 cnp->cn_hash =
2797 namei_hash(cnp->cn_nameptr, &xcp);
2798 nfs_cache_enter(ndp->ni_dvp,
2799 ndp->ni_vp, cnp);
2800 }
2801 }
2802 }
2803 error = 0;
2804 }
2805 } else {
2806 /* Just skip over the file handle */
2807 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2808 i = fxdr_unsigned(int, *tl);
2809 nfsm_adv(nfsm_rndup(i));
2810 }
2811 if (newvp != NULLVP) {
2812 if (newvp == vp)
2813 vrele(newvp);
2814 else
2815 vput(newvp);
2816 newvp = NULLVP;
2817 }
2818 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2819 more_dirs = fxdr_unsigned(int, *tl);
2820 }
2821 /*
2822 * If at end of rpc data, get the eof boolean
2823 */
2824 if (!more_dirs) {
2825 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2826 more_dirs = (fxdr_unsigned(int, *tl) == 0);
2827
2828 /*
2829 * kludge: see a comment in nfs_readdirrpc.
2830 */
2831
2832 if (uiop->uio_resid >= NFS_DIRBLKSIZ)
2833 more_dirs = 0;
2834 }
2835 m_freem(mrep);
2836 }
2837 /*
2838 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ
2839 * by increasing d_reclen for the last record.
2840 */
2841 if (blksiz > 0) {
2842 left = NFS_DIRFRAGSIZ - blksiz;
2843 memset(uiop->uio_iov->iov_base, 0, left);
2844 dp->d_reclen += left;
2845 NFS_STASHCOOKIE(dp, uiop->uio_offset);
2846 UIO_ADVANCE(uiop, left);
2847 }
2848
2849 /*
2850 * We are now either at the end of the directory or have filled the
2851 * block.
2852 */
2853 if (bigenough) {
2854 dnp->n_direofoffset = uiop->uio_offset;
2855 dnp->n_flag |= NEOFVALID;
2856 }
2857 nfsmout:
2858 if (newvp != NULLVP) {
2859 if(newvp == vp)
2860 vrele(newvp);
2861 else
2862 vput(newvp);
2863 }
2864 return (error);
2865 }
2866 #endif
2867
2868 /*
2869 * Silly rename. To make the NFS filesystem that is stateless look a little
2870 * more like the "ufs" a remove of an active vnode is translated to a rename
2871 * to a funny looking filename that is removed by nfs_inactive on the
2872 * nfsnode. There is the potential for another process on a different client
2873 * to create the same funny name between the nfs_lookitup() fails and the
2874 * nfs_rename() completes, but...
2875 */
2876 int
2877 nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp, bool dolink)
2878 {
2879 struct sillyrename *sp;
2880 struct nfsnode *np;
2881 int error;
2882 pid_t pid;
2883
2884 cache_purge(dvp);
2885 np = VTONFS(vp);
2886 #ifndef DIAGNOSTIC
2887 if (vp->v_type == VDIR)
2888 panic("nfs: sillyrename dir");
2889 #endif
2890 sp = kmem_alloc(sizeof(*sp), KM_SLEEP);
2891 sp->s_cred = kauth_cred_dup(cnp->cn_cred);
2892 sp->s_dvp = dvp;
2893 vref(dvp);
2894
2895 /* Fudge together a funny name */
2896 pid = curlwp->l_proc->p_pid;
2897 memcpy(sp->s_name, ".nfsAxxxx4.4", 13);
2898 sp->s_namlen = 12;
2899 sp->s_name[8] = hexdigits[pid & 0xf];
2900 sp->s_name[7] = hexdigits[(pid >> 4) & 0xf];
2901 sp->s_name[6] = hexdigits[(pid >> 8) & 0xf];
2902 sp->s_name[5] = hexdigits[(pid >> 12) & 0xf];
2903
2904 /* Try lookitups until we get one that isn't there */
2905 while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2906 curlwp, (struct nfsnode **)0) == 0) {
2907 sp->s_name[4]++;
2908 if (sp->s_name[4] > 'z') {
2909 error = EINVAL;
2910 goto bad;
2911 }
2912 }
2913 if (dolink) {
2914 error = nfs_linkrpc(dvp, vp, sp->s_name, sp->s_namlen,
2915 sp->s_cred, curlwp);
2916 /*
2917 * nfs_request maps NFSERR_NOTSUPP to ENOTSUP.
2918 */
2919 if (error == ENOTSUP) {
2920 error = nfs_renameit(dvp, cnp, sp);
2921 }
2922 } else {
2923 error = nfs_renameit(dvp, cnp, sp);
2924 }
2925 if (error)
2926 goto bad;
2927 error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2928 curlwp, &np);
2929 np->n_sillyrename = sp;
2930 return (0);
2931 bad:
2932 vrele(sp->s_dvp);
2933 kauth_cred_free(sp->s_cred);
2934 kmem_free(sp, sizeof(*sp));
2935 return (error);
2936 }
2937
2938 /*
2939 * Look up a file name and optionally either update the file handle or
2940 * allocate an nfsnode, depending on the value of npp.
2941 * npp == NULL --> just do the lookup
2942 * *npp == NULL --> allocate a new nfsnode and make sure attributes are
2943 * handled too
2944 * *npp != NULL --> update the file handle in the vnode
2945 */
2946 int
2947 nfs_lookitup(struct vnode *dvp, const char *name, int len, kauth_cred_t cred, struct lwp *l, struct nfsnode **npp)
2948 {
2949 u_int32_t *tl;
2950 char *cp;
2951 int32_t t1, t2;
2952 struct vnode *newvp = (struct vnode *)0;
2953 struct nfsnode *np, *dnp = VTONFS(dvp);
2954 char *bpos, *dpos, *cp2;
2955 int error = 0, fhlen;
2956 #ifndef NFS_V2_ONLY
2957 int attrflag;
2958 #endif
2959 struct mbuf *mreq, *mrep, *md, *mb;
2960 nfsfh_t *nfhp;
2961 const int v3 = NFS_ISV3(dvp);
2962
2963 nfsstats.rpccnt[NFSPROC_LOOKUP]++;
2964 nfsm_reqhead(dnp, NFSPROC_LOOKUP,
2965 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
2966 nfsm_fhtom(dnp, v3);
2967 nfsm_strtom(name, len, NFS_MAXNAMLEN);
2968 nfsm_request(dnp, NFSPROC_LOOKUP, l, cred);
2969 if (npp && !error) {
2970 nfsm_getfh(nfhp, fhlen, v3);
2971 if (*npp) {
2972 np = *npp;
2973 if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) {
2974 kmem_free(np->n_fhp, np->n_fhsize);
2975 np->n_fhp = &np->n_fh;
2976 }
2977 #if NFS_SMALLFH < NFSX_V3FHMAX
2978 else if (np->n_fhsize <= NFS_SMALLFH && fhlen > NFS_SMALLFH)
2979 np->n_fhp = kmem_alloc(fhlen, KM_SLEEP);
2980 #endif
2981 memcpy(np->n_fhp, nfhp, fhlen);
2982 np->n_fhsize = fhlen;
2983 newvp = NFSTOV(np);
2984 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) {
2985 vref(dvp);
2986 newvp = dvp;
2987 np = dnp;
2988 } else {
2989 error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np);
2990 if (error) {
2991 m_freem(mrep);
2992 return (error);
2993 }
2994 newvp = NFSTOV(np);
2995 }
2996 #ifndef NFS_V2_ONLY
2997 if (v3) {
2998 nfsm_postop_attr(newvp, attrflag, 0);
2999 if (!attrflag && *npp == NULL) {
3000 m_freem(mrep);
3001 vput(newvp);
3002 return (ENOENT);
3003 }
3004 } else
3005 #endif
3006 nfsm_loadattr(newvp, (struct vattr *)0, 0);
3007 }
3008 nfsm_reqdone;
3009 if (npp && *npp == NULL) {
3010 if (error) {
3011 if (newvp)
3012 vput(newvp);
3013 } else
3014 *npp = np;
3015 }
3016 return (error);
3017 }
3018
3019 #ifndef NFS_V2_ONLY
3020 /*
3021 * Nfs Version 3 commit rpc
3022 */
3023 int
3024 nfs_commit(struct vnode *vp, off_t offset, uint32_t cnt, struct lwp *l)
3025 {
3026 char *cp;
3027 u_int32_t *tl;
3028 int32_t t1, t2;
3029 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
3030 char *bpos, *dpos, *cp2;
3031 int error = 0, wccflag = NFSV3_WCCRATTR;
3032 struct mbuf *mreq, *mrep, *md, *mb;
3033 struct nfsnode *np;
3034
3035 KASSERT(NFS_ISV3(vp));
3036
3037 #ifdef NFS_DEBUG_COMMIT
3038 printf("commit %lu - %lu\n", (unsigned long)offset,
3039 (unsigned long)(offset + cnt));
3040 #endif
3041
3042 mutex_enter(&nmp->nm_lock);
3043 if ((nmp->nm_iflag & NFSMNT_HASWRITEVERF) == 0) {
3044 mutex_exit(&nmp->nm_lock);
3045 return (0);
3046 }
3047 mutex_exit(&nmp->nm_lock);
3048 nfsstats.rpccnt[NFSPROC_COMMIT]++;
3049 np = VTONFS(vp);
3050 nfsm_reqhead(np, NFSPROC_COMMIT, NFSX_FH(1));
3051 nfsm_fhtom(np, 1);
3052 nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
3053 txdr_hyper(offset, tl);
3054 tl += 2;
3055 *tl = txdr_unsigned(cnt);
3056 nfsm_request(np, NFSPROC_COMMIT, l, np->n_wcred);
3057 nfsm_wcc_data(vp, wccflag, NAC_NOTRUNC, false);
3058 if (!error) {
3059 nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF);
3060 mutex_enter(&nmp->nm_lock);
3061 if ((nmp->nm_iflag & NFSMNT_STALEWRITEVERF) ||
3062 memcmp(nmp->nm_writeverf, tl, NFSX_V3WRITEVERF)) {
3063 memcpy(nmp->nm_writeverf, tl, NFSX_V3WRITEVERF);
3064 error = NFSERR_STALEWRITEVERF;
3065 nmp->nm_iflag |= NFSMNT_STALEWRITEVERF;
3066 }
3067 mutex_exit(&nmp->nm_lock);
3068 }
3069 nfsm_reqdone;
3070 return (error);
3071 }
3072 #endif
3073
3074 /*
3075 * Kludge City..
3076 * - make nfs_bmap() essentially a no-op that does no translation
3077 * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc
3078 * (Maybe I could use the process's page mapping, but I was concerned that
3079 * Kernel Write might not be enabled and also figured copyout() would do
3080 * a lot more work than memcpy() and also it currently happens in the
3081 * context of the swapper process (2).
3082 */
3083 int
3084 nfs_bmap(void *v)
3085 {
3086 struct vop_bmap_args /* {
3087 struct vnode *a_vp;
3088 daddr_t a_bn;
3089 struct vnode **a_vpp;
3090 daddr_t *a_bnp;
3091 int *a_runp;
3092 } */ *ap = v;
3093 struct vnode *vp = ap->a_vp;
3094 int bshift = vp->v_mount->mnt_fs_bshift - vp->v_mount->mnt_dev_bshift;
3095
3096 if (ap->a_vpp != NULL)
3097 *ap->a_vpp = vp;
3098 if (ap->a_bnp != NULL)
3099 *ap->a_bnp = ap->a_bn << bshift;
3100 if (ap->a_runp != NULL)
3101 *ap->a_runp = 1024 * 1024; /* XXX */
3102 return (0);
3103 }
3104
3105 /*
3106 * Strategy routine.
3107 * For async requests when nfsiod(s) are running, queue the request by
3108 * calling nfs_asyncio(), otherwise just all nfs_doio() to do the
3109 * request.
3110 */
3111 int
3112 nfs_strategy(void *v)
3113 {
3114 struct vop_strategy_args *ap = v;
3115 struct buf *bp = ap->a_bp;
3116 int error = 0;
3117
3118 if ((bp->b_flags & (B_PHYS|B_ASYNC)) == (B_PHYS|B_ASYNC))
3119 panic("nfs physio/async");
3120
3121 /*
3122 * If the op is asynchronous and an i/o daemon is waiting
3123 * queue the request, wake it up and wait for completion
3124 * otherwise just do it ourselves.
3125 */
3126 if ((bp->b_flags & B_ASYNC) == 0 || nfs_asyncio(bp))
3127 error = nfs_doio(bp);
3128 return (error);
3129 }
3130
3131 /*
3132 * fsync vnode op. Just call nfs_flush() with commit == 1.
3133 */
3134 /* ARGSUSED */
3135 int
3136 nfs_fsync(void *v)
3137 {
3138 struct vop_fsync_args /* {
3139 struct vnodeop_desc *a_desc;
3140 struct vnode * a_vp;
3141 kauth_cred_t a_cred;
3142 int a_flags;
3143 off_t offlo;
3144 off_t offhi;
3145 struct lwp * a_l;
3146 } */ *ap = v;
3147
3148 struct vnode *vp = ap->a_vp;
3149
3150 if (vp->v_type != VREG)
3151 return 0;
3152
3153 return (nfs_flush(vp, ap->a_cred,
3154 (ap->a_flags & FSYNC_WAIT) != 0 ? MNT_WAIT : 0, curlwp, 1));
3155 }
3156
3157 /*
3158 * Flush all the data associated with a vnode.
3159 */
3160 int
3161 nfs_flush(struct vnode *vp, kauth_cred_t cred, int waitfor, struct lwp *l,
3162 int commit)
3163 {
3164 struct nfsnode *np = VTONFS(vp);
3165 int error;
3166 int flushflags = PGO_ALLPAGES|PGO_CLEANIT|PGO_SYNCIO;
3167 UVMHIST_FUNC("nfs_flush"); UVMHIST_CALLED(ubchist);
3168
3169 mutex_enter(&vp->v_interlock);
3170 error = VOP_PUTPAGES(vp, 0, 0, flushflags);
3171 if (np->n_flag & NWRITEERR) {
3172 error = np->n_error;
3173 np->n_flag &= ~NWRITEERR;
3174 }
3175 UVMHIST_LOG(ubchist, "returning %d", error,0,0,0);
3176 return (error);
3177 }
3178
3179 /*
3180 * Return POSIX pathconf information applicable to nfs.
3181 *
3182 * N.B. The NFS V2 protocol doesn't support this RPC.
3183 */
3184 /* ARGSUSED */
3185 int
3186 nfs_pathconf(void *v)
3187 {
3188 struct vop_pathconf_args /* {
3189 struct vnode *a_vp;
3190 int a_name;
3191 register_t *a_retval;
3192 } */ *ap = v;
3193 struct nfsv3_pathconf *pcp;
3194 struct vnode *vp = ap->a_vp;
3195 struct mbuf *mreq, *mrep, *md, *mb;
3196 int32_t t1, t2;
3197 u_int32_t *tl;
3198 char *bpos, *dpos, *cp, *cp2;
3199 int error = 0, attrflag;
3200 #ifndef NFS_V2_ONLY
3201 struct nfsmount *nmp;
3202 unsigned int l;
3203 u_int64_t maxsize;
3204 #endif
3205 const int v3 = NFS_ISV3(vp);
3206 struct nfsnode *np = VTONFS(vp);
3207
3208 switch (ap->a_name) {
3209 /* Names that can be resolved locally. */
3210 case _PC_PIPE_BUF:
3211 *ap->a_retval = PIPE_BUF;
3212 break;
3213 case _PC_SYNC_IO:
3214 *ap->a_retval = 1;
3215 break;
3216 /* Names that cannot be resolved locally; do an RPC, if possible. */
3217 case _PC_LINK_MAX:
3218 case _PC_NAME_MAX:
3219 case _PC_CHOWN_RESTRICTED:
3220 case _PC_NO_TRUNC:
3221 if (!v3) {
3222 error = EINVAL;
3223 break;
3224 }
3225 nfsstats.rpccnt[NFSPROC_PATHCONF]++;
3226 nfsm_reqhead(np, NFSPROC_PATHCONF, NFSX_FH(1));
3227 nfsm_fhtom(np, 1);
3228 nfsm_request(np, NFSPROC_PATHCONF,
3229 curlwp, curlwp->l_cred); /* XXX */
3230 nfsm_postop_attr(vp, attrflag, 0);
3231 if (!error) {
3232 nfsm_dissect(pcp, struct nfsv3_pathconf *,
3233 NFSX_V3PATHCONF);
3234 switch (ap->a_name) {
3235 case _PC_LINK_MAX:
3236 *ap->a_retval =
3237 fxdr_unsigned(register_t, pcp->pc_linkmax);
3238 break;
3239 case _PC_NAME_MAX:
3240 *ap->a_retval =
3241 fxdr_unsigned(register_t, pcp->pc_namemax);
3242 break;
3243 case _PC_CHOWN_RESTRICTED:
3244 *ap->a_retval =
3245 (pcp->pc_chownrestricted == nfs_true);
3246 break;
3247 case _PC_NO_TRUNC:
3248 *ap->a_retval =
3249 (pcp->pc_notrunc == nfs_true);
3250 break;
3251 }
3252 }
3253 nfsm_reqdone;
3254 break;
3255 case _PC_FILESIZEBITS:
3256 #ifndef NFS_V2_ONLY
3257 if (v3) {
3258 nmp = VFSTONFS(vp->v_mount);
3259 if ((nmp->nm_iflag & NFSMNT_GOTFSINFO) == 0)
3260 if ((error = nfs_fsinfo(nmp, vp,
3261 curlwp->l_cred, curlwp)) != 0) /* XXX */
3262 break;
3263 for (l = 0, maxsize = nmp->nm_maxfilesize;
3264 (maxsize >> l) > 0; l++)
3265 ;
3266 *ap->a_retval = l + 1;
3267 } else
3268 #endif
3269 {
3270 *ap->a_retval = 32; /* NFS V2 limitation */
3271 }
3272 break;
3273 default:
3274 error = EINVAL;
3275 break;
3276 }
3277
3278 return (error);
3279 }
3280
3281 /*
3282 * NFS advisory byte-level locks.
3283 */
3284 int
3285 nfs_advlock(void *v)
3286 {
3287 struct vop_advlock_args /* {
3288 struct vnode *a_vp;
3289 void *a_id;
3290 int a_op;
3291 struct flock *a_fl;
3292 int a_flags;
3293 } */ *ap = v;
3294 struct nfsnode *np = VTONFS(ap->a_vp);
3295
3296 return lf_advlock(ap, &np->n_lockf, np->n_size);
3297 }
3298
3299 /*
3300 * Print out the contents of an nfsnode.
3301 */
3302 int
3303 nfs_print(void *v)
3304 {
3305 struct vop_print_args /* {
3306 struct vnode *a_vp;
3307 } */ *ap = v;
3308 struct vnode *vp = ap->a_vp;
3309 struct nfsnode *np = VTONFS(vp);
3310
3311 printf("tag VT_NFS, fileid %lld fsid 0x%llx",
3312 (unsigned long long)np->n_vattr->va_fileid,
3313 (unsigned long long)np->n_vattr->va_fsid);
3314 if (vp->v_type == VFIFO)
3315 VOCALL(fifo_vnodeop_p, VOFFSET(vop_print), v);
3316 printf("\n");
3317 return (0);
3318 }
3319
3320 /*
3321 * nfs unlock wrapper.
3322 */
3323 int
3324 nfs_unlock(void *v)
3325 {
3326 struct vop_unlock_args /* {
3327 struct vnode *a_vp;
3328 int a_flags;
3329 } */ *ap = v;
3330 struct vnode *vp = ap->a_vp;
3331
3332 /*
3333 * VOP_UNLOCK can be called by nfs_loadattrcache
3334 * with v_data == 0.
3335 */
3336 if (VTONFS(vp)) {
3337 nfs_delayedtruncate(vp);
3338 }
3339
3340 return genfs_unlock(v);
3341 }
3342
3343 /*
3344 * nfs special file access vnode op.
3345 * Essentially just get vattr and then imitate iaccess() since the device is
3346 * local to the client.
3347 */
3348 int
3349 nfsspec_access(void *v)
3350 {
3351 struct vop_access_args /* {
3352 struct vnode *a_vp;
3353 int a_mode;
3354 kauth_cred_t a_cred;
3355 struct lwp *a_l;
3356 } */ *ap = v;
3357 struct vattr va;
3358 struct vnode *vp = ap->a_vp;
3359 int error;
3360
3361 error = VOP_GETATTR(vp, &va, ap->a_cred);
3362 if (error)
3363 return (error);
3364
3365 /*
3366 * Disallow write attempts on filesystems mounted read-only;
3367 * unless the file is a socket, fifo, or a block or character
3368 * device resident on the filesystem.
3369 */
3370 if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
3371 switch (vp->v_type) {
3372 case VREG:
3373 case VDIR:
3374 case VLNK:
3375 return (EROFS);
3376 default:
3377 break;
3378 }
3379 }
3380
3381 return (genfs_can_access(va.va_type, va.va_mode,
3382 va.va_uid, va.va_gid, ap->a_mode, ap->a_cred));
3383 }
3384
3385 /*
3386 * Read wrapper for special devices.
3387 */
3388 int
3389 nfsspec_read(void *v)
3390 {
3391 struct vop_read_args /* {
3392 struct vnode *a_vp;
3393 struct uio *a_uio;
3394 int a_ioflag;
3395 kauth_cred_t a_cred;
3396 } */ *ap = v;
3397 struct nfsnode *np = VTONFS(ap->a_vp);
3398
3399 /*
3400 * Set access flag.
3401 */
3402 np->n_flag |= NACC;
3403 getnanotime(&np->n_atim);
3404 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap));
3405 }
3406
3407 /*
3408 * Write wrapper for special devices.
3409 */
3410 int
3411 nfsspec_write(void *v)
3412 {
3413 struct vop_write_args /* {
3414 struct vnode *a_vp;
3415 struct uio *a_uio;
3416 int a_ioflag;
3417 kauth_cred_t a_cred;
3418 } */ *ap = v;
3419 struct nfsnode *np = VTONFS(ap->a_vp);
3420
3421 /*
3422 * Set update flag.
3423 */
3424 np->n_flag |= NUPD;
3425 getnanotime(&np->n_mtim);
3426 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap));
3427 }
3428
3429 /*
3430 * Close wrapper for special devices.
3431 *
3432 * Update the times on the nfsnode then do device close.
3433 */
3434 int
3435 nfsspec_close(void *v)
3436 {
3437 struct vop_close_args /* {
3438 struct vnode *a_vp;
3439 int a_fflag;
3440 kauth_cred_t a_cred;
3441 struct lwp *a_l;
3442 } */ *ap = v;
3443 struct vnode *vp = ap->a_vp;
3444 struct nfsnode *np = VTONFS(vp);
3445 struct vattr vattr;
3446
3447 if (np->n_flag & (NACC | NUPD)) {
3448 np->n_flag |= NCHG;
3449 if (vp->v_usecount == 1 &&
3450 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
3451 vattr_null(&vattr);
3452 if (np->n_flag & NACC)
3453 vattr.va_atime = np->n_atim;
3454 if (np->n_flag & NUPD)
3455 vattr.va_mtime = np->n_mtim;
3456 (void)VOP_SETATTR(vp, &vattr, ap->a_cred);
3457 }
3458 }
3459 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap));
3460 }
3461
3462 /*
3463 * Read wrapper for fifos.
3464 */
3465 int
3466 nfsfifo_read(void *v)
3467 {
3468 struct vop_read_args /* {
3469 struct vnode *a_vp;
3470 struct uio *a_uio;
3471 int a_ioflag;
3472 kauth_cred_t a_cred;
3473 } */ *ap = v;
3474 struct nfsnode *np = VTONFS(ap->a_vp);
3475
3476 /*
3477 * Set access flag.
3478 */
3479 np->n_flag |= NACC;
3480 getnanotime(&np->n_atim);
3481 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap));
3482 }
3483
3484 /*
3485 * Write wrapper for fifos.
3486 */
3487 int
3488 nfsfifo_write(void *v)
3489 {
3490 struct vop_write_args /* {
3491 struct vnode *a_vp;
3492 struct uio *a_uio;
3493 int a_ioflag;
3494 kauth_cred_t a_cred;
3495 } */ *ap = v;
3496 struct nfsnode *np = VTONFS(ap->a_vp);
3497
3498 /*
3499 * Set update flag.
3500 */
3501 np->n_flag |= NUPD;
3502 getnanotime(&np->n_mtim);
3503 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap));
3504 }
3505
3506 /*
3507 * Close wrapper for fifos.
3508 *
3509 * Update the times on the nfsnode then do fifo close.
3510 */
3511 int
3512 nfsfifo_close(void *v)
3513 {
3514 struct vop_close_args /* {
3515 struct vnode *a_vp;
3516 int a_fflag;
3517 kauth_cred_t a_cred;
3518 struct lwp *a_l;
3519 } */ *ap = v;
3520 struct vnode *vp = ap->a_vp;
3521 struct nfsnode *np = VTONFS(vp);
3522 struct vattr vattr;
3523
3524 if (np->n_flag & (NACC | NUPD)) {
3525 struct timespec ts;
3526
3527 getnanotime(&ts);
3528 if (np->n_flag & NACC)
3529 np->n_atim = ts;
3530 if (np->n_flag & NUPD)
3531 np->n_mtim = ts;
3532 np->n_flag |= NCHG;
3533 if (vp->v_usecount == 1 &&
3534 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
3535 vattr_null(&vattr);
3536 if (np->n_flag & NACC)
3537 vattr.va_atime = np->n_atim;
3538 if (np->n_flag & NUPD)
3539 vattr.va_mtime = np->n_mtim;
3540 (void)VOP_SETATTR(vp, &vattr, ap->a_cred);
3541 }
3542 }
3543 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
3544 }
3545