FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
/*
 * Return a znode for the extended attribute directory for zp.
 * ** If the directory does not already exist, it is created **
 *
 *	IN:	zp	- znode to obtain attribute directory from
 *		cr	- credentials of caller
 *		flags	- flags from the VOP_LOOKUP call
 *
 *	OUT:	xzpp	- pointer to extended attribute znode
 *
 *	RETURN:	0 on success
 *		error number on failure
 */
Return a znode for the extended attribute directory for zp.
If the directory does not already exist, it is created

zp      - znode to obtain attribute directory from
cr      - credentials of caller
flags   - flags from the VOP_LOOKUP call

xzpp    - pointer to extended attribute znode

0 on success
error number on failure
Return a znode for the extended attribute directory for zp . If the directory does not already exist it is created zp - znode to obtain attribute directory from cr - credentials of caller flags - flags from the VOP_LOOKUP call xzpp - pointer to extended attribute znode 0 on success error number on failure
int
zfs_get_xattrdir(znode_t *zp, vnode_t **xvpp, cred_t *cr, int flags)
{
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
	znode_t		*xzp;
	vattr_t		va;
	int		error;
top:
	error = zfs_dirent_lookup(zp, "", &xzp, ZXATTR);
	if (error)
		return (error);
	if (xzp != NULL) {
		*xvpp = ZTOV(xzp);
		return (0);
	}
	if (!(flags & CREATE_XATTR_DIR)) {
#ifdef illumos
		return (SET_ERROR(ENOENT));
#else
		return (SET_ERROR(ENOATTR));
#endif
	}
	if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) {
		return (SET_ERROR(EROFS));
	}
	va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
	va.va_type = VDIR;
	va.va_mode = S_IFDIR | S_ISVTX | 0777;
	zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid);
	error = zfs_make_xattrdir(zp, &va, xvpp, cr);
	if (error == ERESTART) {
		goto top;
	}
	if (error == 0)
		VOP_UNLOCK(*xvpp, 0);
	return (error);
}
int zfs_get_xattrdir ( znode_t * zp , vnode_t * * xvpp , cred_t * cr , int flags ) { zfsvfs_t * zfsvfs = zp -> z_zfsvfs ; znode_t * xzp ; vattr_t va ; int error ; top : error = zfs_dirent_lookup ( zp , " " , & xzp , ZXATTR ) ; if ( error ) return ( error ) ; if ( xzp != NULL ) { * xvpp = ZTOV ( xzp ) ; return ( 0 ) ; } if ( ! ( flags & CREATE_XATTR_DIR ) ) { #ifdef illumos return ( SET_ERROR ( ENOENT ) ) ; #else return ( SET_ERROR ( ENOATTR ) ) ; #endif } if ( zfsvfs -> z_vfs -> vfs_flag & VFS_RDONLY ) { return ( SET_ERROR ( EROFS ) ) ; } va . va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID ; va . va_type = VDIR ; va . va_mode = S_IFDIR | S_ISVTX | 0777 ; zfs_fuid_map_ids ( zp , cr , & va . va_uid , & va . va_gid ) ; error = zfs_make_xattrdir ( zp , & va , xvpp , cr ) ; if ( error == ERESTART ) { goto top ; } if ( error == 0 ) VOP_UNLOCK ( * xvpp , 0 ) ; return ( error ) ; }
Return a znode for the extended attribute directory for zp.
Return a znode for the extended attribute directory for zp .
/*
	 * The ability to 'create' files in an attribute
	 * directory comes from the write_xattr permission on the base file.
	 *
	 * The ability to 'search' an attribute directory requires
	 * read_xattr permission on the base file.
	 *
	 * Once in a directory the ability to read/write attributes
	 * is controlled by the permissions on the attribute file.
	 */ /* NB: we already did dmu_tx_wait() if necessary */