NFS - Fix remaining VM/BIO issues
[dragonfly.git] / sys / vfs / nfs / nfs_vnops.c
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  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *      @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
37  * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $
38  * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.80 2008/10/18 01:13:54 dillon Exp $
39  */
40
41
42 /*
43  * vnode op calls for Sun NFS version 2 and 3
44  */
45
46 #include "opt_inet.h"
47
48 #include <sys/param.h>
49 #include <sys/kernel.h>
50 #include <sys/systm.h>
51 #include <sys/resourcevar.h>
52 #include <sys/proc.h>
53 #include <sys/mount.h>
54 #include <sys/buf.h>
55 #include <sys/malloc.h>
56 #include <sys/mbuf.h>
57 #include <sys/namei.h>
58 #include <sys/nlookup.h>
59 #include <sys/socket.h>
60 #include <sys/vnode.h>
61 #include <sys/dirent.h>
62 #include <sys/fcntl.h>
63 #include <sys/lockf.h>
64 #include <sys/stat.h>
65 #include <sys/sysctl.h>
66 #include <sys/conf.h>
67
68 #include <vm/vm.h>
69 #include <vm/vm_extern.h>
70 #include <vm/vm_zone.h>
71
72 #include <sys/buf2.h>
73
74 #include <vfs/fifofs/fifo.h>
75 #include <vfs/ufs/dir.h>
76
77 #undef DIRBLKSIZ
78
79 #include "rpcv2.h"
80 #include "nfsproto.h"
81 #include "nfs.h"
82 #include "nfsmount.h"
83 #include "nfsnode.h"
84 #include "xdr_subs.h"
85 #include "nfsm_subs.h"
86
87 #include <net/if.h>
88 #include <netinet/in.h>
89 #include <netinet/in_var.h>
90
91 #include <sys/thread2.h>
92
93 /* Defs */
94 #define TRUE    1
95 #define FALSE   0
96
97 static int      nfsfifo_read (struct vop_read_args *);
98 static int      nfsfifo_write (struct vop_write_args *);
99 static int      nfsfifo_close (struct vop_close_args *);
100 #define nfs_poll vop_nopoll
101 static int      nfs_setattrrpc (struct vnode *,struct vattr *,struct ucred *,struct thread *);
102 static  int     nfs_lookup (struct vop_old_lookup_args *);
103 static  int     nfs_create (struct vop_old_create_args *);
104 static  int     nfs_mknod (struct vop_old_mknod_args *);
105 static  int     nfs_open (struct vop_open_args *);
106 static  int     nfs_close (struct vop_close_args *);
107 static  int     nfs_access (struct vop_access_args *);
108 static  int     nfs_getattr (struct vop_getattr_args *);
109 static  int     nfs_setattr (struct vop_setattr_args *);
110 static  int     nfs_read (struct vop_read_args *);
111 static  int     nfs_mmap (struct vop_mmap_args *);
112 static  int     nfs_fsync (struct vop_fsync_args *);
113 static  int     nfs_remove (struct vop_old_remove_args *);
114 static  int     nfs_link (struct vop_old_link_args *);
115 static  int     nfs_rename (struct vop_old_rename_args *);
116 static  int     nfs_mkdir (struct vop_old_mkdir_args *);
117 static  int     nfs_rmdir (struct vop_old_rmdir_args *);
118 static  int     nfs_symlink (struct vop_old_symlink_args *);
119 static  int     nfs_readdir (struct vop_readdir_args *);
120 static  int     nfs_bmap (struct vop_bmap_args *);
121 static  int     nfs_strategy (struct vop_strategy_args *);
122 static  int     nfs_lookitup (struct vnode *, const char *, int,
123                         struct ucred *, struct thread *, struct nfsnode **);
124 static  int     nfs_sillyrename (struct vnode *,struct vnode *,struct componentname *);
125 static int      nfs_laccess (struct vop_access_args *);
126 static int      nfs_readlink (struct vop_readlink_args *);
127 static int      nfs_print (struct vop_print_args *);
128 static int      nfs_advlock (struct vop_advlock_args *);
129
130 static  int     nfs_nresolve (struct vop_nresolve_args *);
131 /*
132  * Global vfs data structures for nfs
133  */
134 struct vop_ops nfsv2_vnode_vops = {
135         .vop_default =          vop_defaultop,
136         .vop_access =           nfs_access,
137         .vop_advlock =          nfs_advlock,
138         .vop_bmap =             nfs_bmap,
139         .vop_close =            nfs_close,
140         .vop_old_create =       nfs_create,
141         .vop_fsync =            nfs_fsync,
142         .vop_getattr =          nfs_getattr,
143         .vop_getpages =         nfs_getpages,
144         .vop_putpages =         nfs_putpages,
145         .vop_inactive =         nfs_inactive,
146         .vop_old_link =         nfs_link,
147         .vop_old_lookup =       nfs_lookup,
148         .vop_old_mkdir =        nfs_mkdir,
149         .vop_old_mknod =        nfs_mknod,
150         .vop_mmap =             nfs_mmap,
151         .vop_open =             nfs_open,
152         .vop_poll =             nfs_poll,
153         .vop_print =            nfs_print,
154         .vop_read =             nfs_read,
155         .vop_readdir =          nfs_readdir,
156         .vop_readlink =         nfs_readlink,
157         .vop_reclaim =          nfs_reclaim,
158         .vop_old_remove =       nfs_remove,
159         .vop_old_rename =       nfs_rename,
160         .vop_old_rmdir =        nfs_rmdir,
161         .vop_setattr =          nfs_setattr,
162         .vop_strategy =         nfs_strategy,
163         .vop_old_symlink =      nfs_symlink,
164         .vop_write =            nfs_write,
165         .vop_nresolve =         nfs_nresolve
166 };
167
168 /*
169  * Special device vnode ops
170  */
171 struct vop_ops nfsv2_spec_vops = {
172         .vop_default =          vop_defaultop,
173         .vop_access =           nfs_laccess,
174         .vop_close =            nfs_close,
175         .vop_fsync =            nfs_fsync,
176         .vop_getattr =          nfs_getattr,
177         .vop_inactive =         nfs_inactive,
178         .vop_print =            nfs_print,
179         .vop_read =             vop_stdnoread,
180         .vop_reclaim =          nfs_reclaim,
181         .vop_setattr =          nfs_setattr,
182         .vop_write =            vop_stdnowrite
183 };
184
185 struct vop_ops nfsv2_fifo_vops = {
186         .vop_default =          fifo_vnoperate,
187         .vop_access =           nfs_laccess,
188         .vop_close =            nfsfifo_close,
189         .vop_fsync =            nfs_fsync,
190         .vop_getattr =          nfs_getattr,
191         .vop_inactive =         nfs_inactive,
192         .vop_print =            nfs_print,
193         .vop_read =             nfsfifo_read,
194         .vop_reclaim =          nfs_reclaim,
195         .vop_setattr =          nfs_setattr,
196         .vop_write =            nfsfifo_write
197 };
198
199 static int      nfs_mknodrpc (struct vnode *dvp, struct vnode **vpp,
200                                   struct componentname *cnp,
201                                   struct vattr *vap);
202 static int      nfs_removerpc (struct vnode *dvp, const char *name,
203                                    int namelen,
204                                    struct ucred *cred, struct thread *td);
205 static int      nfs_renamerpc (struct vnode *fdvp, const char *fnameptr,
206                                    int fnamelen, struct vnode *tdvp,
207                                    const char *tnameptr, int tnamelen,
208                                    struct ucred *cred, struct thread *td);
209 static int      nfs_renameit (struct vnode *sdvp,
210                                   struct componentname *scnp,
211                                   struct sillyrename *sp);
212
213 SYSCTL_DECL(_vfs_nfs);
214
215 static int nfs_flush_on_rename = 1;
216 SYSCTL_INT(_vfs_nfs, OID_AUTO, flush_on_rename, CTLFLAG_RW, 
217            &nfs_flush_on_rename, 0, "flush fvp prior to rename");
218 static int nfs_flush_on_hlink = 0;
219 SYSCTL_INT(_vfs_nfs, OID_AUTO, flush_on_hlink, CTLFLAG_RW, 
220            &nfs_flush_on_hlink, 0, "flush fvp prior to hard link");
221
222 static int      nfsaccess_cache_timeout = NFS_DEFATTRTIMO;
223 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW, 
224            &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout");
225
226 static int      nfsneg_cache_timeout = NFS_MINATTRTIMO;
227 SYSCTL_INT(_vfs_nfs, OID_AUTO, neg_cache_timeout, CTLFLAG_RW, 
228            &nfsneg_cache_timeout, 0, "NFS NEGATIVE NAMECACHE timeout");
229
230 static int      nfspos_cache_timeout = NFS_MINATTRTIMO;
231 SYSCTL_INT(_vfs_nfs, OID_AUTO, pos_cache_timeout, CTLFLAG_RW, 
232            &nfspos_cache_timeout, 0, "NFS POSITIVE NAMECACHE timeout");
233
234 static int      nfsv3_commit_on_close = 0;
235 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, 
236            &nfsv3_commit_on_close, 0, "write+commit on close, else only write");
237 #if 0
238 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, 
239            &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count");
240
241 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, 
242            &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count");
243 #endif
244
245 #define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY          \
246                          | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE     \
247                          | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP)
248 static int
249 nfs3_access_otw(struct vnode *vp, int wmode,
250                 struct thread *td, struct ucred *cred)
251 {
252         struct nfsnode *np = VTONFS(vp);
253         int attrflag;
254         int error = 0;
255         u_int32_t *tl;
256         u_int32_t rmode;
257         struct nfsm_info info;
258
259         info.mrep = NULL;
260         info.v3 = 1;
261
262         nfsstats.rpccnt[NFSPROC_ACCESS]++;
263         nfsm_reqhead(&info, vp, NFSPROC_ACCESS,
264                      NFSX_FH(info.v3) + NFSX_UNSIGNED);
265         ERROROUT(nfsm_fhtom(&info, vp));
266         tl = nfsm_build(&info, NFSX_UNSIGNED);
267         *tl = txdr_unsigned(wmode); 
268         NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_ACCESS, td, cred, &error));
269         ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, NFS_LATTR_NOSHRINK));
270         if (error == 0) {
271                 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED));
272                 rmode = fxdr_unsigned(u_int32_t, *tl);
273                 np->n_mode = rmode;
274                 np->n_modeuid = cred->cr_uid;
275                 np->n_modestamp = mycpu->gd_time_seconds;
276         }
277         m_freem(info.mrep);
278         info.mrep = NULL;
279 nfsmout:
280         return error;
281 }
282
283 /*
284  * nfs access vnode op.
285  * For nfs version 2, just return ok. File accesses may fail later.
286  * For nfs version 3, use the access rpc to check accessibility. If file modes
287  * are changed on the server, accesses might still fail later.
288  *
289  * nfs_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
290  */
291 static int
292 nfs_access(struct vop_access_args *ap)
293 {
294         struct vnode *vp = ap->a_vp;
295         thread_t td = curthread;
296         int error = 0;
297         u_int32_t mode, wmode;
298         struct nfsnode *np = VTONFS(vp);
299         int v3 = NFS_ISV3(vp);
300
301         /*
302          * Disallow write attempts on filesystems mounted read-only;
303          * unless the file is a socket, fifo, or a block or character
304          * device resident on the filesystem.
305          */
306         if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
307                 switch (vp->v_type) {
308                 case VREG:
309                 case VDIR:
310                 case VLNK:
311                         return (EROFS);
312                 default:
313                         break;
314                 }
315         }
316         /*
317          * For nfs v3, check to see if we have done this recently, and if
318          * so return our cached result instead of making an ACCESS call.
319          * If not, do an access rpc, otherwise you are stuck emulating
320          * ufs_access() locally using the vattr. This may not be correct,
321          * since the server may apply other access criteria such as
322          * client uid-->server uid mapping that we do not know about.
323          */
324         if (v3) {
325                 if (ap->a_mode & VREAD)
326                         mode = NFSV3ACCESS_READ;
327                 else
328                         mode = 0;
329                 if (vp->v_type != VDIR) {
330                         if (ap->a_mode & VWRITE)
331                                 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
332                         if (ap->a_mode & VEXEC)
333                                 mode |= NFSV3ACCESS_EXECUTE;
334                 } else {
335                         if (ap->a_mode & VWRITE)
336                                 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
337                                          NFSV3ACCESS_DELETE);
338                         if (ap->a_mode & VEXEC)
339                                 mode |= NFSV3ACCESS_LOOKUP;
340                 }
341                 /* XXX safety belt, only make blanket request if caching */
342                 if (nfsaccess_cache_timeout > 0) {
343                         wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY | 
344                                 NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE | 
345                                 NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP;
346                 } else {
347                         wmode = mode;
348                 }
349
350                 /*
351                  * Does our cached result allow us to give a definite yes to
352                  * this request?
353                  */
354                 if (np->n_modestamp && 
355                    (mycpu->gd_time_seconds < (np->n_modestamp + nfsaccess_cache_timeout)) &&
356                    (ap->a_cred->cr_uid == np->n_modeuid) &&
357                    ((np->n_mode & mode) == mode)) {
358                         nfsstats.accesscache_hits++;
359                 } else {
360                         /*
361                          * Either a no, or a don't know.  Go to the wire.
362                          */
363                         nfsstats.accesscache_misses++;
364                         error = nfs3_access_otw(vp, wmode, td, ap->a_cred);
365                         if (!error) {
366                                 if ((np->n_mode & mode) != mode) {
367                                         error = EACCES;
368                                 }
369                         }
370                 }
371         } else {
372                 if ((error = nfs_laccess(ap)) != 0)
373                         return (error);
374
375                 /*
376                  * Attempt to prevent a mapped root from accessing a file
377                  * which it shouldn't.  We try to read a byte from the file
378                  * if the user is root and the file is not zero length.
379                  * After calling nfs_laccess, we should have the correct
380                  * file size cached.
381                  */
382                 if (ap->a_cred->cr_uid == 0 && (ap->a_mode & VREAD)
383                     && VTONFS(vp)->n_size > 0) {
384                         struct iovec aiov;
385                         struct uio auio;
386                         char buf[1];
387
388                         aiov.iov_base = buf;
389                         aiov.iov_len = 1;
390                         auio.uio_iov = &aiov;
391                         auio.uio_iovcnt = 1;
392                         auio.uio_offset = 0;
393                         auio.uio_resid = 1;
394                         auio.uio_segflg = UIO_SYSSPACE;
395                         auio.uio_rw = UIO_READ;
396                         auio.uio_td = td;
397
398                         if (vp->v_type == VREG) {
399                                 error = nfs_readrpc_uio(vp, &auio);
400                         } else if (vp->v_type == VDIR) {
401                                 char* bp;
402                                 bp = kmalloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK);
403                                 aiov.iov_base = bp;
404                                 aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ;
405                                 error = nfs_readdirrpc_uio(vp, &auio);
406                                 kfree(bp, M_TEMP);
407                         } else if (vp->v_type == VLNK) {
408                                 error = nfs_readlinkrpc_uio(vp, &auio);
409                         } else {
410                                 error = EACCES;
411                         }
412                 }
413         }
414         /*
415          * [re]record creds for reading and/or writing if access
416          * was granted.  Assume the NFS server will grant read access
417          * for execute requests.
418          */
419         if (error == 0) {
420                 if ((ap->a_mode & (VREAD|VEXEC)) && ap->a_cred != np->n_rucred) {
421                         crhold(ap->a_cred);
422                         if (np->n_rucred)
423                                 crfree(np->n_rucred);
424                         np->n_rucred = ap->a_cred;
425                 }
426                 if ((ap->a_mode & VWRITE) && ap->a_cred != np->n_wucred) {
427                         crhold(ap->a_cred);
428                         if (np->n_wucred)
429                                 crfree(np->n_wucred);
430                         np->n_wucred = ap->a_cred;
431                 }
432         }
433         return(error);
434 }
435
436 /*
437  * nfs open vnode op
438  * Check to see if the type is ok
439  * and that deletion is not in progress.
440  * For paged in text files, you will need to flush the page cache
441  * if consistency is lost.
442  *
443  * nfs_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
444  *          struct file *a_fp)
445  */
446 /* ARGSUSED */
447 static int
448 nfs_open(struct vop_open_args *ap)
449 {
450         struct vnode *vp = ap->a_vp;
451         struct nfsnode *np = VTONFS(vp);
452         struct vattr vattr;
453         int error;
454
455         if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
456 #ifdef DIAGNOSTIC
457                 kprintf("open eacces vtyp=%d\n",vp->v_type);
458 #endif
459                 return (EOPNOTSUPP);
460         }
461
462         /*
463          * Save valid creds for reading and writing for later RPCs.
464          */
465         if ((ap->a_mode & FREAD) && ap->a_cred != np->n_rucred) {
466                 crhold(ap->a_cred);
467                 if (np->n_rucred)
468                         crfree(np->n_rucred);
469                 np->n_rucred = ap->a_cred;
470         }
471         if ((ap->a_mode & FWRITE) && ap->a_cred != np->n_wucred) {
472                 crhold(ap->a_cred);
473                 if (np->n_wucred)
474                         crfree(np->n_wucred);
475                 np->n_wucred = ap->a_cred;
476         }
477
478         /*
479          * Clear the attribute cache only if opening with write access.  It
480          * is unclear if we should do this at all here, but we certainly
481          * should not clear the cache unconditionally simply because a file
482          * is being opened.
483          */
484         if (ap->a_mode & FWRITE)
485                 np->n_attrstamp = 0;
486
487         /*
488          * For normal NFS, reconcile changes made locally verses 
489          * changes made remotely.  Note that VOP_GETATTR only goes
490          * to the wire if the cached attribute has timed out or been
491          * cleared.
492          *
493          * If local modifications have been made clear the attribute
494          * cache to force an attribute and modified time check.  If
495          * GETATTR detects that the file has been changed by someone
496          * other then us it will set NRMODIFIED.
497          *
498          * If we are opening a directory and local changes have been
499          * made we have to invalidate the cache in order to ensure
500          * that we get the most up-to-date information from the
501          * server.  XXX
502          */
503         if (np->n_flag & NLMODIFIED) {
504                 np->n_attrstamp = 0;
505                 if (vp->v_type == VDIR) {
506                         error = nfs_vinvalbuf(vp, V_SAVE, 1);
507                         if (error == EINTR)
508                                 return (error);
509                         nfs_invaldir(vp);
510                 }
511         }
512         error = VOP_GETATTR(vp, &vattr);
513         if (error)
514                 return (error);
515         if (np->n_flag & NRMODIFIED) {
516                 if (vp->v_type == VDIR)
517                         nfs_invaldir(vp);
518                 error = nfs_vinvalbuf(vp, V_SAVE, 1);
519                 if (error == EINTR)
520                         return (error);
521                 np->n_flag &= ~NRMODIFIED;
522         }
523
524         return (vop_stdopen(ap));
525 }
526
527 /*
528  * nfs close vnode op
529  * What an NFS client should do upon close after writing is a debatable issue.
530  * Most NFS clients push delayed writes to the server upon close, basically for
531  * two reasons:
532  * 1 - So that any write errors may be reported back to the client process
533  *     doing the close system call. By far the two most likely errors are
534  *     NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure.
535  * 2 - To put a worst case upper bound on cache inconsistency between
536  *     multiple clients for the file.
537  * There is also a consistency problem for Version 2 of the protocol w.r.t.
538  * not being able to tell if other clients are writing a file concurrently,
539  * since there is no way of knowing if the changed modify time in the reply
540  * is only due to the write for this client.
541  * (NFS Version 3 provides weak cache consistency data in the reply that
542  *  should be sufficient to detect and handle this case.)
543  *
544  * The current code does the following:
545  * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers
546  * for NFS Version 3 - flush dirty buffers to the server but don't invalidate
547  *                     or commit them (this satisfies 1 and 2 except for the
548  *                     case where the server crashes after this close but
549  *                     before the commit RPC, which is felt to be "good
550  *                     enough". Changing the last argument to nfs_flush() to
551  *                     a 1 would force a commit operation, if it is felt a
552  *                     commit is necessary now.
553  * for NQNFS         - do nothing now, since 2 is dealt with via leases and
554  *                     1 should be dealt with via an fsync() system call for
555  *                     cases where write errors are important.
556  *
557  * nfs_close(struct vnode *a_vp, int a_fflag)
558  */
559 /* ARGSUSED */
560 static int
561 nfs_close(struct vop_close_args *ap)
562 {
563         struct vnode *vp = ap->a_vp;
564         struct nfsnode *np = VTONFS(vp);
565         int error = 0;
566         thread_t td = curthread;
567
568         if (vp->v_type == VREG) {
569             if (np->n_flag & NLMODIFIED) {
570                 if (NFS_ISV3(vp)) {
571                     /*
572                      * Under NFSv3 we have dirty buffers to dispose of.  We
573                      * must flush them to the NFS server.  We have the option
574                      * of waiting all the way through the commit rpc or just
575                      * waiting for the initial write.  The default is to only
576                      * wait through the initial write so the data is in the
577                      * server's cache, which is roughly similar to the state
578                      * a standard disk subsystem leaves the file in on close().
579                      *
580                      * We cannot clear the NLMODIFIED bit in np->n_flag due to
581                      * potential races with other processes, and certainly
582                      * cannot clear it if we don't commit.
583                      */
584                     int cm = nfsv3_commit_on_close ? 1 : 0;
585                     error = nfs_flush(vp, MNT_WAIT, td, cm);
586                     /* np->n_flag &= ~NLMODIFIED; */
587                 } else {
588                     error = nfs_vinvalbuf(vp, V_SAVE, 1);
589                 }
590                 np->n_attrstamp = 0;
591             }
592             if (np->n_flag & NWRITEERR) {
593                 np->n_flag &= ~NWRITEERR;
594                 error = np->n_error;
595             }
596         }
597         vop_stdclose(ap);
598         return (error);
599 }
600
601 /*
602  * nfs getattr call from vfs.
603  *
604  * nfs_getattr(struct vnode *a_vp, struct vattr *a_vap)
605  */
606 static int
607 nfs_getattr(struct vop_getattr_args *ap)
608 {
609         struct vnode *vp = ap->a_vp;
610         struct nfsnode *np = VTONFS(vp);
611         int error = 0;
612         thread_t td = curthread;
613         struct nfsm_info info;
614
615         info.mrep = NULL;
616         info.v3 = NFS_ISV3(vp);
617         
618         /*
619          * Update local times for special files.
620          */
621         if (np->n_flag & (NACC | NUPD))
622                 np->n_flag |= NCHG;
623         /*
624          * First look in the cache.
625          */
626         if (nfs_getattrcache(vp, ap->a_vap) == 0)
627                 return (0);
628
629         if (info.v3 && nfsaccess_cache_timeout > 0) {
630                 nfsstats.accesscache_misses++;
631                 nfs3_access_otw(vp, NFSV3ACCESS_ALL, td, nfs_vpcred(vp, ND_CHECK));
632                 if (nfs_getattrcache(vp, ap->a_vap) == 0)
633                         return (0);
634         }
635
636         nfsstats.rpccnt[NFSPROC_GETATTR]++;
637         nfsm_reqhead(&info, vp, NFSPROC_GETATTR, NFSX_FH(info.v3));
638         ERROROUT(nfsm_fhtom(&info, vp));
639         NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_GETATTR, td,
640                                 nfs_vpcred(vp, ND_CHECK), &error));
641         if (error == 0) {
642                 ERROROUT(nfsm_loadattr(&info, vp, ap->a_vap));
643         }
644         m_freem(info.mrep);
645         info.mrep = NULL;
646 nfsmout:
647         return (error);
648 }
649
650 /*
651  * nfs setattr call.
652  *
653  * nfs_setattr(struct vnode *a_vp, struct vattr *a_vap, struct ucred *a_cred)
654  */
655 static int
656 nfs_setattr(struct vop_setattr_args *ap)
657 {
658         struct vnode *vp = ap->a_vp;
659         struct nfsnode *np = VTONFS(vp);
660         struct vattr *vap = ap->a_vap;
661         struct buf *bp;
662         int biosize = vp->v_mount->mnt_stat.f_iosize;
663         int error = 0;
664         int boff;
665         off_t tsize;
666         thread_t td = curthread;
667
668 #ifndef nolint
669         tsize = (off_t)0;
670 #endif
671
672         /*
673          * Setting of flags is not supported.
674          */
675         if (vap->va_flags != VNOVAL)
676                 return (EOPNOTSUPP);
677
678         /*
679          * Disallow write attempts if the filesystem is mounted read-only.
680          */
681         if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
682             vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
683             vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
684             (vp->v_mount->mnt_flag & MNT_RDONLY))
685                 return (EROFS);
686
687         if (vap->va_size != VNOVAL) {
688                 /*
689                  * truncation requested
690                  */
691                 switch (vp->v_type) {
692                 case VDIR:
693                         return (EISDIR);
694                 case VCHR:
695                 case VBLK:
696                 case VSOCK:
697                 case VFIFO:
698                         if (vap->va_mtime.tv_sec == VNOVAL &&
699                             vap->va_atime.tv_sec == VNOVAL &&
700                             vap->va_mode == (mode_t)VNOVAL &&
701                             vap->va_uid == (uid_t)VNOVAL &&
702                             vap->va_gid == (gid_t)VNOVAL)
703                                 return (0);
704                         vap->va_size = VNOVAL;
705                         break;
706                 default:
707                         /*
708                          * Disallow write attempts if the filesystem is
709                          * mounted read-only.
710                          */
711                         if (vp->v_mount->mnt_flag & MNT_RDONLY)
712                                 return (EROFS);
713
714                         /*
715                          * This is nasty.  The RPCs we send to flush pending
716                          * data often return attribute information which is
717                          * cached via a callback to nfs_loadattrcache(), which
718                          * has the effect of changing our notion of the file
719                          * size.  Due to flushed appends and other operations
720                          * the file size can be set to virtually anything, 
721                          * including values that do not match either the old
722                          * or intended file size.
723                          *
724                          * When this condition is detected we must loop to
725                          * try the operation again.  Hopefully no more
726                          * flushing is required on the loop so it works the
727                          * second time around.  THIS CASE ALMOST ALWAYS
728                          * HAPPENS!
729                          */
730                         tsize = np->n_size;
731 again:
732                         boff = (int)vap->va_size & (biosize - 1);
733                         bp = nfs_meta_setsize(vp, td, vap->va_size - boff,
734                                               boff, 0);
735                         if (bp) {
736                                 error = 0;
737                                 brelse(bp);
738                         } else {
739                                 error = EINTR;
740                         }
741
742                         if (np->n_flag & NLMODIFIED) {
743                             if (vap->va_size == 0)
744                                 error = nfs_vinvalbuf(vp, 0, 1);
745                             else
746                                 error = nfs_vinvalbuf(vp, V_SAVE, 1);
747                         }
748                         /*
749                          * note: this loop case almost always happens at 
750                          * least once per truncation.
751                          */
752                         if (error == 0 && np->n_size != vap->va_size)
753                                 goto again;
754                         np->n_vattr.va_size = vap->va_size;
755                         break;
756                 }
757         } else if ((np->n_flag & NLMODIFIED) && vp->v_type == VREG) {
758                 /*
759                  * What to do.  If we are modifying the mtime we lose
760                  * mtime detection of changes made by the server or other
761                  * clients.  But programs like rsync/rdist/cpdup are going
762                  * to call utimes a lot.  We don't want to piecemeal sync.
763                  *
764                  * For now sync if any prior remote changes were detected,
765                  * but allow us to lose track of remote changes made during
766                  * the utimes operation.
767                  */
768                 if (np->n_flag & NRMODIFIED)
769                         error = nfs_vinvalbuf(vp, V_SAVE, 1);
770                 if (error == EINTR)
771                         return (error);
772                 if (error == 0) {
773                         if (vap->va_mtime.tv_sec != VNOVAL) {
774                                 np->n_mtime = vap->va_mtime.tv_sec;
775                         }
776                 }
777         }
778         error = nfs_setattrrpc(vp, vap, ap->a_cred, td);
779
780         /*
781          * Sanity check if a truncation was issued.  This should only occur
782          * if multiple processes are racing on the same file.
783          */
784         if (error == 0 && vap->va_size != VNOVAL && 
785             np->n_size != vap->va_size) {
786                 kprintf("NFS ftruncate: server disagrees on the file size: "
787                         "%jd/%jd/%jd\n",
788                         (intmax_t)tsize,
789                         (intmax_t)vap->va_size,
790                         (intmax_t)np->n_size);
791                 goto again;
792         }
793         if (error && vap->va_size != VNOVAL) {
794                 np->n_size = np->n_vattr.va_size = tsize;
795                 boff = (int)np->n_size & (biosize - 1);
796                 vnode_pager_setsize(vp, np->n_size);
797         }
798         return (error);
799 }
800
801 /*
802  * Do an nfs setattr rpc.
803  */
804 static int
805 nfs_setattrrpc(struct vnode *vp, struct vattr *vap,
806                struct ucred *cred, struct thread *td)
807 {
808         struct nfsv2_sattr *sp;
809         struct nfsnode *np = VTONFS(vp);
810         u_int32_t *tl;
811         int error = 0, wccflag = NFSV3_WCCRATTR;
812         struct nfsm_info info;
813
814         info.mrep = NULL;
815         info.v3 = NFS_ISV3(vp);
816
817         nfsstats.rpccnt[NFSPROC_SETATTR]++;
818         nfsm_reqhead(&info, vp, NFSPROC_SETATTR,
819                      NFSX_FH(info.v3) + NFSX_SATTR(info.v3));
820         ERROROUT(nfsm_fhtom(&info, vp));
821         if (info.v3) {
822                 nfsm_v3attrbuild(&info, vap, TRUE);
823                 tl = nfsm_build(&info, NFSX_UNSIGNED);
824                 *tl = nfs_false;
825         } else {
826                 sp = nfsm_build(&info, NFSX_V2SATTR);
827                 if (vap->va_mode == (mode_t)VNOVAL)
828                         sp->sa_mode = nfs_xdrneg1;
829                 else
830                         sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode);
831                 if (vap->va_uid == (uid_t)VNOVAL)
832                         sp->sa_uid = nfs_xdrneg1;
833                 else
834                         sp->sa_uid = txdr_unsigned(vap->va_uid);
835                 if (vap->va_gid == (gid_t)VNOVAL)
836                         sp->sa_gid = nfs_xdrneg1;
837                 else
838                         sp->sa_gid = txdr_unsigned(vap->va_gid);
839                 sp->sa_size = txdr_unsigned(vap->va_size);
840                 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
841                 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
842         }
843         NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_SETATTR, td, cred, &error));
844         if (info.v3) {
845                 np->n_modestamp = 0;
846                 ERROROUT(nfsm_wcc_data(&info, vp, &wccflag));
847         } else {
848                 ERROROUT(nfsm_loadattr(&info, vp, NULL));
849         }
850         m_freem(info.mrep);
851         info.mrep = NULL;
852 nfsmout:
853         return (error);
854 }
855
856 static
857 void
858 nfs_cache_setvp(struct nchandle *nch, struct vnode *vp, int nctimeout)
859 {
860         if (nctimeout == 0)
861                 nctimeout = 1;
862         else
863                 nctimeout *= hz;
864         cache_setvp(nch, vp);
865         cache_settimeout(nch, nctimeout);
866 }
867
868 /*
869  * NEW API CALL - replaces nfs_lookup().  However, we cannot remove 
870  * nfs_lookup() until all remaining new api calls are implemented.
871  *
872  * Resolve a namecache entry.  This function is passed a locked ncp and
873  * must call nfs_cache_setvp() on it as appropriate to resolve the entry.
874  */
875 static int
876 nfs_nresolve(struct vop_nresolve_args *ap)
877 {
878         struct thread *td = curthread;
879         struct namecache *ncp;
880         struct ucred *cred;
881         struct nfsnode *np;
882         struct vnode *dvp;
883         struct vnode *nvp;
884         nfsfh_t *fhp;
885         int attrflag;
886         int fhsize;
887         int error;
888         int tmp_error;
889         int len;
890         struct nfsm_info info;
891
892         cred = ap->a_cred;
893         dvp = ap->a_dvp;
894
895         if ((error = vget(dvp, LK_SHARED)) != 0)
896                 return (error);
897
898         info.mrep = NULL;
899         info.v3 = NFS_ISV3(dvp);
900
901         nvp = NULL;
902         nfsstats.lookupcache_misses++;
903         nfsstats.rpccnt[NFSPROC_LOOKUP]++;
904         ncp = ap->a_nch->ncp;
905         len = ncp->nc_nlen;
906         nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP,
907                      NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len));
908         ERROROUT(nfsm_fhtom(&info, dvp));
909         ERROROUT(nfsm_strtom(&info, ncp->nc_name, len, NFS_MAXNAMLEN));
910         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, td,
911                                 ap->a_cred, &error));
912         if (error) {
913                 /*
914                  * Cache negatve lookups to reduce NFS traffic, but use
915                  * a fast timeout.  Otherwise use a timeout of 1 tick.
916                  * XXX we should add a namecache flag for no-caching
917                  * to uncache the negative hit as soon as possible, but
918                  * we cannot simply destroy the entry because it is used
919                  * as a placeholder by the caller.
920                  *
921                  * The refactored nfs code will overwrite a non-zero error
922                  * with 0 when we use ERROROUT(), so don't here.
923                  */
924                 if (error == ENOENT)
925                         nfs_cache_setvp(ap->a_nch, NULL, nfsneg_cache_timeout);
926                 tmp_error = nfsm_postop_attr(&info, dvp, &attrflag,
927                                              NFS_LATTR_NOSHRINK);
928                 if (tmp_error) {
929                         error = tmp_error;
930                         goto nfsmout;
931                 }
932                 m_freem(info.mrep);
933                 info.mrep = NULL;
934                 goto nfsmout;
935         }
936
937         /*
938          * Success, get the file handle, do various checks, and load 
939          * post-operation data from the reply packet.  Theoretically
940          * we should never be looking up "." so, theoretically, we
941          * should never get the same file handle as our directory.  But
942          * we check anyway. XXX
943          *
944          * Note that no timeout is set for the positive cache hit.  We
945          * assume, theoretically, that ESTALE returns will be dealt with
946          * properly to handle NFS races and in anycase we cannot depend
947          * on a timeout to deal with NFS open/create/excl issues so instead
948          * of a bad hack here the rest of the NFS client code needs to do
949          * the right thing.
950          */
951         NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp));
952
953         np = VTONFS(dvp);
954         if (NFS_CMPFH(np, fhp, fhsize)) {
955                 vref(dvp);
956                 nvp = dvp;
957         } else {
958                 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
959                 if (error) {
960                         m_freem(info.mrep);
961                         info.mrep = NULL;
962                         vput(dvp);
963                         return (error);
964                 }
965                 nvp = NFSTOV(np);
966         }
967         if (info.v3) {
968                 ERROROUT(nfsm_postop_attr(&info, nvp, &attrflag,
969                                           NFS_LATTR_NOSHRINK));
970                 ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag,
971                                           NFS_LATTR_NOSHRINK));
972         } else {
973                 ERROROUT(nfsm_loadattr(&info, nvp, NULL));
974         }
975         nfs_cache_setvp(ap->a_nch, nvp, nfspos_cache_timeout);
976         m_freem(info.mrep);
977         info.mrep = NULL;
978 nfsmout:
979         vput(dvp);
980         if (nvp) {
981                 if (nvp == dvp)
982                         vrele(nvp);
983                 else
984                         vput(nvp);
985         }
986         return (error);
987 }
988
989 /*
990  * 'cached' nfs directory lookup
991  *
992  * NOTE: cannot be removed until NFS implements all the new n*() API calls.
993  *
994  * nfs_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
995  *            struct componentname *a_cnp)
996  */
997 static int
998 nfs_lookup(struct vop_old_lookup_args *ap)
999 {
1000         struct componentname *cnp = ap->a_cnp;
1001         struct vnode *dvp = ap->a_dvp;
1002         struct vnode **vpp = ap->a_vpp;
1003         int flags = cnp->cn_flags;
1004         struct vnode *newvp;
1005         struct nfsmount *nmp;
1006         long len;
1007         nfsfh_t *fhp;
1008         struct nfsnode *np;
1009         int lockparent, wantparent, attrflag, fhsize;
1010         int error;
1011         int tmp_error;
1012         struct nfsm_info info;
1013
1014         info.mrep = NULL;
1015         info.v3 = NFS_ISV3(dvp);
1016         error = 0;
1017
1018         /*
1019          * Read-only mount check and directory check.
1020          */
1021         *vpp = NULLVP;
1022         if ((dvp->v_mount->mnt_flag & MNT_RDONLY) &&
1023             (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME))
1024                 return (EROFS);
1025
1026         if (dvp->v_type != VDIR)
1027                 return (ENOTDIR);
1028
1029         /*
1030          * Look it up in the cache.  Note that ENOENT is only returned if we
1031          * previously entered a negative hit (see later on).  The additional
1032          * nfsneg_cache_timeout check causes previously cached results to
1033          * be instantly ignored if the negative caching is turned off.
1034          */
1035         lockparent = flags & CNP_LOCKPARENT;
1036         wantparent = flags & (CNP_LOCKPARENT|CNP_WANTPARENT);
1037         nmp = VFSTONFS(dvp->v_mount);
1038         np = VTONFS(dvp);
1039
1040         /*
1041          * Go to the wire.
1042          */
1043         error = 0;
1044         newvp = NULLVP;
1045         nfsstats.lookupcache_misses++;
1046         nfsstats.rpccnt[NFSPROC_LOOKUP]++;
1047         len = cnp->cn_namelen;
1048         nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP,
1049                      NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len));
1050         ERROROUT(nfsm_fhtom(&info, dvp));
1051         ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN));
1052         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, cnp->cn_td,
1053                                 cnp->cn_cred, &error));
1054         if (error) {
1055                 tmp_error = nfsm_postop_attr(&info, dvp, &attrflag,
1056                                              NFS_LATTR_NOSHRINK);
1057                 if (tmp_error) {
1058                         error = tmp_error;
1059                         goto nfsmout;
1060                 }
1061
1062                 m_freem(info.mrep);
1063                 info.mrep = NULL;
1064                 goto nfsmout;
1065         }
1066         NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp));
1067
1068         /*
1069          * Handle RENAME case...
1070          */
1071         if (cnp->cn_nameiop == NAMEI_RENAME && wantparent) {
1072                 if (NFS_CMPFH(np, fhp, fhsize)) {
1073                         m_freem(info.mrep);
1074                         info.mrep = NULL;
1075                         return (EISDIR);
1076                 }
1077                 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
1078                 if (error) {
1079                         m_freem(info.mrep);
1080                         info.mrep = NULL;
1081                         return (error);
1082                 }
1083                 newvp = NFSTOV(np);
1084                 if (info.v3) {
1085                         ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag,
1086                                                   NFS_LATTR_NOSHRINK));
1087                         ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag,
1088                                                   NFS_LATTR_NOSHRINK));
1089                 } else {
1090                         ERROROUT(nfsm_loadattr(&info, newvp, NULL));
1091                 }
1092                 *vpp = newvp;
1093                 m_freem(info.mrep);
1094                 info.mrep = NULL;
1095                 if (!lockparent) {
1096                         vn_unlock(dvp);
1097                         cnp->cn_flags |= CNP_PDIRUNLOCK;
1098                 }
1099                 return (0);
1100         }
1101
1102         if (flags & CNP_ISDOTDOT) {
1103                 vn_unlock(dvp);
1104                 cnp->cn_flags |= CNP_PDIRUNLOCK;
1105                 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
1106                 if (error) {
1107                         vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1108                         cnp->cn_flags &= ~CNP_PDIRUNLOCK;
1109                         return (error); /* NOTE: return error from nget */
1110                 }
1111                 newvp = NFSTOV(np);
1112                 if (lockparent) {
1113                         error = vn_lock(dvp, LK_EXCLUSIVE);
1114                         if (error) {
1115                                 vput(newvp);
1116                                 return (error);
1117                         }
1118                         cnp->cn_flags |= CNP_PDIRUNLOCK;
1119                 }
1120         } else if (NFS_CMPFH(np, fhp, fhsize)) {
1121                 vref(dvp);
1122                 newvp = dvp;
1123         } else {
1124                 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
1125                 if (error) {
1126                         m_freem(info.mrep);
1127                         info.mrep = NULL;
1128                         return (error);
1129                 }
1130                 if (!lockparent) {
1131                         vn_unlock(dvp);
1132                         cnp->cn_flags |= CNP_PDIRUNLOCK;
1133                 }
1134                 newvp = NFSTOV(np);
1135         }
1136         if (info.v3) {
1137                 ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag,
1138                                           NFS_LATTR_NOSHRINK));
1139                 ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag,
1140                                           NFS_LATTR_NOSHRINK));
1141         } else {
1142                 ERROROUT(nfsm_loadattr(&info, newvp, NULL));
1143         }
1144 #if 0
1145         /* XXX MOVE TO nfs_nremove() */
1146         if ((cnp->cn_flags & CNP_MAKEENTRY) &&
1147             cnp->cn_nameiop != NAMEI_DELETE) {
1148                 np->n_ctime = np->n_vattr.va_ctime.tv_sec; /* XXX */
1149         }
1150 #endif
1151         *vpp = newvp;
1152         m_freem(info.mrep);
1153         info.mrep = NULL;
1154 nfsmout:
1155         if (error) {
1156                 if (newvp != NULLVP) {
1157                         vrele(newvp);
1158                         *vpp = NULLVP;
1159                 }
1160                 if ((cnp->cn_nameiop == NAMEI_CREATE || 
1161                      cnp->cn_nameiop == NAMEI_RENAME) &&
1162                     error == ENOENT) {
1163                         if (!lockparent) {
1164                                 vn_unlock(dvp);
1165                                 cnp->cn_flags |= CNP_PDIRUNLOCK;
1166                         }
1167                         if (dvp->v_mount->mnt_flag & MNT_RDONLY)
1168                                 error = EROFS;
1169                         else
1170                                 error = EJUSTRETURN;
1171                 }
1172         }
1173         return (error);
1174 }
1175
1176 /*
1177  * nfs read call.
1178  * Just call nfs_bioread() to do the work.
1179  *
1180  * nfs_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
1181  *          struct ucred *a_cred)
1182  */
1183 static int
1184 nfs_read(struct vop_read_args *ap)
1185 {
1186         struct vnode *vp = ap->a_vp;
1187
1188         return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag));
1189 }
1190
1191 /*
1192  * nfs readlink call
1193  *
1194  * nfs_readlink(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
1195  */
1196 static int
1197 nfs_readlink(struct vop_readlink_args *ap)
1198 {
1199         struct vnode *vp = ap->a_vp;
1200
1201         if (vp->v_type != VLNK)
1202                 return (EINVAL);
1203         return (nfs_bioread(vp, ap->a_uio, 0));
1204 }
1205
1206 /*
1207  * Do a readlink rpc.
1208  * Called by nfs_doio() from below the buffer cache.
1209  */
1210 int
1211 nfs_readlinkrpc_uio(struct vnode *vp, struct uio *uiop)
1212 {
1213         int error = 0, len, attrflag;
1214         struct nfsm_info info;
1215
1216         info.mrep = NULL;
1217         info.v3 = NFS_ISV3(vp);
1218
1219         nfsstats.rpccnt[NFSPROC_READLINK]++;
1220         nfsm_reqhead(&info, vp, NFSPROC_READLINK, NFSX_FH(info.v3));
1221         ERROROUT(nfsm_fhtom(&info, vp));
1222         NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READLINK, uiop->uio_td,
1223                                 nfs_vpcred(vp, ND_CHECK), &error));
1224         if (info.v3) {
1225                 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag,
1226                                           NFS_LATTR_NOSHRINK));
1227         }
1228         if (!error) {
1229                 NEGATIVEOUT(len = nfsm_strsiz(&info, NFS_MAXPATHLEN));
1230                 if (len == NFS_MAXPATHLEN) {
1231                         struct nfsnode *np = VTONFS(vp);
1232                         if (np->n_size && np->n_size < NFS_MAXPATHLEN)
1233                                 len = np->n_size;
1234                 }
1235                 ERROROUT(nfsm_mtouio(&info, uiop, len));
1236         }
1237         m_freem(info.mrep);
1238         info.mrep = NULL;
1239 nfsmout:
1240         return (error);
1241 }
1242
1243 /*
1244  * nfs synchronous read rpc using UIO
1245  */
1246 int
1247 nfs_readrpc_uio(struct vnode *vp, struct uio *uiop)
1248 {
1249         u_int32_t *tl;
1250         struct nfsmount *nmp;
1251         int error = 0, len, retlen, tsiz, eof, attrflag;
1252         struct nfsm_info info;
1253         off_t tmp_off;
1254
1255         info.mrep = NULL;
1256         info.v3 = NFS_ISV3(vp);
1257
1258 #ifndef nolint
1259         eof = 0;
1260 #endif
1261         nmp = VFSTONFS(vp->v_mount);
1262         tsiz = uiop->uio_resid;
1263         tmp_off = uiop->uio_offset + tsiz;
1264         if (tmp_off > nmp->nm_maxfilesize || tmp_off < uiop->uio_offset)
1265                 return (EFBIG);
1266         tmp_off = uiop->uio_offset;
1267         while (tsiz > 0) {
1268                 nfsstats.rpccnt[NFSPROC_READ]++;
1269                 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
1270                 nfsm_reqhead(&info, vp, NFSPROC_READ,
1271                              NFSX_FH(info.v3) + NFSX_UNSIGNED * 3);
1272                 ERROROUT(nfsm_fhtom(&info, vp));
1273                 tl = nfsm_build(&info, NFSX_UNSIGNED * 3);
1274                 if (info.v3) {
1275                         txdr_hyper(uiop->uio_offset, tl);
1276                         *(tl + 2) = txdr_unsigned(len);
1277                 } else {
1278                         *tl++ = txdr_unsigned(uiop->uio_offset);
1279                         *tl++ = txdr_unsigned(len);
1280                         *tl = 0;
1281                 }
1282                 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READ, uiop->uio_td,
1283                                         nfs_vpcred(vp, ND_READ), &error));
1284                 if (info.v3) {
1285                         ERROROUT(nfsm_postop_attr(&info, vp, &attrflag,
1286                                                  NFS_LATTR_NOSHRINK));
1287                         NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED));
1288                         eof = fxdr_unsigned(int, *(tl + 1));
1289                 } else {
1290                         ERROROUT(nfsm_loadattr(&info, vp, NULL));
1291                 }
1292                 NEGATIVEOUT(retlen = nfsm_strsiz(&info, len));
1293                 ERROROUT(nfsm_mtouio(&info, uiop, retlen));
1294                 m_freem(info.mrep);
1295                 info.mrep = NULL;
1296
1297                 /*
1298                  * Handle short-read from server (NFSv3).  If EOF is not
1299                  * flagged (and no error occurred), but retlen is less
1300                  * then the request size, we must zero-fill the remainder.
1301                  */
1302                 if (retlen < len && info.v3 && eof == 0) {
1303                         ERROROUT(uiomovez(len - retlen, uiop));
1304                         retlen = len;
1305                 }
1306                 tsiz -= retlen;
1307
1308                 /*
1309                  * Terminate loop on EOF or zero-length read.
1310                  *
1311                  * For NFSv2 a short-read indicates EOF, not zero-fill,
1312                  * and also terminates the loop.
1313                  */
1314                 if (info.v3) {
1315                         if (eof || retlen == 0)
1316                                 tsiz = 0;
1317                 } else if (retlen < len) {
1318                         tsiz = 0;
1319                 }
1320         }
1321 nfsmout:
1322         return (error);
1323 }
1324
1325 /*
1326  * nfs write call
1327  */
1328 int
1329 nfs_writerpc_uio(struct vnode *vp, struct uio *uiop,
1330                  int *iomode, int *must_commit)
1331 {
1332         u_int32_t *tl;
1333         int32_t backup;
1334         struct nfsmount *nmp = VFSTONFS(vp->v_mount);
1335         int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit;
1336         int  committed = NFSV3WRITE_FILESYNC;
1337         struct nfsm_info info;
1338
1339         info.mrep = NULL;
1340         info.v3 = NFS_ISV3(vp);
1341
1342 #ifndef DIAGNOSTIC
1343         if (uiop->uio_iovcnt != 1)
1344                 panic("nfs: writerpc iovcnt > 1");
1345 #endif
1346         *must_commit = 0;
1347         tsiz = uiop->uio_resid;
1348         if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
1349                 return (EFBIG);
1350         while (tsiz > 0) {
1351                 nfsstats.rpccnt[NFSPROC_WRITE]++;
1352                 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
1353                 nfsm_reqhead(&info, vp, NFSPROC_WRITE,
1354                              NFSX_FH(info.v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len));
1355                 ERROROUT(nfsm_fhtom(&info, vp));
1356                 if (info.v3) {
1357                         tl = nfsm_build(&info, 5 * NFSX_UNSIGNED);
1358                         txdr_hyper(uiop->uio_offset, tl);
1359                         tl += 2;
1360                         *tl++ = txdr_unsigned(len);
1361                         *tl++ = txdr_unsigned(*iomode);
1362                         *tl = txdr_unsigned(len);
1363                 } else {
1364                         u_int32_t x;
1365
1366                         tl = nfsm_build(&info, 4 * NFSX_UNSIGNED);
1367                         /* Set both "begin" and "current" to non-garbage. */
1368                         x = txdr_unsigned((u_int32_t)uiop->uio_offset);
1369                         *tl++ = x;      /* "begin offset" */
1370                         *tl++ = x;      /* "current offset" */
1371                         x = txdr_unsigned(len);
1372                         *tl++ = x;      /* total to this offset */
1373                         *tl = x;        /* size of this write */
1374                 }
1375                 ERROROUT(nfsm_uiotom(&info, uiop, len));
1376                 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_WRITE, uiop->uio_td,
1377                                         nfs_vpcred(vp, ND_WRITE), &error));
1378                 if (info.v3) {
1379                         /*
1380                          * The write RPC returns a before and after mtime.  The
1381                          * nfsm_wcc_data() macro checks the before n_mtime
1382                          * against the before time and stores the after time
1383                          * in the nfsnode's cached vattr and n_mtime field.
1384                          * The NRMODIFIED bit will be set if the before
1385                          * time did not match the original mtime.
1386                          */
1387                         wccflag = NFSV3_WCCCHK;
1388                         ERROROUT(nfsm_wcc_data(&info, vp, &wccflag));
1389                         if (error == 0) {
1390                                 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED + NFSX_V3WRITEVERF));
1391                                 rlen = fxdr_unsigned(int, *tl++);
1392                                 if (rlen == 0) {
1393                                         error = NFSERR_IO;
1394                                         m_freem(info.mrep);
1395                                         info.mrep = NULL;
1396                                         break;
1397                                 } else if (rlen < len) {
1398                                         backup = len - rlen;
1399                                         uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base - backup;
1400                                         uiop->uio_iov->iov_len += backup;
1401                                         uiop->uio_offset -= backup;
1402                                         uiop->uio_resid += backup;
1403                                         len = rlen;
1404                                 }
1405                                 commit = fxdr_unsigned(int, *tl++);
1406
1407                                 /*
1408                                  * Return the lowest committment level
1409                                  * obtained by any of the RPCs.
1410                                  */
1411                                 if (committed == NFSV3WRITE_FILESYNC)
1412                                         committed = commit;
1413                                 else if (committed == NFSV3WRITE_DATASYNC &&
1414                                         commit == NFSV3WRITE_UNSTABLE)
1415                                         committed = commit;
1416                                 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){
1417                                     bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
1418                                         NFSX_V3WRITEVERF);
1419                                     nmp->nm_state |= NFSSTA_HASWRITEVERF;
1420                                 } else if (bcmp((caddr_t)tl,
1421                                     (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) {
1422                                     *must_commit = 1;
1423                                     bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
1424                                         NFSX_V3WRITEVERF);
1425                                 }
1426                         }
1427                 } else {
1428                         ERROROUT(nfsm_loadattr(&info, vp, NULL));
1429                 }
1430                 m_freem(info.mrep);
1431                 info.mrep = NULL;
1432                 if (error)
1433                         break;
1434                 tsiz -= len;
1435         }
1436 nfsmout:
1437         if (vp->v_mount->mnt_flag & MNT_ASYNC)
1438                 committed = NFSV3WRITE_FILESYNC;
1439         *iomode = committed;
1440         if (error)
1441                 uiop->uio_resid = tsiz;
1442         return (error);
1443 }
1444
1445 /*
1446  * nfs mknod rpc
1447  * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
1448  * mode set to specify the file type and the size field for rdev.
1449  */
1450 static int
1451 nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
1452              struct vattr *vap)
1453 {
1454         struct nfsv2_sattr *sp;
1455         u_int32_t *tl;
1456         struct vnode *newvp = NULL;
1457         struct nfsnode *np = NULL;
1458         struct vattr vattr;
1459         int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0;
1460         int rmajor, rminor;
1461         struct nfsm_info info;
1462
1463         info.mrep = NULL;
1464         info.v3 = NFS_ISV3(dvp);
1465
1466         if (vap->va_type == VCHR || vap->va_type == VBLK) {
1467                 rmajor = txdr_unsigned(vap->va_rmajor);
1468                 rminor = txdr_unsigned(vap->va_rminor);
1469         } else if (vap->va_type == VFIFO || vap->va_type == VSOCK) {
1470                 rmajor = nfs_xdrneg1;
1471                 rminor = nfs_xdrneg1;
1472         } else {
1473                 return (EOPNOTSUPP);
1474         }
1475         if ((error = VOP_GETATTR(dvp, &vattr)) != 0) {
1476                 return (error);
1477         }
1478         nfsstats.rpccnt[NFSPROC_MKNOD]++;
1479         nfsm_reqhead(&info, dvp, NFSPROC_MKNOD,
1480                      NFSX_FH(info.v3) + 4 * NFSX_UNSIGNED +
1481                      nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.v3));
1482         ERROROUT(nfsm_fhtom(&info, dvp));
1483         ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
1484                              NFS_MAXNAMLEN));
1485         if (info.v3) {
1486                 tl = nfsm_build(&info, NFSX_UNSIGNED);
1487                 *tl++ = vtonfsv3_type(vap->va_type);
1488                 nfsm_v3attrbuild(&info, vap, FALSE);
1489                 if (vap->va_type == VCHR || vap->va_type == VBLK) {
1490                         tl = nfsm_build(&info, 2 * NFSX_UNSIGNED);
1491                         *tl++ = txdr_unsigned(vap->va_rmajor);
1492                         *tl = txdr_unsigned(vap->va_rminor);
1493                 }
1494         } else {
1495                 sp = nfsm_build(&info, NFSX_V2SATTR);
1496                 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1497                 sp->sa_uid = nfs_xdrneg1;
1498                 sp->sa_gid = nfs_xdrneg1;
1499                 sp->sa_size = makeudev(rmajor, rminor);
1500                 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1501                 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1502         }
1503         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_MKNOD, cnp->cn_td,
1504                                 cnp->cn_cred, &error));
1505         if (!error) {
1506                 ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp));
1507                 if (!gotvp) {
1508                         if (newvp) {
1509                                 vput(newvp);
1510                                 newvp = NULL;
1511                         }
1512                         error = nfs_lookitup(dvp, cnp->cn_nameptr,
1513                             cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np);
1514                         if (!error)
1515                                 newvp = NFSTOV(np);
1516                 }
1517         }
1518         if (info.v3) {
1519                 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag));
1520         }
1521         m_freem(info.mrep);
1522         info.mrep = NULL;
1523 nfsmout:
1524         if (error) {
1525                 if (newvp)
1526                         vput(newvp);
1527         } else {
1528                 *vpp = newvp;
1529         }
1530         VTONFS(dvp)->n_flag |= NLMODIFIED;
1531         if (!wccflag)
1532                 VTONFS(dvp)->n_attrstamp = 0;
1533         return (error);
1534 }
1535
1536 /*
1537  * nfs mknod vop
1538  * just call nfs_mknodrpc() to do the work.
1539  *
1540  * nfs_mknod(struct vnode *a_dvp, struct vnode **a_vpp,
1541  *           struct componentname *a_cnp, struct vattr *a_vap)
1542  */
1543 /* ARGSUSED */
1544 static int
1545 nfs_mknod(struct vop_old_mknod_args *ap)
1546 {
1547         return nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap);
1548 }
1549
1550 static u_long create_verf;
1551 /*
1552  * nfs file create call
1553  *
1554  * nfs_create(struct vnode *a_dvp, struct vnode **a_vpp,
1555  *            struct componentname *a_cnp, struct vattr *a_vap)
1556  */
1557 static int
1558 nfs_create(struct vop_old_create_args *ap)
1559 {
1560         struct vnode *dvp = ap->a_dvp;
1561         struct vattr *vap = ap->a_vap;
1562         struct componentname *cnp = ap->a_cnp;
1563         struct nfsv2_sattr *sp;
1564         u_int32_t *tl;
1565         struct nfsnode *np = NULL;
1566         struct vnode *newvp = NULL;
1567         int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0;
1568         struct vattr vattr;
1569         struct nfsm_info info;
1570
1571         info.mrep = NULL;
1572         info.v3 = NFS_ISV3(dvp);
1573
1574         /*
1575          * Oops, not for me..
1576          */
1577         if (vap->va_type == VSOCK)
1578                 return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap));
1579
1580         if ((error = VOP_GETATTR(dvp, &vattr)) != 0) {
1581                 return (error);
1582         }
1583         if (vap->va_vaflags & VA_EXCLUSIVE)
1584                 fmode |= O_EXCL;
1585 again:
1586         nfsstats.rpccnt[NFSPROC_CREATE]++;
1587         nfsm_reqhead(&info, dvp, NFSPROC_CREATE,
1588                      NFSX_FH(info.v3) + 2 * NFSX_UNSIGNED +
1589                      nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.v3));
1590         ERROROUT(nfsm_fhtom(&info, dvp));
1591         ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
1592                              NFS_MAXNAMLEN));
1593         if (info.v3) {
1594                 tl = nfsm_build(&info, NFSX_UNSIGNED);
1595                 if (fmode & O_EXCL) {
1596                         *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
1597                         tl = nfsm_build(&info, NFSX_V3CREATEVERF);
1598 #ifdef INET
1599                         if (!TAILQ_EMPTY(&in_ifaddrheads[mycpuid]))
1600                                 *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrheads[mycpuid])->ia)->sin_addr.s_addr;
1601                         else
1602 #endif
1603                                 *tl++ = create_verf;
1604                         *tl = ++create_verf;
1605                 } else {
1606                         *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED);
1607                         nfsm_v3attrbuild(&info, vap, FALSE);
1608                 }
1609         } else {
1610                 sp = nfsm_build(&info, NFSX_V2SATTR);
1611                 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1612                 sp->sa_uid = nfs_xdrneg1;
1613                 sp->sa_gid = nfs_xdrneg1;
1614                 sp->sa_size = 0;
1615                 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1616                 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1617         }
1618         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_CREATE, cnp->cn_td,
1619                                 cnp->cn_cred, &error));
1620         if (error == 0) {
1621                 ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp));
1622                 if (!gotvp) {
1623                         if (newvp) {
1624                                 vput(newvp);
1625                                 newvp = NULL;
1626                         }
1627                         error = nfs_lookitup(dvp, cnp->cn_nameptr,
1628                             cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np);
1629                         if (!error)
1630                                 newvp = NFSTOV(np);
1631                 }
1632         }
1633         if (info.v3) {
1634                 if (error == 0)
1635                         error = nfsm_wcc_data(&info, dvp, &wccflag);
1636                 else
1637                         (void)nfsm_wcc_data(&info, dvp, &wccflag);
1638         }
1639         m_freem(info.mrep);
1640         info.mrep = NULL;
1641 nfsmout:
1642         if (error) {
1643                 if (info.v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) {
1644                         KKASSERT(newvp == NULL);
1645                         fmode &= ~O_EXCL;
1646                         goto again;
1647                 }
1648         } else if (info.v3 && (fmode & O_EXCL)) {
1649                 /*
1650                  * We are normally called with only a partially initialized
1651                  * VAP.  Since the NFSv3 spec says that server may use the
1652                  * file attributes to store the verifier, the spec requires
1653                  * us to do a SETATTR RPC. FreeBSD servers store the verifier
1654                  * in atime, but we can't really assume that all servers will
1655                  * so we ensure that our SETATTR sets both atime and mtime.
1656                  */
1657                 if (vap->va_mtime.tv_sec == VNOVAL)
1658                         vfs_timestamp(&vap->va_mtime);
1659                 if (vap->va_atime.tv_sec == VNOVAL)
1660                         vap->va_atime = vap->va_mtime;
1661                 error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_td);
1662         }
1663         if (error == 0) {
1664                 /*
1665                  * The new np may have enough info for access
1666                  * checks, make sure rucred and wucred are
1667                  * initialized for read and write rpc's.
1668                  */
1669                 np = VTONFS(newvp);
1670                 if (np->n_rucred == NULL)
1671                         np->n_rucred = crhold(cnp->cn_cred);
1672                 if (np->n_wucred == NULL)
1673                         np->n_wucred = crhold(cnp->cn_cred);
1674                 *ap->a_vpp = newvp;
1675         } else if (newvp) {
1676                 vput(newvp);
1677         }
1678         VTONFS(dvp)->n_flag |= NLMODIFIED;
1679         if (!wccflag)
1680                 VTONFS(dvp)->n_attrstamp = 0;
1681         return (error);
1682 }
1683
1684 /*
1685  * nfs file remove call
1686  * To try and make nfs semantics closer to ufs semantics, a file that has
1687  * other processes using the vnode is renamed instead of removed and then
1688  * removed later on the last close.
1689  * - If v_sysref.refcnt > 1
1690  *        If a rename is not already in the works
1691  *           call nfs_sillyrename() to set it up
1692  *     else
1693  *        do the remove rpc
1694  *
1695  * nfs_remove(struct vnode *a_dvp, struct vnode *a_vp,
1696  *            struct componentname *a_cnp)
1697  */
1698 static int
1699 nfs_remove(struct vop_old_remove_args *ap)
1700 {
1701         struct vnode *vp = ap->a_vp;
1702         struct vnode *dvp = ap->a_dvp;
1703         struct componentname *cnp = ap->a_cnp;
1704         struct nfsnode *np = VTONFS(vp);
1705         int error = 0;
1706         struct vattr vattr;
1707
1708 #ifndef DIAGNOSTIC
1709         if (vp->v_sysref.refcnt < 1)
1710                 panic("nfs_remove: bad v_sysref.refcnt");
1711 #endif
1712         if (vp->v_type == VDIR)
1713                 error = EPERM;
1714         else if (vp->v_sysref.refcnt == 1 || (np->n_sillyrename &&
1715             VOP_GETATTR(vp, &vattr) == 0 &&
1716             vattr.va_nlink > 1)) {
1717                 /*
1718                  * throw away biocache buffers, mainly to avoid
1719                  * unnecessary delayed writes later.
1720                  */
1721                 error = nfs_vinvalbuf(vp, 0, 1);
1722                 /* Do the rpc */
1723                 if (error != EINTR)
1724                         error = nfs_removerpc(dvp, cnp->cn_nameptr,
1725                                 cnp->cn_namelen, cnp->cn_cred, cnp->cn_td);
1726                 /*
1727                  * Kludge City: If the first reply to the remove rpc is lost..
1728                  *   the reply to the retransmitted request will be ENOENT
1729                  *   since the file was in fact removed
1730                  *   Therefore, we cheat and return success.
1731                  */
1732                 if (error == ENOENT)
1733                         error = 0;
1734         } else if (!np->n_sillyrename) {
1735                 error = nfs_sillyrename(dvp, vp, cnp);
1736         }
1737         np->n_attrstamp = 0;
1738         return (error);
1739 }
1740
1741 /*
1742  * nfs file remove rpc called from nfs_inactive
1743  */
1744 int
1745 nfs_removeit(struct sillyrename *sp)
1746 {
1747         return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen,
1748                 sp->s_cred, NULL));
1749 }
1750
1751 /*
1752  * Nfs remove rpc, called from nfs_remove() and nfs_removeit().
1753  */
1754 static int
1755 nfs_removerpc(struct vnode *dvp, const char *name, int namelen,
1756               struct ucred *cred, struct thread *td)
1757 {
1758         int error = 0, wccflag = NFSV3_WCCRATTR;
1759         struct nfsm_info info;
1760
1761         info.mrep = NULL;
1762         info.v3 = NFS_ISV3(dvp);
1763
1764         nfsstats.rpccnt[NFSPROC_REMOVE]++;
1765         nfsm_reqhead(&info, dvp, NFSPROC_REMOVE,
1766                      NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(namelen));
1767         ERROROUT(nfsm_fhtom(&info, dvp));
1768         ERROROUT(nfsm_strtom(&info, name, namelen, NFS_MAXNAMLEN));
1769         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_REMOVE, td, cred, &error));
1770         if (info.v3) {
1771                 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag));
1772         }
1773         m_freem(info.mrep);
1774         info.mrep = NULL;
1775 nfsmout:
1776         VTONFS(dvp)->n_flag |= NLMODIFIED;
1777         if (!wccflag)
1778                 VTONFS(dvp)->n_attrstamp = 0;
1779         return (error);
1780 }
1781
1782 /*
1783  * nfs file rename call
1784  *
1785  * nfs_rename(struct vnode *a_fdvp, struct vnode *a_fvp,
1786  *            struct componentname *a_fcnp, struct vnode *a_tdvp,
1787  *            struct vnode *a_tvp, struct componentname *a_tcnp)
1788  */
1789 static int
1790 nfs_rename(struct vop_old_rename_args *ap)
1791 {
1792         struct vnode *fvp = ap->a_fvp;
1793         struct vnode *tvp = ap->a_tvp;
1794         struct vnode *fdvp = ap->a_fdvp;
1795         struct vnode *tdvp = ap->a_tdvp;
1796         struct componentname *tcnp = ap->a_tcnp;
1797         struct componentname *fcnp = ap->a_fcnp;
1798         int error;
1799
1800         /* Check for cross-device rename */
1801         if ((fvp->v_mount != tdvp->v_mount) ||
1802             (tvp && (fvp->v_mount != tvp->v_mount))) {
1803                 error = EXDEV;
1804                 goto out;
1805         }
1806
1807         /*
1808          * We shouldn't have to flush fvp on rename for most server-side
1809          * filesystems as the file handle should not change.  Unfortunately
1810          * the inode for some filesystems (msdosfs) might be tied to the
1811          * file name or directory position so to be completely safe
1812          * vfs.nfs.flush_on_rename is set by default.  Clear to improve
1813          * performance.
1814          *
1815          * We must flush tvp on rename because it might become stale on the
1816          * server after the rename.
1817          */
1818         if (nfs_flush_on_rename)
1819             VOP_FSYNC(fvp, MNT_WAIT, 0);
1820         if (tvp)
1821             VOP_FSYNC(tvp, MNT_WAIT, 0);
1822
1823         /*
1824          * If the tvp exists and is in use, sillyrename it before doing the
1825          * rename of the new file over it.
1826          *
1827          * XXX Can't sillyrename a directory.
1828          *
1829          * We do not attempt to do any namecache purges in this old API
1830          * routine.  The new API compat functions have access to the actual
1831          * namecache structures and will do it for us.
1832          */
1833         if (tvp && tvp->v_sysref.refcnt > 1 && !VTONFS(tvp)->n_sillyrename &&
1834                 tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) {
1835                 vput(tvp);
1836                 tvp = NULL;
1837         } else if (tvp) {
1838                 ;
1839         }
1840
1841         error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
1842                 tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred,
1843                 tcnp->cn_td);
1844
1845 out:
1846         if (tdvp == tvp)
1847                 vrele(tdvp);
1848         else
1849                 vput(tdvp);
1850         if (tvp)
1851                 vput(tvp);
1852         vrele(fdvp);
1853         vrele(fvp);
1854         /*
1855          * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
1856          */
1857         if (error == ENOENT)
1858                 error = 0;
1859         return (error);
1860 }
1861
1862 /*
1863  * nfs file rename rpc called from nfs_remove() above
1864  */
1865 static int
1866 nfs_renameit(struct vnode *sdvp, struct componentname *scnp,
1867              struct sillyrename *sp)
1868 {
1869         return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen,
1870                 sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_td));
1871 }
1872
1873 /*
1874  * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit().
1875  */
1876 static int
1877 nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen,
1878               struct vnode *tdvp, const char *tnameptr, int tnamelen,
1879               struct ucred *cred, struct thread *td)
1880 {
1881         int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
1882         struct nfsm_info info;
1883
1884         info.mrep = NULL;
1885         info.v3 = NFS_ISV3(fdvp);
1886
1887         nfsstats.rpccnt[NFSPROC_RENAME]++;
1888         nfsm_reqhead(&info, fdvp, NFSPROC_RENAME,
1889                     (NFSX_FH(info.v3) + NFSX_UNSIGNED)*2 +
1890                     nfsm_rndup(fnamelen) + nfsm_rndup(tnamelen));
1891         ERROROUT(nfsm_fhtom(&info, fdvp));
1892         ERROROUT(nfsm_strtom(&info, fnameptr, fnamelen, NFS_MAXNAMLEN));
1893         ERROROUT(nfsm_fhtom(&info, tdvp));
1894         ERROROUT(nfsm_strtom(&info, tnameptr, tnamelen, NFS_MAXNAMLEN));
1895         NEGKEEPOUT(nfsm_request(&info, fdvp, NFSPROC_RENAME, td, cred, &error));
1896         if (info.v3) {
1897                 ERROROUT(nfsm_wcc_data(&info, fdvp, &fwccflag));
1898                 ERROROUT(nfsm_wcc_data(&info, tdvp, &twccflag));
1899         }
1900         m_freem(info.mrep);
1901         info.mrep = NULL;
1902 nfsmout:
1903         VTONFS(fdvp)->n_flag |= NLMODIFIED;
1904         VTONFS(tdvp)->n_flag |= NLMODIFIED;
1905         if (!fwccflag)
1906                 VTONFS(fdvp)->n_attrstamp = 0;
1907         if (!twccflag)
1908                 VTONFS(tdvp)->n_attrstamp = 0;
1909         return (error);
1910 }
1911
1912 /*
1913  * nfs hard link create call
1914  *
1915  * nfs_link(struct vnode *a_tdvp, struct vnode *a_vp,
1916  *          struct componentname *a_cnp)
1917  */
1918 static int
1919 nfs_link(struct vop_old_link_args *ap)
1920 {
1921         struct vnode *vp = ap->a_vp;
1922         struct vnode *tdvp = ap->a_tdvp;
1923         struct componentname *cnp = ap->a_cnp;
1924         int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
1925         struct nfsm_info info;
1926
1927         if (vp->v_mount != tdvp->v_mount) {
1928                 return (EXDEV);
1929         }
1930
1931         /*
1932          * The attribute cache may get out of sync with the server on link.
1933          * Pushing writes to the server before handle was inherited from
1934          * long long ago and it is unclear if we still need to do this.
1935          * Defaults to off.
1936          */
1937         if (nfs_flush_on_hlink)
1938                 VOP_FSYNC(vp, MNT_WAIT, 0);
1939
1940         info.mrep = NULL;
1941         info.v3 = NFS_ISV3(vp);
1942
1943         nfsstats.rpccnt[NFSPROC_LINK]++;
1944         nfsm_reqhead(&info, vp, NFSPROC_LINK,
1945                      NFSX_FH(info.v3) * 2 + NFSX_UNSIGNED +
1946                      nfsm_rndup(cnp->cn_namelen));
1947         ERROROUT(nfsm_fhtom(&info, vp));
1948         ERROROUT(nfsm_fhtom(&info, tdvp));
1949         ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
1950                              NFS_MAXNAMLEN));
1951         NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_LINK, cnp->cn_td,
1952                                 cnp->cn_cred, &error));
1953         if (info.v3) {
1954                 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag,
1955                                          NFS_LATTR_NOSHRINK));
1956                 ERROROUT(nfsm_wcc_data(&info, tdvp, &wccflag));
1957         }
1958         m_freem(info.mrep);
1959         info.mrep = NULL;
1960 nfsmout:
1961         VTONFS(tdvp)->n_flag |= NLMODIFIED;
1962         if (!attrflag)
1963                 VTONFS(vp)->n_attrstamp = 0;
1964         if (!wccflag)
1965                 VTONFS(tdvp)->n_attrstamp = 0;
1966         /*
1967          * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
1968          */
1969         if (error == EEXIST)
1970                 error = 0;
1971         return (error);
1972 }
1973
1974 /*
1975  * nfs symbolic link create call
1976  *
1977  * nfs_symlink(struct vnode *a_dvp, struct vnode **a_vpp,
1978  *              struct componentname *a_cnp, struct vattr *a_vap,
1979  *              char *a_target)
1980  */
1981 static int
1982 nfs_symlink(struct vop_old_symlink_args *ap)
1983 {
1984         struct vnode *dvp = ap->a_dvp;
1985         struct vattr *vap = ap->a_vap;
1986         struct componentname *cnp = ap->a_cnp;
1987         struct nfsv2_sattr *sp;
1988         int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
1989         struct vnode *newvp = NULL;
1990         struct nfsm_info info;
1991
1992         info.mrep = NULL;
1993         info.v3 = NFS_ISV3(dvp);
1994
1995         nfsstats.rpccnt[NFSPROC_SYMLINK]++;
1996         slen = strlen(ap->a_target);
1997         nfsm_reqhead(&info, dvp, NFSPROC_SYMLINK,
1998                      NFSX_FH(info.v3) + 2*NFSX_UNSIGNED +
1999                      nfsm_rndup(cnp->cn_namelen) +
2000                      nfsm_rndup(slen) + NFSX_SATTR(info.v3));
2001         ERROROUT(nfsm_fhtom(&info, dvp));
2002         ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
2003                              NFS_MAXNAMLEN));
2004         if (info.v3) {
2005                 nfsm_v3attrbuild(&info, vap, FALSE);
2006         }
2007         ERROROUT(nfsm_strtom(&info, ap->a_target, slen, NFS_MAXPATHLEN));
2008         if (info.v3 == 0) {
2009                 sp = nfsm_build(&info, NFSX_V2SATTR);
2010                 sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode);
2011                 sp->sa_uid = nfs_xdrneg1;
2012                 sp->sa_gid = nfs_xdrneg1;
2013                 sp->sa_size = nfs_xdrneg1;
2014                 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
2015                 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
2016         }
2017
2018         /*
2019          * Issue the NFS request and get the rpc response.
2020          *
2021          * Only NFSv3 responses returning an error of 0 actually return
2022          * a file handle that can be converted into newvp without having
2023          * to do an extra lookup rpc.
2024          */
2025         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_SYMLINK, cnp->cn_td,
2026                                 cnp->cn_cred, &error));
2027         if (info.v3) {
2028                 if (error == 0) {
2029                        ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp));
2030                 }
2031                 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag));
2032         }
2033
2034         /*
2035          * out code jumps -> here, mrep is also freed.
2036          */
2037
2038         m_freem(info.mrep);
2039         info.mrep = NULL;
2040 nfsmout:
2041
2042         /*
2043          * If we get an EEXIST error, silently convert it to no-error
2044          * in case of an NFS retry.
2045          */
2046         if (error == EEXIST)
2047                 error = 0;
2048
2049         /*
2050          * If we do not have (or no longer have) an error, and we could
2051          * not extract the newvp from the response due to the request being
2052          * NFSv2 or the error being EEXIST.  We have to do a lookup in order
2053          * to obtain a newvp to return.  
2054          */
2055         if (error == 0 && newvp == NULL) {
2056                 struct nfsnode *np = NULL;
2057
2058                 error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
2059                     cnp->cn_cred, cnp->cn_td, &np);
2060                 if (!error)
2061                         newvp = NFSTOV(np);
2062         }
2063         if (error) {
2064                 if (newvp)
2065                         vput(newvp);
2066         } else {
2067                 *ap->a_vpp = newvp;
2068         }
2069         VTONFS(dvp)->n_flag |= NLMODIFIED;
2070         if (!wccflag)
2071                 VTONFS(dvp)->n_attrstamp = 0;
2072         return (error);
2073 }
2074
2075 /*
2076  * nfs make dir call
2077  *
2078  * nfs_mkdir(struct vnode *a_dvp, struct vnode **a_vpp,
2079  *           struct componentname *a_cnp, struct vattr *a_vap)
2080  */
2081 static int
2082 nfs_mkdir(struct vop_old_mkdir_args *ap)
2083 {
2084         struct vnode *dvp = ap->a_dvp;
2085         struct vattr *vap = ap->a_vap;
2086         struct componentname *cnp = ap->a_cnp;
2087         struct nfsv2_sattr *sp;
2088         struct nfsnode *np = NULL;
2089         struct vnode *newvp = NULL;
2090         struct vattr vattr;
2091         int error = 0, wccflag = NFSV3_WCCRATTR;
2092         int gotvp = 0;
2093         int len;
2094         struct nfsm_info info;
2095
2096         info.mrep = NULL;
2097         info.v3 = NFS_ISV3(dvp);
2098
2099         if ((error = VOP_GETATTR(dvp, &vattr)) != 0) {
2100                 return (error);
2101         }
2102         len = cnp->cn_namelen;
2103         nfsstats.rpccnt[NFSPROC_MKDIR]++;
2104         nfsm_reqhead(&info, dvp, NFSPROC_MKDIR,
2105                      NFSX_FH(info.v3) + NFSX_UNSIGNED +
2106                      nfsm_rndup(len) + NFSX_SATTR(info.v3));
2107         ERROROUT(nfsm_fhtom(&info, dvp));
2108         ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN));
2109         if (info.v3) {
2110                 nfsm_v3attrbuild(&info, vap, FALSE);
2111         } else {
2112                 sp = nfsm_build(&info, NFSX_V2SATTR);
2113                 sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode);
2114                 sp->sa_uid = nfs_xdrneg1;
2115                 sp->sa_gid = nfs_xdrneg1;
2116                 sp->sa_size = nfs_xdrneg1;
2117                 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
2118                 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
2119         }
2120         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_MKDIR, cnp->cn_td,
2121                     cnp->cn_cred, &error));
2122         if (error == 0) {
2123                 ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp));
2124         }
2125         if (info.v3) {
2126                 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag));
2127         }
2128         m_freem(info.mrep);
2129         info.mrep = NULL;
2130 nfsmout:
2131         VTONFS(dvp)->n_flag |= NLMODIFIED;
2132         if (!wccflag)
2133                 VTONFS(dvp)->n_attrstamp = 0;
2134         /*
2135          * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry
2136          * if we can succeed in looking up the directory.
2137          */
2138         if (error == EEXIST || (!error && !gotvp)) {
2139                 if (newvp) {
2140                         vrele(newvp);
2141                         newvp = NULL;
2142                 }
2143                 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred,
2144                         cnp->cn_td, &np);
2145                 if (!error) {
2146                         newvp = NFSTOV(np);
2147                         if (newvp->v_type != VDIR)
2148                                 error = EEXIST;
2149                 }
2150         }
2151         if (error) {
2152                 if (newvp)
2153                         vrele(newvp);
2154         } else
2155                 *ap->a_vpp = newvp;
2156         return (error);
2157 }
2158
2159 /*
2160  * nfs remove directory call
2161  *
2162  * nfs_rmdir(struct vnode *a_dvp, struct vnode *a_vp,
2163  *           struct componentname *a_cnp)
2164  */
2165 static int
2166 nfs_rmdir(struct vop_old_rmdir_args *ap)
2167 {
2168         struct vnode *vp = ap->a_vp;
2169         struct vnode *dvp = ap->a_dvp;
2170         struct componentname *cnp = ap->a_cnp;
2171         int error = 0, wccflag = NFSV3_WCCRATTR;
2172         struct nfsm_info info;
2173
2174         info.mrep = NULL;
2175         info.v3 = NFS_ISV3(dvp);
2176
2177         if (dvp == vp)
2178                 return (EINVAL);
2179         nfsstats.rpccnt[NFSPROC_RMDIR]++;
2180         nfsm_reqhead(&info, dvp, NFSPROC_RMDIR,
2181                      NFSX_FH(info.v3) + NFSX_UNSIGNED +
2182                      nfsm_rndup(cnp->cn_namelen));
2183         ERROROUT(nfsm_fhtom(&info, dvp));
2184         ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
2185                  NFS_MAXNAMLEN));
2186         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_RMDIR, cnp->cn_td,
2187                                 cnp->cn_cred, &error));
2188         if (info.v3) {
2189                 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag));
2190         }
2191         m_freem(info.mrep);
2192         info.mrep = NULL;
2193 nfsmout:
2194         VTONFS(dvp)->n_flag |= NLMODIFIED;
2195         if (!wccflag)
2196                 VTONFS(dvp)->n_attrstamp = 0;
2197         /*
2198          * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
2199          */
2200         if (error == ENOENT)
2201                 error = 0;
2202         return (error);
2203 }
2204
2205 /*
2206  * nfs readdir call
2207  *
2208  * nfs_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
2209  */
2210 static int
2211 nfs_readdir(struct vop_readdir_args *ap)
2212 {
2213         struct vnode *vp = ap->a_vp;
2214         struct nfsnode *np = VTONFS(vp);
2215         struct uio *uio = ap->a_uio;
2216         int tresid, error;
2217         struct vattr vattr;
2218
2219         if (vp->v_type != VDIR)
2220                 return (EPERM);
2221
2222         if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
2223                 return (error);
2224
2225         /*
2226          * If we have a valid EOF offset cache we must call VOP_GETATTR()
2227          * and then check that is still valid, or if this is an NQNFS mount
2228          * we call NQNFS_CKCACHEABLE() instead of VOP_GETATTR().  Note that
2229          * VOP_GETATTR() does not necessarily go to the wire.
2230          */
2231         if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset &&
2232             (np->n_flag & (NLMODIFIED|NRMODIFIED)) == 0) {
2233                 if (VOP_GETATTR(vp, &vattr) == 0 &&
2234                     (np->n_flag & (NLMODIFIED|NRMODIFIED)) == 0
2235                 ) {
2236                         nfsstats.direofcache_hits++;
2237                         goto done;
2238                 }
2239         }
2240
2241         /*
2242          * Call nfs_bioread() to do the real work.  nfs_bioread() does its
2243          * own cache coherency checks so we do not have to.
2244          */
2245         tresid = uio->uio_resid;
2246         error = nfs_bioread(vp, uio, 0);
2247
2248         if (!error && uio->uio_resid == tresid)
2249                 nfsstats.direofcache_misses++;
2250 done:
2251         vn_unlock(vp);
2252         return (error);
2253 }
2254
2255 /*
2256  * Readdir rpc call.  nfs_bioread->nfs_doio->nfs_readdirrpc.
2257  *
2258  * Note that for directories, nfs_bioread maintains the underlying nfs-centric
2259  * offset/block and converts the nfs formatted directory entries for userland
2260  * consumption as well as deals with offsets into the middle of blocks.
2261  * nfs_doio only deals with logical blocks.  In particular, uio_offset will
2262  * be block-bounded.  It must convert to cookies for the actual RPC.
2263  */
2264 int
2265 nfs_readdirrpc_uio(struct vnode *vp, struct uio *uiop)
2266 {
2267         int len, left;
2268         struct nfs_dirent *dp = NULL;
2269         u_int32_t *tl;
2270         nfsuint64 *cookiep;
2271         caddr_t cp;
2272         nfsuint64 cookie;
2273         struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2274         struct nfsnode *dnp = VTONFS(vp);
2275         u_quad_t fileno;
2276         int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1;
2277         int attrflag;
2278         struct nfsm_info info;
2279
2280         info.mrep = NULL;
2281         info.v3 = NFS_ISV3(vp);
2282
2283 #ifndef DIAGNOSTIC
2284         if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) ||
2285                 (uiop->uio_resid & (DIRBLKSIZ - 1)))
2286                 panic("nfs readdirrpc bad uio");
2287 #endif
2288
2289         /*
2290          * If there is no cookie, assume directory was stale.
2291          */
2292         cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
2293         if (cookiep)
2294                 cookie = *cookiep;
2295         else
2296                 return (NFSERR_BAD_COOKIE);
2297         /*
2298          * Loop around doing readdir rpc's of size nm_readdirsize
2299          * truncated to a multiple of DIRBLKSIZ.
2300          * The stopping criteria is EOF or buffer full.
2301          */
2302         while (more_dirs && bigenough) {
2303                 nfsstats.rpccnt[NFSPROC_READDIR]++;
2304                 nfsm_reqhead(&info, vp, NFSPROC_READDIR,
2305                              NFSX_FH(info.v3) + NFSX_READDIR(info.v3));
2306                 ERROROUT(nfsm_fhtom(&info, vp));
2307                 if (info.v3) {
2308                         tl = nfsm_build(&info, 5 * NFSX_UNSIGNED);
2309                         *tl++ = cookie.nfsuquad[0];
2310                         *tl++ = cookie.nfsuquad[1];
2311                         *tl++ = dnp->n_cookieverf.nfsuquad[0];
2312                         *tl++ = dnp->n_cookieverf.nfsuquad[1];
2313                 } else {
2314                         tl = nfsm_build(&info, 2 * NFSX_UNSIGNED);
2315                         *tl++ = cookie.nfsuquad[0];
2316                 }
2317                 *tl = txdr_unsigned(nmp->nm_readdirsize);
2318                 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READDIR,
2319                                         uiop->uio_td,
2320                                         nfs_vpcred(vp, ND_READ), &error));
2321                 if (info.v3) {
2322                         ERROROUT(nfsm_postop_attr(&info, vp, &attrflag,
2323                                                   NFS_LATTR_NOSHRINK));
2324                         NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED));
2325                         dnp->n_cookieverf.nfsuquad[0] = *tl++;
2326                         dnp->n_cookieverf.nfsuquad[1] = *tl;
2327                 }
2328                 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED));
2329                 more_dirs = fxdr_unsigned(int, *tl);
2330         
2331                 /* loop thru the dir entries, converting them to std form */
2332                 while (more_dirs && bigenough) {
2333                         if (info.v3) {
2334                                 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED));
2335                                 fileno = fxdr_hyper(tl);
2336                                 len = fxdr_unsigned(int, *(tl + 2));
2337                         } else {
2338                                 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED));
2339                                 fileno = fxdr_unsigned(u_quad_t, *tl++);
2340                                 len = fxdr_unsigned(int, *tl);
2341                         }
2342                         if (len <= 0 || len > NFS_MAXNAMLEN) {
2343                                 error = EBADRPC;
2344                                 m_freem(info.mrep);
2345                                 info.mrep = NULL;
2346                                 goto nfsmout;
2347                         }
2348
2349                         /*
2350                          * len is the number of bytes in the path element
2351                          * name, not including the \0 termination.
2352                          *
2353                          * tlen is the number of bytes w have to reserve for
2354                          * the path element name.
2355                          */
2356                         tlen = nfsm_rndup(len);
2357                         if (tlen == len)
2358                                 tlen += 4;      /* To ensure null termination */
2359
2360                         /*
2361                          * If the entry would cross a DIRBLKSIZ boundary, 
2362                          * extend the previous nfs_dirent to cover the
2363                          * remaining space.
2364                          */
2365                         left = DIRBLKSIZ - blksiz;
2366                         if ((tlen + sizeof(struct nfs_dirent)) > left) {
2367                                 dp->nfs_reclen += left;
2368                                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left;
2369                                 uiop->uio_iov->iov_len -= left;
2370                                 uiop->uio_offset += left;
2371                                 uiop->uio_resid -= left;
2372                                 blksiz = 0;
2373                         }
2374                         if ((tlen + sizeof(struct nfs_dirent)) > uiop->uio_resid)
2375                                 bigenough = 0;
2376                         if (bigenough) {
2377                                 dp = (struct nfs_dirent *)uiop->uio_iov->iov_base;
2378                                 dp->nfs_ino = fileno;
2379                                 dp->nfs_namlen = len;
2380                                 dp->nfs_reclen = tlen + sizeof(struct nfs_dirent);
2381                                 dp->nfs_type = DT_UNKNOWN;
2382                                 blksiz += dp->nfs_reclen;
2383                                 if (blksiz == DIRBLKSIZ)
2384                                         blksiz = 0;
2385                                 uiop->uio_offset += sizeof(struct nfs_dirent);
2386                                 uiop->uio_resid -= sizeof(struct nfs_dirent);
2387                                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + sizeof(struct nfs_dirent);
2388                                 uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent);
2389                                 ERROROUT(nfsm_mtouio(&info, uiop, len));
2390
2391                                 /*
2392                                  * The uiop has advanced by nfs_dirent + len
2393                                  * but really needs to advance by
2394                                  * nfs_dirent + tlen
2395                                  */
2396                                 cp = uiop->uio_iov->iov_base;
2397                                 tlen -= len;
2398                                 *cp = '\0';     /* null terminate */
2399                                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + tlen;
2400                                 uiop->uio_iov->iov_len -= tlen;
2401                                 uiop->uio_offset += tlen;
2402                                 uiop->uio_resid -= tlen;
2403                         } else {
2404                                 /*
2405                                  * NFS strings must be rounded up (nfsm_myouio
2406                                  * handled that in the bigenough case).
2407                                  */
2408                                 ERROROUT(nfsm_adv(&info, nfsm_rndup(len)));
2409                         }
2410                         if (info.v3) {
2411                                 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED));
2412                         } else {
2413                                 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED));
2414                         }
2415
2416                         /*
2417                          * If we were able to accomodate the last entry,
2418                          * get the cookie for the next one.  Otherwise
2419                          * hold-over the cookie for the one we were not
2420                          * able to accomodate.
2421                          */
2422                         if (bigenough) {
2423                                 cookie.nfsuquad[0] = *tl++;
2424                                 if (info.v3)
2425                                         cookie.nfsuquad[1] = *tl++;
2426                         } else if (info.v3) {
2427                                 tl += 2;
2428                         } else {
2429                                 tl++;
2430                         }
2431                         more_dirs = fxdr_unsigned(int, *tl);
2432                 }
2433                 /*
2434                  * If at end of rpc data, get the eof boolean
2435                  */
2436                 if (!more_dirs) {
2437                         NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED));
2438                         more_dirs = (fxdr_unsigned(int, *tl) == 0);
2439                 }
2440                 m_freem(info.mrep);
2441                 info.mrep = NULL;
2442         }
2443         /*
2444          * Fill last record, iff any, out to a multiple of DIRBLKSIZ
2445          * by increasing d_reclen for the last record.
2446          */
2447         if (blksiz > 0) {
2448                 left = DIRBLKSIZ - blksiz;
2449                 dp->nfs_reclen += left;
2450                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left;
2451                 uiop->uio_iov->iov_len -= left;
2452                 uiop->uio_offset += left;
2453                 uiop->uio_resid -= left;
2454         }
2455
2456         if (bigenough) {
2457                 /*
2458                  * We hit the end of the directory, update direofoffset.
2459                  */
2460                 dnp->n_direofoffset = uiop->uio_offset;
2461         } else {
2462                 /*
2463                  * There is more to go, insert the link cookie so the
2464                  * next block can be read.
2465                  */
2466                 if (uiop->uio_resid > 0)
2467                         kprintf("EEK! readdirrpc resid > 0\n");
2468                 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
2469                 *cookiep = cookie;
2470         }
2471 nfsmout:
2472         return (error);
2473 }
2474
2475 /*
2476  * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
2477  */
2478 int
2479 nfs_readdirplusrpc_uio(struct vnode *vp, struct uio *uiop)
2480 {
2481         int len, left;
2482         struct nfs_dirent *dp;
2483         u_int32_t *tl;
2484         struct vnode *newvp;
2485         nfsuint64 *cookiep;
2486         caddr_t dpossav1, dpossav2;
2487         caddr_t cp;
2488         struct mbuf *mdsav1, *mdsav2;
2489         nfsuint64 cookie;
2490         struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2491         struct nfsnode *dnp = VTONFS(vp), *np;
2492         nfsfh_t *fhp;
2493         u_quad_t fileno;
2494         int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
2495         int attrflag, fhsize;
2496         struct nchandle nch;
2497         struct nchandle dnch;
2498         struct nlcomponent nlc;
2499         struct nfsm_info info;
2500
2501         info.mrep = NULL;
2502         info.v3 = 1;
2503
2504 #ifndef nolint
2505         dp = NULL;
2506 #endif
2507 #ifndef DIAGNOSTIC
2508         if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) ||
2509                 (uiop->uio_resid & (DIRBLKSIZ - 1)))
2510                 panic("nfs readdirplusrpc bad uio");
2511 #endif
2512         /*
2513          * Obtain the namecache record for the directory so we have something
2514          * to use as a basis for creating the entries.  This function will
2515          * return a held (but not locked) ncp.  The ncp may be disconnected
2516          * from the tree and cannot be used for upward traversals, and the
2517          * ncp may be unnamed.  Note that other unrelated operations may 
2518          * cause the ncp to be named at any time.
2519          */
2520         cache_fromdvp(vp, NULL, 0, &dnch);
2521         bzero(&nlc, sizeof(nlc));
2522         newvp = NULLVP;
2523
2524         /*
2525          * If there is no cookie, assume directory was stale.
2526          */
2527         cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
2528         if (cookiep)
2529                 cookie = *cookiep;
2530         else
2531                 return (NFSERR_BAD_COOKIE);
2532         /*
2533          * Loop around doing readdir rpc's of size nm_readdirsize
2534          * truncated to a multiple of DIRBLKSIZ.
2535          * The stopping criteria is EOF or buffer full.
2536          */
2537         while (more_dirs && bigenough) {
2538                 nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
2539                 nfsm_reqhead(&info, vp, NFSPROC_READDIRPLUS,
2540                              NFSX_FH(1) + 6 * NFSX_UNSIGNED);
2541                 ERROROUT(nfsm_fhtom(&info, vp));
2542                 tl = nfsm_build(&info, 6 * NFSX_UNSIGNED);
2543                 *tl++ = cookie.nfsuquad[0];
2544                 *tl++ = cookie.nfsuquad[1];
2545                 *tl++ = dnp->n_cookieverf.nfsuquad[0];
2546                 *tl++ = dnp->n_cookieverf.nfsuquad[1];
2547                 *tl++ = txdr_unsigned(nmp->nm_readdirsize);
2548                 *tl = txdr_unsigned(nmp->nm_rsize);
2549                 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READDIRPLUS,
2550                                         uiop->uio_td,
2551                                         nfs_vpcred(vp, ND_READ), &error));
2552                 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag,
2553                                           NFS_LATTR_NOSHRINK));
2554                 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED));
2555                 dnp->n_cookieverf.nfsuquad[0] = *tl++;
2556                 dnp->n_cookieverf.nfsuquad[1] = *tl++;
2557                 more_dirs = fxdr_unsigned(int, *tl);
2558
2559                 /* loop thru the dir entries, doctoring them to 4bsd form */
2560                 while (more_dirs && bigenough) {
2561                         NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED));
2562                         fileno = fxdr_hyper(tl);
2563                         len = fxdr_unsigned(int, *(tl + 2));
2564                         if (len <= 0 || len > NFS_MAXNAMLEN) {
2565                                 error = EBADRPC;
2566                                 m_freem(info.mrep);
2567                                 info.mrep = NULL;
2568                                 goto nfsmout;
2569                         }
2570                         tlen = nfsm_rndup(len);
2571                         if (tlen == len)
2572                                 tlen += 4;      /* To ensure null termination*/
2573                         left = DIRBLKSIZ - blksiz;
2574                         if ((tlen + sizeof(struct nfs_dirent)) > left) {
2575                                 dp->nfs_reclen += left;
2576                                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left;
2577                                 uiop->uio_iov->iov_len -= left;
2578                                 uiop->uio_offset += left;
2579                                 uiop->uio_resid -= left;
2580                                 blksiz = 0;
2581                         }
2582                         if ((tlen + sizeof(struct nfs_dirent)) > uiop->uio_resid)
2583                                 bigenough = 0;
2584                         if (bigenough) {
2585                                 dp = (struct nfs_dirent *)uiop->uio_iov->iov_base;
2586                                 dp->nfs_ino = fileno;
2587                                 dp->nfs_namlen = len;
2588                                 dp->nfs_reclen = tlen + sizeof(struct nfs_dirent);
2589                                 dp->nfs_type = DT_UNKNOWN;
2590                                 blksiz += dp->nfs_reclen;
2591                                 if (blksiz == DIRBLKSIZ)
2592                                         blksiz = 0;
2593                                 uiop->uio_offset += sizeof(struct nfs_dirent);
2594                                 uiop->uio_resid -= sizeof(struct nfs_dirent);
2595                                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + sizeof(struct nfs_dirent);
2596                                 uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent);
2597                                 nlc.nlc_nameptr = uiop->uio_iov->iov_base;
2598                                 nlc.nlc_namelen = len;
2599                                 ERROROUT(nfsm_mtouio(&info, uiop, len));
2600                                 cp = uiop->uio_iov->iov_base;
2601                                 tlen -= len;
2602                                 *cp = '\0';
2603                                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + tlen;
2604                                 uiop->uio_iov->iov_len -= tlen;
2605                                 uiop->uio_offset += tlen;
2606                                 uiop->uio_resid -= tlen;
2607                         } else {
2608                                 ERROROUT(nfsm_adv(&info, nfsm_rndup(len)));
2609                         }
2610                         NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED));
2611                         if (bigenough) {
2612                                 cookie.nfsuquad[0] = *tl++;
2613                                 cookie.nfsuquad[1] = *tl++;
2614                         } else
2615                                 tl += 2;
2616
2617                         /*
2618                          * Since the attributes are before the file handle
2619                          * (sigh), we must skip over the attributes and then
2620                          * come back and get them.
2621                          */
2622                         attrflag = fxdr_unsigned(int, *tl);
2623                         if (attrflag) {
2624                             dpossav1 = info.dpos;
2625                             mdsav1 = info.md;
2626                             ERROROUT(nfsm_adv(&info, NFSX_V3FATTR));
2627                             NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED));
2628                             doit = fxdr_unsigned(int, *tl);
2629                             if (doit) {
2630                                 NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp));
2631                                 if (NFS_CMPFH(dnp, fhp, fhsize)) {
2632                                     vref(vp);
2633                                     newvp = vp;
2634                                     np = dnp;
2635                                 } else {
2636                                     error = nfs_nget(vp->v_mount, fhp,
2637                                         fhsize, &np);
2638                                     if (error)
2639                                         doit = 0;
2640                                     else
2641                                         newvp = NFSTOV(np);
2642                                 }
2643                             }
2644                             if (doit && bigenough) {
2645                                 dpossav2 = info.dpos;
2646                                 info.dpos = dpossav1;
2647                                 mdsav2 = info.md;
2648                                 info.md = mdsav1;
2649                                 ERROROUT(nfsm_loadattr(&info, newvp, NULL));
2650                                 info.dpos = dpossav2;
2651                                 info.md = mdsav2;
2652                                 dp->nfs_type =
2653                                     IFTODT(VTTOIF(np->n_vattr.va_type));
2654                                 if (dnch.ncp) {
2655                                     kprintf("NFS/READDIRPLUS, ENTER %*.*s\n",
2656                                         nlc.nlc_namelen, nlc.nlc_namelen,
2657                                         nlc.nlc_nameptr);
2658                                     nch = cache_nlookup(&dnch, &nlc);
2659                                     cache_setunresolved(&nch);
2660                                     nfs_cache_setvp(&nch, newvp,
2661                                                     nfspos_cache_timeout);
2662                                     cache_put(&nch);
2663                                 } else {
2664                                     kprintf("NFS/READDIRPLUS, UNABLE TO ENTER"
2665                                         " %*.*s\n",
2666                                         nlc.nlc_namelen, nlc.nlc_namelen,
2667                                         nlc.nlc_nameptr);
2668                                 }
2669                             }
2670                         } else {
2671                             /* Just skip over the file handle */
2672                             NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED));
2673                             i = fxdr_unsigned(int, *tl);
2674                             ERROROUT(nfsm_adv(&info, nfsm_rndup(i)));
2675                         }
2676                         if (newvp != NULLVP) {
2677                             if (newvp == vp)
2678                                 vrele(newvp);
2679                             else
2680                                 vput(newvp);
2681                             newvp = NULLVP;
2682                         }
2683                         NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED));
2684                         more_dirs = fxdr_unsigned(int, *tl);
2685                 }
2686                 /*
2687                  * If at end of rpc data, get the eof boolean
2688                  */
2689                 if (!more_dirs) {
2690                         NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED));
2691                         more_dirs = (fxdr_unsigned(int, *tl) == 0);
2692                 }
2693                 m_freem(info.mrep);
2694                 info.mrep = NULL;
2695         }
2696         /*
2697          * Fill last record, iff any, out to a multiple of DIRBLKSIZ
2698          * by increasing d_reclen for the last record.
2699          */
2700         if (blksiz > 0) {
2701                 left = DIRBLKSIZ - blksiz;
2702                 dp->nfs_reclen += left;
2703                 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left;
2704                 uiop->uio_iov->iov_len -= left;
2705                 uiop->uio_offset += left;
2706                 uiop->uio_resid -= left;
2707         }
2708
2709         /*
2710          * We are now either at the end of the directory or have filled the
2711          * block.
2712          */
2713         if (bigenough)
2714                 dnp->n_direofoffset = uiop->uio_offset;
2715         else {
2716                 if (uiop->uio_resid > 0)
2717                         kprintf("EEK! readdirplusrpc resid > 0\n");
2718                 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
2719                 *cookiep = cookie;
2720         }
2721 nfsmout:
2722         if (newvp != NULLVP) {
2723                 if (newvp == vp)
2724                         vrele(newvp);
2725                 else
2726                         vput(newvp);
2727                 newvp = NULLVP;
2728         }
2729         if (dnch.ncp)
2730                 cache_drop(&dnch);
2731         return (error);
2732 }
2733
2734 /*
2735  * Silly rename. To make the NFS filesystem that is stateless look a little
2736  * more like the "ufs" a remove of an active vnode is translated to a rename
2737  * to a funny looking filename that is removed by nfs_inactive on the
2738  * nfsnode. There is the potential for another process on a different client
2739  * to create the same funny name between the nfs_lookitup() fails and the
2740  * nfs_rename() completes, but...
2741  */
2742 static int
2743 nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
2744 {
2745         struct sillyrename *sp;
2746         struct nfsnode *np;
2747         int error;
2748
2749         /*
2750          * We previously purged dvp instead of vp.  I don't know why, it
2751          * completely destroys performance.  We can't do it anyway with the
2752          * new VFS API since we would be breaking the namecache topology.
2753          */
2754         cache_purge(vp);        /* XXX */
2755         np = VTONFS(vp);
2756 #ifndef DIAGNOSTIC
2757         if (vp->v_type == VDIR)
2758                 panic("nfs: sillyrename dir");
2759 #endif
2760         MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
2761                 M_NFSREQ, M_WAITOK);
2762         sp->s_cred = crdup(cnp->cn_cred);
2763         sp->s_dvp = dvp;
2764         vref(dvp);
2765
2766         /* Fudge together a funny name */
2767         sp->s_namlen = ksprintf(sp->s_name, ".nfsA%08x4.4",
2768                                 (int)(intptr_t)cnp->cn_td);
2769
2770         /* Try lookitups until we get one that isn't there */
2771         while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2772                 cnp->cn_td, NULL) == 0) {
2773                 sp->s_name[4]++;
2774                 if (sp->s_name[4] > 'z') {
2775                         error = EINVAL;
2776                         goto bad;
2777                 }
2778         }
2779         error = nfs_renameit(dvp, cnp, sp);
2780         if (error)
2781                 goto bad;
2782         error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2783                 cnp->cn_td, &np);
2784         np->n_sillyrename = sp;
2785         return (0);
2786 bad:
2787         vrele(sp->s_dvp);
2788         crfree(sp->s_cred);
2789         kfree((caddr_t)sp, M_NFSREQ);
2790         return (error);
2791 }
2792
2793 /*
2794  * Look up a file name and optionally either update the file handle or
2795  * allocate an nfsnode, depending on the value of npp.
2796  * npp == NULL  --> just do the lookup
2797  * *npp == NULL --> allocate a new nfsnode and make sure attributes are
2798  *                      handled too
2799  * *npp != NULL --> update the file handle in the vnode
2800  */
2801 static int
2802 nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred,
2803              struct thread *td, struct nfsnode **npp)
2804 {
2805         struct vnode *newvp = NULL;
2806         struct nfsnode *np, *dnp = VTONFS(dvp);
2807         int error = 0, fhlen, attrflag;
2808         nfsfh_t *nfhp;
2809         struct nfsm_info info;
2810
2811         info.mrep = NULL;
2812         info.v3 = NFS_ISV3(dvp);
2813
2814         nfsstats.rpccnt[NFSPROC_LOOKUP]++;
2815         nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP,
2816                      NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len));
2817         ERROROUT(nfsm_fhtom(&info, dvp));
2818         ERROROUT(nfsm_strtom(&info, name, len, NFS_MAXNAMLEN));
2819         NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, td, cred, &error));
2820         if (npp && !error) {
2821                 NEGATIVEOUT(fhlen = nfsm_getfh(&info, &nfhp));
2822                 if (*npp) {
2823                     np = *npp;
2824                     if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) {
2825                         kfree((caddr_t)np->n_fhp, M_NFSBIGFH);
2826                         np->n_fhp = &np->n_fh;
2827                     } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH)
2828                         np->n_fhp =(nfsfh_t *)kmalloc(fhlen,M_NFSBIGFH,M_WAITOK);
2829                     bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen);
2830                     np->n_fhsize = fhlen;
2831                     newvp = NFSTOV(np);
2832                 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) {
2833                     vref(dvp);
2834                     newvp = dvp;
2835                 } else {
2836                     error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np);
2837                     if (error) {
2838                         m_freem(info.mrep);
2839                         info.mrep = NULL;
2840                         return (error);
2841                     }
2842                     newvp = NFSTOV(np);
2843                 }
2844                 if (info.v3) {
2845                         ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag,
2846                                                   NFS_LATTR_NOSHRINK));
2847                         if (!attrflag && *npp == NULL) {
2848                                 m_freem(info.mrep);
2849                                 info.mrep = NULL;
2850                                 if (newvp == dvp)
2851                                         vrele(newvp);
2852                                 else
2853                                         vput(newvp);
2854                                 return (ENOENT);
2855                         }
2856                 } else {
2857                         ERROROUT(error = nfsm_loadattr(&info, newvp, NULL));
2858                 }
2859         }
2860         m_freem(info.mrep);
2861         info.mrep = NULL;
2862 nfsmout:
2863         if (npp && *npp == NULL) {
2864                 if (error) {
2865                         if (newvp) {
2866                                 if (newvp == dvp)
2867                                         vrele(newvp);
2868                                 else
2869                                         vput(newvp);
2870                         }
2871                 } else
2872                         *npp = np;
2873         }
2874         return (error);
2875 }
2876
2877 /*
2878  * Nfs Version 3 commit rpc
2879  *
2880  * We call it 'uio' to distinguish it from 'bio' but there is no real uio
2881  * involved.
2882  */
2883 int
2884 nfs_commitrpc_uio(struct vnode *vp, u_quad_t offset, int cnt, struct thread *td)
2885 {
2886         struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2887         int error = 0, wccflag = NFSV3_WCCRATTR;
2888         struct nfsm_info info;
2889         u_int32_t *tl;
2890
2891         info.mrep = NULL;
2892         info.v3 = 1;
2893         
2894         if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0)
2895                 return (0);
2896         nfsstats.rpccnt[NFSPROC_COMMIT]++;
2897         nfsm_reqhead(&info, vp, NFSPROC_COMMIT, NFSX_FH(1));
2898         ERROROUT(nfsm_fhtom(&info, vp));
2899         tl = nfsm_build(&info, 3 * NFSX_UNSIGNED);
2900         txdr_hyper(offset, tl);
2901         tl += 2;
2902         *tl = txdr_unsigned(cnt);
2903         NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_COMMIT, td,
2904                                 nfs_vpcred(vp, ND_WRITE), &error));
2905         ERROROUT(nfsm_wcc_data(&info, vp, &wccflag));
2906         if (!error) {
2907                 NULLOUT(tl = nfsm_dissect(&info, NFSX_V3WRITEVERF));
2908                 if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl,
2909                         NFSX_V3WRITEVERF)) {
2910                         bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
2911                                 NFSX_V3WRITEVERF);
2912                         error = NFSERR_STALEWRITEVERF;
2913                 }
2914         }
2915         m_freem(info.mrep);
2916         info.mrep = NULL;
2917 nfsmout:
2918         return (error);
2919 }
2920
2921 /*
2922  * Kludge City..
2923  * - make nfs_bmap() essentially a no-op that does no translation
2924  * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc
2925  *   (Maybe I could use the process's page mapping, but I was concerned that
2926  *    Kernel Write might not be enabled and also figured copyout() would do
2927  *    a lot more work than bcopy() and also it currently happens in the
2928  *    context of the swapper process (2).
2929  *
2930  * nfs_bmap(struct vnode *a_vp, off_t a_loffset,
2931  *          off_t *a_doffsetp, int *a_runp, int *a_runb)
2932  */
2933 static int
2934 nfs_bmap(struct vop_bmap_args *ap)
2935 {
2936         if (ap->a_doffsetp != NULL)
2937                 *ap->a_doffsetp = ap->a_loffset;
2938         if (ap->a_runp != NULL)
2939                 *ap->a_runp = 0;
2940         if (ap->a_runb != NULL)
2941                 *ap->a_runb = 0;
2942         return (0);
2943 }
2944
2945 /*
2946  * Strategy routine.
2947  */
2948 static int
2949 nfs_strategy(struct vop_strategy_args *ap)
2950 {
2951         struct bio *bio = ap->a_bio;
2952         struct bio *nbio;
2953         struct buf *bp = bio->bio_buf;
2954         struct thread *td;
2955         int error;
2956
2957         KASSERT(bp->b_cmd != BUF_CMD_DONE,
2958                 ("nfs_strategy: buffer %p unexpectedly marked done", bp));
2959         KASSERT(BUF_REFCNT(bp) > 0,
2960                 ("nfs_strategy: buffer %p not locked", bp));
2961
2962         if (bio->bio_flags & BIO_SYNC)
2963                 td = curthread; /* XXX */
2964         else
2965                 td = NULL;
2966
2967         /*
2968          * We probably don't need to push an nbio any more since no
2969          * block conversion is required due to the use of 64 bit byte
2970          * offsets, but do it anyway.
2971          *
2972          * NOTE: When NFS callers itself via this strategy routines and
2973          *       sets up a synchronous I/O, it expects the I/O to run
2974          *       synchronously (its bio_done routine just assumes it),
2975          *       so for now we have to honor the bit.
2976          */
2977         nbio = push_bio(bio);
2978         nbio->bio_offset = bio->bio_offset;
2979         nbio->bio_flags = bio->bio_flags & BIO_SYNC;
2980
2981         /*
2982          * If the op is asynchronous and an i/o daemon is waiting
2983          * queue the request, wake it up and wait for completion
2984          * otherwise just do it ourselves.
2985          */
2986         if (bio->bio_flags & BIO_SYNC) {
2987                 error = nfs_doio(ap->a_vp, nbio, td);
2988         } else {
2989                 nfs_asyncio(ap->a_vp, nbio);
2990                 error = 0;
2991         }
2992         return (error);
2993 }
2994
2995 /*
2996  * Mmap a file
2997  *
2998  * NB Currently unsupported.
2999  *
3000  * nfs_mmap(struct vnode *a_vp, int a_fflags, struct ucred *a_cred)
3001  */
3002 /* ARGSUSED */
3003 static int
3004 nfs_mmap(struct vop_mmap_args *ap)
3005 {
3006         return (EINVAL);
3007 }
3008
3009 /*
3010  * fsync vnode op. Just call nfs_flush() with commit == 1.
3011  *
3012  * nfs_fsync(struct vnode *a_vp, int a_waitfor)
3013  */
3014 /* ARGSUSED */
3015 static int
3016 nfs_fsync(struct vop_fsync_args *ap)
3017 {
3018         return (nfs_flush(ap->a_vp, ap->a_waitfor, curthread, 1));
3019 }
3020
3021 /*
3022  * Flush all the blocks associated with a vnode.   Dirty NFS buffers may be
3023  * in one of two states:  If B_NEEDCOMMIT is clear then the buffer contains
3024  * new NFS data which needs to be written to the server.  If B_NEEDCOMMIT is
3025  * set the buffer contains data that has already been written to the server
3026  * and which now needs a commit RPC.
3027  *
3028  * If commit is 0 we only take one pass and only flush buffers containing new
3029  * dirty data.
3030  *
3031  * If commit is 1 we take two passes, issuing a commit RPC in the second
3032  * pass.
3033  *
3034  * If waitfor is MNT_WAIT and commit is 1, we loop as many times as required
3035  * to completely flush all pending data.
3036  *
3037  * Note that the RB_SCAN code properly handles the case where the
3038  * callback might block and directly or indirectly (another thread) cause
3039  * the RB tree to change.
3040  */
3041
3042 #ifndef NFS_COMMITBVECSIZ
3043 #define NFS_COMMITBVECSIZ       16
3044 #endif
3045
3046 struct nfs_flush_info {
3047         enum { NFI_FLUSHNEW, NFI_COMMIT } mode;
3048         struct thread *td;
3049         struct vnode *vp;
3050         int waitfor;
3051         int slpflag;
3052         int slptimeo;
3053         int loops;
3054         struct buf *bvary[NFS_COMMITBVECSIZ];
3055         int bvsize;
3056         off_t beg_off;
3057         off_t end_off;
3058 };
3059
3060 static int nfs_flush_bp(struct buf *bp, void *data);
3061 static int nfs_flush_docommit(struct nfs_flush_info *info, int error);
3062
3063 int
3064 nfs_flush(struct vnode *vp, int waitfor, struct thread *td, int commit)
3065 {
3066         struct nfsnode *np = VTONFS(vp);
3067         struct nfsmount *nmp = VFSTONFS(vp->v_mount);
3068         struct nfs_flush_info info;
3069         lwkt_tokref vlock;
3070         int error;
3071
3072         bzero(&info, sizeof(info));
3073         info.td = td;
3074         info.vp = vp;
3075         info.waitfor = waitfor;
3076         info.slpflag = (nmp->nm_flag & NFSMNT_INT) ? PCATCH : 0;
3077         info.loops = 0;
3078         lwkt_gettoken(&vlock, &vp->v_token);
3079
3080         do {
3081                 /*
3082                  * Flush mode
3083                  */
3084                 info.mode = NFI_FLUSHNEW;
3085                 error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL, 
3086                                 nfs_flush_bp, &info);
3087
3088                 /*
3089                  * Take a second pass if committing and no error occured.  
3090                  * Clean up any left over collection (whether an error 
3091                  * occurs or not).
3092                  */
3093                 if (commit && error == 0) {
3094                         info.mode = NFI_COMMIT;
3095                         error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL, 
3096                                         nfs_flush_bp, &info);
3097                         if (info.bvsize)
3098                                 error = nfs_flush_docommit(&info, error);
3099                 }
3100
3101                 /*
3102                  * Wait for pending I/O to complete before checking whether
3103                  * any further dirty buffers exist.
3104                  */
3105                 while (waitfor == MNT_WAIT &&
3106                        bio_track_active(&vp->v_track_write)) {
3107                         error = bio_track_wait(&vp->v_track_write,
3108                                                info.slpflag, info.slptimeo);
3109                         if (error) {
3110                                 /*
3111                                  * We have to be able to break out if this 
3112                                  * is an 'intr' mount.
3113                                  */
3114                                 if (nfs_sigintr(nmp, NULL, td)) {
3115                                         error = -EINTR;
3116                                         break;
3117                                 }
3118
3119                                 /*
3120                                  * Since we do not process pending signals,
3121                                  * once we get a PCATCH our tsleep() will no
3122                                  * longer sleep, switch to a fixed timeout
3123                                  * instead.
3124                                  */
3125                                 if (info.slpflag == PCATCH) {
3126                                         info.slpflag = 0;
3127                                         info.slptimeo = 2 * hz;
3128                                 }
3129                                 error = 0;
3130                         }
3131                 }
3132                 ++info.loops;
3133                 /*
3134                  * Loop if we are flushing synchronous as well as committing,
3135                  * and dirty buffers are still present.  Otherwise we might livelock.
3136                  */
3137         } while (waitfor == MNT_WAIT && commit && 
3138                  error == 0 && !RB_EMPTY(&vp->v_rbdirty_tree));
3139
3140         /*
3141          * The callbacks have to return a negative error to terminate the
3142          * RB scan.
3143          */
3144         if (error < 0)
3145                 error = -error;
3146
3147         /*
3148          * Deal with any error collection
3149          */
3150         if (np->n_flag & NWRITEERR) {
3151                 error = np->n_error;
3152                 np->n_flag &= ~NWRITEERR;
3153         }
3154         lwkt_reltoken(&vlock);
3155         return (error);
3156 }
3157
3158 static
3159 int
3160 nfs_flush_bp(struct buf *bp, void *data)
3161 {
3162         struct nfs_flush_info *info = data;
3163         int lkflags;
3164         int error;
3165         off_t toff;
3166
3167         error = 0;
3168         switch(info->mode) {
3169         case NFI_FLUSHNEW:
3170                 error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT);
3171                 if (error && info->loops && info->waitfor == MNT_WAIT) {
3172                         error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT);
3173                         if (error) {
3174                                 lkflags = LK_EXCLUSIVE | LK_SLEEPFAIL;
3175                                 if (info->slpflag & PCATCH)
3176                                         lkflags |= LK_PCATCH;
3177                                 error = BUF_TIMELOCK(bp, lkflags, "nfsfsync",
3178                                                      info->slptimeo);
3179                         }
3180                 }
3181
3182                 /*
3183                  * Ignore locking errors
3184                  */
3185                 if (error) {
3186                         error = 0;
3187                         break;
3188                 }
3189
3190                 /*
3191                  * The buffer may have changed out from under us, even if
3192                  * we did not block (MPSAFE).  Check again now that it is
3193                  * locked.
3194                  */
3195                 if (bp->b_vp == info->vp &&
3196                     (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) == B_DELWRI) {
3197                         bremfree(bp);
3198                         bawrite(bp);
3199                 } else {
3200                         BUF_UNLOCK(bp);
3201                 }
3202                 break;
3203         case NFI_COMMIT:
3204                 /*
3205                  * Only process buffers in need of a commit which we can
3206                  * immediately lock.  This may prevent a buffer from being
3207                  * committed, but the normal flush loop will block on the
3208                  * same buffer so we shouldn't get into an endless loop.
3209                  */
3210                 if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != 
3211                     (B_DELWRI | B_NEEDCOMMIT)) {
3212                         break;
3213                 }
3214                 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
3215                         break;
3216
3217                 /*
3218                  * We must recheck after successfully locking the buffer.
3219                  */
3220                 if (bp->b_vp != info->vp ||
3221                     (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) !=
3222                     (B_DELWRI | B_NEEDCOMMIT)) {
3223                         BUF_UNLOCK(bp);
3224                         break;
3225                 }
3226
3227                 /*
3228                  * NOTE: storing the bp in the bvary[] basically sets
3229                  * it up for a commit operation.
3230                  *
3231                  * We must call vfs_busy_pages() now so the commit operation
3232                  * is interlocked with user modifications to memory mapped
3233                  * pages.  The b_dirtyoff/b_dirtyend range is not correct
3234                  * until after the pages have been busied.
3235                  *
3236                  * Note: to avoid loopback deadlocks, we do not
3237                  * assign b_runningbufspace.
3238                  */
3239                 bremfree(bp);
3240                 bp->b_cmd = BUF_CMD_WRITE;
3241                 vfs_busy_pages(bp->b_vp, bp);
3242                 info->bvary[info->bvsize] = bp;
3243                 toff = bp->b_bio2.bio_offset + bp->b_dirtyoff;
3244                 if (info->bvsize == 0 || toff < info->beg_off)
3245                         info->beg_off = toff;
3246                 toff += (off_t)(bp->b_dirtyend - bp->b_dirtyoff);
3247                 if (info->bvsize == 0 || toff > info->end_off)
3248                         info->end_off = toff;
3249                 ++info->bvsize;
3250                 if (info->bvsize == NFS_COMMITBVECSIZ) {
3251                         error = nfs_flush_docommit(info, 0);
3252                         KKASSERT(info->bvsize == 0);
3253                 }
3254         }
3255         return (error);
3256 }
3257
3258 static
3259 int
3260 nfs_flush_docommit(struct nfs_flush_info *info, int error)
3261 {
3262         struct vnode *vp;
3263         struct buf *bp;
3264         off_t bytes;
3265         int retv;
3266         int i;
3267
3268         vp = info->vp;
3269
3270         if (info->bvsize > 0) {
3271                 /*
3272                  * Commit data on the server, as required.  Note that
3273                  * nfs_commit will use the vnode's cred for the commit.
3274                  * The NFSv3 commit RPC is limited to a 32 bit byte count.
3275                  */
3276                 bytes = info->end_off - info->beg_off;
3277                 if (bytes > 0x40000000)
3278                         bytes = 0x40000000;
3279                 if (error) {
3280                         retv = -error;
3281                 } else {
3282                         retv = nfs_commitrpc_uio(vp, info->beg_off,
3283                                                  (int)bytes, info->td);
3284                         if (retv == NFSERR_STALEWRITEVERF)
3285                                 nfs_clearcommit(vp->v_mount);
3286                 }
3287
3288                 /*
3289                  * Now, either mark the blocks I/O done or mark the
3290                  * blocks dirty, depending on whether the commit
3291                  * succeeded.
3292                  */
3293                 for (i = 0; i < info->bvsize; ++i) {
3294                         bp = info->bvary[i];
3295                         bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
3296                         if (retv) {
3297                                 /*
3298                                  * Error, leave B_DELWRI intact
3299                                  */
3300                                 vfs_unbusy_pages(bp);
3301                                 bp->b_cmd = BUF_CMD_DONE;
3302                                 brelse(bp);
3303                         } else {
3304                                 /*
3305                                  * Success, remove B_DELWRI ( bundirty() ).
3306                                  *
3307                                  * b_dirtyoff/b_dirtyend seem to be NFS 
3308                                  * specific.  We should probably move that
3309                                  * into bundirty(). XXX
3310                                  *
3311                                  * We are faking an I/O write, we have to 
3312                                  * start the transaction in order to
3313                                  * immediately biodone() it.
3314                                  */
3315                                 bundirty(bp);
3316                                 bp->b_flags &= ~B_ERROR;
3317                                 bp->b_dirtyoff = bp->b_dirtyend = 0;
3318                                 biodone(&bp->b_bio1);
3319                         }
3320                 }
3321                 info->bvsize = 0;
3322         }
3323         return (error);
3324 }
3325
3326 /*
3327  * NFS advisory byte-level locks.
3328  * Currently unsupported.
3329  *
3330  * nfs_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
3331  *              int a_flags)
3332  */
3333 static int
3334 nfs_advlock(struct vop_advlock_args *ap)
3335 {
3336         struct nfsnode *np = VTONFS(ap->a_vp);
3337
3338         /*
3339          * The following kludge is to allow diskless support to work
3340          * until a real NFS lockd is implemented. Basically, just pretend
3341          * that this is a local lock.
3342          */
3343         return (lf_advlock(ap, &(np->n_lockf), np->n_size));
3344 }
3345
3346 /*
3347  * Print out the contents of an nfsnode.
3348  *
3349  * nfs_print(struct vnode *a_vp)
3350  */
3351 static int
3352 nfs_print(struct vop_print_args *ap)
3353 {
3354         struct vnode *vp = ap->a_vp;
3355         struct nfsnode *np = VTONFS(vp);
3356
3357         kprintf("tag VT_NFS, fileid %lld fsid 0x%x",
3358                 (long long)np->n_vattr.va_fileid, np->n_vattr.va_fsid);
3359         if (vp->v_type == VFIFO)
3360                 fifo_printinfo(vp);
3361         kprintf("\n");
3362         return (0);
3363 }
3364
3365 /*
3366  * nfs special file access vnode op.
3367  *
3368  * nfs_laccess(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
3369  */
3370 static int
3371 nfs_laccess(struct vop_access_args *ap)
3372 {
3373         struct vattr vattr;
3374         int error;
3375
3376         error = VOP_GETATTR(ap->a_vp, &vattr);
3377         if (!error)
3378                 error = vop_helper_access(ap, vattr.va_uid, vattr.va_gid, 
3379                                 vattr.va_mode, 0);
3380         return (error);
3381 }
3382
3383 /*
3384  * Read wrapper for fifos.
3385  *
3386  * nfsfifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
3387  *              struct ucred *a_cred)
3388  */
3389 static int
3390 nfsfifo_read(struct vop_read_args *ap)
3391 {
3392         struct nfsnode *np = VTONFS(ap->a_vp);
3393
3394         /*
3395          * Set access flag.
3396          */
3397         np->n_flag |= NACC;
3398         getnanotime(&np->n_atim);
3399         return (VOCALL(&fifo_vnode_vops, &ap->a_head));
3400 }
3401
3402 /*
3403  * Write wrapper for fifos.
3404  *
3405  * nfsfifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
3406  *               struct ucred *a_cred)
3407  */
3408 static int
3409 nfsfifo_write(struct vop_write_args *ap)
3410 {
3411         struct nfsnode *np = VTONFS(ap->a_vp);
3412
3413         /*
3414          * Set update flag.
3415          */
3416         np->n_flag |= NUPD;
3417         getnanotime(&np->n_mtim);
3418         return (VOCALL(&fifo_vnode_vops, &ap->a_head));
3419 }
3420
3421 /*
3422  * Close wrapper for fifos.
3423  *
3424  * Update the times on the nfsnode then do fifo close.
3425  *
3426  * nfsfifo_close(struct vnode *a_vp, int a_fflag)
3427  */
3428 static int
3429 nfsfifo_close(struct vop_close_args *ap)
3430 {
3431         struct vnode *vp = ap->a_vp;
3432         struct nfsnode *np = VTONFS(vp);
3433         struct vattr vattr;
3434         struct timespec ts;
3435
3436         if (np->n_flag & (NACC | NUPD)) {
3437                 getnanotime(&ts);
3438                 if (np->n_flag & NACC)
3439                         np->n_atim = ts;
3440                 if (np->n_flag & NUPD)
3441                         np->n_mtim = ts;
3442                 np->n_flag |= NCHG;
3443                 if (vp->v_sysref.refcnt == 1 &&
3444                     (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
3445                         VATTR_NULL(&vattr);
3446                         if (np->n_flag & NACC)
3447                                 vattr.va_atime = np->n_atim;
3448                         if (np->n_flag & NUPD)
3449                                 vattr.va_mtime = np->n_mtim;
3450                         (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE));
3451                 }
3452         }
3453         return (VOCALL(&fifo_vnode_vops, &ap->a_head));
3454 }
3455