1 /*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
33 */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD: releng/6.4/sys/nfsclient/nfs_vnops.c 178459 2008-04-24 10:46:25Z dfr $");
37
38 /*
39 * vnode op calls for Sun NFS version 2 and 3
40 */
41
42 #include "opt_inet.h"
43
44 #include <sys/param.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
47 #include <sys/resourcevar.h>
48 #include <sys/proc.h>
49 #include <sys/mount.h>
50 #include <sys/bio.h>
51 #include <sys/buf.h>
52 #include <sys/malloc.h>
53 #include <sys/mbuf.h>
54 #include <sys/namei.h>
55 #include <sys/socket.h>
56 #include <sys/vnode.h>
57 #include <sys/dirent.h>
58 #include <sys/fcntl.h>
59 #include <sys/lockf.h>
60 #include <sys/stat.h>
61 #include <sys/sysctl.h>
62 #include <sys/signalvar.h>
63
64 #include <vm/vm.h>
65 #include <vm/vm_object.h>
66 #include <vm/vm_extern.h>
67 #include <vm/vm_object.h>
68
69 #include <fs/fifofs/fifo.h>
70
71 #include <rpc/rpcclnt.h>
72
73 #include <nfs/rpcv2.h>
74 #include <nfs/nfsproto.h>
75 #include <nfsclient/nfs.h>
76 #include <nfsclient/nfsnode.h>
77 #include <nfsclient/nfsmount.h>
78 #include <nfsclient/nfs_lock.h>
79 #include <nfs/xdr_subs.h>
80 #include <nfsclient/nfsm_subs.h>
81
82 #include <net/if.h>
83 #include <netinet/in.h>
84 #include <netinet/in_var.h>
85
86 /* Defs */
87 #define TRUE 1
88 #define FALSE 0
89
90 /*
91 * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these
92 * calls are not in getblk() and brelse() so that they would not be necessary
93 * here.
94 */
95 #ifndef B_VMIO
96 #define vfs_busy_pages(bp, f)
97 #endif
98
99 static vop_read_t nfsfifo_read;
100 static vop_write_t nfsfifo_write;
101 static vop_close_t nfsfifo_close;
102 static int nfs_flush(struct vnode *, int, struct thread *,
103 int);
104 static int nfs_setattrrpc(struct vnode *, struct vattr *, struct ucred *,
105 struct thread *);
106 static vop_lookup_t nfs_lookup;
107 static vop_create_t nfs_create;
108 static vop_mknod_t nfs_mknod;
109 static vop_open_t nfs_open;
110 static vop_close_t nfs_close;
111 static vop_access_t nfs_access;
112 static vop_getattr_t nfs_getattr;
113 static vop_setattr_t nfs_setattr;
114 static vop_read_t nfs_read;
115 static vop_fsync_t nfs_fsync;
116 static vop_remove_t nfs_remove;
117 static vop_link_t nfs_link;
118 static vop_rename_t nfs_rename;
119 static vop_mkdir_t nfs_mkdir;
120 static vop_rmdir_t nfs_rmdir;
121 static vop_symlink_t nfs_symlink;
122 static vop_readdir_t nfs_readdir;
123 static vop_strategy_t nfs_strategy;
124 static int nfs_lookitup(struct vnode *, const char *, int,
125 struct ucred *, struct thread *, struct nfsnode **);
126 static int nfs_sillyrename(struct vnode *, struct vnode *,
127 struct componentname *);
128 static vop_access_t nfsspec_access;
129 static vop_readlink_t nfs_readlink;
130 static vop_print_t nfs_print;
131 static vop_advlock_t nfs_advlock;
132 static vop_advlockasync_t nfs_advlockasync;
133
134 /*
135 * Global vfs data structures for nfs
136 */
137 struct vop_vector nfs_vnodeops = {
138 .vop_default = &default_vnodeops,
139 .vop_access = nfs_access,
140 .vop_advlock = nfs_advlock,
141 .vop_advlockasync = nfs_advlockasync,
142 .vop_close = nfs_close,
143 .vop_create = nfs_create,
144 .vop_fsync = nfs_fsync,
145 .vop_getattr = nfs_getattr,
146 .vop_getpages = nfs_getpages,
147 .vop_putpages = nfs_putpages,
148 .vop_inactive = nfs_inactive,
149 .vop_lease = VOP_NULL,
150 .vop_link = nfs_link,
151 .vop_lookup = nfs_lookup,
152 .vop_mkdir = nfs_mkdir,
153 .vop_mknod = nfs_mknod,
154 .vop_open = nfs_open,
155 .vop_print = nfs_print,
156 .vop_read = nfs_read,
157 .vop_readdir = nfs_readdir,
158 .vop_readlink = nfs_readlink,
159 .vop_reclaim = nfs_reclaim,
160 .vop_remove = nfs_remove,
161 .vop_rename = nfs_rename,
162 .vop_rmdir = nfs_rmdir,
163 .vop_setattr = nfs_setattr,
164 .vop_strategy = nfs_strategy,
165 .vop_symlink = nfs_symlink,
166 .vop_write = nfs_write,
167 };
168
169 struct vop_vector nfs_fifoops = {
170 .vop_default = &fifo_specops,
171 .vop_access = nfsspec_access,
172 .vop_close = nfsfifo_close,
173 .vop_fsync = nfs_fsync,
174 .vop_getattr = nfs_getattr,
175 .vop_inactive = nfs_inactive,
176 .vop_print = nfs_print,
177 .vop_read = nfsfifo_read,
178 .vop_reclaim = nfs_reclaim,
179 .vop_setattr = nfs_setattr,
180 .vop_write = nfsfifo_write,
181 };
182
183 static int nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp,
184 struct componentname *cnp, struct vattr *vap);
185 static int nfs_removerpc(struct vnode *dvp, const char *name, int namelen,
186 struct ucred *cred, struct thread *td);
187 static int nfs_renamerpc(struct vnode *fdvp, const char *fnameptr,
188 int fnamelen, struct vnode *tdvp,
189 const char *tnameptr, int tnamelen,
190 struct ucred *cred, struct thread *td);
191 static int nfs_renameit(struct vnode *sdvp, struct componentname *scnp,
192 struct sillyrename *sp);
193
194 /*
195 * Global variables
196 */
197 struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
198 struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
199 int nfs_numasync = 0;
200 #define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
201
202 SYSCTL_DECL(_vfs_nfs);
203
204 static int nfsaccess_cache_timeout = NFS_MAXATTRTIMO;
205 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW,
206 &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout");
207
208 static int nfsv3_commit_on_close = 0;
209 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW,
210 &nfsv3_commit_on_close, 0, "write+commit on close, else only write");
211
212 static int nfs_clean_pages_on_close = 1;
213 SYSCTL_INT(_vfs_nfs, OID_AUTO, clean_pages_on_close, CTLFLAG_RW,
214 &nfs_clean_pages_on_close, 0, "NFS clean dirty pages on close");
215
216 int nfs_directio_enable = 0;
217 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_directio_enable, CTLFLAG_RW,
218 &nfs_directio_enable, 0, "Enable NFS directio");
219
220 /*
221 * This sysctl allows other processes to mmap a file that has been opened
222 * O_DIRECT by a process. In general, having processes mmap the file while
223 * Direct IO is in progress can lead to Data Inconsistencies. But, we allow
224 * this by default to prevent DoS attacks - to prevent a malicious user from
225 * opening up files O_DIRECT preventing other users from mmap'ing these
226 * files. "Protected" environments where stricter consistency guarantees are
227 * required can disable this knob. The process that opened the file O_DIRECT
228 * cannot mmap() the file, because mmap'ed IO on an O_DIRECT open() is not
229 * meaningful.
230 */
231 int nfs_directio_allow_mmap = 1;
232 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_directio_allow_mmap, CTLFLAG_RW,
233 &nfs_directio_allow_mmap, 0, "Enable mmaped IO on file with O_DIRECT opens");
234
235 #if 0
236 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD,
237 &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count");
238
239 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD,
240 &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count");
241 #endif
242
243 #define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY \
244 | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \
245 | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP)
246 static int
247 nfs3_access_otw(struct vnode *vp, int wmode, struct thread *td,
248 struct ucred *cred)
249 {
250 const int v3 = 1;
251 u_int32_t *tl;
252 int error = 0, attrflag;
253
254 struct mbuf *mreq, *mrep, *md, *mb;
255 caddr_t bpos, dpos;
256 u_int32_t rmode;
257 struct nfsnode *np = VTONFS(vp);
258
259 nfsstats.rpccnt[NFSPROC_ACCESS]++;
260 mreq = nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED);
261 mb = mreq;
262 bpos = mtod(mb, caddr_t);
263 nfsm_fhtom(vp, v3);
264 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
265 *tl = txdr_unsigned(wmode);
266 nfsm_request(vp, NFSPROC_ACCESS, td, cred);
267 nfsm_postop_attr(vp, attrflag);
268 if (!error) {
269 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
270 rmode = fxdr_unsigned(u_int32_t, *tl);
271 np->n_mode = rmode;
272 np->n_modeuid = cred->cr_uid;
273 np->n_modestamp = time_second;
274 }
275 m_freem(mrep);
276 nfsmout:
277 return (error);
278 }
279
280 /*
281 * nfs access vnode op.
282 * For nfs version 2, just return ok. File accesses may fail later.
283 * For nfs version 3, use the access rpc to check accessibility. If file modes
284 * are changed on the server, accesses might still fail later.
285 */
286 static int
287 nfs_access(struct vop_access_args *ap)
288 {
289 struct vnode *vp = ap->a_vp;
290 int error = 0;
291 u_int32_t mode, wmode;
292 int v3 = NFS_ISV3(vp);
293 struct nfsnode *np = VTONFS(vp);
294
295 /*
296 * Disallow write attempts on filesystems mounted read-only;
297 * unless the file is a socket, fifo, or a block or character
298 * device resident on the filesystem.
299 */
300 if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
301 switch (vp->v_type) {
302 case VREG:
303 case VDIR:
304 case VLNK:
305 return (EROFS);
306 default:
307 break;
308 }
309 }
310 /*
311 * For nfs v3, check to see if we have done this recently, and if
312 * so return our cached result instead of making an ACCESS call.
313 * If not, do an access rpc, otherwise you are stuck emulating
314 * ufs_access() locally using the vattr. This may not be correct,
315 * since the server may apply other access criteria such as
316 * client uid-->server uid mapping that we do not know about.
317 */
318 if (v3) {
319 if (ap->a_mode & VREAD)
320 mode = NFSV3ACCESS_READ;
321 else
322 mode = 0;
323 if (vp->v_type != VDIR) {
324 if (ap->a_mode & VWRITE)
325 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
326 if (ap->a_mode & VEXEC)
327 mode |= NFSV3ACCESS_EXECUTE;
328 } else {
329 if (ap->a_mode & VWRITE)
330 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
331 NFSV3ACCESS_DELETE);
332 if (ap->a_mode & VEXEC)
333 mode |= NFSV3ACCESS_LOOKUP;
334 }
335 /* XXX safety belt, only make blanket request if caching */
336 if (nfsaccess_cache_timeout > 0) {
337 wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY |
338 NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE |
339 NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP;
340 } else {
341 wmode = mode;
342 }
343
344 /*
345 * Does our cached result allow us to give a definite yes to
346 * this request?
347 */
348 if ((time_second < (np->n_modestamp + nfsaccess_cache_timeout)) &&
349 (ap->a_cred->cr_uid == np->n_modeuid) &&
350 ((np->n_mode & mode) == mode)) {
351 nfsstats.accesscache_hits++;
352 } else {
353 /*
354 * Either a no, or a don't know. Go to the wire.
355 */
356 nfsstats.accesscache_misses++;
357 error = nfs3_access_otw(vp, wmode, ap->a_td,ap->a_cred);
358 if (!error) {
359 if ((np->n_mode & mode) != mode) {
360 error = EACCES;
361 }
362 }
363 }
364 return (error);
365 } else {
366 if ((error = nfsspec_access(ap)) != 0)
367 return (error);
368
369 /*
370 * Attempt to prevent a mapped root from accessing a file
371 * which it shouldn't. We try to read a byte from the file
372 * if the user is root and the file is not zero length.
373 * After calling nfsspec_access, we should have the correct
374 * file size cached.
375 */
376 if (ap->a_cred->cr_uid == 0 && (ap->a_mode & VREAD)
377 && VTONFS(vp)->n_size > 0) {
378 struct iovec aiov;
379 struct uio auio;
380 char buf[1];
381
382 aiov.iov_base = buf;
383 aiov.iov_len = 1;
384 auio.uio_iov = &aiov;
385 auio.uio_iovcnt = 1;
386 auio.uio_offset = 0;
387 auio.uio_resid = 1;
388 auio.uio_segflg = UIO_SYSSPACE;
389 auio.uio_rw = UIO_READ;
390 auio.uio_td = ap->a_td;
391
392 if (vp->v_type == VREG)
393 error = nfs_readrpc(vp, &auio, ap->a_cred);
394 else if (vp->v_type == VDIR) {
395 char* bp;
396 bp = malloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK);
397 aiov.iov_base = bp;
398 aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ;
399 error = nfs_readdirrpc(vp, &auio, ap->a_cred);
400 free(bp, M_TEMP);
401 } else if (vp->v_type == VLNK)
402 error = nfs_readlinkrpc(vp, &auio, ap->a_cred);
403 else
404 error = EACCES;
405 }
406 return (error);
407 }
408 }
409
410 /*
411 * nfs open vnode op
412 * Check to see if the type is ok
413 * and that deletion is not in progress.
414 * For paged in text files, you will need to flush the page cache
415 * if consistency is lost.
416 */
417 /* ARGSUSED */
418 static int
419 nfs_open(struct vop_open_args *ap)
420 {
421 struct vnode *vp = ap->a_vp;
422 struct nfsnode *np = VTONFS(vp);
423 struct vattr vattr;
424 int error;
425 int fmode = ap->a_mode;
426
427 if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
428 return (EOPNOTSUPP);
429
430 /*
431 * Get a valid lease. If cached data is stale, flush it.
432 */
433 if (np->n_flag & NMODIFIED) {
434 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
435 if (error == EINTR || error == EIO)
436 return (error);
437 np->n_attrstamp = 0;
438 if (vp->v_type == VDIR)
439 np->n_direofoffset = 0;
440 error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td);
441 if (error)
442 return (error);
443 np->n_mtime = vattr.va_mtime;
444 } else {
445 np->n_attrstamp = 0;
446 error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td);
447 if (error)
448 return (error);
449 if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
450 if (vp->v_type == VDIR)
451 np->n_direofoffset = 0;
452 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
453 if (error == EINTR || error == EIO)
454 return (error);
455 np->n_mtime = vattr.va_mtime;
456 }
457 }
458 /*
459 * If the object has >= 1 O_DIRECT active opens, we disable caching.
460 */
461 if (nfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) {
462 if (np->n_directio_opens == 0) {
463 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
464 if (error)
465 return (error);
466 np->n_flag |= NNONCACHE;
467 }
468 np->n_directio_opens++;
469 }
470 np->ra_expect_lbn = 0;
471 vnode_create_vobject_off(vp, vattr.va_size, ap->a_td);
472 return (0);
473 }
474
475 /*
476 * nfs close vnode op
477 * What an NFS client should do upon close after writing is a debatable issue.
478 * Most NFS clients push delayed writes to the server upon close, basically for
479 * two reasons:
480 * 1 - So that any write errors may be reported back to the client process
481 * doing the close system call. By far the two most likely errors are
482 * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure.
483 * 2 - To put a worst case upper bound on cache inconsistency between
484 * multiple clients for the file.
485 * There is also a consistency problem for Version 2 of the protocol w.r.t.
486 * not being able to tell if other clients are writing a file concurrently,
487 * since there is no way of knowing if the changed modify time in the reply
488 * is only due to the write for this client.
489 * (NFS Version 3 provides weak cache consistency data in the reply that
490 * should be sufficient to detect and handle this case.)
491 *
492 * The current code does the following:
493 * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers
494 * for NFS Version 3 - flush dirty buffers to the server but don't invalidate
495 * or commit them (this satisfies 1 and 2 except for the
496 * case where the server crashes after this close but
497 * before the commit RPC, which is felt to be "good
498 * enough". Changing the last argument to nfs_flush() to
499 * a 1 would force a commit operation, if it is felt a
500 * commit is necessary now.
501 */
502 /* ARGSUSED */
503 static int
504 nfs_close(struct vop_close_args *ap)
505 {
506 struct vnode *vp = ap->a_vp;
507 struct nfsnode *np = VTONFS(vp);
508 int error = 0;
509 int fmode = ap->a_fflag;
510
511 if (vp->v_type == VREG) {
512 /*
513 * Examine and clean dirty pages, regardless of NMODIFIED.
514 * This closes a major hole in close-to-open consistency.
515 * We want to push out all dirty pages (and buffers) on
516 * close, regardless of whether they were dirtied by
517 * mmap'ed writes or via write().
518 */
519 if (nfs_clean_pages_on_close && vp->v_object) {
520 VM_OBJECT_LOCK(vp->v_object);
521 vm_object_page_clean(vp->v_object, 0, 0, 0);
522 VM_OBJECT_UNLOCK(vp->v_object);
523 }
524 if (np->n_flag & NMODIFIED) {
525 if (NFS_ISV3(vp)) {
526 /*
527 * Under NFSv3 we have dirty buffers to dispose of. We
528 * must flush them to the NFS server. We have the option
529 * of waiting all the way through the commit rpc or just
530 * waiting for the initial write. The default is to only
531 * wait through the initial write so the data is in the
532 * server's cache, which is roughly similar to the state
533 * a standard disk subsystem leaves the file in on close().
534 *
535 * We cannot clear the NMODIFIED bit in np->n_flag due to
536 * potential races with other processes, and certainly
537 * cannot clear it if we don't commit.
538 */
539 int cm = nfsv3_commit_on_close ? 1 : 0;
540 error = nfs_flush(vp, MNT_WAIT, ap->a_td, cm);
541 /* np->n_flag &= ~NMODIFIED; */
542 } else
543 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
544 }
545 /*
546 * Invalidate the attribute cache in all cases.
547 * An open is going to fetch fresh attrs any way, other procs
548 * on this node that have file open will be forced to do an
549 * otw attr fetch, but this is safe.
550 */
551 np->n_attrstamp = 0;
552 if (np->n_flag & NWRITEERR) {
553 np->n_flag &= ~NWRITEERR;
554 error = np->n_error;
555 }
556 }
557 if (nfs_directio_enable)
558 KASSERT((np->n_directio_asyncwr == 0),
559 ("nfs_close: dirty unflushed (%d) directio buffers\n",
560 np->n_directio_asyncwr));
561 if (nfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) {
562 KASSERT((np->n_directio_opens > 0),
563 ("nfs_close: unexpectedly value (0) of n_directio_opens\n"));
564 np->n_directio_opens--;
565 if (np->n_directio_opens == 0)
566 np->n_flag &= ~NNONCACHE;
567 }
568 return (error);
569 }
570
571 /*
572 * nfs getattr call from vfs.
573 */
574 static int
575 nfs_getattr(struct vop_getattr_args *ap)
576 {
577 struct vnode *vp = ap->a_vp;
578 struct nfsnode *np = VTONFS(vp);
579 caddr_t bpos, dpos;
580 int error = 0;
581 struct mbuf *mreq, *mrep, *md, *mb;
582 int v3 = NFS_ISV3(vp);
583
584 /*
585 * Update local times for special files.
586 */
587 if (np->n_flag & (NACC | NUPD))
588 np->n_flag |= NCHG;
589 /*
590 * First look in the cache.
591 */
592 if (nfs_getattrcache(vp, ap->a_vap) == 0)
593 return (0);
594
595 if (v3 && nfsaccess_cache_timeout > 0) {
596 nfsstats.accesscache_misses++;
597 nfs3_access_otw(vp, NFSV3ACCESS_ALL, ap->a_td, ap->a_cred);
598 if (nfs_getattrcache(vp, ap->a_vap) == 0)
599 return (0);
600 }
601
602 nfsstats.rpccnt[NFSPROC_GETATTR]++;
603 mreq = nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3));
604 mb = mreq;
605 bpos = mtod(mb, caddr_t);
606 nfsm_fhtom(vp, v3);
607 nfsm_request(vp, NFSPROC_GETATTR, ap->a_td, ap->a_cred);
608 if (!error) {
609 nfsm_loadattr(vp, ap->a_vap);
610 }
611 m_freem(mrep);
612 nfsmout:
613 return (error);
614 }
615
616 /*
617 * nfs setattr call.
618 */
619 static int
620 nfs_setattr(struct vop_setattr_args *ap)
621 {
622 struct vnode *vp = ap->a_vp;
623 struct nfsnode *np = VTONFS(vp);
624 struct vattr *vap = ap->a_vap;
625 int error = 0;
626 u_quad_t tsize;
627
628 #ifndef nolint
629 tsize = (u_quad_t)0;
630 #endif
631
632 /*
633 * Setting of flags and marking of atimes are not supported.
634 */
635 if (vap->va_flags != VNOVAL || (vap->va_vaflags & VA_MARK_ATIME))
636 return (EOPNOTSUPP);
637
638 /*
639 * Disallow write attempts if the filesystem is mounted read-only.
640 */
641 if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
642 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
643 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
644 (vp->v_mount->mnt_flag & MNT_RDONLY))
645 return (EROFS);
646 if (vap->va_size != VNOVAL) {
647 switch (vp->v_type) {
648 case VDIR:
649 return (EISDIR);
650 case VCHR:
651 case VBLK:
652 case VSOCK:
653 case VFIFO:
654 if (vap->va_mtime.tv_sec == VNOVAL &&
655 vap->va_atime.tv_sec == VNOVAL &&
656 vap->va_mode == (mode_t)VNOVAL &&
657 vap->va_uid == (uid_t)VNOVAL &&
658 vap->va_gid == (gid_t)VNOVAL)
659 return (0);
660 vap->va_size = VNOVAL;
661 break;
662 default:
663 /*
664 * Disallow write attempts if the filesystem is
665 * mounted read-only.
666 */
667 if (vp->v_mount->mnt_flag & MNT_RDONLY)
668 return (EROFS);
669
670 /*
671 * We run vnode_pager_setsize() early (why?),
672 * we must set np->n_size now to avoid vinvalbuf
673 * V_SAVE races that might setsize a lower
674 * value.
675 */
676
677 tsize = np->n_size;
678 error = nfs_meta_setsize(vp, ap->a_cred,
679 ap->a_td, vap->va_size);
680
681 if (np->n_flag & NMODIFIED) {
682 if (vap->va_size == 0)
683 error = nfs_vinvalbuf(vp, 0, ap->a_td, 1);
684 else
685 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
686 if (error) {
687 vnode_pager_setsize(vp, np->n_size);
688 return (error);
689 }
690 }
691 /*
692 * np->n_size has already been set to vap->va_size
693 * in nfs_meta_setsize(). We must set it again since
694 * nfs_loadattrcache() could be called through
695 * nfs_meta_setsize() and could modify np->n_size.
696 */
697 np->n_vattr.va_size = np->n_size = vap->va_size;
698 };
699 } else if ((vap->va_mtime.tv_sec != VNOVAL ||
700 vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NMODIFIED) &&
701 vp->v_type == VREG &&
702 (error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1)) != 0 &&
703 (error == EINTR || error == EIO))
704 return (error);
705 error = nfs_setattrrpc(vp, vap, ap->a_cred, ap->a_td);
706 if (error && vap->va_size != VNOVAL) {
707 np->n_size = np->n_vattr.va_size = tsize;
708 vnode_pager_setsize(vp, np->n_size);
709 }
710 return (error);
711 }
712
713 /*
714 * Do an nfs setattr rpc.
715 */
716 static int
717 nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred,
718 struct thread *td)
719 {
720 struct nfsv2_sattr *sp;
721 struct nfsnode *np = VTONFS(vp);
722 caddr_t bpos, dpos;
723 u_int32_t *tl;
724 int error = 0, wccflag = NFSV3_WCCRATTR;
725 struct mbuf *mreq, *mrep, *md, *mb;
726 int v3 = NFS_ISV3(vp);
727
728 nfsstats.rpccnt[NFSPROC_SETATTR]++;
729 mreq = nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3));
730 mb = mreq;
731 bpos = mtod(mb, caddr_t);
732 nfsm_fhtom(vp, v3);
733 if (v3) {
734 nfsm_v3attrbuild(vap, TRUE);
735 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
736 *tl = nfs_false;
737 } else {
738 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
739 if (vap->va_mode == (mode_t)VNOVAL)
740 sp->sa_mode = nfs_xdrneg1;
741 else
742 sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode);
743 if (vap->va_uid == (uid_t)VNOVAL)
744 sp->sa_uid = nfs_xdrneg1;
745 else
746 sp->sa_uid = txdr_unsigned(vap->va_uid);
747 if (vap->va_gid == (gid_t)VNOVAL)
748 sp->sa_gid = nfs_xdrneg1;
749 else
750 sp->sa_gid = txdr_unsigned(vap->va_gid);
751 sp->sa_size = txdr_unsigned(vap->va_size);
752 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
753 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
754 }
755 nfsm_request(vp, NFSPROC_SETATTR, td, cred);
756 if (v3) {
757 np->n_modestamp = 0;
758 nfsm_wcc_data(vp, wccflag);
759 } else
760 nfsm_loadattr(vp, NULL);
761 m_freem(mrep);
762 nfsmout:
763 return (error);
764 }
765
766 /*
767 * nfs lookup call, one step at a time...
768 * First look in cache
769 * If not found, unlock the directory nfsnode and do the rpc
770 */
771 static int
772 nfs_lookup(struct vop_lookup_args *ap)
773 {
774 struct componentname *cnp = ap->a_cnp;
775 struct vnode *dvp = ap->a_dvp;
776 struct vnode **vpp = ap->a_vpp;
777 int flags = cnp->cn_flags;
778 struct vnode *newvp;
779 struct nfsmount *nmp;
780 caddr_t bpos, dpos;
781 struct mbuf *mreq, *mrep, *md, *mb;
782 long len;
783 nfsfh_t *fhp;
784 struct nfsnode *np;
785 int error = 0, attrflag, fhsize;
786 int v3 = NFS_ISV3(dvp);
787 struct thread *td = cnp->cn_thread;
788
789 *vpp = NULLVP;
790 if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
791 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
792 return (EROFS);
793 if (dvp->v_type != VDIR)
794 return (ENOTDIR);
795 nmp = VFSTONFS(dvp->v_mount);
796 np = VTONFS(dvp);
797 if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0) {
798 *vpp = NULLVP;
799 return (error);
800 }
801 if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) {
802 struct vattr vattr;
803
804 newvp = *vpp;
805 if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred, td)
806 && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) {
807 nfsstats.lookupcache_hits++;
808 if (cnp->cn_nameiop != LOOKUP &&
809 (flags & ISLASTCN))
810 cnp->cn_flags |= SAVENAME;
811 return (0);
812 }
813 cache_purge(newvp);
814 if (dvp != newvp)
815 vput(newvp);
816 else
817 vrele(newvp);
818 *vpp = NULLVP;
819 }
820 error = 0;
821 newvp = NULLVP;
822 nfsstats.lookupcache_misses++;
823 nfsstats.rpccnt[NFSPROC_LOOKUP]++;
824 len = cnp->cn_namelen;
825 mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP,
826 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
827 mb = mreq;
828 bpos = mtod(mb, caddr_t);
829 nfsm_fhtom(dvp, v3);
830 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
831 nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_thread, cnp->cn_cred);
832 if (error) {
833 if (v3) {
834 nfsm_postop_attr(dvp, attrflag);
835 m_freem(mrep);
836 }
837 goto nfsmout;
838 }
839 nfsm_getfh(fhp, fhsize, v3);
840
841 /*
842 * Handle RENAME case...
843 */
844 if (cnp->cn_nameiop == RENAME && (flags & ISLASTCN)) {
845 if (NFS_CMPFH(np, fhp, fhsize)) {
846 m_freem(mrep);
847 return (EISDIR);
848 }
849 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
850 if (error) {
851 m_freem(mrep);
852 return (error);
853 }
854 newvp = NFSTOV(np);
855 if (v3) {
856 nfsm_postop_attr(newvp, attrflag);
857 nfsm_postop_attr(dvp, attrflag);
858 } else
859 nfsm_loadattr(newvp, NULL);
860 *vpp = newvp;
861 m_freem(mrep);
862 cnp->cn_flags |= SAVENAME;
863 return (0);
864 }
865
866 if (flags & ISDOTDOT) {
867 VOP_UNLOCK(dvp, 0, td);
868 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, cnp->cn_lkflags);
869 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
870 if (error)
871 return (error);
872 newvp = NFSTOV(np);
873 } else if (NFS_CMPFH(np, fhp, fhsize)) {
874 VREF(dvp);
875 newvp = dvp;
876 } else {
877 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, cnp->cn_lkflags);
878 if (error) {
879 m_freem(mrep);
880 return (error);
881 }
882 newvp = NFSTOV(np);
883 }
884 if (v3) {
885 nfsm_postop_attr(newvp, attrflag);
886 nfsm_postop_attr(dvp, attrflag);
887 } else
888 nfsm_loadattr(newvp, NULL);
889 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
890 cnp->cn_flags |= SAVENAME;
891 if ((cnp->cn_flags & MAKEENTRY) &&
892 (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) {
893 np->n_ctime = np->n_vattr.va_ctime.tv_sec;
894 cache_enter(dvp, newvp, cnp);
895 }
896 *vpp = newvp;
897 m_freem(mrep);
898 nfsmout:
899 if (error) {
900 if (newvp != NULLVP) {
901 vput(newvp);
902 *vpp = NULLVP;
903 }
904 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
905 (flags & ISLASTCN) && error == ENOENT) {
906 if (dvp->v_mount->mnt_flag & MNT_RDONLY)
907 error = EROFS;
908 else
909 error = EJUSTRETURN;
910 }
911 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
912 cnp->cn_flags |= SAVENAME;
913 }
914 return (error);
915 }
916
917 /*
918 * nfs read call.
919 * Just call nfs_bioread() to do the work.
920 */
921 static int
922 nfs_read(struct vop_read_args *ap)
923 {
924 struct vnode *vp = ap->a_vp;
925
926 switch (vp->v_type) {
927 case VREG:
928 return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
929 case VDIR:
930 return (EISDIR);
931 default:
932 return (EOPNOTSUPP);
933 }
934 }
935
936 /*
937 * nfs readlink call
938 */
939 static int
940 nfs_readlink(struct vop_readlink_args *ap)
941 {
942 struct vnode *vp = ap->a_vp;
943
944 if (vp->v_type != VLNK)
945 return (EINVAL);
946 return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred));
947 }
948
949 /*
950 * Do a readlink rpc.
951 * Called by nfs_doio() from below the buffer cache.
952 */
953 int
954 nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
955 {
956 caddr_t bpos, dpos;
957 int error = 0, len, attrflag;
958 struct mbuf *mreq, *mrep, *md, *mb;
959 int v3 = NFS_ISV3(vp);
960
961 nfsstats.rpccnt[NFSPROC_READLINK]++;
962 mreq = nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3));
963 mb = mreq;
964 bpos = mtod(mb, caddr_t);
965 nfsm_fhtom(vp, v3);
966 nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, cred);
967 if (v3)
968 nfsm_postop_attr(vp, attrflag);
969 if (!error) {
970 nfsm_strsiz(len, NFS_MAXPATHLEN);
971 if (len == NFS_MAXPATHLEN) {
972 struct nfsnode *np = VTONFS(vp);
973 if (np->n_size && np->n_size < NFS_MAXPATHLEN)
974 len = np->n_size;
975 }
976 nfsm_mtouio(uiop, len);
977 }
978 m_freem(mrep);
979 nfsmout:
980 return (error);
981 }
982
983 /*
984 * nfs read rpc call
985 * Ditto above
986 */
987 int
988 nfs_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
989 {
990 u_int32_t *tl;
991 caddr_t bpos, dpos;
992 struct mbuf *mreq, *mrep, *md, *mb;
993 struct nfsmount *nmp;
994 int error = 0, len, retlen, tsiz, eof, attrflag;
995 int v3 = NFS_ISV3(vp);
996
997 #ifndef nolint
998 eof = 0;
999 #endif
1000 nmp = VFSTONFS(vp->v_mount);
1001 tsiz = uiop->uio_resid;
1002 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
1003 return (EFBIG);
1004 while (tsiz > 0) {
1005 nfsstats.rpccnt[NFSPROC_READ]++;
1006 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
1007 mreq = nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3);
1008 mb = mreq;
1009 bpos = mtod(mb, caddr_t);
1010 nfsm_fhtom(vp, v3);
1011 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED * 3);
1012 if (v3) {
1013 txdr_hyper(uiop->uio_offset, tl);
1014 *(tl + 2) = txdr_unsigned(len);
1015 } else {
1016 *tl++ = txdr_unsigned(uiop->uio_offset);
1017 *tl++ = txdr_unsigned(len);
1018 *tl = 0;
1019 }
1020 nfsm_request(vp, NFSPROC_READ, uiop->uio_td, cred);
1021 if (v3) {
1022 nfsm_postop_attr(vp, attrflag);
1023 if (error) {
1024 m_freem(mrep);
1025 goto nfsmout;
1026 }
1027 tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED);
1028 eof = fxdr_unsigned(int, *(tl + 1));
1029 } else
1030 nfsm_loadattr(vp, NULL);
1031 nfsm_strsiz(retlen, nmp->nm_rsize);
1032 nfsm_mtouio(uiop, retlen);
1033 m_freem(mrep);
1034 tsiz -= retlen;
1035 if (v3) {
1036 if (eof || retlen == 0) {
1037 tsiz = 0;
1038 }
1039 } else if (retlen < len) {
1040 tsiz = 0;
1041 }
1042 }
1043 nfsmout:
1044 return (error);
1045 }
1046
1047 /*
1048 * nfs write call
1049 */
1050 int
1051 nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
1052 int *iomode, int *must_commit)
1053 {
1054 u_int32_t *tl;
1055 int32_t backup;
1056 caddr_t bpos, dpos;
1057 struct mbuf *mreq, *mrep, *md, *mb;
1058 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
1059 int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit;
1060 int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC;
1061
1062 #ifndef DIAGNOSTIC
1063 if (uiop->uio_iovcnt != 1)
1064 panic("nfs: writerpc iovcnt > 1");
1065 #endif
1066 *must_commit = 0;
1067 tsiz = uiop->uio_resid;
1068 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
1069 return (EFBIG);
1070 while (tsiz > 0) {
1071 nfsstats.rpccnt[NFSPROC_WRITE]++;
1072 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
1073 mreq = nfsm_reqhead(vp, NFSPROC_WRITE,
1074 NFSX_FH(v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len));
1075 mb = mreq;
1076 bpos = mtod(mb, caddr_t);
1077 nfsm_fhtom(vp, v3);
1078 if (v3) {
1079 tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED);
1080 txdr_hyper(uiop->uio_offset, tl);
1081 tl += 2;
1082 *tl++ = txdr_unsigned(len);
1083 *tl++ = txdr_unsigned(*iomode);
1084 *tl = txdr_unsigned(len);
1085 } else {
1086 u_int32_t x;
1087
1088 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
1089 /* Set both "begin" and "current" to non-garbage. */
1090 x = txdr_unsigned((u_int32_t)uiop->uio_offset);
1091 *tl++ = x; /* "begin offset" */
1092 *tl++ = x; /* "current offset" */
1093 x = txdr_unsigned(len);
1094 *tl++ = x; /* total to this offset */
1095 *tl = x; /* size of this write */
1096 }
1097 nfsm_uiotom(uiop, len);
1098 nfsm_request(vp, NFSPROC_WRITE, uiop->uio_td, cred);
1099 if (v3) {
1100 wccflag = NFSV3_WCCCHK;
1101 nfsm_wcc_data(vp, wccflag);
1102 if (!error) {
1103 tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED
1104 + NFSX_V3WRITEVERF);
1105 rlen = fxdr_unsigned(int, *tl++);
1106 if (rlen == 0) {
1107 error = NFSERR_IO;
1108 m_freem(mrep);
1109 break;
1110 } else if (rlen < len) {
1111 backup = len - rlen;
1112 uiop->uio_iov->iov_base =
1113 (char *)uiop->uio_iov->iov_base -
1114 backup;
1115 uiop->uio_iov->iov_len += backup;
1116 uiop->uio_offset -= backup;
1117 uiop->uio_resid += backup;
1118 len = rlen;
1119 }
1120 commit = fxdr_unsigned(int, *tl++);
1121
1122 /*
1123 * Return the lowest committment level
1124 * obtained by any of the RPCs.
1125 */
1126 if (committed == NFSV3WRITE_FILESYNC)
1127 committed = commit;
1128 else if (committed == NFSV3WRITE_DATASYNC &&
1129 commit == NFSV3WRITE_UNSTABLE)
1130 committed = commit;
1131 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){
1132 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
1133 NFSX_V3WRITEVERF);
1134 nmp->nm_state |= NFSSTA_HASWRITEVERF;
1135 } else if (bcmp((caddr_t)tl,
1136 (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) {
1137 *must_commit = 1;
1138 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
1139 NFSX_V3WRITEVERF);
1140 }
1141 }
1142 } else
1143 nfsm_loadattr(vp, NULL);
1144 if (wccflag)
1145 VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime;
1146 m_freem(mrep);
1147 if (error)
1148 break;
1149 tsiz -= len;
1150 }
1151 nfsmout:
1152 if (vp->v_mount->mnt_flag & MNT_ASYNC)
1153 committed = NFSV3WRITE_FILESYNC;
1154 *iomode = committed;
1155 if (error)
1156 uiop->uio_resid = tsiz;
1157 return (error);
1158 }
1159
1160 /*
1161 * nfs mknod rpc
1162 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
1163 * mode set to specify the file type and the size field for rdev.
1164 */
1165 static int
1166 nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
1167 struct vattr *vap)
1168 {
1169 struct nfsv2_sattr *sp;
1170 u_int32_t *tl;
1171 struct vnode *newvp = NULL;
1172 struct nfsnode *np = NULL;
1173 struct vattr vattr;
1174 caddr_t bpos, dpos;
1175 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0;
1176 struct mbuf *mreq, *mrep, *md, *mb;
1177 u_int32_t rdev;
1178 int v3 = NFS_ISV3(dvp);
1179
1180 if (vap->va_type == VCHR || vap->va_type == VBLK)
1181 rdev = txdr_unsigned(vap->va_rdev);
1182 else if (vap->va_type == VFIFO || vap->va_type == VSOCK)
1183 rdev = nfs_xdrneg1;
1184 else {
1185 return (EOPNOTSUPP);
1186 }
1187 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_thread)) != 0) {
1188 return (error);
1189 }
1190 nfsstats.rpccnt[NFSPROC_MKNOD]++;
1191 mreq = nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED +
1192 + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
1193 mb = mreq;
1194 bpos = mtod(mb, caddr_t);
1195 nfsm_fhtom(dvp, v3);
1196 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1197 if (v3) {
1198 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
1199 *tl++ = vtonfsv3_type(vap->va_type);
1200 nfsm_v3attrbuild(vap, FALSE);
1201 if (vap->va_type == VCHR || vap->va_type == VBLK) {
1202 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
1203 *tl++ = txdr_unsigned(umajor(vap->va_rdev));
1204 *tl = txdr_unsigned(uminor(vap->va_rdev));
1205 }
1206 } else {
1207 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
1208 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1209 sp->sa_uid = nfs_xdrneg1;
1210 sp->sa_gid = nfs_xdrneg1;
1211 sp->sa_size = rdev;
1212 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1213 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1214 }
1215 nfsm_request(dvp, NFSPROC_MKNOD, cnp->cn_thread, cnp->cn_cred);
1216 if (!error) {
1217 nfsm_mtofh(dvp, newvp, v3, gotvp);
1218 if (!gotvp) {
1219 if (newvp) {
1220 vput(newvp);
1221 newvp = NULL;
1222 }
1223 error = nfs_lookitup(dvp, cnp->cn_nameptr,
1224 cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np);
1225 if (!error)
1226 newvp = NFSTOV(np);
1227 }
1228 }
1229 if (v3)
1230 nfsm_wcc_data(dvp, wccflag);
1231 m_freem(mrep);
1232 nfsmout:
1233 if (error) {
1234 if (newvp)
1235 vput(newvp);
1236 } else {
1237 if (cnp->cn_flags & MAKEENTRY)
1238 cache_enter(dvp, newvp, cnp);
1239 *vpp = newvp;
1240 }
1241 VTONFS(dvp)->n_flag |= NMODIFIED;
1242 if (!wccflag)
1243 VTONFS(dvp)->n_attrstamp = 0;
1244 return (error);
1245 }
1246
1247 /*
1248 * nfs mknod vop
1249 * just call nfs_mknodrpc() to do the work.
1250 */
1251 /* ARGSUSED */
1252 static int
1253 nfs_mknod(struct vop_mknod_args *ap)
1254 {
1255
1256 return (nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap));
1257 }
1258
1259 static u_long create_verf;
1260 /*
1261 * nfs file create call
1262 */
1263 static int
1264 nfs_create(struct vop_create_args *ap)
1265 {
1266 struct vnode *dvp = ap->a_dvp;
1267 struct vattr *vap = ap->a_vap;
1268 struct componentname *cnp = ap->a_cnp;
1269 struct nfsv2_sattr *sp;
1270 u_int32_t *tl;
1271 struct nfsnode *np = NULL;
1272 struct vnode *newvp = NULL;
1273 caddr_t bpos, dpos;
1274 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0;
1275 struct mbuf *mreq, *mrep, *md, *mb;
1276 struct vattr vattr;
1277 int v3 = NFS_ISV3(dvp);
1278
1279 /*
1280 * Oops, not for me..
1281 */
1282 if (vap->va_type == VSOCK)
1283 return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap));
1284
1285 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_thread)) != 0) {
1286 return (error);
1287 }
1288 if (vap->va_vaflags & VA_EXCLUSIVE)
1289 fmode |= O_EXCL;
1290 again:
1291 nfsstats.rpccnt[NFSPROC_CREATE]++;
1292 mreq = nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED +
1293 nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
1294 mb = mreq;
1295 bpos = mtod(mb, caddr_t);
1296 nfsm_fhtom(dvp, v3);
1297 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1298 if (v3) {
1299 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
1300 if (fmode & O_EXCL) {
1301 *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
1302 tl = nfsm_build(u_int32_t *, NFSX_V3CREATEVERF);
1303 #ifdef INET
1304 if (!TAILQ_EMPTY(&in_ifaddrhead))
1305 *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr;
1306 else
1307 #endif
1308 *tl++ = create_verf;
1309 *tl = ++create_verf;
1310 } else {
1311 *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED);
1312 nfsm_v3attrbuild(vap, FALSE);
1313 }
1314 } else {
1315 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
1316 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1317 sp->sa_uid = nfs_xdrneg1;
1318 sp->sa_gid = nfs_xdrneg1;
1319 sp->sa_size = 0;
1320 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1321 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1322 }
1323 nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_thread, cnp->cn_cred);
1324 if (!error) {
1325 nfsm_mtofh(dvp, newvp, v3, gotvp);
1326 if (!gotvp) {
1327 if (newvp) {
1328 vput(newvp);
1329 newvp = NULL;
1330 }
1331 error = nfs_lookitup(dvp, cnp->cn_nameptr,
1332 cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np);
1333 if (!error)
1334 newvp = NFSTOV(np);
1335 }
1336 }
1337 if (v3)
1338 nfsm_wcc_data(dvp, wccflag);
1339 m_freem(mrep);
1340 nfsmout:
1341 if (error) {
1342 if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) {
1343 fmode &= ~O_EXCL;
1344 goto again;
1345 }
1346 if (newvp)
1347 vput(newvp);
1348 } else if (v3 && (fmode & O_EXCL)) {
1349 /*
1350 * We are normally called with only a partially initialized
1351 * VAP. Since the NFSv3 spec says that server may use the
1352 * file attributes to store the verifier, the spec requires
1353 * us to do a SETATTR RPC. FreeBSD servers store the verifier
1354 * in atime, but we can't really assume that all servers will
1355 * so we ensure that our SETATTR sets both atime and mtime.
1356 */
1357 if (vap->va_mtime.tv_sec == VNOVAL)
1358 vfs_timestamp(&vap->va_mtime);
1359 if (vap->va_atime.tv_sec == VNOVAL)
1360 vap->va_atime = vap->va_mtime;
1361 error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_thread);
1362 if (error)
1363 vput(newvp);
1364 }
1365 if (!error) {
1366 if (cnp->cn_flags & MAKEENTRY)
1367 cache_enter(dvp, newvp, cnp);
1368 *ap->a_vpp = newvp;
1369 }
1370 VTONFS(dvp)->n_flag |= NMODIFIED;
1371 if (!wccflag)
1372 VTONFS(dvp)->n_attrstamp = 0;
1373 return (error);
1374 }
1375
1376 /*
1377 * nfs file remove call
1378 * To try and make nfs semantics closer to ufs semantics, a file that has
1379 * other processes using the vnode is renamed instead of removed and then
1380 * removed later on the last close.
1381 * - If v_usecount > 1
1382 * If a rename is not already in the works
1383 * call nfs_sillyrename() to set it up
1384 * else
1385 * do the remove rpc
1386 */
1387 static int
1388 nfs_remove(struct vop_remove_args *ap)
1389 {
1390 struct vnode *vp = ap->a_vp;
1391 struct vnode *dvp = ap->a_dvp;
1392 struct componentname *cnp = ap->a_cnp;
1393 struct nfsnode *np = VTONFS(vp);
1394 int error = 0;
1395 struct vattr vattr;
1396
1397 #ifndef DIAGNOSTIC
1398 if ((cnp->cn_flags & HASBUF) == 0)
1399 panic("nfs_remove: no name");
1400 if (vrefcnt(vp) < 1)
1401 panic("nfs_remove: bad v_usecount");
1402 #endif
1403 if (vp->v_type == VDIR)
1404 error = EPERM;
1405 else if (vrefcnt(vp) == 1 || (np->n_sillyrename &&
1406 VOP_GETATTR(vp, &vattr, cnp->cn_cred, cnp->cn_thread) == 0 &&
1407 vattr.va_nlink > 1)) {
1408 /*
1409 * Purge the name cache so that the chance of a lookup for
1410 * the name succeeding while the remove is in progress is
1411 * minimized. Without node locking it can still happen, such
1412 * that an I/O op returns ESTALE, but since you get this if
1413 * another host removes the file..
1414 */
1415 cache_purge(vp);
1416 /*
1417 * throw away biocache buffers, mainly to avoid
1418 * unnecessary delayed writes later.
1419 */
1420 error = nfs_vinvalbuf(vp, 0, cnp->cn_thread, 1);
1421 /* Do the rpc */
1422 if (error != EINTR && error != EIO)
1423 error = nfs_removerpc(dvp, cnp->cn_nameptr,
1424 cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread);
1425 /*
1426 * Kludge City: If the first reply to the remove rpc is lost..
1427 * the reply to the retransmitted request will be ENOENT
1428 * since the file was in fact removed
1429 * Therefore, we cheat and return success.
1430 */
1431 if (error == ENOENT)
1432 error = 0;
1433 } else if (!np->n_sillyrename)
1434 error = nfs_sillyrename(dvp, vp, cnp);
1435 np->n_attrstamp = 0;
1436 return (error);
1437 }
1438
1439 /*
1440 * nfs file remove rpc called from nfs_inactive
1441 */
1442 int
1443 nfs_removeit(struct sillyrename *sp)
1444 {
1445
1446 /*
1447 * Make sure that the directory vnode is still valid.
1448 * XXX we should lock sp->s_dvp here.
1449 */
1450 if (sp->s_dvp->v_type == VBAD)
1451 return (0);
1452 return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred,
1453 NULL));
1454 }
1455
1456 /*
1457 * Nfs remove rpc, called from nfs_remove() and nfs_removeit().
1458 */
1459 static int
1460 nfs_removerpc(struct vnode *dvp, const char *name, int namelen,
1461 struct ucred *cred, struct thread *td)
1462 {
1463 caddr_t bpos, dpos;
1464 int error = 0, wccflag = NFSV3_WCCRATTR;
1465 struct mbuf *mreq, *mrep, *md, *mb;
1466 int v3 = NFS_ISV3(dvp);
1467
1468 nfsstats.rpccnt[NFSPROC_REMOVE]++;
1469 mreq = nfsm_reqhead(dvp, NFSPROC_REMOVE,
1470 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen));
1471 mb = mreq;
1472 bpos = mtod(mb, caddr_t);
1473 nfsm_fhtom(dvp, v3);
1474 nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
1475 nfsm_request(dvp, NFSPROC_REMOVE, td, cred);
1476 if (v3)
1477 nfsm_wcc_data(dvp, wccflag);
1478 m_freem(mrep);
1479 nfsmout:
1480 VTONFS(dvp)->n_flag |= NMODIFIED;
1481 if (!wccflag)
1482 VTONFS(dvp)->n_attrstamp = 0;
1483 return (error);
1484 }
1485
1486 /*
1487 * nfs file rename call
1488 */
1489 static int
1490 nfs_rename(struct vop_rename_args *ap)
1491 {
1492 struct vnode *fvp = ap->a_fvp;
1493 struct vnode *tvp = ap->a_tvp;
1494 struct vnode *fdvp = ap->a_fdvp;
1495 struct vnode *tdvp = ap->a_tdvp;
1496 struct componentname *tcnp = ap->a_tcnp;
1497 struct componentname *fcnp = ap->a_fcnp;
1498 int error;
1499
1500 #ifndef DIAGNOSTIC
1501 if ((tcnp->cn_flags & HASBUF) == 0 ||
1502 (fcnp->cn_flags & HASBUF) == 0)
1503 panic("nfs_rename: no name");
1504 #endif
1505 /* Check for cross-device rename */
1506 if ((fvp->v_mount != tdvp->v_mount) ||
1507 (tvp && (fvp->v_mount != tvp->v_mount))) {
1508 error = EXDEV;
1509 goto out;
1510 }
1511
1512 if (fvp == tvp) {
1513 printf("nfs_rename: fvp == tvp (can't happen)\n");
1514 error = 0;
1515 goto out;
1516 }
1517 if ((error = vn_lock(fvp, LK_EXCLUSIVE, fcnp->cn_thread)) != 0)
1518 goto out;
1519
1520 /*
1521 * We have to flush B_DELWRI data prior to renaming
1522 * the file. If we don't, the delayed-write buffers
1523 * can be flushed out later after the file has gone stale
1524 * under NFSV3. NFSV2 does not have this problem because
1525 * ( as far as I can tell ) it flushes dirty buffers more
1526 * often.
1527 *
1528 * Skip the rename operation if the fsync fails, this can happen
1529 * due to the server's volume being full, when we pushed out data
1530 * that was written back to our cache earlier. Not checking for
1531 * this condition can result in potential (silent) data loss.
1532 */
1533 error = VOP_FSYNC(fvp, MNT_WAIT, fcnp->cn_thread);
1534 VOP_UNLOCK(fvp, 0, fcnp->cn_thread);
1535 if (!error && tvp)
1536 error = VOP_FSYNC(tvp, MNT_WAIT, tcnp->cn_thread);
1537 if (error)
1538 goto out;
1539
1540 /*
1541 * If the tvp exists and is in use, sillyrename it before doing the
1542 * rename of the new file over it.
1543 * XXX Can't sillyrename a directory.
1544 */
1545 if (tvp && vrefcnt(tvp) > 1 && !VTONFS(tvp)->n_sillyrename &&
1546 tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) {
1547 vput(tvp);
1548 tvp = NULL;
1549 }
1550
1551 error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
1552 tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred,
1553 tcnp->cn_thread);
1554
1555 if (fvp->v_type == VDIR) {
1556 if (tvp != NULL && tvp->v_type == VDIR)
1557 cache_purge(tdvp);
1558 cache_purge(fdvp);
1559 }
1560
1561 out:
1562 if (tdvp == tvp)
1563 vrele(tdvp);
1564 else
1565 vput(tdvp);
1566 if (tvp)
1567 vput(tvp);
1568 vrele(fdvp);
1569 vrele(fvp);
1570 /*
1571 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
1572 */
1573 if (error == ENOENT)
1574 error = 0;
1575 return (error);
1576 }
1577
1578 /*
1579 * nfs file rename rpc called from nfs_remove() above
1580 */
1581 static int
1582 nfs_renameit(struct vnode *sdvp, struct componentname *scnp,
1583 struct sillyrename *sp)
1584 {
1585
1586 return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, sdvp,
1587 sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread));
1588 }
1589
1590 /*
1591 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit().
1592 */
1593 static int
1594 nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen,
1595 struct vnode *tdvp, const char *tnameptr, int tnamelen, struct ucred *cred,
1596 struct thread *td)
1597 {
1598 caddr_t bpos, dpos;
1599 int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
1600 struct mbuf *mreq, *mrep, *md, *mb;
1601 int v3 = NFS_ISV3(fdvp);
1602
1603 nfsstats.rpccnt[NFSPROC_RENAME]++;
1604 mreq = nfsm_reqhead(fdvp, NFSPROC_RENAME,
1605 (NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) +
1606 nfsm_rndup(tnamelen));
1607 mb = mreq;
1608 bpos = mtod(mb, caddr_t);
1609 nfsm_fhtom(fdvp, v3);
1610 nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN);
1611 nfsm_fhtom(tdvp, v3);
1612 nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN);
1613 nfsm_request(fdvp, NFSPROC_RENAME, td, cred);
1614 if (v3) {
1615 nfsm_wcc_data(fdvp, fwccflag);
1616 nfsm_wcc_data(tdvp, twccflag);
1617 }
1618 m_freem(mrep);
1619 nfsmout:
1620 VTONFS(fdvp)->n_flag |= NMODIFIED;
1621 VTONFS(tdvp)->n_flag |= NMODIFIED;
1622 if (!fwccflag)
1623 VTONFS(fdvp)->n_attrstamp = 0;
1624 if (!twccflag)
1625 VTONFS(tdvp)->n_attrstamp = 0;
1626 return (error);
1627 }
1628
1629 /*
1630 * nfs hard link create call
1631 */
1632 static int
1633 nfs_link(struct vop_link_args *ap)
1634 {
1635 struct vnode *vp = ap->a_vp;
1636 struct vnode *tdvp = ap->a_tdvp;
1637 struct componentname *cnp = ap->a_cnp;
1638 caddr_t bpos, dpos;
1639 int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
1640 struct mbuf *mreq, *mrep, *md, *mb;
1641 int v3;
1642
1643 if (vp->v_mount != tdvp->v_mount) {
1644 return (EXDEV);
1645 }
1646
1647 /*
1648 * Push all writes to the server, so that the attribute cache
1649 * doesn't get "out of sync" with the server.
1650 * XXX There should be a better way!
1651 */
1652 VOP_FSYNC(vp, MNT_WAIT, cnp->cn_thread);
1653
1654 v3 = NFS_ISV3(vp);
1655 nfsstats.rpccnt[NFSPROC_LINK]++;
1656 mreq = nfsm_reqhead(vp, NFSPROC_LINK,
1657 NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
1658 mb = mreq;
1659 bpos = mtod(mb, caddr_t);
1660 nfsm_fhtom(vp, v3);
1661 nfsm_fhtom(tdvp, v3);
1662 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1663 nfsm_request(vp, NFSPROC_LINK, cnp->cn_thread, cnp->cn_cred);
1664 if (v3) {
1665 nfsm_postop_attr(vp, attrflag);
1666 nfsm_wcc_data(tdvp, wccflag);
1667 }
1668 m_freem(mrep);
1669 nfsmout:
1670 VTONFS(tdvp)->n_flag |= NMODIFIED;
1671 if (!attrflag)
1672 VTONFS(vp)->n_attrstamp = 0;
1673 if (!wccflag)
1674 VTONFS(tdvp)->n_attrstamp = 0;
1675 return (error);
1676 }
1677
1678 /*
1679 * nfs symbolic link create call
1680 */
1681 static int
1682 nfs_symlink(struct vop_symlink_args *ap)
1683 {
1684 struct vnode *dvp = ap->a_dvp;
1685 struct vattr *vap = ap->a_vap;
1686 struct componentname *cnp = ap->a_cnp;
1687 struct nfsv2_sattr *sp;
1688 caddr_t bpos, dpos;
1689 int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
1690 struct mbuf *mreq, *mrep, *md, *mb;
1691 struct vnode *newvp = NULL;
1692 int v3 = NFS_ISV3(dvp);
1693
1694 nfsstats.rpccnt[NFSPROC_SYMLINK]++;
1695 slen = strlen(ap->a_target);
1696 mreq = nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED +
1697 nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3));
1698 mb = mreq;
1699 bpos = mtod(mb, caddr_t);
1700 nfsm_fhtom(dvp, v3);
1701 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1702 if (v3) {
1703 nfsm_v3attrbuild(vap, FALSE);
1704 }
1705 nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN);
1706 if (!v3) {
1707 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
1708 sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode);
1709 sp->sa_uid = nfs_xdrneg1;
1710 sp->sa_gid = nfs_xdrneg1;
1711 sp->sa_size = nfs_xdrneg1;
1712 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1713 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1714 }
1715
1716 /*
1717 * Issue the NFS request and get the rpc response.
1718 *
1719 * Only NFSv3 responses returning an error of 0 actually return
1720 * a file handle that can be converted into newvp without having
1721 * to do an extra lookup rpc.
1722 */
1723 nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_thread, cnp->cn_cred);
1724 if (v3) {
1725 if (error == 0)
1726 nfsm_mtofh(dvp, newvp, v3, gotvp);
1727 nfsm_wcc_data(dvp, wccflag);
1728 }
1729
1730 /*
1731 * out code jumps -> here, mrep is also freed.
1732 */
1733
1734 m_freem(mrep);
1735 nfsmout:
1736
1737 /*
1738 * If we do not have an error and we could not extract the newvp from
1739 * the response due to the request being NFSv2, we have to do a
1740 * lookup in order to obtain a newvp to return.
1741 */
1742 if (error == 0 && newvp == NULL) {
1743 struct nfsnode *np = NULL;
1744
1745 error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
1746 cnp->cn_cred, cnp->cn_thread, &np);
1747 if (!error)
1748 newvp = NFSTOV(np);
1749 }
1750 if (error) {
1751 if (newvp)
1752 vput(newvp);
1753 } else {
1754 *ap->a_vpp = newvp;
1755 }
1756 VTONFS(dvp)->n_flag |= NMODIFIED;
1757 if (!wccflag)
1758 VTONFS(dvp)->n_attrstamp = 0;
1759 return (error);
1760 }
1761
1762 /*
1763 * nfs make dir call
1764 */
1765 static int
1766 nfs_mkdir(struct vop_mkdir_args *ap)
1767 {
1768 struct vnode *dvp = ap->a_dvp;
1769 struct vattr *vap = ap->a_vap;
1770 struct componentname *cnp = ap->a_cnp;
1771 struct nfsv2_sattr *sp;
1772 int len;
1773 struct nfsnode *np = NULL;
1774 struct vnode *newvp = NULL;
1775 caddr_t bpos, dpos;
1776 int error = 0, wccflag = NFSV3_WCCRATTR;
1777 int gotvp = 0;
1778 struct mbuf *mreq, *mrep, *md, *mb;
1779 struct vattr vattr;
1780 int v3 = NFS_ISV3(dvp);
1781
1782 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_thread)) != 0) {
1783 return (error);
1784 }
1785 len = cnp->cn_namelen;
1786 nfsstats.rpccnt[NFSPROC_MKDIR]++;
1787 mreq = nfsm_reqhead(dvp, NFSPROC_MKDIR,
1788 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3));
1789 mb = mreq;
1790 bpos = mtod(mb, caddr_t);
1791 nfsm_fhtom(dvp, v3);
1792 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
1793 if (v3) {
1794 nfsm_v3attrbuild(vap, FALSE);
1795 } else {
1796 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
1797 sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode);
1798 sp->sa_uid = nfs_xdrneg1;
1799 sp->sa_gid = nfs_xdrneg1;
1800 sp->sa_size = nfs_xdrneg1;
1801 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1802 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1803 }
1804 nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_thread, cnp->cn_cred);
1805 if (!error)
1806 nfsm_mtofh(dvp, newvp, v3, gotvp);
1807 if (v3)
1808 nfsm_wcc_data(dvp, wccflag);
1809 m_freem(mrep);
1810 nfsmout:
1811 VTONFS(dvp)->n_flag |= NMODIFIED;
1812 if (!wccflag)
1813 VTONFS(dvp)->n_attrstamp = 0;
1814 if (error == 0 && newvp == NULL) {
1815 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred,
1816 cnp->cn_thread, &np);
1817 if (!error) {
1818 newvp = NFSTOV(np);
1819 if (newvp->v_type != VDIR)
1820 error = EEXIST;
1821 }
1822 }
1823 if (error) {
1824 if (newvp)
1825 vput(newvp);
1826 } else
1827 *ap->a_vpp = newvp;
1828 return (error);
1829 }
1830
1831 /*
1832 * nfs remove directory call
1833 */
1834 static int
1835 nfs_rmdir(struct vop_rmdir_args *ap)
1836 {
1837 struct vnode *vp = ap->a_vp;
1838 struct vnode *dvp = ap->a_dvp;
1839 struct componentname *cnp = ap->a_cnp;
1840 caddr_t bpos, dpos;
1841 int error = 0, wccflag = NFSV3_WCCRATTR;
1842 struct mbuf *mreq, *mrep, *md, *mb;
1843 int v3 = NFS_ISV3(dvp);
1844
1845 if (dvp == vp)
1846 return (EINVAL);
1847 nfsstats.rpccnt[NFSPROC_RMDIR]++;
1848 mreq = nfsm_reqhead(dvp, NFSPROC_RMDIR,
1849 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
1850 mb = mreq;
1851 bpos = mtod(mb, caddr_t);
1852 nfsm_fhtom(dvp, v3);
1853 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1854 nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_thread, cnp->cn_cred);
1855 if (v3)
1856 nfsm_wcc_data(dvp, wccflag);
1857 m_freem(mrep);
1858 nfsmout:
1859 VTONFS(dvp)->n_flag |= NMODIFIED;
1860 if (!wccflag)
1861 VTONFS(dvp)->n_attrstamp = 0;
1862 cache_purge(dvp);
1863 cache_purge(vp);
1864 /*
1865 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
1866 */
1867 if (error == ENOENT)
1868 error = 0;
1869 return (error);
1870 }
1871
1872 /*
1873 * nfs readdir call
1874 */
1875 static int
1876 nfs_readdir(struct vop_readdir_args *ap)
1877 {
1878 struct vnode *vp = ap->a_vp;
1879 struct nfsnode *np = VTONFS(vp);
1880 struct uio *uio = ap->a_uio;
1881 int tresid, error;
1882 struct vattr vattr;
1883
1884 if (vp->v_type != VDIR)
1885 return (EPERM);
1886 /*
1887 * First, check for hit on the EOF offset cache
1888 */
1889 if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset &&
1890 (np->n_flag & NMODIFIED) == 0) {
1891 if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_td) == 0 &&
1892 !NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
1893 nfsstats.direofcache_hits++;
1894 return (0);
1895 }
1896 }
1897
1898 /*
1899 * Call nfs_bioread() to do the real work.
1900 */
1901 tresid = uio->uio_resid;
1902 error = nfs_bioread(vp, uio, 0, ap->a_cred);
1903
1904 if (!error && uio->uio_resid == tresid)
1905 nfsstats.direofcache_misses++;
1906 return (error);
1907 }
1908
1909 /*
1910 * Readdir rpc call.
1911 * Called from below the buffer cache by nfs_doio().
1912 */
1913 int
1914 nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
1915 {
1916 int len, left;
1917 struct dirent *dp = NULL;
1918 u_int32_t *tl;
1919 caddr_t cp;
1920 nfsuint64 *cookiep;
1921 caddr_t bpos, dpos;
1922 struct mbuf *mreq, *mrep, *md, *mb;
1923 nfsuint64 cookie;
1924 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
1925 struct nfsnode *dnp = VTONFS(vp);
1926 u_quad_t fileno;
1927 int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1;
1928 int attrflag;
1929 int v3 = NFS_ISV3(vp);
1930
1931 #ifndef DIAGNOSTIC
1932 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) ||
1933 (uiop->uio_resid & (DIRBLKSIZ - 1)))
1934 panic("nfs readdirrpc bad uio");
1935 #endif
1936
1937 /*
1938 * If there is no cookie, assume directory was stale.
1939 */
1940 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
1941 if (cookiep)
1942 cookie = *cookiep;
1943 else
1944 return (NFSERR_BAD_COOKIE);
1945 /*
1946 * Loop around doing readdir rpc's of size nm_readdirsize
1947 * truncated to a multiple of DIRBLKSIZ.
1948 * The stopping criteria is EOF or buffer full.
1949 */
1950 while (more_dirs && bigenough) {
1951 nfsstats.rpccnt[NFSPROC_READDIR]++;
1952 mreq = nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) +
1953 NFSX_READDIR(v3));
1954 mb = mreq;
1955 bpos = mtod(mb, caddr_t);
1956 nfsm_fhtom(vp, v3);
1957 if (v3) {
1958 tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED);
1959 *tl++ = cookie.nfsuquad[0];
1960 *tl++ = cookie.nfsuquad[1];
1961 *tl++ = dnp->n_cookieverf.nfsuquad[0];
1962 *tl++ = dnp->n_cookieverf.nfsuquad[1];
1963 } else {
1964 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
1965 *tl++ = cookie.nfsuquad[0];
1966 }
1967 *tl = txdr_unsigned(nmp->nm_readdirsize);
1968 nfsm_request(vp, NFSPROC_READDIR, uiop->uio_td, cred);
1969 if (v3) {
1970 nfsm_postop_attr(vp, attrflag);
1971 if (!error) {
1972 tl = nfsm_dissect(u_int32_t *,
1973 2 * NFSX_UNSIGNED);
1974 dnp->n_cookieverf.nfsuquad[0] = *tl++;
1975 dnp->n_cookieverf.nfsuquad[1] = *tl;
1976 } else {
1977 m_freem(mrep);
1978 goto nfsmout;
1979 }
1980 }
1981 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
1982 more_dirs = fxdr_unsigned(int, *tl);
1983
1984 /* loop thru the dir entries, doctoring them to 4bsd form */
1985 while (more_dirs && bigenough) {
1986 if (v3) {
1987 tl = nfsm_dissect(u_int32_t *,
1988 3 * NFSX_UNSIGNED);
1989 fileno = fxdr_hyper(tl);
1990 len = fxdr_unsigned(int, *(tl + 2));
1991 } else {
1992 tl = nfsm_dissect(u_int32_t *,
1993 2 * NFSX_UNSIGNED);
1994 fileno = fxdr_unsigned(u_quad_t, *tl++);
1995 len = fxdr_unsigned(int, *tl);
1996 }
1997 if (len <= 0 || len > NFS_MAXNAMLEN) {
1998 error = EBADRPC;
1999 m_freem(mrep);
2000 goto nfsmout;
2001 }
2002 tlen = nfsm_rndup(len);
2003 if (tlen == len)
2004 tlen += 4; /* To ensure null termination */
2005 left = DIRBLKSIZ - blksiz;
2006 if ((tlen + DIRHDSIZ) > left) {
2007 dp->d_reclen += left;
2008 uiop->uio_iov->iov_base =
2009 (char *)uiop->uio_iov->iov_base + left;
2010 uiop->uio_iov->iov_len -= left;
2011 uiop->uio_offset += left;
2012 uiop->uio_resid -= left;
2013 blksiz = 0;
2014 }
2015 if ((tlen + DIRHDSIZ) > uiop->uio_resid)
2016 bigenough = 0;
2017 if (bigenough) {
2018 dp = (struct dirent *)uiop->uio_iov->iov_base;
2019 dp->d_fileno = (int)fileno;
2020 dp->d_namlen = len;
2021 dp->d_reclen = tlen + DIRHDSIZ;
2022 dp->d_type = DT_UNKNOWN;
2023 blksiz += dp->d_reclen;
2024 if (blksiz == DIRBLKSIZ)
2025 blksiz = 0;
2026 uiop->uio_offset += DIRHDSIZ;
2027 uiop->uio_resid -= DIRHDSIZ;
2028 uiop->uio_iov->iov_base =
2029 (char *)uiop->uio_iov->iov_base + DIRHDSIZ;
2030 uiop->uio_iov->iov_len -= DIRHDSIZ;
2031 nfsm_mtouio(uiop, len);
2032 cp = uiop->uio_iov->iov_base;
2033 tlen -= len;
2034 *cp = '\0'; /* null terminate */
2035 uiop->uio_iov->iov_base =
2036 (char *)uiop->uio_iov->iov_base + tlen;
2037 uiop->uio_iov->iov_len -= tlen;
2038 uiop->uio_offset += tlen;
2039 uiop->uio_resid -= tlen;
2040 } else
2041 nfsm_adv(nfsm_rndup(len));
2042 if (v3) {
2043 tl = nfsm_dissect(u_int32_t *,
2044 3 * NFSX_UNSIGNED);
2045 } else {
2046 tl = nfsm_dissect(u_int32_t *,
2047 2 * NFSX_UNSIGNED);
2048 }
2049 if (bigenough) {
2050 cookie.nfsuquad[0] = *tl++;
2051 if (v3)
2052 cookie.nfsuquad[1] = *tl++;
2053 } else if (v3)
2054 tl += 2;
2055 else
2056 tl++;
2057 more_dirs = fxdr_unsigned(int, *tl);
2058 }
2059 /*
2060 * If at end of rpc data, get the eof boolean
2061 */
2062 if (!more_dirs) {
2063 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
2064 more_dirs = (fxdr_unsigned(int, *tl) == 0);
2065 }
2066 m_freem(mrep);
2067 }
2068 /*
2069 * Fill last record, iff any, out to a multiple of DIRBLKSIZ
2070 * by increasing d_reclen for the last record.
2071 */
2072 if (blksiz > 0) {
2073 left = DIRBLKSIZ - blksiz;
2074 dp->d_reclen += left;
2075 uiop->uio_iov->iov_base =
2076 (char *)uiop->uio_iov->iov_base + left;
2077 uiop->uio_iov->iov_len -= left;
2078 uiop->uio_offset += left;
2079 uiop->uio_resid -= left;
2080 }
2081
2082 /*
2083 * We are now either at the end of the directory or have filled the
2084 * block.
2085 */
2086 if (bigenough)
2087 dnp->n_direofoffset = uiop->uio_offset;
2088 else {
2089 if (uiop->uio_resid > 0)
2090 printf("EEK! readdirrpc resid > 0\n");
2091 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
2092 *cookiep = cookie;
2093 }
2094 nfsmout:
2095 return (error);
2096 }
2097
2098 /*
2099 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
2100 */
2101 int
2102 nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
2103 {
2104 int len, left;
2105 struct dirent *dp;
2106 u_int32_t *tl;
2107 caddr_t cp;
2108 struct vnode *newvp;
2109 nfsuint64 *cookiep;
2110 caddr_t bpos, dpos, dpossav1, dpossav2;
2111 struct mbuf *mreq, *mrep, *md, *mb, *mdsav1, *mdsav2;
2112 struct nameidata nami, *ndp = &nami;
2113 struct componentname *cnp = &ndp->ni_cnd;
2114 nfsuint64 cookie;
2115 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2116 struct nfsnode *dnp = VTONFS(vp), *np;
2117 nfsfh_t *fhp;
2118 u_quad_t fileno;
2119 int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
2120 int attrflag, fhsize;
2121
2122 #ifndef nolint
2123 dp = NULL;
2124 #endif
2125 #ifndef DIAGNOSTIC
2126 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) ||
2127 (uiop->uio_resid & (DIRBLKSIZ - 1)))
2128 panic("nfs readdirplusrpc bad uio");
2129 #endif
2130 ndp->ni_dvp = vp;
2131 newvp = NULLVP;
2132
2133 /*
2134 * If there is no cookie, assume directory was stale.
2135 */
2136 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
2137 if (cookiep)
2138 cookie = *cookiep;
2139 else
2140 return (NFSERR_BAD_COOKIE);
2141 /*
2142 * Loop around doing readdir rpc's of size nm_readdirsize
2143 * truncated to a multiple of DIRBLKSIZ.
2144 * The stopping criteria is EOF or buffer full.
2145 */
2146 while (more_dirs && bigenough) {
2147 nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
2148 mreq = nfsm_reqhead(vp, NFSPROC_READDIRPLUS,
2149 NFSX_FH(1) + 6 * NFSX_UNSIGNED);
2150 mb = mreq;
2151 bpos = mtod(mb, caddr_t);
2152 nfsm_fhtom(vp, 1);
2153 tl = nfsm_build(u_int32_t *, 6 * NFSX_UNSIGNED);
2154 *tl++ = cookie.nfsuquad[0];
2155 *tl++ = cookie.nfsuquad[1];
2156 *tl++ = dnp->n_cookieverf.nfsuquad[0];
2157 *tl++ = dnp->n_cookieverf.nfsuquad[1];
2158 *tl++ = txdr_unsigned(nmp->nm_readdirsize);
2159 *tl = txdr_unsigned(nmp->nm_rsize);
2160 nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, cred);
2161 nfsm_postop_attr(vp, attrflag);
2162 if (error) {
2163 m_freem(mrep);
2164 goto nfsmout;
2165 }
2166 tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED);
2167 dnp->n_cookieverf.nfsuquad[0] = *tl++;
2168 dnp->n_cookieverf.nfsuquad[1] = *tl++;
2169 more_dirs = fxdr_unsigned(int, *tl);
2170
2171 /* loop thru the dir entries, doctoring them to 4bsd form */
2172 while (more_dirs && bigenough) {
2173 tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED);
2174 fileno = fxdr_hyper(tl);
2175 len = fxdr_unsigned(int, *(tl + 2));
2176 if (len <= 0 || len > NFS_MAXNAMLEN) {
2177 error = EBADRPC;
2178 m_freem(mrep);
2179 goto nfsmout;
2180 }
2181 tlen = nfsm_rndup(len);
2182 if (tlen == len)
2183 tlen += 4; /* To ensure null termination*/
2184 left = DIRBLKSIZ - blksiz;
2185 if ((tlen + DIRHDSIZ) > left) {
2186 dp->d_reclen += left;
2187 uiop->uio_iov->iov_base =
2188 (char *)uiop->uio_iov->iov_base + left;
2189 uiop->uio_iov->iov_len -= left;
2190 uiop->uio_offset += left;
2191 uiop->uio_resid -= left;
2192 blksiz = 0;
2193 }
2194 if ((tlen + DIRHDSIZ) > uiop->uio_resid)
2195 bigenough = 0;
2196 if (bigenough) {
2197 dp = (struct dirent *)uiop->uio_iov->iov_base;
2198 dp->d_fileno = (int)fileno;
2199 dp->d_namlen = len;
2200 dp->d_reclen = tlen + DIRHDSIZ;
2201 dp->d_type = DT_UNKNOWN;
2202 blksiz += dp->d_reclen;
2203 if (blksiz == DIRBLKSIZ)
2204 blksiz = 0;
2205 uiop->uio_offset += DIRHDSIZ;
2206 uiop->uio_resid -= DIRHDSIZ;
2207 uiop->uio_iov->iov_base =
2208 (char *)uiop->uio_iov->iov_base + DIRHDSIZ;
2209 uiop->uio_iov->iov_len -= DIRHDSIZ;
2210 cnp->cn_nameptr = uiop->uio_iov->iov_base;
2211 cnp->cn_namelen = len;
2212 nfsm_mtouio(uiop, len);
2213 cp = uiop->uio_iov->iov_base;
2214 tlen -= len;
2215 *cp = '\0';
2216 uiop->uio_iov->iov_base =
2217 (char *)uiop->uio_iov->iov_base + tlen;
2218 uiop->uio_iov->iov_len -= tlen;
2219 uiop->uio_offset += tlen;
2220 uiop->uio_resid -= tlen;
2221 } else
2222 nfsm_adv(nfsm_rndup(len));
2223 tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED);
2224 if (bigenough) {
2225 cookie.nfsuquad[0] = *tl++;
2226 cookie.nfsuquad[1] = *tl++;
2227 } else
2228 tl += 2;
2229
2230 /*
2231 * Since the attributes are before the file handle
2232 * (sigh), we must skip over the attributes and then
2233 * come back and get them.
2234 */
2235 attrflag = fxdr_unsigned(int, *tl);
2236 if (attrflag) {
2237 dpossav1 = dpos;
2238 mdsav1 = md;
2239 nfsm_adv(NFSX_V3FATTR);
2240 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
2241 doit = fxdr_unsigned(int, *tl);
2242 /*
2243 * Skip loading the attrs for "..". There's a
2244 * race between loading the attrs here and
2245 * lookups that look for the directory currently
2246 * being read (in the parent). We try to acquire
2247 * the exclusive lock on ".." here, owning the
2248 * lock on the directory being read. Lookup will
2249 * hold the lock on ".." and try to acquire the
2250 * lock on the directory being read.
2251 *
2252 * There are other ways of fixing this, one would
2253 * be to do a trylock on the ".." vnode and skip
2254 * loading the attrs on ".." if it happens to be
2255 * locked by another process. But skipping the
2256 * attrload on ".." seems the easiest option.
2257 */
2258 if (strcmp(dp->d_name, "..") == 0) {
2259 doit = 0;
2260 /*
2261 * We've already skipped over the attrs,
2262 * skip over the filehandle. And store d_type
2263 * as VDIR.
2264 */
2265 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
2266 i = fxdr_unsigned(int, *tl);
2267 nfsm_adv(nfsm_rndup(i));
2268 dp->d_type = IFTODT(VTTOIF(VDIR));
2269 }
2270 if (doit) {
2271 nfsm_getfh(fhp, fhsize, 1);
2272 if (NFS_CMPFH(dnp, fhp, fhsize)) {
2273 VREF(vp);
2274 newvp = vp;
2275 np = dnp;
2276 } else {
2277 error = nfs_nget(vp->v_mount, fhp,
2278 fhsize, &np, LK_EXCLUSIVE);
2279 if (error)
2280 doit = 0;
2281 else
2282 newvp = NFSTOV(np);
2283 }
2284 }
2285 if (doit && bigenough) {
2286 dpossav2 = dpos;
2287 dpos = dpossav1;
2288 mdsav2 = md;
2289 md = mdsav1;
2290 nfsm_loadattr(newvp, NULL);
2291 dpos = dpossav2;
2292 md = mdsav2;
2293 dp->d_type =
2294 IFTODT(VTTOIF(np->n_vattr.va_type));
2295 ndp->ni_vp = newvp;
2296 /* Update n_ctime, so subsequent lookup doesn't purge entry */
2297 np->n_ctime = np->n_vattr.va_ctime.tv_sec;
2298 cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp);
2299 }
2300 } else {
2301 /* Just skip over the file handle */
2302 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
2303 i = fxdr_unsigned(int, *tl);
2304 if (i) {
2305 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
2306 fhsize = fxdr_unsigned(int, *tl);
2307 nfsm_adv(nfsm_rndup(fhsize));
2308 }
2309 }
2310 if (newvp != NULLVP) {
2311 if (newvp == vp)
2312 vrele(newvp);
2313 else
2314 vput(newvp);
2315 newvp = NULLVP;
2316 }
2317 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
2318 more_dirs = fxdr_unsigned(int, *tl);
2319 }
2320 /*
2321 * If at end of rpc data, get the eof boolean
2322 */
2323 if (!more_dirs) {
2324 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
2325 more_dirs = (fxdr_unsigned(int, *tl) == 0);
2326 }
2327 m_freem(mrep);
2328 }
2329 /*
2330 * Fill last record, iff any, out to a multiple of DIRBLKSIZ
2331 * by increasing d_reclen for the last record.
2332 */
2333 if (blksiz > 0) {
2334 left = DIRBLKSIZ - blksiz;
2335 dp->d_reclen += left;
2336 uiop->uio_iov->iov_base =
2337 (char *)uiop->uio_iov->iov_base + left;
2338 uiop->uio_iov->iov_len -= left;
2339 uiop->uio_offset += left;
2340 uiop->uio_resid -= left;
2341 }
2342
2343 /*
2344 * We are now either at the end of the directory or have filled the
2345 * block.
2346 */
2347 if (bigenough)
2348 dnp->n_direofoffset = uiop->uio_offset;
2349 else {
2350 if (uiop->uio_resid > 0)
2351 printf("EEK! readdirplusrpc resid > 0\n");
2352 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
2353 *cookiep = cookie;
2354 }
2355 nfsmout:
2356 if (newvp != NULLVP) {
2357 if (newvp == vp)
2358 vrele(newvp);
2359 else
2360 vput(newvp);
2361 newvp = NULLVP;
2362 }
2363 return (error);
2364 }
2365
2366 /*
2367 * Silly rename. To make the NFS filesystem that is stateless look a little
2368 * more like the "ufs" a remove of an active vnode is translated to a rename
2369 * to a funny looking filename that is removed by nfs_inactive on the
2370 * nfsnode. There is the potential for another process on a different client
2371 * to create the same funny name between the nfs_lookitup() fails and the
2372 * nfs_rename() completes, but...
2373 */
2374 static int
2375 nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
2376 {
2377 struct sillyrename *sp;
2378 struct nfsnode *np;
2379 int error;
2380 short pid;
2381 unsigned int lticks;
2382
2383 cache_purge(dvp);
2384 np = VTONFS(vp);
2385 #ifndef DIAGNOSTIC
2386 if (vp->v_type == VDIR)
2387 panic("nfs: sillyrename dir");
2388 #endif
2389 MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
2390 M_NFSREQ, M_WAITOK);
2391 sp->s_cred = crhold(cnp->cn_cred);
2392 sp->s_dvp = dvp;
2393 sp->s_removeit = nfs_removeit;
2394 VREF(dvp);
2395
2396 /*
2397 * Fudge together a funny name.
2398 * Changing the format of the funny name to accomodate more
2399 * sillynames per directory.
2400 * The name is now changed to .nfs.<ticks>.<pid>.4, where ticks is
2401 * CPU ticks since boot.
2402 */
2403 pid = cnp->cn_thread->td_proc->p_pid;
2404 lticks = (unsigned int)ticks;
2405 for ( ; ; ) {
2406 sp->s_namlen = sprintf(sp->s_name,
2407 ".nfs.%08x.%04x4.4", lticks,
2408 pid);
2409 if (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2410 cnp->cn_thread, NULL))
2411 break;
2412 lticks++;
2413 }
2414 error = nfs_renameit(dvp, cnp, sp);
2415 if (error)
2416 goto bad;
2417 error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2418 cnp->cn_thread, &np);
2419 np->n_sillyrename = sp;
2420 return (0);
2421 bad:
2422 vrele(sp->s_dvp);
2423 crfree(sp->s_cred);
2424 free((caddr_t)sp, M_NFSREQ);
2425 return (error);
2426 }
2427
2428 /*
2429 * Look up a file name and optionally either update the file handle or
2430 * allocate an nfsnode, depending on the value of npp.
2431 * npp == NULL --> just do the lookup
2432 * *npp == NULL --> allocate a new nfsnode and make sure attributes are
2433 * handled too
2434 * *npp != NULL --> update the file handle in the vnode
2435 */
2436 static int
2437 nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred,
2438 struct thread *td, struct nfsnode **npp)
2439 {
2440 struct vnode *newvp = NULL;
2441 struct nfsnode *np, *dnp = VTONFS(dvp);
2442 caddr_t bpos, dpos;
2443 int error = 0, fhlen, attrflag;
2444 struct mbuf *mreq, *mrep, *md, *mb;
2445 nfsfh_t *nfhp;
2446 int v3 = NFS_ISV3(dvp);
2447
2448 nfsstats.rpccnt[NFSPROC_LOOKUP]++;
2449 mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP,
2450 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
2451 mb = mreq;
2452 bpos = mtod(mb, caddr_t);
2453 nfsm_fhtom(dvp, v3);
2454 nfsm_strtom(name, len, NFS_MAXNAMLEN);
2455 nfsm_request(dvp, NFSPROC_LOOKUP, td, cred);
2456 if (npp && !error) {
2457 nfsm_getfh(nfhp, fhlen, v3);
2458 if (*npp) {
2459 np = *npp;
2460 if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) {
2461 free((caddr_t)np->n_fhp, M_NFSBIGFH);
2462 np->n_fhp = &np->n_fh;
2463 } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH)
2464 np->n_fhp =(nfsfh_t *)malloc(fhlen, M_NFSBIGFH, M_WAITOK);
2465 bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen);
2466 np->n_fhsize = fhlen;
2467 newvp = NFSTOV(np);
2468 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) {
2469 VREF(dvp);
2470 newvp = dvp;
2471 } else {
2472 error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, LK_EXCLUSIVE);
2473 if (error) {
2474 m_freem(mrep);
2475 return (error);
2476 }
2477 newvp = NFSTOV(np);
2478 }
2479 if (v3) {
2480 nfsm_postop_attr(newvp, attrflag);
2481 if (!attrflag && *npp == NULL) {
2482 m_freem(mrep);
2483 if (newvp == dvp)
2484 vrele(newvp);
2485 else
2486 vput(newvp);
2487 return (ENOENT);
2488 }
2489 } else
2490 nfsm_loadattr(newvp, NULL);
2491 }
2492 m_freem(mrep);
2493 nfsmout:
2494 if (npp && *npp == NULL) {
2495 if (error) {
2496 if (newvp) {
2497 if (newvp == dvp)
2498 vrele(newvp);
2499 else
2500 vput(newvp);
2501 }
2502 } else
2503 *npp = np;
2504 }
2505 return (error);
2506 }
2507
2508 /*
2509 * Nfs Version 3 commit rpc
2510 */
2511 int
2512 nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred,
2513 struct thread *td)
2514 {
2515 u_int32_t *tl;
2516 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2517 caddr_t bpos, dpos;
2518 int error = 0, wccflag = NFSV3_WCCRATTR;
2519 struct mbuf *mreq, *mrep, *md, *mb;
2520
2521 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0)
2522 return (0);
2523 nfsstats.rpccnt[NFSPROC_COMMIT]++;
2524 mreq = nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1));
2525 mb = mreq;
2526 bpos = mtod(mb, caddr_t);
2527 nfsm_fhtom(vp, 1);
2528 tl = nfsm_build(u_int32_t *, 3 * NFSX_UNSIGNED);
2529 txdr_hyper(offset, tl);
2530 tl += 2;
2531 *tl = txdr_unsigned(cnt);
2532 nfsm_request(vp, NFSPROC_COMMIT, td, cred);
2533 nfsm_wcc_data(vp, wccflag);
2534 if (!error) {
2535 tl = nfsm_dissect(u_int32_t *, NFSX_V3WRITEVERF);
2536 if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl,
2537 NFSX_V3WRITEVERF)) {
2538 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
2539 NFSX_V3WRITEVERF);
2540 error = NFSERR_STALEWRITEVERF;
2541 }
2542 }
2543 m_freem(mrep);
2544 nfsmout:
2545 return (error);
2546 }
2547
2548 /*
2549 * Strategy routine.
2550 * For async requests when nfsiod(s) are running, queue the request by
2551 * calling nfs_asyncio(), otherwise just all nfs_doio() to do the
2552 * request.
2553 */
2554 static int
2555 nfs_strategy(struct vop_strategy_args *ap)
2556 {
2557 struct buf *bp = ap->a_bp;
2558 struct ucred *cr;
2559
2560 KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp));
2561 KASSERT(BUF_REFCNT(bp) > 0, ("nfs_strategy: buffer %p not locked", bp));
2562
2563 if (bp->b_iocmd == BIO_READ)
2564 cr = bp->b_rcred;
2565 else
2566 cr = bp->b_wcred;
2567
2568 /*
2569 * If the op is asynchronous and an i/o daemon is waiting
2570 * queue the request, wake it up and wait for completion
2571 * otherwise just do it ourselves.
2572 */
2573 if ((bp->b_flags & B_ASYNC) == 0 ||
2574 nfs_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
2575 (void)nfs_doio(ap->a_vp, bp, cr, curthread);
2576 return (0);
2577 }
2578
2579 /*
2580 * fsync vnode op. Just call nfs_flush() with commit == 1.
2581 */
2582 /* ARGSUSED */
2583 static int
2584 nfs_fsync(struct vop_fsync_args *ap)
2585 {
2586
2587 return (nfs_flush(ap->a_vp, ap->a_waitfor, ap->a_td, 1));
2588 }
2589
2590 /*
2591 * Flush all the blocks associated with a vnode.
2592 * Walk through the buffer pool and push any dirty pages
2593 * associated with the vnode.
2594 */
2595 static int
2596 nfs_flush(struct vnode *vp, int waitfor, struct thread *td,
2597 int commit)
2598 {
2599 struct nfsnode *np = VTONFS(vp);
2600 struct buf *bp;
2601 int i;
2602 struct buf *nbp;
2603 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2604 int s, error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos;
2605 int passone = 1;
2606 u_quad_t off, endoff, toff;
2607 struct ucred* wcred = NULL;
2608 struct buf **bvec = NULL;
2609 #ifndef NFS_COMMITBVECSIZ
2610 #define NFS_COMMITBVECSIZ 20
2611 #endif
2612 struct buf *bvec_on_stack[NFS_COMMITBVECSIZ];
2613 int bvecsize = 0, bveccount;
2614
2615 if (nmp->nm_flag & NFSMNT_INT)
2616 slpflag = PCATCH;
2617 if (!commit)
2618 passone = 0;
2619 /*
2620 * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the
2621 * server, but has not been committed to stable storage on the server
2622 * yet. On the first pass, the byte range is worked out and the commit
2623 * rpc is done. On the second pass, nfs_writebp() is called to do the
2624 * job.
2625 */
2626 again:
2627 off = (u_quad_t)-1;
2628 endoff = 0;
2629 bvecpos = 0;
2630 if (NFS_ISV3(vp) && commit) {
2631 s = splbio();
2632 if (bvec != NULL && bvec != bvec_on_stack)
2633 free(bvec, M_TEMP);
2634 /*
2635 * Count up how many buffers waiting for a commit.
2636 */
2637 bveccount = 0;
2638 VI_LOCK(vp);
2639 TAILQ_FOREACH_SAFE(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs, nbp) {
2640 if (BUF_REFCNT(bp) == 0 &&
2641 (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT))
2642 == (B_DELWRI | B_NEEDCOMMIT))
2643 bveccount++;
2644 }
2645 /*
2646 * Allocate space to remember the list of bufs to commit. It is
2647 * important to use M_NOWAIT here to avoid a race with nfs_write.
2648 * If we can't get memory (for whatever reason), we will end up
2649 * committing the buffers one-by-one in the loop below.
2650 */
2651 if (bveccount > NFS_COMMITBVECSIZ) {
2652 /*
2653 * Release the vnode interlock to avoid a lock
2654 * order reversal.
2655 */
2656 VI_UNLOCK(vp);
2657 bvec = (struct buf **)
2658 malloc(bveccount * sizeof(struct buf *),
2659 M_TEMP, M_NOWAIT);
2660 VI_LOCK(vp);
2661 if (bvec == NULL) {
2662 bvec = bvec_on_stack;
2663 bvecsize = NFS_COMMITBVECSIZ;
2664 } else
2665 bvecsize = bveccount;
2666 } else {
2667 bvec = bvec_on_stack;
2668 bvecsize = NFS_COMMITBVECSIZ;
2669 }
2670 TAILQ_FOREACH_SAFE(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs, nbp) {
2671 if (bvecpos >= bvecsize)
2672 break;
2673 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) {
2674 nbp = TAILQ_NEXT(bp, b_bobufs);
2675 continue;
2676 }
2677 if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) !=
2678 (B_DELWRI | B_NEEDCOMMIT)) {
2679 BUF_UNLOCK(bp);
2680 nbp = TAILQ_NEXT(bp, b_bobufs);
2681 continue;
2682 }
2683 VI_UNLOCK(vp);
2684 bremfree(bp);
2685 /*
2686 * Work out if all buffers are using the same cred
2687 * so we can deal with them all with one commit.
2688 *
2689 * NOTE: we are not clearing B_DONE here, so we have
2690 * to do it later on in this routine if we intend to
2691 * initiate I/O on the bp.
2692 *
2693 * Note: to avoid loopback deadlocks, we do not
2694 * assign b_runningbufspace.
2695 */
2696 if (wcred == NULL)
2697 wcred = bp->b_wcred;
2698 else if (wcred != bp->b_wcred)
2699 wcred = NOCRED;
2700 vfs_busy_pages(bp, 1);
2701
2702 VI_LOCK(vp);
2703 /*
2704 * bp is protected by being locked, but nbp is not
2705 * and vfs_busy_pages() may sleep. We have to
2706 * recalculate nbp.
2707 */
2708 nbp = TAILQ_NEXT(bp, b_bobufs);
2709
2710 /*
2711 * A list of these buffers is kept so that the
2712 * second loop knows which buffers have actually
2713 * been committed. This is necessary, since there
2714 * may be a race between the commit rpc and new
2715 * uncommitted writes on the file.
2716 */
2717 bvec[bvecpos++] = bp;
2718 toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE +
2719 bp->b_dirtyoff;
2720 if (toff < off)
2721 off = toff;
2722 toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff);
2723 if (toff > endoff)
2724 endoff = toff;
2725 }
2726 splx(s);
2727 VI_UNLOCK(vp);
2728 }
2729 if (bvecpos > 0) {
2730 /*
2731 * Commit data on the server, as required.
2732 * If all bufs are using the same wcred, then use that with
2733 * one call for all of them, otherwise commit each one
2734 * separately.
2735 */
2736 if (wcred != NOCRED)
2737 retv = nfs_commit(vp, off, (int)(endoff - off),
2738 wcred, td);
2739 else {
2740 retv = 0;
2741 for (i = 0; i < bvecpos; i++) {
2742 off_t off, size;
2743 bp = bvec[i];
2744 off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE +
2745 bp->b_dirtyoff;
2746 size = (u_quad_t)(bp->b_dirtyend
2747 - bp->b_dirtyoff);
2748 retv = nfs_commit(vp, off, (int)size,
2749 bp->b_wcred, td);
2750 if (retv) break;
2751 }
2752 }
2753
2754 if (retv == NFSERR_STALEWRITEVERF)
2755 nfs_clearcommit(vp->v_mount);
2756
2757 /*
2758 * Now, either mark the blocks I/O done or mark the
2759 * blocks dirty, depending on whether the commit
2760 * succeeded.
2761 */
2762 for (i = 0; i < bvecpos; i++) {
2763 bp = bvec[i];
2764 bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
2765 if (retv) {
2766 /*
2767 * Error, leave B_DELWRI intact
2768 */
2769 vfs_unbusy_pages(bp);
2770 brelse(bp);
2771 } else {
2772 /*
2773 * Success, remove B_DELWRI ( bundirty() ).
2774 *
2775 * b_dirtyoff/b_dirtyend seem to be NFS
2776 * specific. We should probably move that
2777 * into bundirty(). XXX
2778 */
2779 s = splbio();
2780 bufobj_wref(&vp->v_bufobj);
2781 bp->b_flags |= B_ASYNC;
2782 bundirty(bp);
2783 bp->b_flags &= ~B_DONE;
2784 bp->b_ioflags &= ~BIO_ERROR;
2785 bp->b_dirtyoff = bp->b_dirtyend = 0;
2786 splx(s);
2787 bufdone(bp);
2788 }
2789 }
2790 }
2791
2792 /*
2793 * Start/do any write(s) that are required.
2794 */
2795 loop:
2796 s = splbio();
2797 VI_LOCK(vp);
2798 TAILQ_FOREACH_SAFE(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs, nbp) {
2799 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) {
2800 if (waitfor != MNT_WAIT || passone)
2801 continue;
2802
2803 error = BUF_TIMELOCK(bp,
2804 LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK,
2805 VI_MTX(vp), "nfsfsync", slpflag, slptimeo);
2806 splx(s);
2807 if (error == 0)
2808 panic("nfs_fsync: inconsistent lock");
2809 if (error == ENOLCK)
2810 goto loop;
2811 if (nfs_sigintr(nmp, NULL, td)) {
2812 error = EINTR;
2813 goto done;
2814 }
2815 if (slpflag == PCATCH) {
2816 slpflag = 0;
2817 slptimeo = 2 * hz;
2818 }
2819 goto loop;
2820 }
2821 if ((bp->b_flags & B_DELWRI) == 0)
2822 panic("nfs_fsync: not dirty");
2823 if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) {
2824 BUF_UNLOCK(bp);
2825 continue;
2826 }
2827 VI_UNLOCK(vp);
2828 bremfree(bp);
2829 if (passone || !commit)
2830 bp->b_flags |= B_ASYNC;
2831 else
2832 bp->b_flags |= B_ASYNC;
2833 splx(s);
2834 bwrite(bp);
2835 if (nfs_sigintr(nmp, NULL, td)) {
2836 error = EINTR;
2837 goto done;
2838 }
2839 goto loop;
2840 }
2841 splx(s);
2842 if (passone) {
2843 passone = 0;
2844 VI_UNLOCK(vp);
2845 goto again;
2846 }
2847 if (waitfor == MNT_WAIT) {
2848 while (vp->v_bufobj.bo_numoutput) {
2849 error = bufobj_wwait(&vp->v_bufobj, slpflag, slptimeo);
2850 if (error) {
2851 VI_UNLOCK(vp);
2852 error = nfs_sigintr(nmp, NULL, td);
2853 if (error)
2854 goto done;
2855 if (slpflag == PCATCH) {
2856 slpflag = 0;
2857 slptimeo = 2 * hz;
2858 }
2859 VI_LOCK(vp);
2860 }
2861 }
2862 if (vp->v_bufobj.bo_dirty.bv_cnt != 0 && commit) {
2863 VI_UNLOCK(vp);
2864 goto loop;
2865 }
2866 VI_UNLOCK(vp);
2867 /*
2868 * Wait for all the async IO requests to drain
2869 */
2870 while (np->n_directio_asyncwr > 0) {
2871 np->n_flag |= NFSYNCWAIT;
2872 error = nfs_tsleep(td, (caddr_t)&np->n_directio_asyncwr,
2873 slpflag | (PRIBIO + 1), "nfsfsync", 0);
2874 if (error) {
2875 if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) {
2876 error = EINTR;
2877 goto done;
2878 }
2879 }
2880 }
2881
2882 } else
2883 VI_UNLOCK(vp);
2884 if (np->n_flag & NWRITEERR) {
2885 error = np->n_error;
2886 np->n_flag &= ~NWRITEERR;
2887 }
2888 if (commit && vp->v_bufobj.bo_dirty.bv_cnt == 0 &&
2889 vp->v_bufobj.bo_numoutput == 0 && np->n_directio_asyncwr == 0)
2890 np->n_flag &= ~NMODIFIED;
2891 done:
2892 if (bvec != NULL && bvec != bvec_on_stack)
2893 free(bvec, M_TEMP);
2894 return (error);
2895 }
2896
2897 /*
2898 * NFS advisory byte-level locks.
2899 */
2900 static int
2901 nfs_advlock(struct vop_advlock_args *ap)
2902 {
2903
2904 if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) {
2905 struct nfsnode *np = VTONFS(ap->a_vp);
2906
2907 return (lf_advlock(ap, &(np->n_lockf), np->n_size));
2908 }
2909 return (nfs_dolock(ap));
2910 }
2911
2912 /*
2913 * NFS advisory byte-level locks.
2914 */
2915 static int
2916 nfs_advlockasync(struct vop_advlockasync_args *ap)
2917 {
2918 int error;
2919
2920 mtx_lock(&Giant);
2921 if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) {
2922 struct nfsnode *np = VTONFS(ap->a_vp);
2923
2924 error = lf_advlockasync(ap, &(np->n_lockf), np->n_size);
2925 goto out;
2926 }
2927 error = EOPNOTSUPP;
2928 out:
2929 mtx_unlock(&Giant);
2930 return (error);
2931 }
2932
2933 /*
2934 * Print out the contents of an nfsnode.
2935 */
2936 static int
2937 nfs_print(struct vop_print_args *ap)
2938 {
2939 struct vnode *vp = ap->a_vp;
2940 struct nfsnode *np = VTONFS(vp);
2941
2942 printf("\tfileid %ld fsid 0x%x",
2943 np->n_vattr.va_fileid, np->n_vattr.va_fsid);
2944 if (vp->v_type == VFIFO)
2945 fifo_printinfo(vp);
2946 printf("\n");
2947 return (0);
2948 }
2949
2950 /*
2951 * This is the "real" nfs::bwrite(struct buf*).
2952 * We set B_CACHE if this is a VMIO buffer.
2953 */
2954 int
2955 nfs_writebp(struct buf *bp, int force __unused, struct thread *td)
2956 {
2957 int s;
2958 int oldflags = bp->b_flags;
2959 #if 0
2960 int retv = 1;
2961 off_t off;
2962 #endif
2963
2964 if (BUF_REFCNT(bp) == 0)
2965 panic("bwrite: buffer is not locked???");
2966
2967 if (bp->b_flags & B_INVAL) {
2968 brelse(bp);
2969 return(0);
2970 }
2971
2972 bp->b_flags |= B_CACHE;
2973
2974 /*
2975 * Undirty the bp. We will redirty it later if the I/O fails.
2976 */
2977
2978 s = splbio();
2979 bundirty(bp);
2980 bp->b_flags &= ~B_DONE;
2981 bp->b_ioflags &= ~BIO_ERROR;
2982 bp->b_iocmd = BIO_WRITE;
2983
2984 bufobj_wref(bp->b_bufobj);
2985 curthread->td_proc->p_stats->p_ru.ru_oublock++;
2986 splx(s);
2987
2988 /*
2989 * Note: to avoid loopback deadlocks, we do not
2990 * assign b_runningbufspace.
2991 */
2992 vfs_busy_pages(bp, 1);
2993
2994 BUF_KERNPROC(bp);
2995 bp->b_iooffset = dbtob(bp->b_blkno);
2996 bstrategy(bp);
2997
2998 if( (oldflags & B_ASYNC) == 0) {
2999 int rtval = bufwait(bp);
3000
3001 if (oldflags & B_DELWRI) {
3002 s = splbio();
3003 reassignbuf(bp);
3004 splx(s);
3005 }
3006
3007 brelse(bp);
3008 return (rtval);
3009 }
3010
3011 return (0);
3012 }
3013
3014 /*
3015 * nfs special file access vnode op.
3016 * Essentially just get vattr and then imitate iaccess() since the device is
3017 * local to the client.
3018 */
3019 static int
3020 nfsspec_access(struct vop_access_args *ap)
3021 {
3022 struct vattr *vap;
3023 struct ucred *cred = ap->a_cred;
3024 struct vnode *vp = ap->a_vp;
3025 mode_t mode = ap->a_mode;
3026 struct vattr vattr;
3027 int error;
3028
3029 /*
3030 * Disallow write attempts on filesystems mounted read-only;
3031 * unless the file is a socket, fifo, or a block or character
3032 * device resident on the filesystem.
3033 */
3034 if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
3035 switch (vp->v_type) {
3036 case VREG:
3037 case VDIR:
3038 case VLNK:
3039 return (EROFS);
3040 default:
3041 break;
3042 }
3043 }
3044 vap = &vattr;
3045 error = VOP_GETATTR(vp, vap, cred, ap->a_td);
3046 if (error)
3047 return (error);
3048 return (vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid,
3049 mode, cred, NULL));
3050 }
3051
3052 /*
3053 * Read wrapper for fifos.
3054 */
3055 static int
3056 nfsfifo_read(struct vop_read_args *ap)
3057 {
3058 struct nfsnode *np = VTONFS(ap->a_vp);
3059
3060 /*
3061 * Set access flag.
3062 */
3063 np->n_flag |= NACC;
3064 getnanotime(&np->n_atim);
3065 return (fifo_specops.vop_read(ap));
3066 }
3067
3068 /*
3069 * Write wrapper for fifos.
3070 */
3071 static int
3072 nfsfifo_write(struct vop_write_args *ap)
3073 {
3074 struct nfsnode *np = VTONFS(ap->a_vp);
3075
3076 /*
3077 * Set update flag.
3078 */
3079 np->n_flag |= NUPD;
3080 getnanotime(&np->n_mtim);
3081 return (fifo_specops.vop_write(ap));
3082 }
3083
3084 /*
3085 * Close wrapper for fifos.
3086 *
3087 * Update the times on the nfsnode then do fifo close.
3088 */
3089 static int
3090 nfsfifo_close(struct vop_close_args *ap)
3091 {
3092 struct vnode *vp = ap->a_vp;
3093 struct nfsnode *np = VTONFS(vp);
3094 struct vattr vattr;
3095 struct timespec ts;
3096
3097 if (np->n_flag & (NACC | NUPD)) {
3098 getnanotime(&ts);
3099 if (np->n_flag & NACC)
3100 np->n_atim = ts;
3101 if (np->n_flag & NUPD)
3102 np->n_mtim = ts;
3103 np->n_flag |= NCHG;
3104 if (vrefcnt(vp) == 1 &&
3105 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
3106 VATTR_NULL(&vattr);
3107 if (np->n_flag & NACC)
3108 vattr.va_atime = np->n_atim;
3109 if (np->n_flag & NUPD)
3110 vattr.va_mtime = np->n_mtim;
3111 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_td);
3112 }
3113 }
3114 return (fifo_specops.vop_close(ap));
3115 }
3116
3117 /*
3118 * Just call nfs_writebp() with the force argument set to 1.
3119 *
3120 * NOTE: B_DONE may or may not be set in a_bp on call.
3121 */
3122 static int
3123 nfs_bwrite(struct buf *bp)
3124 {
3125
3126 return (nfs_writebp(bp, 1, curthread));
3127 }
3128
3129 struct buf_ops buf_ops_nfs = {
3130 .bop_name = "buf_ops_nfs",
3131 .bop_write = nfs_bwrite,
3132 .bop_strategy = bufstrategy,
3133 .bop_sync = bufsync,
3134 .bop_bdflush = bufbdflush,
3135 };
Cache object: ac516d346f9b45bd261a1d29f890f97f
|