[Ocfs2-tools-devel] [patch 04/11] Remove the old mechanism of extent map.

tao.ma at oracle.com tao.ma at oracle.com
Wed Aug 15 10:55:08 PDT 2007


Remove the old cache of extent map and use "path find" instead.
===================================================================
--- test.ocfs2-tools.orig/libocfs2/extent_map.c	2007-08-16 00:27:42.000000000 -0400
+++ test.ocfs2-tools/libocfs2/extent_map.c	2007-08-16 00:36:28.000000000 -0400
@@ -27,484 +27,272 @@
 
 #include <string.h>
 #include <inttypes.h>
+#include <assert.h>
 
 #include "ocfs2.h"
 
 #include "extent_map.h"
 
-struct extent_map_context {
-	ocfs2_cached_inode *cinode;
-	errcode_t errcode;
-};
-
 /*
- * Find an entry in the tree that intersects the region passed in.
- * Note that this will find straddled intervals, it is up to the
- * callers to enforce any boundary conditions.
- *
- * The rb_node garbage lets insertion share the search.  Trivial
- * callers pass NULL.
+ * Return the 1st index within el which contains an extent start
+ * larger than v_cluster.
  */
-static ocfs2_extent_map_entry *
-ocfs2_extent_map_lookup(ocfs2_extent_map *em,
-			uint32_t cpos, uint32_t clusters,
-			struct rb_node ***ret_p,
-			struct rb_node **ret_parent)
-{
-	struct rb_node **p = &em->em_extents.rb_node;
-	struct rb_node *parent = NULL;
-	ocfs2_extent_map_entry *ent = NULL;
-
-	while (*p)
-	{
-		parent = *p;
-		ent = rb_entry(parent, ocfs2_extent_map_entry, e_node); if ((cpos + clusters) <= ent->e_rec.e_cpos) {
-			p = &(*p)->rb_left;
-			ent = NULL;
-		} else if (cpos >= (ent->e_rec.e_cpos +
-				    ent->e_rec.e_clusters)) {
-			p = &(*p)->rb_right;
-			ent = NULL;
-		} else
-			break;
-	}
-
-	if (ret_p != NULL)
-		*ret_p = p;
-	if (ret_parent != NULL)
-		*ret_parent = parent;
-	return ent;
-}
-
-static errcode_t ocfs2_extent_map_find_leaf(ocfs2_cached_inode *cinode,
-					    uint32_t cpos,
-					    uint32_t clusters,
-					    struct ocfs2_extent_list *el)
+static int ocfs2_search_for_hole_index(struct ocfs2_extent_list *el,
+				       uint32_t v_cluster)
 {
-	errcode_t ret;
 	int i;
-	char *eb_buf = NULL;
-	uint64_t blkno;
-	struct ocfs2_extent_block *eb;
 	struct ocfs2_extent_rec *rec;
 
-	if (el->l_tree_depth) {
-		ret = ocfs2_malloc_block(cinode->ci_fs->fs_io, &eb_buf);
-		if (ret)
-			return ret;
-	}
-
-	while (el->l_tree_depth)
-	{
-		blkno = 0;
-		for (i = 0; i < el->l_next_free_rec; i++) {
-			rec = &el->l_recs[i];
-
-			ret = OCFS2_ET_CORRUPT_EXTENT_BLOCK;
-			if (rec->e_cpos >=
-			    cinode->ci_inode->i_clusters)
-				goto out_free;
-
-			if ((rec->e_cpos + rec->e_clusters) <= cpos) {
-				ret = ocfs2_extent_map_insert(cinode,
-							      rec,
-							      el->l_tree_depth);
-				if (ret)
-					goto out_free;
-				continue;
-			}
-			if ((cpos + clusters) <= rec->e_cpos) {
-				ret = ocfs2_extent_map_insert(cinode,
-							      rec,
-							      el->l_tree_depth);
-				if (ret)
-					goto out_free;
-				continue;
-			}
-			
-			/* Check to see if we're stradling */
-			ret = OCFS2_ET_INVALID_EXTENT_LOOKUP;
-			if ((rec->e_cpos > cpos) ||
-			    ((cpos + clusters) >
-			     (rec->e_cpos + rec->e_clusters)))
-				goto out_free;
-
-			/*
-			 * We don't insert this record because we're
-			 * about to traverse it
-			 */
-
-			ret = OCFS2_ET_CORRUPT_EXTENT_BLOCK;
-			if (blkno)
-				goto out_free;
-			blkno = rec->e_blkno;
-		}
-
-		/*
-		 * We don't support holes, and we're still up
-		 * in the branches, so we'd better have found someone
-		 */
-		ret = OCFS2_ET_CORRUPT_EXTENT_BLOCK;
-		if (!blkno)
-			goto out_free;
-
-		ret = ocfs2_read_extent_block(cinode->ci_fs,
-					      blkno, eb_buf);
-		if (ret)
-			goto out_free;
-
-		eb = (struct ocfs2_extent_block *)eb_buf;
-		el = &eb->h_list;
-	}
-
-	if (el->l_tree_depth)
-		abort();
-
-	for (i = 0; i < el->l_next_free_rec; i++) {
+	for(i = 0; i < el->l_next_free_rec; i++) {
 		rec = &el->l_recs[i];
-		ret = ocfs2_extent_map_insert(cinode, rec,
-					      el->l_tree_depth);
-		if (ret)
-			goto out_free;
-	}
 
-	ret = 0;
-
-out_free:
-	if (eb_buf)
-		ocfs2_free(&eb_buf);
+		if (v_cluster < rec->e_cpos)
+			break;
+	}
 
-	return ret;
+	return i;
 }
 
 /*
- * This lookup actually will read from disk.  It has one invariant:
- * It will never re-traverse blocks.  This means that all inserts should
- * be new regions or more granular regions (both allowed by insert).
+ * 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_buf is NULL. Otherwise, eb_buf should point to the extent block
+ * containing el.
  */
-static errcode_t ocfs2_extent_map_lookup_read(ocfs2_cached_inode *cinode,
-				      uint32_t cpos,
-				      uint32_t clusters,
-				      ocfs2_extent_map_entry **ret_ent)
-{
-	errcode_t ret;
-	ocfs2_extent_map_entry *ent;
-	char *eb_buf = NULL;
-	ocfs2_extent_map *em = cinode->ci_map;
-	struct ocfs2_extent_block *eb;
-	struct ocfs2_extent_list *el;
+static int ocfs2_figure_hole_clusters(ocfs2_cached_inode *cinode,
+				      struct ocfs2_extent_list *el,
+				      char *eb_buf,
+				      uint32_t v_cluster,
+				      uint32_t *num_clusters)
+{
+	int ret, i;
+	char *next_eb_buf = NULL;
+	struct ocfs2_extent_block *eb, *next_eb;
 
-	ent = ocfs2_extent_map_lookup(em, cpos, clusters, NULL, NULL);
-	if (ent) {
-		if (!ent->e_tree_depth) {
-			*ret_ent = ent;
-			return 0;
-		}
-
-		ret = ocfs2_malloc_block(cinode->ci_fs->fs_io,
-					 &eb_buf);
-		if (ret)
-			return ret;
-
-		ret = ocfs2_read_extent_block(cinode->ci_fs,
-					      ent->e_rec.e_blkno,
-					      eb_buf);
-		if (ret) {
-			ocfs2_free(&eb_buf);
-			return ret;
-		}
+	i = ocfs2_search_for_hole_index(el, v_cluster);
 
+	if (i == el->l_next_free_rec && eb_buf) {
 		eb = (struct ocfs2_extent_block *)eb_buf;
-		el = &eb->h_list;
-	} else 
-		el = &cinode->ci_inode->id2.i_list;
-
-	ret = ocfs2_extent_map_find_leaf(cinode, cpos, clusters, el);
-	if (eb_buf)
-		ocfs2_free(&eb_buf);
-	if (ret)
-		return ret;
-
-	ent = ocfs2_extent_map_lookup(em, cpos, clusters, NULL, NULL);
-	if (!ent || ent->e_tree_depth)
-		return OCFS2_ET_CORRUPT_EXTENT_BLOCK;
-
-	*ret_ent = ent;
-
-	return 0;
-}
-
-static errcode_t ocfs2_extent_map_insert_entry(ocfs2_extent_map *em,
-					       ocfs2_extent_map_entry *ent)
-{
-	struct rb_node **p, *parent;
-	ocfs2_extent_map_entry *old_ent;
-	
-	old_ent = ocfs2_extent_map_lookup(em, ent->e_rec.e_cpos,
-					  ent->e_rec.e_clusters,
-					  &p, &parent);
-	if (old_ent)
-		return OCFS2_ET_INVALID_EXTENT_LOOKUP;
-
-	rb_link_node(&ent->e_node, parent, p);
-	rb_insert_color(&ent->e_node, &em->em_extents);
-
-	return 0;
-}
-
-errcode_t ocfs2_extent_map_insert(ocfs2_cached_inode *cinode,
-				  struct ocfs2_extent_rec *rec,
-				  int tree_depth)
-{
-	errcode_t ret;
-	ocfs2_extent_map *em = cinode->ci_map;
-	ocfs2_extent_map_entry *old_ent, *new_ent;
-	ocfs2_extent_map_entry *left_ent = NULL, *right_ent = NULL;
-
-	if (!em)
-		return OCFS2_ET_INVALID_ARGUMENT;
 
-	if ((rec->e_cpos + rec->e_clusters) > em->em_clusters)
-		return OCFS2_ET_INVALID_EXTENT_LOOKUP;
-
-	ret = ocfs2_malloc0(sizeof(struct _ocfs2_extent_map_entry),
-			    &new_ent);
-	if (ret)
-		return ret;
-
-	new_ent->e_rec = *rec;
-	new_ent->e_tree_depth = tree_depth;
-	ret = ocfs2_extent_map_insert_entry(em, new_ent);
-	if (!ret)
-		return 0;
-
-	ret = OCFS2_ET_INTERNAL_FAILURE;
-	old_ent = ocfs2_extent_map_lookup(em, rec->e_cpos,
-					  rec->e_clusters, NULL, NULL);
-
-	if (!old_ent)
-		goto out_free;
-
-	ret = OCFS2_ET_INVALID_EXTENT_LOOKUP;
-	if (old_ent->e_tree_depth < tree_depth)
-		goto out_free;
-	if (old_ent->e_tree_depth == tree_depth) {
-		if (!memcmp(rec, &old_ent->e_rec,
-			    sizeof(struct ocfs2_extent_rec)))
-			ret = 0;  /* Same entry, just skip */
-		goto out_free;
-	}
+		/*
+		 * Check the next leaf for any extents.
+		 */
+		if (eb->h_next_leaf_blk == 0)
+			goto no_more_extents;
 
-	/*
-	 * We do it in this order specifically so that malloc failures
-	 * do not leave an inconsistent tree.
-	 */
-	if (rec->e_cpos > old_ent->e_rec.e_cpos) {
-		ret = ocfs2_malloc0(sizeof(struct _ocfs2_extent_map_entry),
-				    &left_ent);
-		if (ret)
-			goto out_free;
-		*left_ent = *old_ent;
-		left_ent->e_rec.e_clusters =
-			rec->e_cpos - left_ent->e_rec.e_cpos;
-	}
-	if ((old_ent->e_rec.e_cpos +
-	     old_ent->e_rec.e_clusters) > 
-	    (rec->e_cpos + rec->e_clusters)) {
-		ret = ocfs2_malloc0(sizeof(struct _ocfs2_extent_map_entry),
-				    &right_ent);
+		ret = ocfs2_malloc_block(cinode->ci_fs->fs_io, &next_eb_buf);
 		if (ret)
-			goto out_free;
-		*right_ent = *old_ent;
-		right_ent->e_rec.e_cpos =
-			rec->e_cpos + rec->e_clusters;
-		right_ent->e_rec.e_clusters =
-			(old_ent->e_rec.e_cpos +
-			 old_ent->e_rec.e_clusters) -
-			right_ent->e_rec.e_cpos;
-	}
+			goto out;
 
-	rb_erase(&old_ent->e_node, &em->em_extents);
-
-	if (left_ent) {
-		ret = ocfs2_extent_map_insert_entry(em,
-						    left_ent);
+		ret = ocfs2_read_extent_block(cinode->ci_fs,
+					      eb->h_next_leaf_blk, next_eb_buf);
 		if (ret)
-			goto out_free;
-		left_ent = NULL;
-	}
+			goto out;
 
-	ret = ocfs2_extent_map_insert_entry(em, new_ent);
-	if (ret)
-		goto out_free;
-	new_ent = NULL;
+		next_eb = (struct ocfs2_extent_block *)next_eb_buf;
 
-	if (right_ent) {
-		ret = ocfs2_extent_map_insert_entry(em,
-						    right_ent);
-		if (ret)
-			goto out_free;
-	}
+		el = &next_eb->h_list;
 
-	ocfs2_free(&old_ent);
-
-	return 0;
+		i = ocfs2_search_for_hole_index(el, v_cluster);
+		if (i > 0) {
+			if ((i > 1) || ocfs2_rec_clusters(el->l_tree_depth,
+							  &el->l_recs[0])) {
+				ret = OCFS2_ET_CORRUPT_EXTENT_BLOCK;
+			goto out;
+			}
+		}
+	}
 
-out_free:
-	if (left_ent)
-		ocfs2_free(&left_ent);
-	if (right_ent)
-		ocfs2_free(&right_ent);
-	if (new_ent)
-		ocfs2_free(&new_ent);
+no_more_extents:
+	if (i == 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 = UINT32_MAX - v_cluster;
+	} else
+		*num_clusters = el->l_recs[i].e_cpos - v_cluster;
 
+	ret = 0;
+out:
+	if (next_eb_buf)
+		ocfs2_free(&next_eb_buf);
 	return ret;
 }
 
-
 /*
- * Look up the record containing this cluster offset.  This record is
- * part of the extent map.  Do not free it.  Any changes you make to
- * it will reflect in the extent map.  So, if your last extent
- * is (cpos = 10, clusters = 10) and you truncate the file by 5
- * clusters, you want to do:
+ * Return the index of the extent record which contains cluster #v_cluster.
+ * -1 is returned if it was not found.
  *
- * ret = ocfs2_extent_map_get_rec(em, orig_size - 5, &rec);
- * rec->e_clusters -= 5;
+ * Should work fine on interior and exterior nodes.
  */
-errcode_t ocfs2_extent_map_get_rec(ocfs2_cached_inode *cinode,
-				   uint32_t cpos,
-				   struct ocfs2_extent_rec **rec)
+static int ocfs2_search_extent_list(struct ocfs2_extent_list *el,
+				    uint32_t v_cluster)
 {
-	errcode_t ret = OCFS2_ET_EXTENT_NOT_FOUND;
-	ocfs2_extent_map *em = cinode->ci_map;
-	ocfs2_extent_map_entry *ent = NULL;
-
-	*rec = NULL;
+	int ret = -1;
+	int i;
+	struct ocfs2_extent_rec *rec;
+	uint32_t rec_end, rec_start, clusters;
 
-	if (!em)
-		return OCFS2_ET_INVALID_ARGUMENT;
+	for(i = 0; i < el->l_next_free_rec; i++) {
+		rec = &el->l_recs[i];
 
-	if (cpos >= cinode->ci_inode->i_clusters)
-		return OCFS2_ET_INVALID_EXTENT_LOOKUP;
+		rec_start = rec->e_cpos;
+		clusters = ocfs2_rec_clusters(el->l_tree_depth, rec);
+		rec_end = rec_start + clusters;
 
-	ent = ocfs2_extent_map_lookup(em, cpos, 1, NULL, NULL);
-	
-	if (ent) {
-		*rec = &ent->e_rec;
-		ret = 0;
+		if (v_cluster >= rec_start && v_cluster < rec_end) {
+			ret = i;
+			break;
+		}
 	}
 
 	return ret;
 }
 
-errcode_t ocfs2_extent_map_get_clusters(ocfs2_cached_inode *cinode,
-					uint32_t v_cpos, int count,
-					uint32_t *p_cpos,
-					int *ret_count)
+static errcode_t ocfs2_get_clusters(ocfs2_cached_inode *cinode,
+				    uint32_t v_cluster,
+				    uint32_t *p_cluster,
+		 		    uint32_t *num_clusters)
 {
-	errcode_t ret;
-	uint32_t coff, ccount;
-	ocfs2_extent_map_entry *ent = NULL;
+	int i;
+	errcode_t ret =  0;
 	ocfs2_filesys *fs = cinode->ci_fs;
+	struct ocfs2_dinode *di;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list *el;
+	struct ocfs2_extent_rec *rec;
+	char *eb_buf = NULL;
+	uint32_t coff;
 
-	*p_cpos = ccount = 0;
+	di = cinode->ci_inode;
+	el = &di->id2.i_list;
 
-	if (!cinode->ci_map)
-		return OCFS2_ET_INVALID_ARGUMENT;
+	if (el->l_tree_depth) {
+		ret = ocfs2_find_leaf(fs, di, v_cluster, &eb_buf);
+		if (ret)
+			goto out;
 
-	if ((v_cpos + count) > cinode->ci_map->em_clusters)
-		return OCFS2_ET_INVALID_EXTENT_LOOKUP;
+		eb = (struct ocfs2_extent_block *) eb_buf;
+		el = &eb->h_list;
 
-	ret = ocfs2_extent_map_lookup_read(cinode, v_cpos, count, &ent);
-	if (ret)
-		return ret;
+		if (el->l_tree_depth) {
+			ret = OCFS2_ET_CORRUPT_EXTENT_BLOCK;
+			goto out;
+		}
+	}
+
+	i = ocfs2_search_extent_list(el, v_cluster);
+	if (i == -1) {
+		/*
+		 * 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) {
+			ret = ocfs2_figure_hole_clusters(cinode, el, eb_buf,
+							 v_cluster,
+							 num_clusters);
+			if (ret)
+				goto out;
+		}
+	} else {
+		rec = &el->l_recs[i];
 
-	if (ent) {
-		/* We should never find ourselves straddling an interval */
-		if ((ent->e_rec.e_cpos > v_cpos) ||
-		    ((v_cpos + count) >
-		     (ent->e_rec.e_cpos + ent->e_rec.e_clusters)))
-			return OCFS2_ET_INVALID_EXTENT_LOOKUP;
-
-		coff = v_cpos - ent->e_rec.e_cpos;
-		*p_cpos = ocfs2_blocks_to_clusters(fs,
-						   ent->e_rec.e_blkno) +
-			coff;
+		assert(v_cluster >= rec->e_cpos);
 
-		if (ret_count)
-			*ret_count = ent->e_rec.e_clusters - coff;
+		if (!rec->e_blkno) {
+			ret = OCFS2_ET_BAD_BLKNO;
+			goto out;
+		}
 
-		return 0;
-	}
+		coff = v_cluster - rec->e_cpos;
+
+		*p_cluster = ocfs2_blocks_to_clusters(fs, rec->e_blkno);
+		*p_cluster = *p_cluster + coff;
 
+		if (num_clusters)
+			*num_clusters = ocfs2_rec_clusters(el->l_tree_depth,
+							   rec) - coff;
+	}
 
-	return OCFS2_ET_EXTENT_NOT_FOUND;
+out:
+	if (eb_buf)
+		ocfs2_free(&eb_buf);
+	return ret;
 }
 
 errcode_t ocfs2_extent_map_get_blocks(ocfs2_cached_inode *cinode,
 				      uint64_t v_blkno, int count,
-				      uint64_t *p_blkno, int *ret_count)
+				      uint64_t *p_blkno, uint64_t *ret_count)
 {
 	errcode_t ret;
-	uint64_t boff;
-	uint32_t cpos, clusters;
+	int bpc;
+	uint32_t cpos, num_clusters, p_cluster;
+	uint64_t boff = 0;
 	ocfs2_filesys *fs = cinode->ci_fs;
-	int bpc = ocfs2_clusters_to_blocks(fs, 1);
-	ocfs2_extent_map_entry *ent = NULL;
-	struct ocfs2_extent_rec *rec;
-
-	*p_blkno = 0;
-
-	if (!cinode->ci_map)
-		return OCFS2_ET_INVALID_ARGUMENT;
 
+	bpc = ocfs2_clusters_to_blocks(fs, 1);
 	cpos = ocfs2_blocks_to_clusters(fs, v_blkno);
-	clusters = ocfs2_blocks_to_clusters(fs,
-					    (uint64_t)count + bpc - 1);
-	if ((cpos + clusters) > cinode->ci_map->em_clusters)
-		return OCFS2_ET_INVALID_EXTENT_LOOKUP;
 
-	ret = ocfs2_extent_map_lookup_read(cinode, cpos, clusters, &ent);
+	ret = ocfs2_get_clusters(cinode, cpos, &p_cluster, &num_clusters);
 	if (ret)
-		return ret;
+		goto out;
 
-	if (ent)
-	{
-		rec = &ent->e_rec;
-
-		/* We should never find ourselves straddling an interval */
-		if ((rec->e_cpos > cpos) ||
-		    ((cpos + clusters) >
-		     (rec->e_cpos + rec->e_clusters)))
-			return OCFS2_ET_INVALID_EXTENT_LOOKUP;
-
-		boff = ocfs2_clusters_to_blocks(fs, cpos - rec->e_cpos);
-		boff += (v_blkno % bpc);
-		*p_blkno = rec->e_blkno + boff;
-
-		if (ret_count) {
-			*ret_count = ocfs2_clusters_to_blocks(fs,
-							      rec->e_clusters) - boff;
-		}
+	/*
+	 * p_cluster == 0 indicates a hole.
+	 */
+	if (p_cluster) {
+		boff = ocfs2_clusters_to_blocks(fs, p_cluster);
+		boff += (v_blkno & (uint64_t)(bpc - 1));
+	}
 
-		return 0;
+	*p_blkno = boff;
+
+	if (ret_count) {
+		*ret_count = ocfs2_clusters_to_blocks(fs, num_clusters);
+		*ret_count -= v_blkno & (uint64_t)(bpc - 1);
 	}
 
-	return OCFS2_ET_EXTENT_NOT_FOUND;
+out:
+	return ret;
 }
 
 errcode_t ocfs2_extent_map_init(ocfs2_filesys *fs,
 				ocfs2_cached_inode *cinode)
 {
 	errcode_t ret;
+	uint64_t blocks;
+	uint32_t clusters;
 
 	ret = ocfs2_malloc0(sizeof(struct _ocfs2_extent_map),
 			    &cinode->ci_map);
 	if (ret)
 		return ret;
 
-	cinode->ci_map->em_clusters = cinode->ci_inode->i_clusters;
+	/* we may meet with two different situation here:
+	 * 1. The user call ocfs2_extend_allocation but don't increase the size.
+	 * 2. The user call ocfs2_extend_file but don't increase the clusters.
+	 * so we have to use the larger one to indicate the cluster's range for
+	 * an inode.
+	 *
+	 * Actually, there still exists a situation that we can't handle here.
+	 * A user first call ocfs2_extend_file to increase the size and then do
+	 * ocfs2_extend_allocation to append clusters to the end of the file,
+	 * there is no way for us to decide the real file's size.
+	 */
+	blocks = ocfs2_blocks_in_bytes(fs, cinode->ci_inode->i_size);
+	clusters = ocfs2_max(cinode->ci_inode->i_clusters,
+			     ocfs2_clusters_in_blocks(fs, blocks));
+	cinode->ci_map->em_clusters = clusters;
 	cinode->ci_map->em_extents = RB_ROOT;
 
 	return 0;
@@ -515,186 +303,9 @@ void ocfs2_extent_map_free(ocfs2_cached_
 	if (!cinode->ci_map)
 		return;
 
-	ocfs2_extent_map_drop(cinode, 0);
 	ocfs2_free(&cinode->ci_map);
 }
 
-
-static int extent_map_func(ocfs2_filesys *fs,
-			   struct ocfs2_extent_rec *rec,
-		  	   int tree_depth,
-			   uint32_t ccount,
-			   uint64_t ref_blkno,
-			   int ref_recno,
-			   void *priv_data)
-{
-	errcode_t ret;
-	int iret = 0;
-	struct extent_map_context *ctxt = priv_data;
-
-	if (rec->e_cpos >= ctxt->cinode->ci_inode->i_clusters) {
-		ctxt->errcode = OCFS2_ET_CORRUPT_EXTENT_BLOCK;
-		iret |= OCFS2_EXTENT_ABORT;
-	} else {
-		ret = ocfs2_extent_map_insert(ctxt->cinode, rec,
-					      tree_depth);
-		if (ret) {
-			ctxt->errcode = ret;
-			iret |= OCFS2_EXTENT_ABORT;
-		}
-	}
-
-	return iret;
-}
-
-errcode_t ocfs2_load_extent_map(ocfs2_filesys *fs,
-				ocfs2_cached_inode *cinode)
-{
-	errcode_t ret;
-	struct extent_map_context ctxt;
-
-	if (!cinode)
-		return OCFS2_ET_INVALID_ARGUMENT;
-
-	ret = ocfs2_extent_map_init(fs, cinode);
-	if (ret)
-		return ret;
-
-	ctxt.cinode = cinode;
-	ctxt.errcode = 0;
-
-	ret = ocfs2_extent_iterate(fs, cinode->ci_blkno, 0, NULL,
-				   extent_map_func, &ctxt);
-	if (ret)
-		goto cleanup;
-
-	if (ctxt.errcode) {
-		ret = ctxt.errcode;
-		goto cleanup;
-	}
-
-	return 0;
-
-	ocfs2_extent_map_free(cinode);
-
-	return ret;
-}
-
-static void __ocfs2_extent_map_drop(ocfs2_cached_inode  *cinode,
-				    uint32_t new_clusters,
-				    struct rb_node **free_head,
-				    ocfs2_extent_map_entry **tail_ent)
-{
-	struct rb_node *node, *next;
-	ocfs2_extent_map *em = cinode->ci_map;
-	ocfs2_extent_map_entry *ent;
-
-	*free_head = NULL;
-
-	ent = NULL;
-	node = rb_last(&em->em_extents);
-	while (node)
-	{
-		next = rb_prev(node);
-
-		ent = rb_entry(node, ocfs2_extent_map_entry,
-			       e_node);
-		if (ent->e_rec.e_cpos < new_clusters)
-			break;
-
-		rb_erase(&ent->e_node, &em->em_extents);
-
-		node->rb_right = *free_head;
-		*free_head = node;
-
-		ent = NULL;
-		node = next;
-	}
-
-	/* Do we have an entry straddling new_clusters? */
-	if (tail_ent) {
-		if (ent &&
-		    ((ent->e_rec.e_cpos + ent->e_rec.e_clusters) >
-		     new_clusters))
-			*tail_ent = ent;
-		else
-			*tail_ent = NULL;
-	}
-
-	return;
-}
-
-static void __ocfs2_extent_map_drop_cleanup(struct rb_node *free_head)
-{
-	struct rb_node *node;
-	ocfs2_extent_map_entry *ent;
-
-	while (free_head) {
-		node = free_head;
-		free_head = node->rb_right;
-
-		ent = rb_entry(node, ocfs2_extent_map_entry,
-			       e_node);
-		ocfs2_free(&ent);
-	}
-}
-
-
-/*
- * Remove all entries past new_clusters, inclusive of an entry that
- * contains new_clusters.  This is effectively a cache forget.
- *
- * If you want to also clip the last extent by some number of clusters,
- * you need to call ocfs2_extent_map_trunc().
- */
-errcode_t ocfs2_extent_map_drop(ocfs2_cached_inode *cinode,
-				uint32_t new_clusters)
-{
-	struct rb_node *free_head = NULL;
-	ocfs2_extent_map *em = cinode->ci_map;
-	ocfs2_extent_map_entry *ent;
-
-	if (!em)
-		return OCFS2_ET_INVALID_ARGUMENT;
-
-	__ocfs2_extent_map_drop(cinode, new_clusters, &free_head, &ent);
-
-	if (ent) {
-		rb_erase(&ent->e_node, &em->em_extents);
-		ent->e_node.rb_right = free_head;
-		free_head = &ent->e_node;
-	}
-
-	if (free_head)
-		__ocfs2_extent_map_drop_cleanup(free_head);
-
-	return 0;
-}
-
-/*
- * Remove all entries past new_clusters and also clip any extent
- * straddling new_clusters, if there is one.
- */
-errcode_t ocfs2_extent_map_trunc(ocfs2_cached_inode *cinode,
-				 uint32_t new_clusters)
-{
-	struct rb_node *free_head = NULL;
-	ocfs2_extent_map_entry *ent = NULL;
-
-	__ocfs2_extent_map_drop(cinode, new_clusters, &free_head, &ent);
-
-	if (ent)
-		ent->e_rec.e_clusters =
-			new_clusters - ent->e_rec.e_cpos;
-
-	if (free_head)
-		__ocfs2_extent_map_drop_cleanup(free_head);
-
-	return 0;
-}
-
-
 #ifdef DEBUG_EXE
 #include <stdlib.h>
 #include <getopt.h>
@@ -702,10 +313,7 @@ errcode_t ocfs2_extent_map_trunc(ocfs2_c
 
 enum debug_op {
 	OP_NONE = 0,
-	OP_WALK,
-	OP_LOOKUP_CLUSTER,
 	OP_LOOKUP_BLOCK,
-	OP_LOOKUP_REC,
 };
 
 static uint64_t read_number(const char *num)
@@ -773,65 +381,9 @@ static int read_c_numbers(const char *nu
 static void print_usage(void)
 {
 	fprintf(stderr,
-		"Usage: extent_map -i <inode_blkno> -w <filename>\n"
-		"       extent_map -i <inode_blkno> -b <blkno>:<blocks> <filename>\n"
-		"       extent_map -i <inode_blkno> -c <cpos>:<clusters> <filename>\n"
-		"       extent_map -i <inode_blkno> -r <cpos> <filename>\n");
+		"Usage: extent_map -i <inode_blkno> -b <blkno>:<blocks> <filename>\n");
 }
 
-static int walk_extents_func(ocfs2_filesys *fs,
-			     ocfs2_cached_inode *cinode, int op)
-{
-	ocfs2_extent_map *em;
-	struct rb_node *node;
-	uint32_t ccount;
-	ocfs2_extent_map_entry *ent;
-	int i;
-
-	em = cinode->ci_map;
-
-	fprintf(stdout, "EXTENTS:\n");
-
-	ccount = 0;
-
-	for (node = rb_first(&em->em_extents); node; node = rb_next(node)) {
-		ent = rb_entry(node, ocfs2_extent_map_entry, e_node);
-
-		if (op == OP_WALK) {
-			fprintf(stdout,
-				"(%08"PRIu32", %08"PRIu32", %08"PRIu64") |"
-				" + %08"PRIu32" = %08"PRIu32" / %08"PRIu32"\n",
-				ent->e_rec.e_cpos,
-				ent->e_rec.e_clusters,
-				ent->e_rec.e_blkno, ccount,
-				ccount + ent->e_rec.e_clusters,
-				cinode->ci_inode->i_clusters);
-
-			ccount += ent->e_rec.e_clusters;
-		} else {
-			fprintf(stdout, "@%d: ",
-				ent->e_tree_depth);
-
-			for (i = cinode->ci_inode->id2.i_list.l_tree_depth;
-			     i > ent->e_tree_depth; i--)
-				fprintf(stdout, "  ");
-
-			fprintf(stdout,
-				"(%08"PRIu32", %08"PRIu32", %09"PRIu64")\n",
-				ent->e_rec.e_cpos,
-				ent->e_rec.e_clusters,
-				ent->e_rec.e_blkno);
-		}
-	}
-
-	if (op == OP_WALK)
-		fprintf(stdout, "TOTAL: %"PRIu32"\n",
-			cinode->ci_inode->i_clusters);
-
-	return 0;
-}
-
-
 extern int opterr, optind;
 extern char *optarg;
 
@@ -851,7 +403,7 @@ int main(int argc, char *argv[])
 
 	initialize_ocfs_error_table();
 
-	while ((c = getopt(argc, argv, "i:b:c:r:w")) != EOF) {
+	while ((c = getopt(argc, argv, "i:b:")) != EOF) {
 		switch (c) {
 			case 'i':
 				blkno = read_number(optarg);
@@ -864,15 +416,6 @@ int main(int argc, char *argv[])
 				}
 				break;
 
-			case 'w':
-				if (op) {
-					fprintf(stderr, "Cannot specify more than one operation\n");
-					print_usage();
-					return 1;
-				}
-				op = OP_WALK;
-				break;
-
 			case 'b':
 				if (op) {
 					fprintf(stderr, "Cannot specify more than one operation\n");
@@ -888,31 +431,6 @@ int main(int argc, char *argv[])
 				op = OP_LOOKUP_BLOCK;
 				break;
 
-			case 'c':
-				if (op) {
-					fprintf(stderr, "Cannot specify more than one operation\n");
-					print_usage();
-					return 1;
-				}
-				if (read_c_numbers(optarg,
-						   &cpos, &count)) {
-					fprintf(stderr, "Invalid cluster range: %s\n", optarg);
-					print_usage();
-					return 1;
-				}
-				op = OP_LOOKUP_CLUSTER;
-				break;
-
-			case 'r':
-				if (op) {
-					fprintf(stderr, "Cannot specify more than one operation\n");
-					print_usage();
-					return 1;
-				}
-				cpos = read_number(optarg);
-				op = OP_LOOKUP_REC;
-				break;
-
 			default:
 				print_usage();
 				return 1;
@@ -950,75 +468,25 @@ int main(int argc, char *argv[])
 		blkno, filename,
 		cinode->ci_inode->id2.i_list.l_tree_depth);
 
-	if (op == OP_WALK) {
-		ret = ocfs2_load_extent_map(fs, cinode);
-		if (ret) {
-			com_err(argv[0], ret,
-				"while loading extents");
-			goto out_free;
-		}
-	} else {
-		ret = ocfs2_extent_map_init(fs, cinode);
-		if (ret) {
-			com_err(argv[0], ret,
-				"while initializing extent map");
-			goto out_free;
-		}
-
-		switch (op) {
-			case OP_LOOKUP_BLOCK:
-				ret = ocfs2_extent_map_get_blocks(cinode,
-								  blkoff,
-								  count,
-								  &blkno,
-								  &contig);
-				if (ret) {
-					com_err(argv[0], ret, 
-						"looking up block range %"PRIu64":%d", blkoff, count);
-					goto out_free;
-				}
-				fprintf(stdout, "Lookup of block range %"PRIu64":%d returned %"PRIu64":%d\n",
-					blkoff, count, blkno, contig);
-				break;
-
-			case OP_LOOKUP_CLUSTER:
-				ret = ocfs2_extent_map_get_clusters(cinode,
-								  cpos,
-								  count,
-								  &coff,
-								  &contig);
-				if (ret) {
-					com_err(argv[0], ret, 
-						"looking up cluster range %"PRIu32":%d", cpos, count);
-					goto out_free;
-				}
-				fprintf(stdout, "Lookup of cluster range %"PRIu32":%d returned %"PRIu32":%d\n",
-					cpos, count, coff, contig);
-				break;
-				
-			case OP_LOOKUP_REC:
-				ret = ocfs2_extent_map_get_rec(cinode,
-							       cpos,
-							       &rec);
-				if (ret) {
-					com_err(argv[0], ret, 
-						"looking up cluster %"PRIu32"", cpos);
-					goto out_free;
-				}
-				fprintf(stdout, "Lookup of cluster %"PRIu32" returned (%"PRIu32", %"PRIu32", %"PRIu64")\n",
-					cpos, rec->e_cpos,
-					rec->e_clusters, rec->e_blkno);
-				break;
-
-			default:
-				ret = OCFS2_ET_INTERNAL_FAILURE;
-				com_err(argv[0], ret,
-					"Invalid op can't happen!\n");
-				goto out_free;
-		}
+	ret = ocfs2_extent_map_init(fs, cinode);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while initializing extent map");
+		goto out_free;
 	}
 
-	walk_extents_func(fs, cinode, op);
+	ret = ocfs2_extent_map_get_blocks(cinode,
+					  blkoff,
+					  count,
+					  &blkno,
+					  &contig);
+	if (ret) {
+		com_err(argv[0], ret,
+			"looking up block range %"PRIu64":%d", blkoff, count);
+		goto out_free;
+	}
+	fprintf(stdout, "Lookup of block range %"PRIu64":%d returned %"PRIu64":%d\n",
+		blkoff, count, blkno, contig);
 
 out_free:
 	ocfs2_free_cached_inode(fs, cinode);

-- 



More information about the Ocfs2-tools-devel mailing list