コード例 #1
0
ファイル: smb_pathname.c プロジェクト: apprisi/illumos-gate
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);
}
コード例 #2
0
/*
 * 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);
}
コード例 #3
0
/*
 * 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);
}
コード例 #4
0
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;
}
コード例 #5
0
/*
 * 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);
}
コード例 #6
0
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;
}
コード例 #7
0
ファイル: zfs_ctldir.c プロジェクト: coyizumi/cs111
/*
 * 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);
}
コード例 #8
0
/*
 * 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);
}
コード例 #9
0
ファイル: xfs_iops.c プロジェクト: JBTech/ralink_rt5350
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;
}
コード例 #10
0
ファイル: gfs.c プロジェクト: pcd1193182/openzfs
/*
 * 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);
}
コード例 #11
0
/*
 * 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);
}
コード例 #12
0
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);
}
コード例 #13
0
ファイル: smbfs_vfsops.c プロジェクト: apprisi/illumos-gate
/*
 * 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);
}
コード例 #14
0
ファイル: smb_pathname.c プロジェクト: apprisi/illumos-gate
/*
 * 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);
}
コード例 #15
0
ファイル: zfs_ctldir.c プロジェクト: glycerine/zfs
/*
 * 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;
}
コード例 #16
0
/* 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);
}
コード例 #17
0
ファイル: lookup.c プロジェクト: bahamas10/openzfs
/*
 * 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));
}
コード例 #18
0
ファイル: specvfsops.c プロジェクト: andreiw/polaris
/*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);
}
コード例 #19
0
ファイル: zfs_dir.c プロジェクト: darthur/zfs
/*
 * 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);
}
コード例 #20
0
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);
}
コード例 #21
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);
}
コード例 #22
0
ファイル: lookup.c プロジェクト: bahamas10/openzfs
/*
 * 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);
}
コード例 #23
0
ファイル: ctfs_root.c プロジェクト: andreiw/polaris
/*
 * 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);
}
コード例 #24
0
ファイル: xfs_acl.c プロジェクト: AhmadTux/freebsd
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;
}
コード例 #25
0
ファイル: vnops.c プロジェクト: AlissonGiron/open-vm-tools
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;
}
コード例 #26
0
ファイル: gfs.c プロジェクト: pcd1193182/openzfs
/*
 * 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);
}
コード例 #27
0
ファイル: sdev_profile.c プロジェクト: bahamas10/openzfs
/*
 * 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);
	}
}
コード例 #28
0
/*
 * 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;
}
コード例 #29
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));
}
コード例 #30
0
ファイル: sdev_profile.c プロジェクト: bahamas10/openzfs
/*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));
}