]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/nfs/nfs4_vnops.c
xnu-2782.40.9.tar.gz
[apple/xnu.git] / bsd / nfs / nfs4_vnops.c
index ca874aa7cd4943e9edf11fe00adab83d879ee1f8..2682d94be706efbdcbae313e7942881f8a04bf86 100644 (file)
@@ -80,7 +80,7 @@
 #include <kern/sched_prim.h>
 
 int
-nfs4_access_rpc(nfsnode_t np, u_int32_t *access, vfs_context_t ctx)
+nfs4_access_rpc(nfsnode_t np, u_int32_t *access, int rpcflags, vfs_context_t ctx)
 {
        int error = 0, lockerror = ENOENT, status, numops, slot;
        u_int64_t xid;
@@ -115,7 +115,9 @@ nfs4_access_rpc(nfsnode_t np, u_int32_t *access, vfs_context_t ctx)
        nfsm_chain_build_done(error, &nmreq);
        nfsm_assert(error, (numops == 0), EPROTO);
        nfsmout_if(error);
-       error = nfs_request(np, NULL, &nmreq, NFSPROC4_COMPOUND, ctx, &si, &nmrep, &xid, &status);
+       error = nfs_request2(np, NULL, &nmreq, NFSPROC4_COMPOUND,
+               vfs_context_thread(ctx), vfs_context_ucred(ctx),
+               &si, rpcflags, &nmrep, &xid, &status);
 
        if ((lockerror = nfs_node_lock(np)))
                error = lockerror;
@@ -189,7 +191,7 @@ nfs4_getattr_rpc(
        struct nfsm_chain nmreq, nmrep;
        struct nfsreq_secinfo_args si;
 
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        acls = (nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_ACL);
@@ -202,6 +204,9 @@ nfs4_getattr_rpc(
        if (flags & NGA_MONITOR) /* vnode monitor requests should be soft */
                rpcflags = R_RECOVER;
 
+       if (flags & NGA_SOFT) /* Return ETIMEDOUT if server not responding */
+               rpcflags |= R_SOFT;
+
        NFSREQ_SECINFO_SET(&si, np, NULL, 0, NULL, 0);
        nfsm_chain_null(&nmreq);
        nfsm_chain_null(&nmrep);
@@ -255,7 +260,7 @@ nfs4_readlink_rpc(nfsnode_t np, char *buf, uint32_t *buflenp, vfs_context_t ctx)
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
                return (EINVAL);
@@ -324,7 +329,7 @@ nfs4_read_rpc_async(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -373,7 +378,7 @@ nfs4_read_rpc_async_finish(
        struct nfsm_chain nmrep;
 
        nmp = NFSTONMP(np);
-       if (!nmp) {
+       if (nfs_mount_gone(nmp)) {
                nfs_request_async_cancel(req);
                return (ENXIO);
        }
@@ -431,7 +436,7 @@ nfs4_write_rpc_async(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -491,7 +496,7 @@ nfs4_write_rpc_async_finish(
        struct nfsm_chain nmrep;
 
        nmp = NFSTONMP(np);
-       if (!nmp) {
+       if (nfs_mount_gone(nmp)) {
                nfs_request_async_cancel(req);
                return (ENXIO);
        }
@@ -503,7 +508,7 @@ nfs4_write_rpc_async_finish(
        if (error == EINPROGRESS) /* async request restarted */
                return (error);
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                error = ENXIO;
        if (!error && (lockerror = nfs_node_lock(np)))
                error = lockerror;
@@ -560,7 +565,7 @@ nfs4_remove_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(dnp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (dnp->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -634,7 +639,7 @@ nfs4_rename_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(fdnp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (fdnp->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -733,7 +738,7 @@ nfs4_readdir_rpc(nfsnode_t dnp, struct nfsbuf *bp, vfs_context_t ctx)
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(dnp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        nmreaddirsize = nmp->nm_readdirsize;
@@ -778,7 +783,7 @@ nfs4_readdir_rpc(nfsnode_t dnp, struct nfsbuf *bp, vfs_context_t ctx)
        } else {
                cookie = bp->nb_lblkno;
                /* increment with every buffer read */
-               OSAddAtomic(1, &nfsstats.readdir_bios);
+               OSAddAtomic64(1, &nfsstats.readdir_bios);
        }
        lastcookie = cookie;
 
@@ -946,7 +951,7 @@ nextbuffer:
                                space_free = nfs_dir_buf_freespace(bp, rdirplus);
                                dp = NFS_DIR_BUF_FIRST_DIRENTRY(bp);
                                /* increment with every buffer read */
-                               OSAddAtomic(1, &nfsstats.readdir_bios);
+                               OSAddAtomic64(1, &nfsstats.readdir_bios);
                        }
                        nmrepsave = nmrep;
                        dp->d_fileno = cookie; /* placeholder */
@@ -1081,7 +1086,7 @@ nfs4_lookup_rpc_async(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(dnp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (dnp->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -1230,7 +1235,7 @@ nfs4_commit_rpc(
 
        nmp = NFSTONMP(np);
        FSDBG(521, np, offset, count, nmp ? nmp->nm_state : 0);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
                return (EINVAL);
@@ -1305,7 +1310,7 @@ nfs4_pathconf_rpc(
        struct nfs_vattr nvattr;
        struct nfsreq_secinfo_args si;
 
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -1373,7 +1378,8 @@ nfs4_vnop_getattr(
        struct nfs_vattr nva;
        int error, acls, ngaflags;
 
-       if (!(nmp = VTONMP(ap->a_vp)))
+       nmp = VTONMP(ap->a_vp);
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        acls = (nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_ACL);
 
@@ -1484,7 +1490,7 @@ nfs4_setattr_rpc(
        nfs_stateid stateid;
        struct nfsreq_secinfo_args si;
 
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -1647,7 +1653,7 @@ nfs_mount_state_in_use_start(struct nfsmount *nmp, thread_t thd)
        struct timespec ts = { 1, 0 };
        int error = 0, slpflag = (NMFLAG(nmp, INTR) && thd) ? PCATCH : 0;
 
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        lck_mtx_lock(&nmp->nm_lock);
        if (nmp->nm_state & (NFSSTA_FORCE|NFSSTA_DEAD)) {
@@ -1678,7 +1684,7 @@ nfs_mount_state_in_use_end(struct nfsmount *nmp, int error)
 {
        int restart = nfs_mount_state_error_should_restart(error);
 
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (restart);
        lck_mtx_lock(&nmp->nm_lock);
        if (restart && (error != NFSERR_OLD_STATEID) && (error != NFSERR_GRACE)) {
@@ -1759,7 +1765,7 @@ nfs_open_state_set_busy(nfsnode_t np, thread_t thd)
        int error = 0, slpflag;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        slpflag = (NMFLAG(nmp, INTR) && thd) ? PCATCH : 0;
 
@@ -1902,7 +1908,7 @@ nfs_open_owner_set_busy(struct nfs_open_owner *noop, thread_t thd)
        int error = 0, slpflag;
 
        nmp = noop->noo_mount;
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        slpflag = (NMFLAG(nmp, INTR) && thd) ? PCATCH : 0;
 
@@ -2083,7 +2089,7 @@ nfs_open_file_set_busy(struct nfs_open_file *nofp, thread_t thd)
        int error = 0, slpflag;
 
        nmp = nofp->nof_owner->noo_mount;
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        slpflag = (NMFLAG(nmp, INTR) && thd) ? PCATCH : 0;
 
@@ -2669,7 +2675,7 @@ nfs_vnop_mmap(
        struct nfs_open_file *nofp = NULL;
 
        nmp = VTONMP(vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (!vnode_isreg(vp) || !(ap->a_fflags & (PROT_READ|PROT_WRITE)))
@@ -2830,6 +2836,26 @@ out:
        }
        if (noop)
                nfs_open_owner_rele(noop);
+
+       if (!error) {
+               int ismapped = 0;
+               nfs_node_lock_force(np);
+               if ((np->n_flag & NISMAPPED) == 0) {
+                       np->n_flag |= NISMAPPED;
+                       ismapped = 1;
+               }
+               nfs_node_unlock(np);
+               if (ismapped) {
+                       lck_mtx_lock(&nmp->nm_lock);
+                       nmp->nm_state &= ~NFSSTA_SQUISHY;
+                       nmp->nm_curdeadtimeout = nmp->nm_deadtimeout;
+                       if (nmp->nm_curdeadtimeout <= 0)
+                               nmp->nm_deadto_start = 0;
+                       nmp->nm_mappers++;
+                       lck_mtx_unlock(&nmp->nm_lock);
+               }
+       }
+
        return (error);
 }
 
@@ -2849,11 +2875,27 @@ nfs_vnop_mnomap(
        struct nfs_open_file *nofp = NULL;
        off_t size;
        int error;
-
+       int is_mapped_flag = 0;
+       
        nmp = VTONMP(vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
+       nfs_node_lock_force(np);
+       if (np->n_flag & NISMAPPED) {
+               is_mapped_flag = 1;
+               np->n_flag &= ~NISMAPPED;
+       }
+       nfs_node_unlock(np);
+       if (is_mapped_flag) {
+               lck_mtx_lock(&nmp->nm_lock);
+               if (nmp->nm_mappers)
+                       nmp->nm_mappers--;
+               else
+                       NP(np, "nfs_vnop_mnomap: removing mmap reference from mount, but mount has no files mmapped");
+               lck_mtx_unlock(&nmp->nm_lock);
+       }
+
        /* flush buffers/ubc before we drop the open (in case it's our last open) */
        nfs_flush(np, MNT_WAIT, vfs_context_thread(ctx), V_IGNORE_WRITEERR);
        if (UBCINFOEXISTS(vp) && (size = ubc_getsize(vp)))
@@ -3019,7 +3061,7 @@ nfs_lock_owner_set_busy(struct nfs_lock_owner *nlop, thread_t thd)
        int error = 0, slpflag;
 
        nmp = nlop->nlo_open_owner->noo_mount;
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        slpflag = (NMFLAG(nmp, INTR) && thd) ? PCATCH : 0;
 
@@ -3179,7 +3221,7 @@ nfs4_setlock_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
                return (EINVAL);
@@ -3302,7 +3344,7 @@ nfs4_unlock_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
                return (EINVAL);
@@ -3379,7 +3421,7 @@ nfs4_getlock_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
                return (EINVAL);
@@ -3463,7 +3505,7 @@ nfs_advlock_getlock(
        int error = 0, answered = 0;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
 restart:
@@ -3539,7 +3581,7 @@ nfs_advlock_setlock(
        struct timespec ts = {1, 0};
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        slpflag = NMFLAG(nmp, INTR) ? PCATCH : 0;
 
@@ -3797,7 +3839,8 @@ error_out:
                        wakeup(newnflp);
                } else {
                        /* remove newnflp from lock list and destroy */
-                       TAILQ_REMOVE(&np->n_locks, newnflp, nfl_link);
+                       if (inqueue)
+                               TAILQ_REMOVE(&np->n_locks, newnflp, nfl_link);
                        nfs_file_lock_destroy(newnflp);
                }
                lck_mtx_unlock(&np->n_openlock);
@@ -3950,7 +3993,7 @@ nfs_advlock_unlock(
        int error = 0, willsplit = 0, send_unlock_rpcs = 1;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
 restart:
@@ -4205,7 +4248,7 @@ nfs_vnop_advlock(
 #define OFF_MAX QUAD_MAX
 
        nmp = VTONMP(ap->a_vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        lck_mtx_lock(&nmp->nm_lock);
        if ((nmp->nm_vers <= NFS_VER3) && (nmp->nm_lockmode == NFS_LOCK_MODE_DISABLED)) {
@@ -4616,7 +4659,7 @@ nfs4_open_rpc_internal(
                return (EINVAL);
 
        nmp = VTONMP(dvp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        namedattrs = (nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR);
@@ -4953,7 +4996,7 @@ nfs4_claim_delegated_open_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
 
@@ -5205,7 +5248,7 @@ nfs4_open_reclaim_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
 
@@ -5392,7 +5435,7 @@ nfs4_open_downgrade_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
 
@@ -5462,7 +5505,7 @@ nfs4_close_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
 
@@ -5753,6 +5796,7 @@ nfs_release_open_state_for_node(nfsnode_t np, int force)
                lck_mtx_lock(&nofp->nof_lock);
                nofp->nof_flags &= ~NFS_OPEN_FILE_REOPEN;
                nofp->nof_flags |= NFS_OPEN_FILE_LOST;
+               
                lck_mtx_unlock(&nofp->nof_lock);
                if (!force && nmp && (nmp->nm_vers >= NFS_VER4))
                        nfs4_close_rpc(np, nofp, NULL, nofp->nof_owner->noo_cred, R_RECOVER);
@@ -5836,7 +5880,7 @@ nfs4_delegation_return_enqueue(nfsnode_t np)
        struct nfsmount *nmp;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return;
 
        lck_mtx_lock(&np->n_openlock);
@@ -5862,7 +5906,7 @@ nfs4_delegation_return(nfsnode_t np, int flags, thread_t thd, kauth_cred_t cred)
        int error;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        /* first, make sure the node's marked for delegation return */
@@ -5993,11 +6037,11 @@ nfs_vnop_read(
        int error;
 
        if (vnode_vtype(ap->a_vp) != VREG)
-               return (EPERM);
+               return (vnode_vtype(vp) == VDIR) ? EISDIR : EPERM;
 
        np = VTONFS(vp);
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        if (np->n_flag & NREVOKE)
                return (EIO);
@@ -6088,7 +6132,7 @@ nfs4_vnop_create(
        struct nfs_open_file *newnofp = NULL, *nofp = NULL;
 
        nmp = VTONMP(dvp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (vap)
@@ -6258,7 +6302,7 @@ nfs4_create_rpc(
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(dnp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        namedattrs = (nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR);
@@ -6445,7 +6489,7 @@ nfs4_vnop_mknod(
        int error;
 
        nmp = VTONMP(ap->a_dvp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (!VATTR_IS_ACTIVE(ap->a_vap, va_type))
@@ -6537,7 +6581,7 @@ nfs4_vnop_link(
                return (EXDEV);
 
        nmp = VTONMP(vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        nfsvers = nmp->nm_vers;
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
@@ -6653,7 +6697,7 @@ nfs4_vnop_rmdir(
                return (EINVAL);
 
        nmp = NFSTONMP(dnp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        namedattrs = (nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR);
 
@@ -6737,7 +6781,7 @@ nfs4_named_attr_dir_get(nfsnode_t np, int fetch, vfs_context_t ctx)
        struct nfsreq_secinfo_args si;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (NULL);
        if (np->n_vattr.nva_flags & NFS_FFLAG_TRIGGER_REFERRAL)
                return (NULL);
@@ -6905,7 +6949,7 @@ nfs4_named_attr_get(
        slen = sizeof(sbuf);
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        NVATTR_INIT(&nvattr);
        negnamecache = !NMFLAG(nmp, NONEGNAMECACHE);
@@ -6984,7 +7028,7 @@ nfs4_named_attr_get(
                        /* FALLTHROUGH */
                case -1:
                        /* cache hit, not really an error */
-                       OSAddAtomic(1, &nfsstats.lookupcache_hits);
+                       OSAddAtomic64(1, &nfsstats.lookupcache_hits);
                        if (!anp && avp)
                                *anpp = anp = VTONFS(avp);
 
@@ -7524,7 +7568,7 @@ nfsmout:
                        /* don't save the data if dirty or potential I/O conflict */
                        if (!error && bp && !bp->nb_dirtyoff && !(bp->nb_dirty & pagemask) &&
                            timevalcmp(&anp->n_lastio, &now, <)) {
-                               OSAddAtomic(1, &nfsstats.read_bios);
+                               OSAddAtomic64(1, &nfsstats.read_bios);
                                CLR(bp->nb_flags, (NB_DONE|NB_ASYNC));
                                SET(bp->nb_flags, NB_READ);
                                NFS_BUF_MAP(bp);
@@ -7590,7 +7634,7 @@ nfs4_named_attr_remove(nfsnode_t np, nfsnode_t anp, const char *name, vfs_contex
        int error, putanp = 0;
 
        nmp = NFSTONMP(np);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        bzero(&cn, sizeof(cn));
@@ -7658,7 +7702,7 @@ nfs4_vnop_getxattr(
        int error = 0, isrsrcfork;
 
        nmp = VTONMP(ap->a_vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (!(nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR))
@@ -7722,7 +7766,7 @@ nfs4_vnop_setxattr(
        struct vnop_write_args vwa;
 
        nmp = VTONMP(ap->a_vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (!(nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR))
@@ -7860,7 +7904,7 @@ nfs4_vnop_removexattr(
        struct nfsmount *nmp = VTONMP(ap->a_vp);
        int error;
 
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
        if (!(nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR))
                return (ENOTSUP);
@@ -7895,7 +7939,7 @@ nfs4_vnop_listxattr(
        struct direntry *dp;
 
        nmp = VTONMP(ap->a_vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (!(nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR))
@@ -7951,7 +7995,7 @@ nfs4_vnop_listxattr(
        nextcookie = lbn = 0;
 
        while (!error && !done) {
-               OSAddAtomic(1, &nfsstats.biocache_readdirs);
+               OSAddAtomic64(1, &nfsstats.biocache_readdirs);
                cookie = nextcookie;
 getbuffer:
                error = nfs_buf_get(adnp, lbn, NFS_DIRBLKSIZ, vfs_context_thread(ctx), NBLK_READ, &bp);
@@ -8041,7 +8085,7 @@ nfs4_vnop_getnamedstream(
        int error = 0;
 
        nmp = VTONMP(ap->a_vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (!(nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR))
@@ -8088,7 +8132,7 @@ nfs4_vnop_makenamedstream(
        int error = 0;
 
        nmp = VTONMP(ap->a_vp);
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        if (!(nmp->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR))
@@ -8126,7 +8170,7 @@ nfs4_vnop_removenamedstream(
        nfsnode_t np = ap->a_vp ? VTONFS(ap->a_vp) : NULL;
        nfsnode_t anp = ap->a_svp ? VTONFS(ap->a_svp) : NULL;
 
-       if (!nmp)
+       if (nfs_mount_gone(nmp))
                return (ENXIO);
 
        /*