/* * Returns non-zero (1) if the vnodeops matches that of the vnode. * Returns zero (0) if not. */ int vn_matchops(vnode_t * vp, vnodeops_t * vnodeops) { return (vn_getops(vp) == vnodeops); }
/* * Create a reference to the vnode representing the file descriptor. * Then, apply the VOP_OPEN operation to that vnode. * * The vnode for the file descriptor may be switched under you. * If it is, search the hash list for an nodep - nodep->nm_filevp * pair. If it exists, return that nodep to the user. * If it does not exist, create a new namenode to attach * to the nodep->nm_filevp then place the pair on the hash list. * * Newly created objects are like children/nodes in the mounted * file system, with the parent being the initial mount. */ int nm_open(vnode_t **vpp, int flag, cred_t *crp, caller_context_t *ct) { struct namenode *nodep = VTONM(*vpp); int error = 0; struct namenode *newnamep; struct vnode *newvp; struct vnode *infilevp; struct vnode *outfilevp; /* * If the vnode is switched under us, the corresponding * VN_RELE for this VN_HOLD will be done by the file system * performing the switch. Otherwise, the corresponding * VN_RELE will be done by nm_close(). */ infilevp = outfilevp = nodep->nm_filevp; VN_HOLD(outfilevp); if ((error = VOP_OPEN(&outfilevp, flag, crp, ct)) != 0) { VN_RELE(outfilevp); return (error); } if (infilevp != outfilevp) { /* * See if the new filevp (outfilevp) is already associated * with the mount point. If it is, then it already has a * namenode associated with it. */ mutex_enter(&ntable_lock); if ((newnamep = namefind(outfilevp, nodep->nm_mountpt)) != NULL) { struct vnode *vp = NMTOV(newnamep); VN_HOLD(vp); goto gotit; } newnamep = kmem_zalloc(sizeof (struct namenode), KM_SLEEP); newvp = vn_alloc(KM_SLEEP); newnamep->nm_vnode = newvp; mutex_init(&newnamep->nm_lock, NULL, MUTEX_DEFAULT, NULL); mutex_enter(&nodep->nm_lock); newvp->v_flag = ((*vpp)->v_flag | VNOMAP | VNOSWAP) & ~VROOT; vn_setops(newvp, vn_getops(*vpp)); newvp->v_vfsp = &namevfs; newvp->v_stream = outfilevp->v_stream; newvp->v_type = outfilevp->v_type; newvp->v_rdev = outfilevp->v_rdev; newvp->v_data = (caddr_t)newnamep; vn_exists(newvp); bcopy(&nodep->nm_vattr, &newnamep->nm_vattr, sizeof (vattr_t)); newnamep->nm_vattr.va_type = outfilevp->v_type; newnamep->nm_vattr.va_nodeid = namenodeno_alloc(); newnamep->nm_vattr.va_size = (u_offset_t)0; newnamep->nm_vattr.va_rdev = outfilevp->v_rdev; newnamep->nm_flag = NMNMNT; newnamep->nm_filevp = outfilevp; newnamep->nm_filep = nodep->nm_filep; newnamep->nm_mountpt = nodep->nm_mountpt; mutex_exit(&nodep->nm_lock); /* * Insert the new namenode into the hash list. */ nameinsert(newnamep); gotit: mutex_exit(&ntable_lock); /* * Release the above reference to the infilevp, the reference * to the NAMEFS vnode, create a reference to the new vnode * and return the new vnode to the user. */ VN_RELE(*vpp); *vpp = NMTOV(newnamep); } return (0); }