// SPDX-License-Identifier: GPL-2.0-only
/*
 * extent_map.c
 *
 * Block/Cluster mapping functions
 *
 * Copyright (C) 2004 Oracle.  All rights reserved.
 */

#include <linux/fs.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/fiemap.h>

#include <cluster/masklog.h>

#include "ocfs2.h"

#include "alloc.h"
#include "dlmglue.h"
#include "extent_map.h"
#include "inode.h"
#include "super.h"
#include "symlink.h"
#include "aops.h"
#include "ocfs2_trace.h"

#include "buffer_head_io.h"

/*
 * The extent caching implementation is intentionally trivial.
 *
 * We only cache a small number of extents stored directly on the
 * inode, so linear order operations are acceptable. If we ever want
 * to increase the size of the extent map, then these algorithms must
 * get smarter.
 */

void ocfs2_extent_map_init(struct inode *inode)
{
	struct ocfs2_inode_info *oi = OCFS2_I(inode);

	oi->ip_extent_map.em_num_items = 0;
	INIT_LIST_HEAD(&oi->ip_extent_map.em_list);
}

static void __ocfs2_extent_map_lookup(struct ocfs2_extent_map *em,
				      unsigned int cpos,
				      struct ocfs2_extent_map_item **ret_emi)
{
	unsigned int range;
	struct ocfs2_extent_map_item *emi;

	*ret_emi = NULL;

	list_for_each_entry(emi, &em->em_list, ei_list) {
		range = emi->ei_cpos + emi->ei_clusters;

		if (cpos >= emi->ei_cpos && cpos < range) {
			list_move(&emi->ei_list, &em->em_list);

			*ret_emi = emi;
			break;
		}
	}
}

static int ocfs2_extent_map_lookup(struct inode *inode, unsigned int cpos,
				   unsigned int *phys, unsigned int *len,
				   unsigned int *flags)
{
	unsigned int coff;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);
	struct ocfs2_extent_map_item *emi;

	spin_lock(&oi->ip_lock);

	__ocfs2_extent_map_lookup(&oi->ip_extent_map, cpos, &emi);
	if (emi) {
		coff = cpos - emi->ei_cpos;
		*phys = emi->ei_phys + coff;
		if (len)
			*len = emi->ei_clusters - coff;
		if (flags)
			*flags = emi->ei_flags;
	}

	spin_unlock(&oi->ip_lock);

	if (emi == NULL)
		return -ENOENT;

	return 0;
}

/*
 * Forget about all clusters equal to or greater than cpos.
 */
void ocfs2_extent_map_trunc(struct inode *inode, unsigned int cpos)
{
	struct ocfs2_extent_map_item *emi, *n;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);
	struct ocfs2_extent_map *em = &oi->ip_extent_map;
	LIST_HEAD(tmp_list);
	unsigned int range;

	spin_lock(&oi->ip_lock);
	list_for_each_entry_safe(emi, n, &em->em_list, ei_list) {
		if (emi->ei_cpos >= cpos) {
			/* Full truncate of this record. */
			list_move(&emi->ei_list, &tmp_list);
			BUG_ON(em->em_num_items == 0);
			em->em_num_items--;
			continue;
		}

		range = emi->ei_cpos + emi->ei_clusters;
		if (range > cpos) {
			/* Partial truncate */
			emi->ei_clusters = cpos - emi->ei_cpos;
		}
	}
	spin_unlock(&oi->ip_lock);

	list_for_each_entry_safe(emi, n, &tmp_list, ei_list) {
		list_del(&emi->ei_list);
		kfree(emi);
	}
}

/*
 * Is any part of emi2 contained within emi1
 */
static int ocfs2_ei_is_contained(struct ocfs2_extent_map_item *emi1,
				 struct ocfs2_extent_map_item *emi2)
{
	unsigned int range1, range2;

	/*
	 * Check if logical start of emi2 is inside emi1
	 */
	range1 = emi1->ei_cpos + emi1->ei_clusters;
	if (emi2->ei_cpos >= emi1->ei_cpos && emi2->ei_cpos < range1)
		return 1;

	/*
	 * Check if logical end of emi2 is inside emi1
	 */
	range2 = emi2->ei_cpos + emi2->ei_clusters;
	if (range2 > emi1->ei_cpos && range2 <= range1)
		return 1;

	return 0;
}

static void ocfs2_copy_emi_fields(struct ocfs2_extent_map_item *dest,
				  struct ocfs2_extent_map_item *src)
{
	dest->ei_cpos = src->ei_cpos;
	dest->ei_phys = src->ei_phys;
	dest->ei_clusters = src->ei_clusters;
	dest->ei_flags = src->ei_flags;
}

/*
 * Try to merge emi with ins. Returns 1 if merge succeeds, zero
 * otherwise.
 */
static int ocfs2_try_to_merge_extent_map(struct ocfs2_extent_map_item *emi,
					 struct ocfs2_extent_map_item *ins)
{
	/*
	 * Handle contiguousness
	 */
	if (ins->ei_phys == (emi->ei_phys + emi->ei_clusters) &&
	    ins->ei_cpos == (emi->ei_cpos + emi->ei_clusters) &&
	    ins->ei_flags == emi->ei_flags) {
		emi->ei_clusters += ins->ei_clusters;
		return 1;
	} else if ((ins->ei_phys + ins->ei_clusters) == emi->ei_phys &&
		   (ins->ei_cpos + ins->ei_clusters) == emi->ei_cpos &&
		   ins->ei_flags == emi->ei_flags) {
		emi->ei_phys = ins->ei_phys;
		emi->ei_cpos = ins->ei_cpos;
		emi->ei_clusters += ins->ei_clusters;
		return 1;
	}

	/*
	 * Overlapping extents - this shouldn't happen unless we've
	 * split an extent to change it's flags. That is exceedingly
	 * rare, so there's no sense in trying to optimize it yet.
	 */
	if (ocfs2_ei_is_contained(emi, ins) ||
	    ocfs2_ei_is_contained(ins, emi)) {
		ocfs2_copy_emi_fields(emi, ins);
		return 1;
	}

	/* No merge was possible. */
	return 0;
}

/*
 * In order to reduce complexity on the caller, this insert function
 * is intentionally liberal in what it will accept.
 *
 * The only rule is that the truncate call *must* be used whenever
 * records have been deleted. This avoids inserting overlapping
 * records with different physical mappings.
 */
void ocfs2_extent_map_insert_rec(struct inode *inode,
				 struct ocfs2_extent_rec *rec)
{
	struct ocfs2_inode_info *oi = OCFS2_I(inode);
	struct ocfs2_extent_map *em = &oi->ip_extent_map;
	struct ocfs2_extent_map_item *emi, *new_emi = NULL;
	struct ocfs2_extent_map_item ins;

	ins.ei_cpos = le32_to_cpu(rec->e_cpos);
	ins.ei_phys = ocfs2_blocks_to_clusters(inode->i_sb,
					       le64_to_cpu(rec->e_blkno));
	ins.ei_clusters = le16_to_cpu(rec->e_leaf_clusters);
	ins.ei_flags = rec->e_flags;

search:
	spin_lock(&oi->ip_lock);

	list_for_each_entry(emi, &em->em_list, ei_list) {
		if (ocfs2_try_to_merge_extent_map(emi, &ins)) {
			list_move(&emi->ei_list, &em->em_list);
			spin_unlock(&oi->ip_lock);
			goto out;
		}
	}

	/*
	 * No item could be merged.
	 *
	 * Either allocate and add a new item, or overwrite the last recently
	 * inserted.
	 */

	if (em->em_num_items < OCFS2_MAX_EXTENT_MAP_ITEMS) {
		if (new_emi == NULL) {
			spin_unlock(&oi->ip_lock);

			new_emi = kmalloc(sizeof(*new_emi), GFP_NOFS);
			if (new_emi == NULL)
				goto out;

			goto search;
		}

		ocfs2_copy_emi_fields(new_emi, &ins);
		list_add(&new_emi->ei_list, &em->em_list);
		em->em_num_items++;
		new_emi = NULL;
	} else {
		BUG_ON(list_empty(&em->em_list) || em->em_num_items == 0);
		emi = list_entry(em->em_list.prev,
				 struct ocfs2_extent_map_item, ei_list);
		list_move(&emi->ei_list, &em->em_list);
		ocfs2_copy_emi_fields(emi, &ins);
	}

	spin_unlock(&oi->ip_lock);

out:
	kfree(new_emi);
}

static int ocfs2_last_eb_is_empty(struct inode *inode,
				  struct ocfs2_dinode *di)
{
	int ret, next_free;
	u64 last_eb_blk = le64_to_cpu(di->i_last_eb_blk);
	struct buffer_head *eb_bh = NULL;
	struct ocfs2_extent_block *eb;
	struct ocfs2_extent_list *el;

	ret = ocfs2_read_extent_block(INODE_CACHE(inode), last_eb_blk, &eb_bh);
	if (ret) {
		mlog_errno(ret);
		goto out;
	}

	eb = (struct ocfs2_extent_block *) eb_bh->b_data;
	el = &eb->h_list;

	if (el->l_tree_depth) {
		ocfs2_error(inode->i_sb,
			    "Inode %lu has non zero tree depth in leaf block %llu\n",
			    inode->i_ino,
			    (unsigned long long)eb_bh->b_blocknr);
		ret = -EROFS;
		goto out;
	}

	next_free = le16_to_cpu(el->l_next_free_rec);

	if (next_free == 0 ||
	    (next_free == 1 && ocfs2_is_empty_extent(&el->l_recs[0])))
		ret = 1;

out:
	brelse(eb_bh);
	return ret;
}

/*
 * Return the 1st index within el which contains an extent start
 * larger than v_cluster.
 */
static int ocfs2_search_for_hole_index(struct ocfs2_extent_list *el,
				       u32 v_cluster)
{
	int i;
	struct ocfs2_extent_rec *rec;

	for(i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
		rec = &el->l_recs[i];

		if (v_cluster < le32_to_cpu(rec->e_cpos))
			break;
	}

	return i;
}

/*
 * Figure out the size of a hole which starts at v_cluster within the given
 * extent list.
 *
 * If there is no more allocation past v_cluster, we return the maximum
 * cluster size minus v_cluster.
 *
 * If we have in-inode extents, then el points to the dinode list and
 * eb_bh is NULL. Otherwise, eb_bh should point to the extent block
 * containing el.
 */
int ocfs2_figure_hole_clusters(struct ocfs2_caching_info *ci,
			       struct ocfs2_extent_list *el,
			       struct buffer_head *eb_bh,
			       u32 v_cluster,
			       u32 *num_clusters)
{
	int ret, i;
	struct buffer_head *next_eb_bh = NULL;
	struct ocfs2_extent_block *eb, *next_eb;

	i = ocfs2_search_for_hole_index(el, v_cluster);

	if (i == le16_to_cpu(el->l_next_free_rec) && eb_bh) {
		eb = (struct ocfs2_extent_block *)eb_bh->b_data;

		/*
		 * Check the next leaf for any extents.
		 */

		if (le64_to_cpu(eb->h_next_leaf_blk) == 0ULL)
			goto no_more_extents;

		ret = ocfs2_read_extent_block(ci,
					      le64_to_cpu(eb->h_next_leaf_blk),
					      &next_eb_bh);
		if (ret) {
			mlog_errno(ret);
			goto out;
		}

		next_eb = (struct ocfs2_extent_block *)next_eb_bh->b_data;
		el = &next_eb->h_list;
		i = ocfs2_search_for_hole_index(el, v_cluster);
	}

no_more_extents:
	if (i == le16_to_cpu(el->l_next_free_rec)) {
		/*
		 * We're at the end of our existing allocation. Just
		 * return the maximum number of clusters we could
		 * possibly allocate.
		 */
		*num_clusters = UINT_MAX - v_cluster;
	} else {
		*num_clusters = le32_to_cpu(el->l_recs[i].e_cpos) - v_cluster;
	}

	ret = 0;
out:
	brelse(next_eb_bh);
	return ret;
}

static int ocfs2_get_clusters_nocache(struct inode *inode,
				      struct buffer_head *di_bh,
				      u32 v_cluster, unsigned int *hole_len,
				      struct ocfs2_extent_rec *ret_rec,
				      unsigned int *is_last)
{
	int i, ret, tree_height, len;
	struct ocfs2_dinode *di;
	struct ocfs2_extent_block *eb;
	struct ocfs2_extent_list *el;
	struct ocfs2_extent_rec *rec;
	struct buffer_head *eb_bh = NULL;

	memset(ret_rec, 0, sizeof(*ret_rec));
	if (is_last)
		*is_last = 0;

	di = (struct ocfs2_dinode *) di_bh->b_data;
	el = &di->id2.i_list;
	tree_height = le16_to_cpu(el->l_tree_depth);

	if (tree_height > 0) {
		ret = ocfs2_find_leaf(INODE_CACHE(inode), el, v_cluster,
				      &eb_bh);
		if (ret) {
			mlog_errno(ret);
			goto out;
		}

		eb = (struct ocfs2_extent_block *) eb_bh->b_data;
		el = &eb->h_list;

		if (el->l_tree_depth) {
			ocfs2_error(inode->i_sb,
				    "Inode %lu has non zero tree depth in leaf block %llu\n",
				    inode->i_ino,
				    (unsigned long long)eb_bh->b_blocknr);
			ret = -EROFS;
			goto out;
		}
	}

	if (le16_to_cpu(el->l_next_free_rec) > le16_to_cpu(el->l_count)) {
		ocfs2_error(inode->i_sb,
			    "Inode %lu has an invalid extent (next_free_rec %u, count %u)\n",
			    inode->i_ino,
			    le16_to_cpu(el->l_next_free_rec),
			    le16_to_cpu(el->l_count));
		ret = -EROFS;
		goto out;
	}

	i = ocfs2_search_extent_list(el, v_cluster);
	if (i == -1) {
		/*
		 * Holes can be larger than the maximum size of an
		 * extent, so we return their lengths in a separate
		 * field.
		 */
		if (hole_len) {
			ret = ocfs2_figure_hole_clusters(INODE_CACHE(inode),
							 el, eb_bh,
							 v_cluster, &len);
			if (ret) {
				mlog_errno(ret);
				goto out;
			}

			*hole_len = len;
		}
		goto out_hole;
	}

	rec = &el->l_recs[i];

	BUG_ON(v_cluster < le32_to_cpu(rec->e_cpos));

	if (!rec->e_blkno) {
		ocfs2_error(inode->i_sb,
			    "Inode %lu has bad extent record (%u, %u, 0)\n",
			    inode->i_ino,
			    le32_to_cpu(rec->e_cpos),
			    ocfs2_rec_clusters(el, rec));
		ret = -EROFS;
		goto out;
	}

	*ret_rec = *rec;

	/*
	 * Checking for last extent is potentially expensive - we
	 * might have to look at the next leaf over to see if it's
	 * empty.
	 *
	 * The first two checks are to see whether the caller even
	 * cares for this information, and if the extent is at least
	 * the last in it's list.
	 *
	 * If those hold true, then the extent is last if any of the
	 * additional conditions hold true:
	 *  - Extent list is in-inode
	 *  - Extent list is right-most
	 *  - Extent list is 2nd to rightmost, with empty right-most
	 */
	if (is_last) {
		if (i == (le16_to_cpu(el->l_next_free_rec) - 1)) {
			if (tree_height == 0)
				*is_last = 1;
			else if (eb->h_blkno == di->i_last_eb_blk)
				*is_last = 1;
			else if (eb->h_next_leaf_blk == di->i_last_eb_blk) {
				ret = ocfs2_last_eb_is_empty(inode, di);
				if (ret < 0) {
					mlog_errno(ret);
					goto out;
				}
				if (ret == 1)
					*is_last = 1;
			}
		}
	}

out_hole:
	ret = 0;
out:
	brelse(eb_bh);
	return ret;
}

static void ocfs2_relative_extent_offsets(struct super_block *sb,
					  u32 v_cluster,
					  struct ocfs2_extent_rec *rec,
					  u32 *p_cluster, u32 *num_clusters)

{
	u32 coff = v_cluster - le32_to_cpu(rec->e_cpos);

	*p_cluster = ocfs2_blocks_to_clusters(sb, le64_to_cpu(rec->e_blkno));
	*p_cluster = *p_cluster + coff;

	if (num_clusters)
		*num_clusters = le16_to_cpu(rec->e_leaf_clusters) - coff;
}

int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster,
			     u32 *p_cluster, u32 *num_clusters,
			     struct ocfs2_extent_list *el,
			     unsigned int *extent_flags)
{
	int ret = 0, i;
	struct buffer_head *eb_bh = NULL;
	struct ocfs2_extent_block *eb;
	struct ocfs2_extent_rec *rec;
	u32 coff;

	if (el->l_tree_depth) {
		ret = ocfs2_find_leaf(INODE_CACHE(inode), el, v_cluster,
				      &eb_bh);
		if (ret) {
			mlog_errno(ret);
			goto out;
		}

		eb = (struct ocfs2_extent_block *) eb_bh->b_data;
		el = &eb->h_list;

		if (el->l_tree_depth) {
			ocfs2_error(inode->i_sb,
				    "Inode %lu has non zero tree depth in xattr leaf block %llu\n",
				    inode->i_ino,
				    (unsigned long long)eb_bh->b_blocknr);
			ret = -EROFS;
			goto out;
		}
	}

	i = ocfs2_search_extent_list(el, v_cluster);
	if (i == -1) {
		ret = -EROFS;
		mlog_errno(ret);
		goto out;
	} else {
		rec = &el->l_recs[i];
		BUG_ON(v_cluster < le32_to_cpu(rec->e_cpos));

		if (!rec->e_blkno) {
			ocfs2_error(inode->i_sb,
				    "Inode %lu has bad extent record (%u, %u, 0) in xattr\n",
				    inode->i_ino,
				    le32_to_cpu(rec->e_cpos),
				    ocfs2_rec_clusters(el, rec));
			ret = -EROFS;
			goto out;
		}
		coff = v_cluster - le32_to_cpu(rec->e_cpos);
		*p_cluster = ocfs2_blocks_to_clusters(inode->i_sb,
						    le64_to_cpu(rec->e_blkno));
		*p_cluster = *p_cluster + coff;
		if (num_clusters)
			*num_clusters = ocfs2_rec_clusters(el, rec) - coff;

		if (extent_flags)
			*extent_flags = rec->e_flags;
	}
out:
	brelse(eb_bh);
	return ret;
}

int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
		       u32 *p_cluster, u32 *num_clusters,
		       unsigned int *extent_flags)
{
	int ret;
	unsigned int hole_len, flags = 0;
	struct buffer_head *di_bh = NULL;
	struct ocfs2_extent_rec rec;

	if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
		ret = -ERANGE;
		mlog_errno(ret);
		goto out;
	}

	ret = ocfs2_extent_map_lookup(inode, v_cluster, p_cluster,
				      num_clusters, extent_flags);
	if (ret == 0)
		goto out;

	ret = ocfs2_read_inode_block(inode, &di_bh);
	if (ret) {
		mlog_errno(ret);
		goto out;
	}

	ret = ocfs2_get_clusters_nocache(inode, di_bh, v_cluster, &hole_len,
					 &rec, NULL);
	if (ret) {
		mlog_errno(ret);
		goto out;
	}

	if (rec.e_blkno == 0ULL) {
		/*
		 * A hole was found. Return some canned values that
		 * callers can key on. If asked for, num_clusters will
		 * be populated with the size of the hole.
		 */
		*p_cluster = 0;
		if (num_clusters) {
			*num_clusters = hole_len;
		}
	} else {
		ocfs2_relative_extent_offsets(inode->i_sb, v_cluster, &rec,
					      p_cluster, num_clusters);
		flags = rec.e_flags;

		ocfs2_extent_map_insert_rec(inode, &rec);
	}

	if (extent_flags)
		*extent_flags = flags;

out:
	brelse(di_bh);
	return ret;
}

/*
 * This expects alloc_sem to be held. The allocation cannot change at
 * all while the map is in the process of being updated.
 */
int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
				u64 *ret_count, unsigned int *extent_flags)
{
	int ret;
	int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
	u32 cpos, num_clusters, p_cluster;
	u64 boff = 0;

	cpos = ocfs2_blocks_to_clusters(inode->i_sb, v_blkno);

	ret = ocfs2_get_clusters(inode, cpos, &p_cluster, &num_clusters,
				 extent_flags);
	if (ret) {
		mlog_errno(ret);
		goto out;
	}

	/*
	 * p_cluster == 0 indicates a hole.
	 */
	if (p_cluster) {
		boff = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
		boff += (v_blkno & (u64)(bpc - 1));
	}

	*p_blkno = boff;

	if (ret_count) {
		*ret_count = ocfs2_clusters_to_blocks(inode->i_sb, num_clusters);
		*ret_count -= v_blkno & (u64)(bpc - 1);
	}

out:
	return ret;
}

/*
 * The ocfs2_fiemap_inline() may be a little bit misleading, since
 * it not only handles the fiemap for inlined files, but also deals
 * with the fast symlink, cause they have no difference for extent
 * mapping per se.
 */
static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
			       struct fiemap_extent_info *fieinfo,
			       u64 map_start)
{
	int ret;
	unsigned int id_count;
	struct ocfs2_dinode *di;
	u64 phys;
	u32 flags = FIEMAP_EXTENT_DATA_INLINE|FIEMAP_EXTENT_LAST;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);

	di = (struct ocfs2_dinode *)di_bh->b_data;
	if (ocfs2_inode_is_fast_symlink(inode))
		id_count = ocfs2_fast_symlink_chars(inode->i_sb);
	else
		id_count = le16_to_cpu(di->id2.i_data.id_count);

	if (map_start < id_count) {
		phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits;
		if (ocfs2_inode_is_fast_symlink(inode))
			phys += offsetof(struct ocfs2_dinode, id2.i_symlink);
		else
			phys += offsetof(struct ocfs2_dinode,
					 id2.i_data.id_data);

		ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count,
					      flags);
		if (ret < 0)
			return ret;
	}

	return 0;
}

int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
		 u64 map_start, u64 map_len)
{
	int ret, is_last;
	u32 mapping_end, cpos;
	unsigned int hole_size;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	u64 len_bytes, phys_bytes, virt_bytes;
	struct buffer_head *di_bh = NULL;
	struct ocfs2_extent_rec rec;

	ret = fiemap_prep(inode, fieinfo, map_start, &map_len, 0);
	if (ret)
		return ret;

	ret = ocfs2_inode_lock(inode, &di_bh, 0);
	if (ret) {
		mlog_errno(ret);
		goto out;
	}

	down_read(&OCFS2_I(inode)->ip_alloc_sem);

	/*
	 * Handle inline-data and fast symlink separately.
	 */
	if ((OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) ||
	    ocfs2_inode_is_fast_symlink(inode)) {
		ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start);
		goto out_unlock;
	}

	cpos = map_start >> osb->s_clustersize_bits;
	mapping_end = ocfs2_clusters_for_bytes(inode->i_sb,
					       map_start + map_len);
	is_last = 0;
	while (cpos < mapping_end && !is_last) {
		u32 fe_flags;

		ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos,
						 &hole_size, &rec, &is_last);
		if (ret) {
			mlog_errno(ret);
			goto out_unlock;
		}

		if (rec.e_blkno == 0ULL) {
			cpos += hole_size;
			continue;
		}

		fe_flags = 0;
		if (rec.e_flags & OCFS2_EXT_UNWRITTEN)
			fe_flags |= FIEMAP_EXTENT_UNWRITTEN;
		if (rec.e_flags & OCFS2_EXT_REFCOUNTED)
			fe_flags |= FIEMAP_EXTENT_SHARED;
		if (is_last)
			fe_flags |= FIEMAP_EXTENT_LAST;
		len_bytes = (u64)le16_to_cpu(rec.e_leaf_clusters) << osb->s_clustersize_bits;
		phys_bytes = le64_to_cpu(rec.e_blkno) << osb->sb->s_blocksize_bits;
		virt_bytes = (u64)le32_to_cpu(rec.e_cpos) << osb->s_clustersize_bits;

		ret = fiemap_fill_next_extent(fieinfo, virt_bytes, phys_bytes,
					      len_bytes, fe_flags);
		if (ret)
			break;

		cpos = le32_to_cpu(rec.e_cpos)+ le16_to_cpu(rec.e_leaf_clusters);
	}

	if (ret > 0)
		ret = 0;

out_unlock:
	brelse(di_bh);

	up_read(&OCFS2_I(inode)->ip_alloc_sem);

	ocfs2_inode_unlock(inode, 0);
out:

	return ret;
}

/* Is IO overwriting allocated blocks? */
int ocfs2_overwrite_io(struct inode *inode, struct buffer_head *di_bh,
		       u64 map_start, u64 map_len)
{
	int ret = 0, is_last;
	u32 mapping_end, cpos;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct ocfs2_extent_rec rec;

	if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
		if (ocfs2_size_fits_inline_data(di_bh, map_start + map_len))
			return ret;
		else
			return -EAGAIN;
	}

	cpos = map_start >> osb->s_clustersize_bits;
	mapping_end = ocfs2_clusters_for_bytes(inode->i_sb,
					       map_start + map_len);
	is_last = 0;
	while (cpos < mapping_end && !is_last) {
		ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos,
						 NULL, &rec, &is_last);
		if (ret) {
			mlog_errno(ret);
			goto out;
		}

		if (rec.e_blkno == 0ULL)
			break;

		if (rec.e_flags & OCFS2_EXT_REFCOUNTED)
			break;

		cpos = le32_to_cpu(rec.e_cpos) +
			le16_to_cpu(rec.e_leaf_clusters);
	}

	if (cpos < mapping_end)
		ret = -EAGAIN;
out:
	return ret;
}

int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int whence)
{
	struct inode *inode = file->f_mapping->host;
	int ret;
	unsigned int is_last = 0, is_data = 0;
	u16 cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
	u32 cpos, cend, clen, hole_size;
	u64 extoff, extlen;
	struct buffer_head *di_bh = NULL;
	struct ocfs2_extent_rec rec;

	BUG_ON(whence != SEEK_DATA && whence != SEEK_HOLE);

	ret = ocfs2_inode_lock(inode, &di_bh, 0);
	if (ret) {
		mlog_errno(ret);
		goto out;
	}

	down_read(&OCFS2_I(inode)->ip_alloc_sem);

	if (*offset >= i_size_read(inode)) {
		ret = -ENXIO;
		goto out_unlock;
	}

	if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
		if (whence == SEEK_HOLE)
			*offset = i_size_read(inode);
		goto out_unlock;
	}

	clen = 0;
	cpos = *offset >> cs_bits;
	cend = ocfs2_clusters_for_bytes(inode->i_sb, i_size_read(inode));

	while (cpos < cend && !is_last) {
		ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos, &hole_size,
						 &rec, &is_last);
		if (ret) {
			mlog_errno(ret);
			goto out_unlock;
		}

		extoff = cpos;
		extoff <<= cs_bits;

		if (rec.e_blkno == 0ULL) {
			clen = hole_size;
			is_data = 0;
		} else {
			clen = le16_to_cpu(rec.e_leaf_clusters) -
				(cpos - le32_to_cpu(rec.e_cpos));
			is_data = (rec.e_flags & OCFS2_EXT_UNWRITTEN) ?  0 : 1;
		}

		if ((!is_data && whence == SEEK_HOLE) ||
		    (is_data && whence == SEEK_DATA)) {
			if (extoff > *offset)
				*offset = extoff;
			goto out_unlock;
		}

		if (!is_last)
			cpos += clen;
	}

	if (whence == SEEK_HOLE) {
		extoff = cpos;
		extoff <<= cs_bits;
		extlen = clen;
		extlen <<=  cs_bits;

		if ((extoff + extlen) > i_size_read(inode))
			extlen = i_size_read(inode) - extoff;
		extoff += extlen;
		if (extoff > *offset)
			*offset = extoff;
		goto out_unlock;
	}

	ret = -ENXIO;

out_unlock:

	brelse(di_bh);

	up_read(&OCFS2_I(inode)->ip_alloc_sem);

	ocfs2_inode_unlock(inode, 0);
out:
	return ret;
}

int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr,
			   struct buffer_head *bhs[], int flags,
			   int (*validate)(struct super_block *sb,
					   struct buffer_head *bh))
{
	int rc = 0;
	u64 p_block, p_count;
	int i, count, done = 0;

	trace_ocfs2_read_virt_blocks(
	     inode, (unsigned long long)v_block, nr, bhs, flags,
	     validate);

	if (((v_block + nr - 1) << inode->i_sb->s_blocksize_bits) >=
	    i_size_read(inode)) {
		BUG_ON(!(flags & OCFS2_BH_READAHEAD));
		goto out;
	}

	while (done < nr) {
		if (!down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem)) {
			rc = -EAGAIN;
			mlog(ML_ERROR,
				 "Inode #%llu ip_alloc_sem is temporarily unavailable\n",
				 (unsigned long long)OCFS2_I(inode)->ip_blkno);
			break;
		}
		rc = ocfs2_extent_map_get_blocks(inode, v_block + done,
						 &p_block, &p_count, NULL);
		up_read(&OCFS2_I(inode)->ip_alloc_sem);
		if (rc) {
			mlog_errno(rc);
			break;
		}

		if (!p_block) {
			rc = -EIO;
			mlog(ML_ERROR,
			     "Inode #%llu contains a hole at offset %llu\n",
			     (unsigned long long)OCFS2_I(inode)->ip_blkno,
			     (unsigned long long)(v_block + done) <<
			     inode->i_sb->s_blocksize_bits);
			break;
		}

		count = nr - done;
		if (p_count < count)
			count = p_count;

		/*
		 * If the caller passed us bhs, they should have come
		 * from a previous readahead call to this function.  Thus,
		 * they should have the right b_blocknr.
		 */
		for (i = 0; i < count; i++) {
			if (!bhs[done + i])
				continue;
			BUG_ON(bhs[done + i]->b_blocknr != (p_block + i));
		}

		rc = ocfs2_read_blocks(INODE_CACHE(inode), p_block, count,
				       bhs + done, flags, validate);
		if (rc) {
			mlog_errno(rc);
			break;
		}
		done += count;
	}

out:
	return rc;
}


