Example #1
0
static int
null_vptocnp(struct vop_vptocnp_args *ap)
{
	struct vnode *vp = ap->a_vp;
	struct vnode **dvp = ap->a_vpp;
	struct vnode *lvp, *ldvp;
	struct ucred *cred = ap->a_cred;
	int error, locked;

	if (vp->v_type == VDIR)
		return (vop_stdvptocnp(ap));

	locked = VOP_ISLOCKED(vp);
	lvp = NULLVPTOLOWERVP(vp);
	vhold(lvp);
	VOP_UNLOCK(vp, 0); /* vp is held by vn_vptocnp_locked that called us */
	ldvp = lvp;
	error = vn_vptocnp(&ldvp, cred, ap->a_buf, ap->a_buflen);
	vdrop(lvp);
	if (error != 0) {
		vn_lock(vp, locked | LK_RETRY);
		return (ENOENT);
	}

	/*
	 * Exclusive lock is required by insmntque1 call in
	 * null_nodeget()
	 */
	error = vn_lock(ldvp, LK_EXCLUSIVE);
	if (error != 0) {
		vn_lock(vp, locked | LK_RETRY);
		vdrop(ldvp);
		return (ENOENT);
	}
	vref(ldvp);
	vdrop(ldvp);
	error = null_nodeget(vp->v_mount, ldvp, dvp);
	if (error == 0) {
#ifdef DIAGNOSTIC
		NULLVPTOLOWERVP(*dvp);
#endif
		vhold(*dvp);
		vput(*dvp);
	} else
		vput(ldvp);

	vn_lock(vp, locked | LK_RETRY);
	return (error);
}
Example #2
0
static int
pefs_node_lookup_name(struct vnode *lvp, struct vnode *ldvp, struct ucred *cred,
    char *encname, int *encname_len)
{
	struct vnode *nldvp;
	int error, locked, dlocked;
	int buflen = *encname_len;

	ASSERT_VOP_LOCKED(lvp, "pefs_node_lookup_name");
	locked = VOP_ISLOCKED(lvp);
	if (ldvp) {
		dlocked = VOP_ISLOCKED(ldvp);
		if (dlocked)
			VOP_UNLOCK(ldvp, 0);
	} else
		dlocked = 0;

	vref(lvp);
	VOP_UNLOCK(lvp, 0);
	nldvp = lvp;
	error = vn_vptocnp(&nldvp, cred, encname, encname_len);
	if (error == 0)
		vrele(nldvp);
	vrele(lvp);
	if (ldvp && dlocked)
		vn_lock(ldvp, dlocked | LK_RETRY);
	vn_lock(lvp, locked | LK_RETRY);
	if (error != 0)
		return (ENOENT);

	memcpy(encname, encname + *encname_len, buflen - *encname_len);
	*encname_len = buflen - *encname_len;
	if (*encname_len < buflen)
		encname[*encname_len] = '\0';

	return (0);
}