FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
/*
 * Look up a directory entry under a locked vnode.
 * dvp being locked gives us a guarantee that there are no concurrent
 * modification of the directory and, thus, if a node can be found in
 * the directory, then it must not be unlinked.
 *
 * Input arguments:
 *	dzp	- znode for directory
 *	name	- name of entry to lock
 *	flag	- ZNEW: if the entry already exists, fail with EEXIST.
 *		  ZEXISTS: if the entry does not exist, fail with ENOENT.
 *		  ZXATTR: we want dzp's xattr directory
 *
 * Output arguments:
 *	zpp	- pointer to the znode for the entry (NULL if there isn't one)
 *
 * Return value: 0 on success or errno on failure.
 *
 * NOTE: Always checks for, and rejects, '.' and '..'.
 */
Look up a directory entry under a locked vnode.
dvp being locked gives us a guarantee that there are no concurrent
modification of the directory and, thus, if a node can be found in
the directory, then it must not be unlinked.

Input arguments:
dzp     - znode for directory
name    - name of entry to lock
flag    - ZNEW: if the entry already exists, fail with EEXIST.
ZEXISTS: if the entry does not exist, fail with ENOENT.
ZXATTR: we want dzp's xattr directory

Output arguments:
zpp     - pointer to the znode for the entry (NULL if there isn't one)

Return value: 0 on success or errno on failure.

Always checks for, and rejects, '.' and '..'.
Look up a directory entry under a locked vnode . dvp being locked gives us a guarantee that there are no concurrent modification of the directory and thus if a node can be found in the directory then it must not be unlinked . Input arguments : dzp - znode for directory name - name of entry to lock flag - ZNEW : if the entry already exists fail with EEXIST . ZEXISTS : if the entry does not exist fail with ENOENT . ZXATTR : we want dzp ' s xattr directory Output arguments : zpp - pointer to the znode for the entry ( NULL if there isn ' t one ) Return value : 0 on success or errno on failure . Always checks for and rejects ' . ' and ' .. ' .
int
zfs_dirent_lookup(znode_t *dzp, const char *name, znode_t **zpp, int flag)
{
	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
	boolean_t	exact;
	uint64_t	zoid;
	vnode_t		*vp = NULL;
	int		error = 0;
	ASSERT_VOP_LOCKED(ZTOV(dzp), __func__);
	*zpp = NULL;
	if (name[0] == '.' &&
	    (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')) ||
	    zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0)
		return (SET_ERROR(EEXIST));
	exact = zfsvfs->z_case == ZFS_CASE_MIXED;
	if (dzp->z_unlinked && !(flag & ZXATTR))
		return (ENOENT);
	if (flag & ZXATTR) {
		error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &zoid,
		    sizeof (zoid));
		if (error == 0)
			error = (zoid == 0 ? ENOENT : 0);
	} else {
		error = zfs_match_find(zfsvfs, dzp, name, exact, &zoid);
	}
	if (error) {
		if (error != ENOENT || (flag & ZEXISTS)) {
			return (error);
		}
	} else {
		if (flag & ZNEW) {
			return (SET_ERROR(EEXIST));
		}
		error = zfs_zget(zfsvfs, zoid, zpp);
		if (error)
			return (error);
		ASSERT(!(*zpp)->z_unlinked);
	}
	return (0);
}
int zfs_dirent_lookup ( znode_t * dzp , const char * name , znode_t * * zpp , int flag ) { zfsvfs_t * zfsvfs = dzp -> z_zfsvfs ; boolean_t exact ; uint64_t zoid ; vnode_t * vp = NULL ; int error = 0 ; ASSERT_VOP_LOCKED ( ZTOV ( dzp ) , __func__ ) ; * zpp = NULL ; if ( name [ 0 ] == ' ' && ( name [ 1 ] == ' \0 ' || ( name [ 1 ] == ' ' && name [ 2 ] == ' \0 ' ) ) || zfs_has_ctldir ( dzp ) && strcmp ( name , ZFS_CTLDIR_NAME ) == 0 ) return ( SET_ERROR ( EEXIST ) ) ; exact = zfsvfs -> z_case == ZFS_CASE_MIXED ; if ( dzp -> z_unlinked && ! ( flag & ZXATTR ) ) return ( ENOENT ) ; if ( flag & ZXATTR ) { error = sa_lookup ( dzp -> z_sa_hdl , SA_ZPL_XATTR ( zfsvfs ) , & zoid , sizeof ( zoid ) ) ; if ( error == 0 ) error = ( zoid == 0 ? ENOENT : 0 ) ; } else { error = zfs_match_find ( zfsvfs , dzp , name , exact , & zoid ) ; } if ( error ) { if ( error != ENOENT || ( flag & ZEXISTS ) ) { return ( error ) ; } } else { if ( flag & ZNEW ) { return ( SET_ERROR ( EEXIST ) ) ; } error = zfs_zget ( zfsvfs , zoid , zpp ) ; if ( error ) return ( error ) ; ASSERT ( ! ( * zpp ) -> z_unlinked ) ; } return ( 0 ) ; }
Look up a directory entry under a locked vnode.
Look up a directory entry under a locked vnode .
/*
	 * Verify that we are not trying to lock '.', '..', or '.zfs'
	 */ /*
	 * Case sensitivity and normalization preferences are set when
	 * the file system is created.  These are stored in the
	 * zfsvfs->z_case and zfsvfs->z_norm fields.  These choices
	 * affect how we perform zap lookups.
	 *
	 * Decide if exact matches should be requested when performing
	 * a zap lookup on file systems supporting case-insensitive
	 * access.
	 *
	 * NB: we do not need to worry about this flag for ZFS_CASE_SENSITIVE
	 * because in that case MT_EXACT and MT_FIRST should produce exactly
	 * the same result.
	 */