FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
/*
 * Note that we must use VRELE_ASYNC in this function as it walks
 * up the directory tree and vrele may need to acquire an exclusive
 * lock if a last reference to a vnode is dropped.
 */
Note that we must use VRELE_ASYNC in this function as it walks
up the directory tree and vrele may need to acquire an exclusive
lock if a last reference to a vnode is dropped.
Note that we must use VRELE_ASYNC in this function as it walks up the directory tree and vrele may need to acquire an exclusive lock if a last reference to a vnode is dropped .
static int
zfs_rename_check(znode_t *szp, znode_t *sdzp, znode_t *tdzp)
{
	zfsvfs_t	*zfsvfs;
	znode_t		*zp, *zp1;
	uint64_t	parent;
	int		error;
	zfsvfs = tdzp->z_zfsvfs;
	if (tdzp == szp)
		return (SET_ERROR(EINVAL));
	if (tdzp == sdzp)
		return (0);
	if (tdzp->z_id == zfsvfs->z_root)
		return (0);
	zp = tdzp;
	for (;;) {
		ASSERT(!zp->z_unlinked);
		if ((error = sa_lookup(zp->z_sa_hdl,
		    SA_ZPL_PARENT(zfsvfs), &parent, sizeof (parent))) != 0)
			break;
		if (parent == szp->z_id) {
			error = SET_ERROR(EINVAL);
			break;
		}
		if (parent == zfsvfs->z_root)
			break;
		if (parent == sdzp->z_id)
			break;
		error = zfs_zget(zfsvfs, parent, &zp1);
		if (error != 0)
			break;
		if (zp != tdzp)
			VN_RELE_ASYNC(ZTOV(zp),
			    dsl_pool_vnrele_taskq(dmu_objset_pool(zfsvfs->z_os)));
		zp = zp1;
	}
	if (error == ENOTDIR)
		panic("checkpath: .. not a directory\n");
	if (zp != tdzp)
		VN_RELE_ASYNC(ZTOV(zp),
		    dsl_pool_vnrele_taskq(dmu_objset_pool(zfsvfs->z_os)));
	return (error);
}
static int zfs_rename_check ( znode_t * szp , znode_t * sdzp , znode_t * tdzp ) { zfsvfs_t * zfsvfs ; znode_t * zp , * zp1 ; uint64_t parent ; int error ; zfsvfs = tdzp -> z_zfsvfs ; if ( tdzp == szp ) return ( SET_ERROR ( EINVAL ) ) ; if ( tdzp == sdzp ) return ( 0 ) ; if ( tdzp -> z_id == zfsvfs -> z_root ) return ( 0 ) ; zp = tdzp ; for ( ; ; ) { ASSERT ( ! zp -> z_unlinked ) ; if ( ( error = sa_lookup ( zp -> z_sa_hdl , SA_ZPL_PARENT ( zfsvfs ) , & parent , sizeof ( parent ) ) ) != 0 ) break ; if ( parent == szp -> z_id ) { error = SET_ERROR ( EINVAL ) ; break ; } if ( parent == zfsvfs -> z_root ) break ; if ( parent == sdzp -> z_id ) break ; error = zfs_zget ( zfsvfs , parent , & zp1 ) ; if ( error != 0 ) break ; if ( zp != tdzp ) VN_RELE_ASYNC ( ZTOV ( zp ) , dsl_pool_vnrele_taskq ( dmu_objset_pool ( zfsvfs -> z_os ) ) ) ; zp = zp1 ; } if ( error == ENOTDIR ) panic ( " \n " ) ; if ( zp != tdzp ) VN_RELE_ASYNC ( ZTOV ( zp ) , dsl_pool_vnrele_taskq ( dmu_objset_pool ( zfsvfs -> z_os ) ) ) ; return ( error ) ; }
Note that we must use VRELE_ASYNC in this function as it walks
 up the directory tree and vrele may need to acquire an exclusive
 lock if a last reference to a vnode is dropped.
Note that we must use VRELE_ASYNC in this function as it walks up the directory tree and vrele may need to acquire an exclusive lock if a last reference to a vnode is dropped .