vnode_t * smb_lookuppathvptovp(smb_request_t *sr, char *path, vnode_t *startvp, vnode_t *rootvp) { pathname_t pn; vnode_t *vp = NULL; int lookup_flags = FOLLOW; if (SMB_TREE_IS_CASEINSENSITIVE(sr)) lookup_flags |= FIGNORECASE; (void) pn_alloc(&pn); if (pn_set(&pn, path) == 0) { VN_HOLD(startvp); if (rootvp != rootdir) VN_HOLD(rootvp); /* lookuppnvp should release the holds */ if (lookuppnvp(&pn, NULL, lookup_flags, NULL, &vp, rootvp, startvp, kcred) != 0) { pn_free(&pn); return (NULL); } } pn_free(&pn); return (vp); }
/* * Get an nfsv4 vnode of the given fid from the visible list of an * nfs filesystem or get the exi_vp if it is the root node. */ int nfs4_vget_pseudo(struct exportinfo *exi, vnode_t **vpp, fid_t *fidp) { fid_t exp_fid; struct exp_visible *visp; int error; /* check if the given fid is in the visible list */ for (visp = exi->exi_visible; visp; visp = visp->vis_next) { if (EQFID(fidp, &visp->vis_fid)) { VN_HOLD(visp->vis_vp); *vpp = visp->vis_vp; return (0); } } /* check if the given fid is the same as the exported node */ bzero(&exp_fid, sizeof (exp_fid)); exp_fid.fid_len = MAXFIDSZ; error = vop_fid_pseudo(exi->exi_vp, &exp_fid); if (error) return (error); if (EQFID(fidp, &exp_fid)) { VN_HOLD(exi->exi_vp); *vpp = exi->exi_vp; return (0); } return (ENOENT); }
/* * Lookup a rnode by fhandle. Ignores rnodes that had failed recovery. * Returns NULL if no match. If an rnode is returned, the reference count * on the master vnode is incremented. * * The caller must be holding the hash queue lock, either shared or exclusive. */ rnode4_t * r4find(r4hashq_t *rhtp, nfs4_sharedfh_t *fh, struct vfs *vfsp) { rnode4_t *rp; vnode_t *vp; ASSERT(RW_LOCK_HELD(&rhtp->r_lock)); for (rp = rhtp->r_hashf; rp != (rnode4_t *)rhtp; rp = rp->r_hashf) { vp = RTOV4(rp); if (vp->v_vfsp == vfsp && SFH4_SAME(rp->r_fh, fh)) { mutex_enter(&rp->r_statelock); if (rp->r_flags & R4RECOVERR) { mutex_exit(&rp->r_statelock); continue; } mutex_exit(&rp->r_statelock); #ifdef DEBUG r4_dup_check(rp, vfsp); #endif if (rp->r_freef != NULL) { mutex_enter(&rp4freelist_lock); /* * If the rnode is on the freelist, * then remove it and use that reference * as the new reference. Otherwise, * need to increment the reference count. */ if (rp->r_freef != NULL) { rp4_rmfree(rp); mutex_exit(&rp4freelist_lock); } else { mutex_exit(&rp4freelist_lock); VN_HOLD(vp); } } else VN_HOLD(vp); /* * if root vnode, set v_flag to indicate that */ if (isrootfh(fh, rp)) { if (!(vp->v_flag & VROOT)) { mutex_enter(&vp->v_lock); vp->v_flag |= VROOT; mutex_exit(&vp->v_lock); } } return (rp); } } return (NULL); }
int xfs_cap_vset( vnode_t *vp, void *cap, size_t size) { posix_cap_xattr *xattr_cap = cap; xfs_cap_set_t xfs_cap; int error; if (!cap) return -EINVAL; error = posix_cap_xattr_to_xfs(xattr_cap, size, &xfs_cap); if (error) return -error; VN_HOLD(vp); error = xfs_cap_allow_set(vp); if (error) goto out; VOP_ATTR_SET(vp, SGI_CAP_LINUX, (char *)&xfs_cap, sizeof(xfs_cap_set_t), ATTR_ROOT, sys_cred, error); out: VN_RELE(vp); return -error; }
/* * New Leaf driver open entry point. We make a vnode and go through specfs * in order to obtain open close exclusions guarantees. Note that we drop * OTYP_LYR if it was specified - we are going through specfs and it provides * last close semantics (FKLYR is provided to open(9E)). Also, since * spec_open will drive attach via e_ddi_hold_devi_by_dev for a makespecvp * vnode with no SDIP_SET on the common snode, the dev_lopen caller no longer * needs to call ddi_hold_installed_driver. */ int dev_lopen(dev_t *devp, int flag, int otype, struct cred *cred) { struct vnode *vp; int error; struct vnode *cvp; vp = makespecvp(*devp, (otype == OTYP_BLK) ? VBLK : VCHR); error = VOP_OPEN(&vp, flag | FKLYR, cred, NULL); if (error == 0) { /* Pick up the (possibly) new dev_t value. */ *devp = vp->v_rdev; /* * Place extra hold on the common vnode, which contains the * open count, so that it is not destroyed by the VN_RELE of * the shadow makespecvp vnode below. */ cvp = STOV(VTOCS(vp)); VN_HOLD(cvp); } /* release the shadow makespecvp vnode. */ VN_RELE(vp); return (error); }
int xfs_cap_vget( vnode_t *vp, void *cap, size_t size) { int error; int len = sizeof(xfs_cap_set_t); int flags = ATTR_ROOT; xfs_cap_set_t xfs_cap = { 0 }; posix_cap_xattr *xattr_cap = cap; char *data = (char *)&xfs_cap; VN_HOLD(vp); if ((error = _MAC_VACCESS(vp, NULL, VREAD))) goto out; if (!size) { flags |= ATTR_KERNOVAL; data = NULL; } VOP_ATTR_GET(vp, SGI_CAP_LINUX, data, &len, flags, sys_cred, error); if (error) goto out; ASSERT(len == sizeof(xfs_cap_set_t)); error = (size)? -posix_cap_xattr_size() : -posix_cap_xfs_to_xattr(&xfs_cap, xattr_cap, size); out: VN_RELE(vp); return -error; }
/* * Given a root znode, retrieve the associated .zfs directory. * Add a hold to the vnode and return it. */ vnode_t * zfsctl_root(znode_t *zp) { ASSERT(zfs_has_ctldir(zp)); VN_HOLD(zp->z_zfsvfs->z_ctldir); return (zp->z_zfsvfs->z_ctldir); }
/* * Find root of lofs mount. */ static int lo_root(struct vfs *vfsp, struct vnode **vpp) { *vpp = vtoli(vfsp)->li_rootvp; #ifdef LODEBUG lo_dprint(4, "lo_root(0x%p) = %p\n", vfsp, *vpp); #endif /* * If the root of the filesystem is a special file, return the specvp * version of the vnode. We don't save the specvp vnode in our * hashtable since that's exclusively for lnodes. */ if (IS_DEVVP(*vpp)) { struct vnode *svp; svp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, kcred); if (svp == NULL) return (ENOSYS); *vpp = svp; } else { VN_HOLD(*vpp); } return (0); }
STATIC int linvfs_link( struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { struct inode *ip; /* inode of guy being linked to */ vnode_t *tdvp; /* target directory for new name/link */ vnode_t *vp; /* vp of name being linked */ int error; ip = old_dentry->d_inode; /* inode being linked to */ if (S_ISDIR(ip->i_mode)) return -EPERM; tdvp = LINVFS_GET_VP(dir); vp = LINVFS_GET_VP(ip); VOP_LINK(tdvp, vp, dentry, NULL, error); if (!error) { VMODIFY(tdvp); VN_HOLD(vp); validate_fields(ip); d_instantiate(dentry, ip); } return -error; }
/* * gfs_file_create(): create a new GFS file * * size - size of private data structure (v_data) * pvp - parent vnode (GFS directory) * ops - vnode operations vector * * In order to use this interface, the parent vnode must have been created by * gfs_dir_create(), and the private data stored in v_data must have a * 'gfs_file_t' as its first field. * * Given these constraints, this routine will automatically: * * - Allocate v_data for the vnode * - Initialize necessary fields in the vnode * - Hold the parent */ vnode_t * gfs_file_create(size_t size, vnode_t *pvp, vnodeops_t *ops) { gfs_file_t *fp; vnode_t *vp; /* * Allocate vnode and internal data structure */ fp = kmem_zalloc(size, KM_SLEEP); vp = vn_alloc(KM_SLEEP); /* * Set up various pointers */ fp->gfs_vnode = vp; fp->gfs_parent = pvp; vp->v_data = fp; fp->gfs_size = size; fp->gfs_type = GFS_FILE; /* * Initialize vnode and hold parent. */ vn_setops(vp, ops); if (pvp) { VN_SET_VFS_TYPE_DEV(vp, pvp->v_vfsp, VREG, 0); VN_HOLD(pvp); } return (vp); }
/* * Traverse backward across mountpoint from the * root vnode of a filesystem to its mounted-on * vnode. */ vnode_t * untraverse(vnode_t *vp) { vnode_t *tvp, *nextvp; tvp = vp; for (;;) { if (! (tvp->v_flag & VROOT)) break; /* lock vfs to prevent unmount of this vfs */ vfs_lock_wait(tvp->v_vfsp); if ((nextvp = tvp->v_vfsp->vfs_vnodecovered) == NULL) { vfs_unlock(tvp->v_vfsp); break; } /* * Hold nextvp to prevent unmount. After unlock vfs and * rele tvp, any number of overlays could be unmounted. * Putting a hold on vfs_vnodecovered will only allow * tvp's vfs to be unmounted. Of course if caller placed * extra hold on vp before calling untraverse, the following * hold would not be needed. Since prev actions of caller * are unknown, we need to hold here just to be safe. */ VN_HOLD(nextvp); vfs_unlock(tvp->v_vfsp); VN_RELE(tvp); tvp = nextvp; } return (tvp); }
static int zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr) { vnode_t *svp = sep->se_root; int error; ASSERT(vn_ismntpt(svp)); /* this will be dropped by dounmount() */ if ((error = vn_vfswlock(svp)) != 0) return (error); VN_HOLD(svp); error = dounmount(vn_mountedvfs(svp), fflags, cr); if (error) { VN_RELE(svp); return (error); } /* * We can't use VN_RELE(), as that will try to invoke * zfsctl_snapdir_inactive(), which would cause us to destroy * the sd_lock mutex held by our caller. */ ASSERT(svp->v_count == 1); gfs_vop_inactive(svp, cr, NULL); kmem_free(sep->se_name, strlen(sep->se_name) + 1); kmem_free(sep, sizeof (zfs_snapentry_t)); return (0); }
/* * find root of smbfs */ static int smbfs_root(vfs_t *vfsp, vnode_t **vpp) { smbmntinfo_t *smi; vnode_t *vp; smi = VFTOSMI(vfsp); if (curproc->p_zone != smi->smi_zone_ref.zref_zone) return (EPERM); if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED) return (EIO); /* * The root vp is created in mount and held * until unmount, so this is paranoia. */ if (smi->smi_root == NULL) return (EIO); /* Just take a reference and return it. */ vp = SMBTOV(smi->smi_root); VN_HOLD(vp); *vpp = vp; return (0); }
/* * Holds on dvp and rootvp (if not rootdir) are required by lookuppnvp() * and will be released within lookuppnvp(). */ static int smb_pathname_lookup(pathname_t *pn, pathname_t *rpn, int flags, vnode_t **vp, vnode_t *rootvp, vnode_t *dvp, smb_attr_t *attr, cred_t *cred) { int err; *vp = NULL; VN_HOLD(dvp); if (rootvp != rootdir) VN_HOLD(rootvp); err = lookuppnvp(pn, rpn, flags, NULL, vp, rootvp, dvp, cred); if ((err == 0) && (attr != NULL)) (void) smb_vop_getattr(*vp, NULL, attr, 0, kcred); return (err); }
/* * Given a root znode, retrieve the associated .zfs directory. * Add a hold to the vnode and return it. */ vnode_t * zfsctl_root(znode_t *zp) { ASSERT(zfs_has_ctldir(zp)); if (VN_HOLD(zp->z_zfsvfs->z_ctldir) != NULL) return (zp->z_zfsvfs->z_ctldir); else return NULL; }
/* ARGSUSED */ static int fdroot(vfs_t *vfsp, vnode_t **vpp) { vnode_t *vp = (vnode_t *)vfsp->vfs_data; VN_HOLD(vp); *vpp = vp; return (0); }
/* * Lookup the user file name from a given vp, using a specific credential. */ int lookuppnatcred( struct pathname *pnp, /* pathname to lookup */ struct pathname *rpnp, /* if non-NULL, return resolved path */ int followlink, /* (don't) follow sym links */ vnode_t **dirvpp, /* ptr for parent vnode */ vnode_t **compvpp, /* ptr for entry vnode */ vnode_t *startvp, /* start search from this vp */ cred_t *cr) /* user credential */ { vnode_t *vp; /* current directory vp */ vnode_t *rootvp; proc_t *p = curproc; if (pnp->pn_pathlen == 0) return (ENOENT); mutex_enter(&p->p_lock); /* for u_rdir and u_cdir */ if ((rootvp = PTOU(p)->u_rdir) == NULL) rootvp = rootdir; else if (rootvp != rootdir) /* no need to VN_HOLD rootdir */ VN_HOLD(rootvp); if (pnp->pn_path[0] == '/') { vp = rootvp; } else { vp = (startvp == NULL) ? PTOU(p)->u_cdir : startvp; } VN_HOLD(vp); mutex_exit(&p->p_lock); /* * Skip over leading slashes */ if (pnp->pn_path[0] == '/') { do { pnp->pn_path++; pnp->pn_pathlen--; } while (pnp->pn_path[0] == '/'); } return (lookuppnvp(pnp, rpnp, followlink, dirvpp, compvpp, rootvp, vp, cr)); }
/*ARGSUSED*/ int spec_sync(struct vfs *vfsp, short flag, struct cred *cr) { struct snode *sync_list; register struct snode **spp, *sp, *spnext; register struct vnode *vp; if (mutex_tryenter(&spec_syncbusy) == 0) return (0); if (flag & SYNC_ATTR) { mutex_exit(&spec_syncbusy); return (0); } mutex_enter(&stable_lock); sync_list = NULL; /* * Find all the snodes that are dirty and add them to the sync_list */ for (spp = stable; spp < &stable[STABLESIZE]; spp++) { for (sp = *spp; sp != NULL; sp = sp->s_next) { vp = STOV(sp); /* * Don't bother sync'ing a vp if it's * part of a virtual swap device. */ if (IS_SWAPVP(vp)) continue; if (vp->v_type == VBLK && vn_has_cached_data(vp)) { /* * Prevent vp from going away before we * we get a chance to do a VOP_PUTPAGE * via sync_list processing */ VN_HOLD(vp); sp->s_list = sync_list; sync_list = sp; } } } mutex_exit(&stable_lock); /* * Now write out all the snodes we marked asynchronously. */ for (sp = sync_list; sp != NULL; sp = spnext) { spnext = sp->s_list; vp = STOV(sp); (void) VOP_PUTPAGE(vp, (offset_t)0, (uint_t)0, B_ASYNC, cr); VN_RELE(vp); /* Release our hold on vnode */ } mutex_exit(&spec_syncbusy); return (0); }
/* * Look up an entry in a directory. * * NOTE: '.' and '..' are handled as special cases because * no directory entries are actually stored for them. If this is * the root of a filesystem, then '.zfs' is also treated as a * special pseudo-directory. */ int zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, int *deflg, pathname_t *rpnp) { zfs_dirlock_t *dl; znode_t *zp; int error = 0; uint64_t parent; if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) { *vpp = ZTOV(dzp); VN_HOLD(*vpp); } else if (name[0] == '.' && name[1] == '.' && name[2] == 0) { zfsvfs_t *zfsvfs = dzp->z_zfsvfs; /* * If we are a snapshot mounted under .zfs, return * the vp for the snapshot directory. */ if ((error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), &parent, sizeof (parent))) != 0) return (error); if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) { error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir, "snapshot", vpp, NULL, 0, NULL, kcred, NULL, NULL, NULL); return (error); } rw_enter(&dzp->z_parent_lock, RW_READER); error = zfs_zget(zfsvfs, parent, &zp); if (error == 0) *vpp = ZTOV(zp); rw_exit(&dzp->z_parent_lock); } else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) { *vpp = zfsctl_root(dzp); } else { int zf; zf = ZEXISTS | ZSHARED; if (flags & FIGNORECASE) zf |= ZCILOOK; error = zfs_dirent_lock(&dl, dzp, name, &zp, zf, deflg, rpnp); if (error == 0) { *vpp = ZTOV(zp); zfs_dirent_unlock(dl); dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */ } rpnp = NULL; } if ((flags & FIGNORECASE) && rpnp && !error) (void) strlcpy(rpnp->pn_buf, name, rpnp->pn_bufsize); return (error); }
static int objfs_root(vfs_t *vfsp, vnode_t **vpp) { objfs_vfs_t *data = vfsp->vfs_data; *vpp = data->objfs_vfs_root; VN_HOLD(*vpp); return (0); }
/* * Create a reference to the root of a mounted file descriptor. * This routine is called from lookupname() in the event a path * is being searched that has a mounted file descriptor in it. */ static int nm_root(vfs_t *vfsp, vnode_t **vpp) { struct namenode *nodep = (struct namenode *)vfsp->vfs_data; struct vnode *vp = NMTOV(nodep); VN_HOLD(vp); *vpp = vp; return (0); }
/* * Given a global path (from rootdir), and a vnode that is the current root, * return the portion of the path that is beneath the current root or NULL on * failure. The path MUST be a resolved path (no '..' entries or symlinks), * otherwise this function will fail. */ static char * localpath(char *path, struct vnode *vrootp, cred_t *cr) { vnode_t *vp; vnode_t *cvp; char component[MAXNAMELEN]; char *ret = NULL; pathname_t pn; /* * We use vn_compare() instead of VN_CMP() in order to detect lofs * mounts and stacked vnodes. */ if (vn_compare(vrootp, rootdir)) return (path); if (pn_get(path, UIO_SYSSPACE, &pn) != 0) return (NULL); vp = rootdir; VN_HOLD(vp); if (vn_ismntpt(vp) && traverse(&vp) != 0) { VN_RELE(vp); pn_free(&pn); return (NULL); } while (pn_pathleft(&pn)) { pn_skipslash(&pn); if (pn_getcomponent(&pn, component) != 0) break; if (VOP_LOOKUP(vp, component, &cvp, &pn, 0, rootdir, cr, NULL, NULL, NULL) != 0) break; VN_RELE(vp); vp = cvp; if (vn_ismntpt(vp) && traverse(&vp) != 0) break; if (vn_compare(vp, vrootp)) { ret = path + (pn.pn_path - pn.pn_buf); break; } } VN_RELE(vp); pn_free(&pn); return (ret); }
/* * ctfs_root - the VFS_ROOT entry point */ static int ctfs_root(vfs_t *vfsp, vnode_t **vpp) { vnode_t *vp; vp = ((ctfs_vfs_t *)vfsp->vfs_data)->ctvfs_root; VN_HOLD(vp); *vpp = vp; return (0); }
int xfs_acl_vset( xfs_vnode_t *vp, void *acl, size_t size, int kind) { posix_acl_xattr_header *ext_acl = acl; xfs_acl_t *xfs_acl; int error; int basicperms = 0; /* more than std unix perms? */ if (!acl) return -EINVAL; if (!(_ACL_ALLOC(xfs_acl))) return -ENOMEM; error = posix_acl_xattr_to_xfs(ext_acl, size, xfs_acl); if (error) { _ACL_FREE(xfs_acl); return -error; } if (!xfs_acl->acl_cnt) { _ACL_FREE(xfs_acl); return 0; } VN_HOLD(vp); error = xfs_acl_allow_set(vp, kind); if (error) goto out; /* Incoming ACL exists, set file mode based on its value */ if (kind == _ACL_TYPE_ACCESS) xfs_acl_setmode(vp, xfs_acl, &basicperms); /* * If we have more than std unix permissions, set up the actual attr. * Otherwise, delete any existing attr. This prevents us from * having actual attrs for permissions that can be stored in the * standard permission bits. */ if (!basicperms) { xfs_acl_set_attr(vp, xfs_acl, kind, &error); } else { xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); } out: VN_RELE(vp); _ACL_FREE(xfs_acl); return -error; }
static int VMBlockLookup(struct vnode *dvp, // IN: Directory to look in char *nm, // IN: Name of component to lookup in directory struct vnode **vpp, // OUT: Pointer to vnode representing found file struct pathname *pnp,// IN: Full pathname being looked up int flags, // IN: Lookup flags (see vnode.h) struct vnode *rdir, // IN: Vnode of root device struct cred *cr // IN: Credentials of caller #if OS_VFS_VERSION >= 5 , caller_context_t *ctx // IN: Caller's context , int *direntflags // IN: , struct pathname *rpnp // IN: #endif ) { struct vnode *realVp; VMBlockMountInfo *mip; int ret; Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMblockLookup: entry\n"); /* First ensure that we are looking in a directory. */ if (dvp->v_type != VDIR) { return ENOTDIR; } /* Don't invoke lookup for ourself. */ if (nm[0] == '\0' || (nm[0] == '.' && nm[1] == '\0')) { VN_HOLD(dvp); *vpp = dvp; return 0; } *vpp = NULL; /* Make sure nm exists before creating our link to it. */ mip = VPTOMIP(dvp); ret = VOP_LOOKUP(mip->redirectVnode, nm, &realVp, pnp, flags, rdir, cr #if OS_VFS_VERSION >= 5 , ctx, direntflags, rpnp #endif ); if (ret) { return ret; } ret = VMBlockVnodeGet(vpp, realVp, nm, strlen(nm), dvp, dvp->v_vfsp, FALSE); if (ret) { VN_RELE(realVp); return ret; } return 0; }
/* * gfs_lookup_dot * * Performs a basic check for "." and ".." directory entries. */ int gfs_lookup_dot(vnode_t **vpp, vnode_t *dvp, vnode_t *pvp, const char *nm) { if (*nm == '\0' || strcmp(nm, ".") == 0) { VN_HOLD(dvp); *vpp = dvp; return (0); } else if (strcmp(nm, "..") == 0) { if (pvp == NULL) { ASSERT(dvp->v_flag & VROOT); VN_HOLD(dvp); *vpp = dvp; } else { VN_HOLD(pvp); *vpp = pvp; } return (0); } return (-1); }
/* * Look up a logical name in the global zone. * Provides the ability to map the global zone's device name * to an alternate name within a zone. The primary example * is the virtual console device /dev/zcons/[zonename]/zconsole * mapped to /[zonename]/root/dev/zconsole. */ static void prof_lookup_globaldev(struct sdev_node *dir, struct sdev_node *gdir, char *name, char *rename) { int error; struct vnode *avp, *gdv, *gddv; struct sdev_node *newdv; struct vattr vattr = {0}; struct pathname pn; /* check if node already exists */ newdv = sdev_cache_lookup(dir, rename); if (newdv) { ASSERT(newdv->sdev_state != SDEV_ZOMBIE); SDEV_SIMPLE_RELE(newdv); return; } /* sanity check arguments */ if (!gdir || pn_get(name, UIO_SYSSPACE, &pn)) return; /* perform a relative lookup of the global /dev instance */ gddv = SDEVTOV(gdir); VN_HOLD(gddv); error = lookuppnvp(&pn, NULL, FOLLOW, NULLVPP, &gdv, rootdir, gddv, kcred); pn_free(&pn); if (error) { sdcmn_err10(("prof_lookup_globaldev: %s not found\n", name)); return; } ASSERT(gdv && gdv->v_type != VLNK); /* * Found the entry in global /dev, figure out attributes * by looking at backing store. Call into devfs for default. * Note, mapped device is persisted under the new name */ prof_getattr(dir, rename, gdv, &vattr, &avp, NULL); if (gdv->v_type != VDIR) { VN_RELE(gdv); gdir = NULL; } else gdir = VTOSDEV(gdv); if (prof_mknode(dir, rename, &newdv, &vattr, avp, (void *)gdir, kcred) == 0) { ASSERT(newdv->sdev_state != SDEV_ZOMBIE); SDEV_SIMPLE_RELE(newdv); } }
/* * xfs_root extracts the root vnode from a vfs. * * vfsp -- the vfs struct for the desired file system * vpp -- address of the caller's vnode pointer which should be * set to the desired fs root vnode */ STATIC int xfs_root( bhv_desc_t *bdp, vnode_t **vpp) { vnode_t *vp; vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); VN_HOLD(vp); *vpp = vp; return 0; }
/* ARGSUSED */ static int fdlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pnp, int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, int *direntflags, pathname_t *realpnp) { if (comp[0] == 0 || strcmp(comp, ".") == 0 || strcmp(comp, "..") == 0) { VN_HOLD(dp); *vpp = dp; return (0); } return (fdget(dp, comp, vpp)); }
/*ARGSUSED*/ int prof_lookup(vnode_t *dvp, char *nm, struct vnode **vpp, struct cred *cred) { struct sdev_node *ddv = VTOSDEV(dvp); struct sdev_node *dv; int nmlen; /* * Empty name or ., return node itself. */ nmlen = strlen(nm); if ((nmlen == 0) || ((nmlen == 1) && (nm[0] == '.'))) { *vpp = SDEVTOV(ddv); VN_HOLD(*vpp); return (0); } /* * .., return the parent directory */ if ((nmlen == 2) && (strcmp(nm, "..") == 0)) { *vpp = SDEVTOV(ddv->sdev_dotdot); VN_HOLD(*vpp); return (0); } rw_enter(&ddv->sdev_contents, RW_READER); dv = sdev_cache_lookup(ddv, nm); if (dv == NULL) { prof_filldir(ddv); dv = sdev_cache_lookup(ddv, nm); } rw_exit(&ddv->sdev_contents); if (dv == NULL) { sdcmn_err10(("prof_lookup: %s not found\n", nm)); return (ENOENT); } return (sdev_to_vp(dv, vpp)); }