The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/nfsclient/nfs_clvnops.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: a59c3455c2dbc42504f9d035f3a9be6a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.