]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/nfs/nfs_serv.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / nfs / nfs_serv.c
index 2ebb8994bdc082f7ee17d8378458212d7935dc31..0346a75028f32f812df4916dede2f5f1953a0b27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2019 Apple Inc.  All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -65,6 +65,9 @@
  * FreeBSD-Id: nfs_serv.c,v 1.52 1997/10/28 15:59:05 bde Exp $
  */
 
+#include <nfs/nfs_conf.h>
+#if CONFIG_NFS_SERVER
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <security/mac_framework.h>
 #endif
 
-#if NFSSERVER
-
 /*
  * NFS server globals
  */
 
 int nfsd_thread_count = 0;
 int nfsd_thread_max = 0;
-lck_grp_t *nfsd_lck_grp;
-lck_mtx_t *nfsd_mutex;
+static LCK_GRP_DECLARE(nfsd_lck_grp, "nfsd");
+LCK_MTX_DECLARE(nfsd_mutex, &nfsd_lck_grp);
 struct nfsd_head nfsd_head, nfsd_queue;
 
-lck_grp_t *nfsrv_slp_rwlock_group;
-lck_grp_t *nfsrv_slp_mutex_group;
+LCK_GRP_DECLARE(nfsrv_slp_rwlock_group, "nfsrv-slp-rwlock");
+LCK_GRP_DECLARE(nfsrv_slp_mutex_group, "nfsrv-slp-mutex");
 struct nfsrv_sockhead nfsrv_socklist, nfsrv_sockwg,
     nfsrv_sockwait, nfsrv_sockwork;
 struct nfsrv_sock *nfsrv_udpsock = NULL;
@@ -131,15 +132,15 @@ struct nfsrv_expfs_list nfsrv_exports;
 struct nfsrv_export_hashhead *nfsrv_export_hashtbl = NULL;
 int nfsrv_export_hash_size = NFSRVEXPHASHSZ;
 u_long nfsrv_export_hash;
-lck_grp_t *nfsrv_export_rwlock_group;
-lck_rw_t nfsrv_export_rwlock;
+static LCK_GRP_DECLARE(nfsrv_export_rwlock_group, "nfsrv-export-rwlock");
+LCK_RW_DECLARE(nfsrv_export_rwlock, &nfsrv_export_rwlock_group);
 
 #if CONFIG_FSE
 /* NFS server file modification event generator */
 struct nfsrv_fmod_hashhead *nfsrv_fmod_hashtbl;
 u_long nfsrv_fmod_hash;
-lck_grp_t *nfsrv_fmod_grp;
-lck_mtx_t *nfsrv_fmod_mutex;
+static LCK_GRP_DECLARE(nfsrv_fmod_grp, "nfsrv_fmod");
+LCK_MTX_DECLARE(nfsrv_fmod_mutex, &nfsrv_fmod_grp);
 static int nfsrv_fmod_timer_on = 0;
 int nfsrv_fsevents_enabled = 1;
 #endif
@@ -157,7 +158,7 @@ uint32_t nfsrv_user_stat_enabled = 1;
 uint32_t nfsrv_user_stat_node_count = 0;
 uint32_t nfsrv_user_stat_max_idle_sec = NFSRV_USER_STAT_DEF_IDLE_SEC;
 uint32_t nfsrv_user_stat_max_nodes = NFSRV_USER_STAT_DEF_MAX_NODES;
-lck_grp_t *nfsrv_active_user_mutex_group;
+LCK_GRP_DECLARE(nfsrv_active_user_mutex_group, "nfs-active-user-mutex");
 
 int nfsrv_wg_delay = NFSRV_WGATHERDELAY * 1000;
 int nfsrv_wg_delay_v3 = 0;
@@ -202,31 +203,12 @@ nfsrv_init(void)
                printf("struct nfsrv_sock bloated (> %dbytes)\n", NFS_SVCALLOC);
        }
 
-       /* init nfsd mutex */
-       nfsd_lck_grp = lck_grp_alloc_init("nfsd", LCK_GRP_ATTR_NULL);
-       nfsd_mutex = lck_mtx_alloc_init(nfsd_lck_grp, LCK_ATTR_NULL);
-
-       /* init slp rwlock */
-       nfsrv_slp_rwlock_group = lck_grp_alloc_init("nfsrv-slp-rwlock", LCK_GRP_ATTR_NULL);
-       nfsrv_slp_mutex_group  = lck_grp_alloc_init("nfsrv-slp-mutex", LCK_GRP_ATTR_NULL);
-
        /* init export data structures */
        LIST_INIT(&nfsrv_exports);
-       nfsrv_export_rwlock_group = lck_grp_alloc_init("nfsrv-export-rwlock", LCK_GRP_ATTR_NULL);
-       lck_rw_init(&nfsrv_export_rwlock, nfsrv_export_rwlock_group, LCK_ATTR_NULL);
-
-       /* init active user list mutex structures */
-       nfsrv_active_user_mutex_group = lck_grp_alloc_init("nfs-active-user-mutex", LCK_GRP_ATTR_NULL);
-
-       /* init nfs server request cache mutex */
-       nfsrv_reqcache_lck_grp = lck_grp_alloc_init("nfsrv_reqcache", LCK_GRP_ATTR_NULL);
-       nfsrv_reqcache_mutex = lck_mtx_alloc_init(nfsrv_reqcache_lck_grp, LCK_ATTR_NULL);
 
 #if CONFIG_FSE
        /* init NFS server file modified event generation */
        nfsrv_fmod_hashtbl = hashinit(NFSRVFMODHASHSZ, M_TEMP, &nfsrv_fmod_hash);
-       nfsrv_fmod_grp = lck_grp_alloc_init("nfsrv_fmod", LCK_GRP_ATTR_NULL);
-       nfsrv_fmod_mutex = lck_mtx_alloc_init(nfsrv_fmod_grp, LCK_ATTR_NULL);
 #endif
 
        /* initialize NFS server timer callouts */
@@ -927,11 +909,11 @@ nfsrv_read(
        mbuf_t *mrepp)
 {
        int error, attrerr, mreadcnt;
-       uint32_t reqlen, maxlen, count, len, tlen, left;
+       uint32_t reqlen, maxlen, count, len, tlen;
        mbuf_t mread, m;
        vnode_t vp;
        struct nfs_filehandle nfh;
-       struct nfs_export *nx;
+       struct nfs_export *nx = NULL;
        struct nfs_export_options *nxo;
        uio_t auio = NULL;
        char *uio_bufp = NULL;
@@ -1011,12 +993,12 @@ nfsrv_read(
        if ((u_quad_t)off >= vap->va_data_size) {
                count = 0;
        } else if (((u_quad_t)off + reqlen) > vap->va_data_size) {
-               count = nfsm_rndup(vap->va_data_size - off);
+               count = (int)nfsm_rndup(vap->va_data_size - off);
        } else {
                count = reqlen;
        }
 
-       len = left = count;
+       len = count;
        if (count > 0) {
                /* get mbuf list to hold read data */
                error = nfsm_mbuf_get_list(count, &mread, &mreadcnt);
@@ -1141,10 +1123,11 @@ nfsrv_fmod_timer(__unused void *param0, __unused void *param1)
        struct nfsrv_fmod_hashhead *headp, firehead;
        struct nfsrv_fmod *fp, *nfp, *pfp;
        uint64_t timenow, next_deadline;
-       int interval = 0, i, fmod_fire;
+       time_t interval = 0;
+       int i, fmod_fire;
 
        LIST_INIT(&firehead);
-       lck_mtx_lock(nfsrv_fmod_mutex);
+       lck_mtx_lock(&nfsrv_fmod_mutex);
 again:
        clock_get_uptime(&timenow);
        clock_interval_to_deadline(nfsrv_fmod_pendtime, 1000 * 1000,
@@ -1192,7 +1175,7 @@ again:
        }
 
        if (fmod_fire) {
-               lck_mtx_unlock(nfsrv_fmod_mutex);
+               lck_mtx_unlock(&nfsrv_fmod_mutex);
                /*
                 * Fire off the content modified fsevent for each
                 * entry and free it.
@@ -1209,7 +1192,7 @@ again:
                        LIST_REMOVE(fp, fm_link);
                        FREE(fp, M_TEMP);
                }
-               lck_mtx_lock(nfsrv_fmod_mutex);
+               lck_mtx_lock(&nfsrv_fmod_mutex);
                nfsrv_fmod_pending -= fmod_fire;
                goto again;
        }
@@ -1221,7 +1204,7 @@ again:
         * entry is ready to send its fsevent.
         */
        if (nfsrv_fmod_pending > 0) {
-               interval = (next_deadline - timenow) / (1000 * 1000);
+               interval = ((time_t)(next_deadline - timenow)) / (1000 * 1000);
                if (interval < nfsrv_fmod_min_interval) {
                        interval = nfsrv_fmod_min_interval;
                }
@@ -1232,7 +1215,7 @@ again:
                nfs_interval_timer_start(nfsrv_fmod_timer_call, interval);
        }
 
-       lck_mtx_unlock(nfsrv_fmod_mutex);
+       lck_mtx_unlock(&nfsrv_fmod_mutex);
 }
 
 /*
@@ -1248,7 +1231,7 @@ nfsrv_modified(vnode_t vp, vfs_context_t ctx)
        struct nfsrv_fmod *fp;
        struct nfsrv_fmod_hashhead *head;
 
-       lck_mtx_lock(nfsrv_fmod_mutex);
+       lck_mtx_lock(&nfsrv_fmod_mutex);
 
        /*
         * Compute the time in the future when the
@@ -1269,7 +1252,7 @@ nfsrv_modified(vnode_t vp, vfs_context_t ctx)
                                LIST_REMOVE(fp, fm_link);
                                LIST_INSERT_HEAD(head, fp, fm_link);
                        }
-                       lck_mtx_unlock(nfsrv_fmod_mutex);
+                       lck_mtx_unlock(&nfsrv_fmod_mutex);
                        return;
                }
        }
@@ -1304,7 +1287,7 @@ nfsrv_modified(vnode_t vp, vfs_context_t ctx)
                    nfsrv_fmod_pendtime);
        }
 done:
-       lck_mtx_unlock(nfsrv_fmod_mutex);
+       lck_mtx_unlock(&nfsrv_fmod_mutex);
        return;
 }
 #endif /* CONFIG_FSE */
@@ -1327,7 +1310,7 @@ nfsrv_write(
        mbuf_t m;
        vnode_t vp;
        struct nfs_filehandle nfh;
-       struct nfs_export *nx;
+       struct nfs_export *nx = NULL;
        struct nfs_export_options *nxo;
        uio_t auio = NULL;
        char *uio_bufp = NULL;
@@ -1438,7 +1421,7 @@ nfsrv_write(
                }
                nfsmerr_if(error);
                for (m = nmreq->nmc_mcur; m; m = mbuf_next(m)) {
-                       if ((mlen = mbuf_len(m)) > 0) {
+                       if ((mlen = (int)mbuf_len(m)) > 0) {
                                uio_addiov(auio, CAST_USER_ADDR_T((caddr_t)mbuf_data(m)), mlen);
                        }
                }
@@ -1554,13 +1537,14 @@ nfsrv_writegather(
        struct nfsrv_wg_delayhash *wpp;
        uid_t saved_uid;
        struct vnode_attr preattr, postattr;
-       int error, mlen, i, ioflags, tlen;
+       int error, mlen, i, ioflags;
+       size_t tlen;
        int preattrerr, postattrerr;
        vnode_t vp;
        mbuf_t m;
        uio_t auio = NULL;
        char *uio_bufp = NULL;
-       u_quad_t cur_usec;
+       time_t cur_usec;
        struct timeval now;
        struct nfsm_chain *nmreq, nmrep;
 
@@ -1578,7 +1562,7 @@ nfsrv_writegather(
                nd->nd_mrep = NULL;
                nd->nd_stable = NFS_WRITE_FILESYNC;
                microuptime(&now);
-               cur_usec = (u_quad_t)now.tv_sec * 1000000 + (u_quad_t)now.tv_usec;
+               cur_usec = now.tv_sec * 1000000 + now.tv_usec;
                nd->nd_time = cur_usec +
                    ((nd->nd_vers == NFS_VER3) ? nfsrv_wg_delay_v3 : nfsrv_wg_delay);
 
@@ -1679,7 +1663,7 @@ nfsmerr:
         */
 loop1:
        microuptime(&now);
-       cur_usec = (u_quad_t)now.tv_sec * 1000000 + (u_quad_t)now.tv_usec;
+       cur_usec = now.tv_sec * 1000000 + now.tv_usec;
        for (nd = slp->ns_tq.lh_first; nd; nd = owp) {
                owp = nd->nd_tq.le_next;
                if (nd->nd_time > cur_usec) {
@@ -1853,7 +1837,7 @@ loop1:
         *
         * Add/Remove the socket in the nfsrv_sockwg queue as needed.
         */
-       lck_mtx_lock(nfsd_mutex);
+       lck_mtx_lock(&nfsd_mutex);
        if (slp->ns_wgtime) {
                if (slp->ns_wgq.tqe_next == SLPNOLIST) {
                        TAILQ_INSERT_HEAD(&nfsrv_sockwg, slp, ns_wgq);
@@ -1867,7 +1851,7 @@ loop1:
                TAILQ_REMOVE(&nfsrv_sockwg, slp, ns_wgq);
                slp->ns_wgq.tqe_next = SLPNOLIST;
        }
-       lck_mtx_unlock(nfsd_mutex);
+       lck_mtx_unlock(&nfsd_mutex);
 
        return 0;
 }
@@ -1882,7 +1866,8 @@ loop1:
 int
 nfsrv_wg_coalesce(struct nfsrv_descript *owp, struct nfsrv_descript *nd)
 {
-       int overlap, error;
+       int error;
+       off_t overlap;
        mbuf_t mp, mpnext;
        struct nfsrv_descript *p;
 
@@ -1894,7 +1879,7 @@ nfsrv_wg_coalesce(struct nfsrv_descript *owp, struct nfsrv_descript *nd)
                        return EIO;
                }
                if (overlap > 0) {
-                       mbuf_adj(nd->nd_nmreq.nmc_mhead, overlap);
+                       mbuf_adj(nd->nd_nmreq.nmc_mhead, (int)overlap);
                }
                mp = owp->nd_nmreq.nmc_mhead;
                while ((mpnext = mbuf_next(mp))) {
@@ -1937,16 +1922,16 @@ void
 nfsrv_wg_timer(__unused void *param0, __unused void *param1)
 {
        struct timeval now;
-       uint64_t cur_usec, next_usec;
-       int interval;
+       time_t cur_usec, next_usec;
+       time_t interval;
        struct nfsrv_sock *slp;
        int writes_pending = 0;
 
        microuptime(&now);
-       cur_usec = (uint64_t)now.tv_sec * 1000000 + (uint64_t)now.tv_usec;
+       cur_usec = now.tv_sec * 1000000 + now.tv_usec;
        next_usec = cur_usec + (NFSRV_WGATHERDELAY * 1000);
 
-       lck_mtx_lock(nfsd_mutex);
+       lck_mtx_lock(&nfsd_mutex);
        TAILQ_FOREACH(slp, &nfsrv_sockwg, ns_wgq) {
                if (slp->ns_wgtime) {
                        writes_pending++;
@@ -1965,10 +1950,10 @@ nfsrv_wg_timer(__unused void *param0, __unused void *param1)
 
        if (writes_pending == 0) {
                nfsrv_wg_timer_on = 0;
-               lck_mtx_unlock(nfsd_mutex);
+               lck_mtx_unlock(&nfsd_mutex);
                return;
        }
-       lck_mtx_unlock(nfsd_mutex);
+       lck_mtx_unlock(&nfsd_mutex);
 
        /*
         * Return the number of msec to wait again
@@ -2016,13 +2001,14 @@ nfsrv_create(
        struct vnode_attr dpreattr, dpostattr, postattr;
        struct vnode_attr va, *vap = &va;
        struct nameidata ni;
-       int error, rdev, dpreattrerr, dpostattrerr, postattrerr;
+       int error, dpreattrerr, dpostattrerr, postattrerr;
        int how, exclusive_flag;
        uint32_t len = 0, cnflags;
+       uint64_t rdev;
        vnode_t vp, dvp, dirp;
        struct nfs_filehandle nfh;
        struct nfs_export *nx = NULL;
-       struct nfs_export_options *nxo;
+       struct nfs_export_options *nxo = NULL;
        u_quad_t tempsize;
        u_char cverf[NFSX_V3CREATEVERF];
        uid_t saved_uid;
@@ -2090,6 +2076,7 @@ nfsrv_create(
                                error = EEXIST;
                                break;
                        }
+                       OS_FALLTHROUGH;
                case NFS_CREATE_UNCHECKED:
                        error = nfsm_chain_get_sattr(nd, nmreq, vap);
                        break;
@@ -2212,7 +2199,7 @@ nfsrv_create(
                        }
                } else if (vap->va_type == VCHR || vap->va_type == VBLK ||
                    vap->va_type == VFIFO) {
-                       if (vap->va_type == VCHR && rdev == (int)0xffffffff) {
+                       if (vap->va_type == VCHR && rdev == 0xffffffff) {
                                VATTR_SET(vap, va_type, VFIFO);
                        }
                        if (vap->va_type != VFIFO) {
@@ -2388,7 +2375,7 @@ nfsrv_mknod(
        vnode_t vp, dvp, dirp;
        struct nfs_filehandle nfh;
        struct nfs_export *nx = NULL;
-       struct nfs_export_options *nxo;
+       struct nfs_export_options *nxo = NULL;
        uid_t saved_uid;
        kauth_acl_t xacl = NULL;
        struct nfsm_chain *nmreq, nmrep;
@@ -2640,7 +2627,7 @@ nfsrv_remove(
        struct vnode_attr dpreattr, dpostattr;
        struct nfs_filehandle nfh;
        struct nfs_export *nx = NULL;
-       struct nfs_export_options *nxo;
+       struct nfs_export_options *nxo = NULL;
        struct nfsm_chain *nmreq, nmrep;
 
        error = 0;
@@ -2707,7 +2694,7 @@ nfsrv_remove(
                if (!error) {
 #if CONFIG_FSE
                        char     *path = NULL;
-                       int       plen;
+                       int       plen = 0;
                        fse_info  finfo;
 
                        if (nfsrv_fsevents_enabled && need_fsevent(FSE_DELETE, dvp)) {
@@ -3142,10 +3129,8 @@ auth_exit:
                        mount_ref(locked_mp, 0);
 
                        /* make a copy of to path to pass to nfsrv_namei() again */
-                       MALLOC_ZONE(topath, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK);
-                       if (topath) {
-                               bcopy(toni.ni_cnd.cn_pnbuf, topath, tolen + 1);
-                       }
+                       topath = zalloc(ZV_NAMEI);
+                       bcopy(toni.ni_cnd.cn_pnbuf, topath, tolen + 1);
 
                        /*
                         * nameidone has to happen before we vnode_put(tdvp)
@@ -3159,10 +3144,8 @@ auth_exit:
                        vnode_put(tdvp);
 
                        /* make a copy of from path to pass to nfsrv_namei() again */
-                       MALLOC_ZONE(frompath, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK);
-                       if (frompath) {
-                               bcopy(fromni.ni_cnd.cn_pnbuf, frompath, fromlen + 1);
-                       }
+                       frompath = zalloc(ZV_NAMEI);
+                       bcopy(fromni.ni_cnd.cn_pnbuf, frompath, fromlen + 1);
 
                        /*
                         * nameidone has to happen before we vnode_put(fdvp)
@@ -3406,10 +3389,10 @@ nfsmout:
                vnode_put(tdirp);
        }
        if (frompath) {
-               FREE_ZONE(frompath, MAXPATHLEN, M_NAMEI);
+               NFS_ZFREE(ZV_NAMEI, frompath);
        }
        if (topath) {
-               FREE_ZONE(topath, MAXPATHLEN, M_NAMEI);
+               NFS_ZFREE(ZV_NAMEI, topath);
        }
        if (saved_cred) {
                kauth_cred_unref(&saved_cred);
@@ -3613,7 +3596,7 @@ nfsrv_symlink(
        vnode_t vp, dvp, dirp;
        struct nfs_filehandle nfh;
        struct nfs_export *nx = NULL;
-       struct nfs_export_options *nxo;
+       struct nfs_export_options *nxo = NULL;
        uio_t auio = NULL;
        char uio_buf[UIO_SIZEOF(1)];
        struct nfsm_chain *nmreq, nmrep;
@@ -3852,7 +3835,7 @@ nfsrv_mkdir(
        vnode_t vp, dvp, dirp;
        struct nfs_filehandle nfh;
        struct nfs_export *nx = NULL;
-       struct nfs_export_options *nxo;
+       struct nfs_export_options *nxo = NULL;
        uid_t saved_uid;
        kauth_acl_t xacl = NULL;
        struct nfsm_chain *nmreq, nmrep;
@@ -4085,7 +4068,7 @@ nfsrv_rmdir(
        struct vnode_attr dpreattr, dpostattr;
        struct nfs_filehandle nfh;
        struct nfs_export *nx = NULL;
-       struct nfs_export_options *nxo;
+       struct nfs_export_options *nxo = NULL;
        struct nameidata ni;
        struct nfsm_chain *nmreq, nmrep;
 
@@ -4163,7 +4146,7 @@ nfsrv_rmdir(
        if (!error) {
 #if CONFIG_FSE
                char     *path = NULL;
-               int       plen;
+               int       plen = 0;
                fse_info  finfo;
 
                if (nfsrv_fsevents_enabled && need_fsevent(FSE_DELETE, dvp)) {
@@ -4276,7 +4259,7 @@ nfsrv_readdir(
        char uio_buf[UIO_SIZEOF(1)];
        int len, nlen, rem, xfer, error, attrerr;
        int siz, count, fullsiz, eofflag, nentries;
-       u_quad_t off, toff, verf;
+       u_quad_t off, toff, verf = 0;
        int vnopflag;
        struct nfsm_chain *nmreq, nmrep;
 
@@ -4786,7 +4769,7 @@ nfsrv_commit(
 {
        vnode_t vp;
        struct nfs_filehandle nfh;
-       struct nfs_export *nx;
+       struct nfs_export *nx = NULL;
        struct nfs_export_options *nxo;
        int error, preattrerr, postattrerr, count;
        struct vnode_attr preattr, postattr;
@@ -4898,6 +4881,7 @@ nfsrv_statfs(
 
        VFSATTR_INIT(&va);
        VFSATTR_WANTED(&va, f_blocks);
+       VFSATTR_WANTED(&va, f_bfree);
        VFSATTR_WANTED(&va, f_bavail);
        VFSATTR_WANTED(&va, f_files);
        VFSATTR_WANTED(&va, f_ffree);
@@ -5012,7 +4996,7 @@ nfsmerr:
                maxsize = NFS_MAXDGRAMDATA;
                prefsize = NFS_PREFDGRAMDATA;
        } else {
-               maxsize = prefsize = NFSRV_MAXDATA;
+               maxsize = prefsize = slp->ns_sobufsize ? slp->ns_sobufsize / 2 : NFSRV_MAXDATA;
        }
 
        nfsm_chain_add_32(error, &nmrep, maxsize);
@@ -5049,8 +5033,8 @@ nfsrv_pathconf(
        vfs_context_t ctx,
        mbuf_t *mrepp)
 {
-       int error, attrerr, linkmax, namemax;
-       int chownres, notrunc, case_sensitive, case_preserving;
+       int error, attrerr, linkmax = 0, namemax = 0;
+       int chownres = 0, notrunc = 0, case_sensitive = 0, case_preserving = 0;
        vnode_t vp;
        struct vnode_attr attr;
        struct nfs_filehandle nfh;
@@ -5284,4 +5268,4 @@ nfsrv_authorize(
        return error;
 }
 
-#endif /* NFSSERVER */
+#endif /* CONFIG_NFS_SERVER */