[Ocfs2-tools-commits] taoma commits r1320 - in branches/sparse-files/libocfs2: . include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Mar 19 22:53:15 PDT 2007


Author: taoma
Date: 2007-03-19 22:53:11 -0700 (Mon, 19 Mar 2007)
New Revision: 1320

Modified:
   branches/sparse-files/libocfs2/extend_file.c
   branches/sparse-files/libocfs2/extent_map.c
   branches/sparse-files/libocfs2/fileio.c
   branches/sparse-files/libocfs2/include/ocfs2.h
Log:
Change extent-map based block searching to find_path based.

This search mechanism is based on the commit Mark checked in ocfs2 kernel on Dec.9th, 2006.
Commit hash is c0bc8e34d4298a632612ab7dc0fa22520377dab2.



Modified: branches/sparse-files/libocfs2/extend_file.c
===================================================================
--- branches/sparse-files/libocfs2/extend_file.c	2007-03-19 05:47:26 UTC (rev 1319)
+++ branches/sparse-files/libocfs2/extend_file.c	2007-03-20 05:53:11 UTC (rev 1320)
@@ -817,6 +817,43 @@
 }
 
 /*
+ * Find the leaf block in the tree which would contain cpos. No
+ * checking of the actual leaf is done.
+ *
+ * This function doesn't handle non btree extent lists.
+ */
+int ocfs2_find_leaf(ocfs2_filesys *fs, struct ocfs2_dinode *di,
+		    uint32_t cpos, char **leaf_buf)
+{
+	int ret;
+	char *buf = NULL;
+	struct ocfs2_path *path = NULL;
+	struct ocfs2_extent_list *el = &di->id2.i_list;
+
+	assert(el->l_tree_depth > 0);
+
+	path = ocfs2_new_inode_path(fs, di);
+	if (!path) {
+		ret = OCFS2_ET_NO_MEMORY;
+		goto out;
+	}
+
+	ret = ocfs2_find_path(fs, path, cpos);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret)
+		goto out;
+
+	memcpy(buf, path_leaf_buf(path), fs->fs_blocksize);
+	*leaf_buf = buf;
+out:
+	ocfs2_free_path(path);
+	return ret;
+}
+
+/*
  * Adjust the adjacent records (left_rec, right_rec) involved in a rotation.
  *
  * Basically, we've moved stuff around at the bottom of the tree and

Modified: branches/sparse-files/libocfs2/extent_map.c
===================================================================
--- branches/sparse-files/libocfs2/extent_map.c	2007-03-19 05:47:26 UTC (rev 1319)
+++ branches/sparse-files/libocfs2/extent_map.c	2007-03-20 05:53:11 UTC (rev 1320)
@@ -27,11 +27,14 @@
 
 #include <string.h>
 #include <inttypes.h>
+#include <assert.h>
 
 #include "ocfs2.h"
 
 #include "extent_map.h"
 
+/* remove all the old extent map mechanism, and use ocfs2_find_path instead. */
+#if 0
 struct extent_map_context {
 	ocfs2_cached_inode *cinode;
 	errcode_t errcode;
@@ -474,87 +477,97 @@
 
 	return ret;
 }
+#endif
 
-
 /*
- * 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;
+	int ret = -1;
+	int i;
+	struct ocfs2_extent_rec *rec;
+	uint32_t rec_end, rec_start;
 
-	*rec = NULL;
+	for(i = 0; i < el->l_next_free_rec; i++) {
+		rec = &el->l_recs[i];
 
-	if (!em)
-		return OCFS2_ET_INVALID_ARGUMENT;
+		rec_start = rec->e_cpos;
+		rec_end = rec_start + rec->e_clusters;
 
-	if (cpos >= em->em_clusters)
-		return OCFS2_ET_INVALID_EXTENT_LOOKUP;
-
-	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 int 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;
+	i = ocfs2_search_extent_list(el, v_cluster);
+	if (i == -1) {
+		/*
+		 * A hole was found. Return some canned values that
+		 * callers can key on.
+		 */
+		*p_cluster = 0;
+		if (num_clusters)
+			*num_clusters = 1;
+	} 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;
+		assert(v_cluster >= rec->e_cpos);
 
-		coff = v_cpos - ent->e_rec.e_cpos;
-		if (ent->e_rec.e_blkno)
-			*p_cpos = ocfs2_blocks_to_clusters(fs,
-						   ent->e_rec.e_blkno) +
-			coff;
+		if (!rec->e_blkno) {
+			fprintf(stderr, "Inode %"PRIu64" has bad extent "
+				    "record (%u, %u, 0)", di->i_blkno,
+				    rec->e_cpos, rec->e_clusters);
+			ret = OCFS2_ET_BAD_BLKNO;
+			goto out;
+		}
 
-		if (ret_count)
-			*ret_count = ent->e_rec.e_clusters - coff;
+		coff = v_cluster - rec->e_cpos;
 
-		return 0;
+		*p_cluster = ocfs2_blocks_to_clusters(fs, rec->e_blkno);
+		*p_cluster = *p_cluster + coff;
+
+		if (num_clusters)
+			*num_clusters = rec->e_clusters - 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,
@@ -562,52 +575,35 @@
 				      uint64_t *p_blkno, int *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;
+	/*
+	 * p_cluster == 0 indicates a hole.
+	 */
+	if (p_cluster) {
+		boff = ocfs2_clusters_to_blocks(fs, p_cluster);
+		boff += (v_blkno & (uint64_t)(bpc - 1));
+	}
 
-		/* 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;
+	*p_blkno = boff;
 
-		boff = ocfs2_clusters_to_blocks(fs, cpos - rec->e_cpos);
-		boff += (v_blkno % bpc);
-		if (rec->e_blkno)
-			*p_blkno = rec->e_blkno + boff;
-
-		if (ret_count) {
-			*ret_count = ocfs2_clusters_to_blocks(fs,
-							      rec->e_clusters) - boff;
-		}
-
-		return 0;
+	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,
@@ -647,11 +643,10 @@
 	if (!cinode->ci_map)
 		return;
 
-	ocfs2_extent_map_drop(cinode, 0);
 	ocfs2_free(&cinode->ci_map);
 }
 
-
+#if 0
 static int extent_map_func(ocfs2_filesys *fs,
 			   struct ocfs2_extent_rec *rec,
 		  	   int tree_depth,
@@ -825,8 +820,8 @@
 
 	return 0;
 }
+#endif
 
-
 #ifdef DEBUG_EXE
 #include <stdlib.h>
 #include <getopt.h>
@@ -834,10 +829,7 @@
 
 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)
@@ -905,65 +897,9 @@
 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;
 
@@ -983,7 +919,7 @@
 
 	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);
@@ -996,15 +932,6 @@
 				}
 				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");
@@ -1020,31 +947,6 @@
 				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;
@@ -1082,88 +984,26 @@
 		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;
-		}
+	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);
-				ret = ocfs2_extent_map_get_clusters(cinode,
-								  11,
-								  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_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);
 
-	walk_extents_func(fs, cinode, op);
-
 out_free:
 	ocfs2_free_cached_inode(fs, cinode);
 

Modified: branches/sparse-files/libocfs2/fileio.c
===================================================================
--- branches/sparse-files/libocfs2/fileio.c	2007-03-19 05:47:26 UTC (rev 1319)
+++ branches/sparse-files/libocfs2/fileio.c	2007-03-20 05:53:11 UTC (rev 1320)
@@ -190,6 +190,31 @@
 	return ret;
 }
 
+/*
+ * Search the space [start_pos, start_pos + n_clusters), and find the
+ * cluster num a hole poccesses starting from start_pos.
+ */
+static uint32_t find_cluster_hole(ocfs2_cached_inode *ci, uint32_t start_pos,
+			       uint32_t n_clusters)
+{
+	errcode_t ret;
+	uint32_t cluster_hole, i;
+	uint64_t blkno = ocfs2_clusters_to_blocks(ci->ci_fs,start_pos);
+	uint32_t bpc = ci->ci_fs->fs_clustersize / ci->ci_fs->fs_blocksize;
+	uint64_t p_blkno;
+	int	 contig_blocks;
+
+	for (i = 0; i < n_clusters; i++, blkno += bpc) {
+		ret = ocfs2_extent_map_get_blocks(ci, blkno, 1,
+						  &p_blkno, &contig_blocks);
+		if (ret || p_blkno)
+			break;
+	}
+	cluster_hole = i;
+
+	return cluster_hole;
+}
+
 errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 			   uint64_t offset, uint32_t *wrote)
 {
@@ -238,6 +263,8 @@
 			cluster_end = ocfs2_blocks_to_clusters(fs,
 						v_blkno + contig_blocks -1);
 			n_clusters = cluster_end - cluster_begin + 1;
+			n_clusters = find_cluster_hole(ci, cluster_begin,
+						       n_clusters);
 			ret = ocfs2_new_clusters(fs, 1, n_clusters, &p_blkno,
 						 &n_clusters);
 			if (ret)

Modified: branches/sparse-files/libocfs2/include/ocfs2.h
===================================================================
--- branches/sparse-files/libocfs2/include/ocfs2.h	2007-03-19 05:47:26 UTC (rev 1319)
+++ branches/sparse-files/libocfs2/include/ocfs2.h	2007-03-20 05:53:11 UTC (rev 1320)
@@ -295,27 +295,12 @@
 errcode_t ocfs2_extent_map_init(ocfs2_filesys *fs,
 				ocfs2_cached_inode *cinode);
 void ocfs2_extent_map_free(ocfs2_cached_inode *cinode);
-errcode_t ocfs2_extent_map_insert(ocfs2_cached_inode *cinode,
-				  struct ocfs2_extent_rec *rec,
-				  int tree_depth);
-errcode_t ocfs2_extent_map_drop(ocfs2_cached_inode *cinode,
-				 uint32_t new_clusters);
-errcode_t ocfs2_extent_map_trunc(ocfs2_cached_inode *cinode,
-				 uint32_t new_clusters);
-errcode_t ocfs2_extent_map_get_rec(ocfs2_cached_inode *cinode,
-				   uint32_t cpos,
-				   struct ocfs2_extent_rec **rec);
-errcode_t ocfs2_extent_map_get_clusters(ocfs2_cached_inode *cinode,
-					uint32_t v_cpos, int count,
-					uint32_t *p_cpos,
-					int *ret_count);
 errcode_t ocfs2_extent_map_get_blocks(ocfs2_cached_inode *cinode,
 				      uint64_t v_blkno, int count,
 				      uint64_t *p_blkno,
 				      int *ret_count);
-errcode_t ocfs2_load_extent_map(ocfs2_filesys *fs,
-				ocfs2_cached_inode *cinode);
-
+int ocfs2_find_leaf(ocfs2_filesys *fs, struct ocfs2_dinode *di,
+		    uint32_t cpos, char **leaf_buf);
 void ocfs2_swap_journal_superblock(journal_superblock_t *jsb);
 errcode_t ocfs2_init_journal_superblock(ocfs2_filesys *fs, char *buf,
 					int buflen, uint32_t jrnl_size);




More information about the Ocfs2-tools-commits mailing list