+ /* do initial loading of attributes */
+ error = nfs_loadattrcache(np, nvap, xidp, 1);
+ if (error) {
+ lck_mtx_lock(nfs_node_hash_mutex);
+ LIST_REMOVE(np, n_hash);
+ np->n_flag &= ~(NHASHED|NINIT);
+ if (np->n_flag & NWINIT) {
+ np->n_flag &= ~NWINIT;
+ wakeup((caddr_t)np);
+ }
+ lck_mtx_unlock(nfs_node_hash_mutex);
+ if (np->n_fhsize > NFS_SMALLFH)
+ FREE_ZONE(np->n_fhp, np->n_fhsize, M_NFSBIGFH);
+ FREE_ZONE(np, sizeof *np, M_NFSNODE);
+ *npp = 0;
+ return (error);
+ }
+ np->n_mtime = nvap->nva_mtime;
+ if (nvap->nva_type == VDIR)
+ np->n_ncmtime = nvap->nva_mtime;
+ NMODEINVALIDATE(np);
+
+ /* now, attempt to get a new vnode */
+ vfsp.vnfs_mp = mntp;
+ vfsp.vnfs_vtype = nvap->nva_type;
+ vfsp.vnfs_str = "nfs";
+ vfsp.vnfs_dvp = dvp;
+ vfsp.vnfs_fsnode = np;
+ if (nvap->nva_type == VFIFO)
+ vfsp.vnfs_vops = fifo_nfsv2nodeop_p;
+ else if (nvap->nva_type == VBLK || nvap->nva_type == VCHR)
+ vfsp.vnfs_vops = spec_nfsv2nodeop_p;
+ else
+ vfsp.vnfs_vops = nfsv2_vnodeop_p;
+ vfsp.vnfs_markroot = (flags & NG_MARKROOT) ? 1 : 0;
+ vfsp.vnfs_marksystem = 0;
+ vfsp.vnfs_rdev = 0;
+ vfsp.vnfs_filesize = nvap->nva_size;
+ vfsp.vnfs_cnp = cnp;
+ if (dvp && cnp && (flags & NG_MAKEENTRY))
+ vfsp.vnfs_flags = 0;
+ else
+ vfsp.vnfs_flags = VNFS_NOCACHE;
+ error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &vfsp, &nvp);
+ if (error) {
+ lck_mtx_lock(nfs_node_hash_mutex);
+ LIST_REMOVE(np, n_hash);
+ np->n_flag &= ~(NHASHED|NINIT);
+ if (np->n_flag & NWINIT) {
+ np->n_flag &= ~NWINIT;
+ wakeup((caddr_t)np);
+ }
+ lck_mtx_unlock(nfs_node_hash_mutex);
+ if (np->n_fhsize > NFS_SMALLFH)
+ FREE_ZONE(np->n_fhp, np->n_fhsize, M_NFSBIGFH);
+ FREE_ZONE(np, sizeof *np, M_NFSNODE);
+ *npp = 0;
+ return (error);
+ }
+ vp = nvp;
+ np->n_vnode = vp;
+ vnode_addfsref(vp);
+ vnode_settag(vp, VT_NFS); // XXX shouldn't this be a vnode_create() parameter?
+ *npp = np;
+ /* node is now initialized */
+
+ /* check if anyone's waiting on this node */
+ lck_mtx_lock(nfs_node_hash_mutex);
+ np->n_flag &= ~NINIT;
+ if (np->n_flag & NWINIT) {
+ np->n_flag &= ~NWINIT;
+ wakeup((caddr_t)np);
+ }
+ lck_mtx_unlock(nfs_node_hash_mutex);