/* Lookups up an inode from "name". If ci_name is not NULL, then a CI match is allowed, otherwise it has to be an exact match. If a CI match is found, ci_name->name will point to a the actual name (caller must free) or will be set to NULL if an exact match is found.  */
int xfs_lookup(xfs_inode_t *dp, struct xfs_name *name, xfs_inode_t **ipp, struct xfs_name *ci_name)
/* Lookups up an inode from "name". If ci_name is not NULL, then a CI match is allowed, otherwise it has to be an exact match. If a CI match is found, ci_name->name will point to a the actual name (caller must free) or will be set to NULL if an exact match is found.  */
int xfs_lookup(xfs_inode_t *dp, struct xfs_name *name, xfs_inode_t **ipp, struct xfs_name *ci_name)
{
	xfs_ino_t		inum;
	int			error;
	uint			lock_mode;
	xfs_itrace_entry(dp);
	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
		return XFS_ERROR(EIO);
	lock_mode = xfs_ilock_map_shared(dp);
	error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
	xfs_iunlock_map_shared(dp, lock_mode);
	if (error)
		goto out;
	error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp, 0);
	if (error)
		goto out_free_name;
	return 0;
out_free_name:
	if (ci_name)
		kmem_free(ci_name->name);
out:
	*ipp = NULL;
	return error;
}