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