[Ocfs2-tools-commits] mfasheh commits r1169 - in trunk/libocfs2: . include

svn-commits@oss.oracle.com svn-commits at oss.oracle.com
Mon Feb 27 17:23:54 CST 2006


Author: mfasheh
Date: 2006-02-27 17:23:53 -0600 (Mon, 27 Feb 2006)
New Revision: 1169

Modified:
   trunk/libocfs2/alloc.c
   trunk/libocfs2/bitmap.c
   trunk/libocfs2/chainalloc.c
   trunk/libocfs2/extend_file.c
   trunk/libocfs2/include/bitmap.h
   trunk/libocfs2/include/ocfs2.h
Log:
* Teach libocfs2 about discontiguous allocation.



Modified: trunk/libocfs2/alloc.c
===================================================================
--- trunk/libocfs2/alloc.c	2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/alloc.c	2006-02-27 23:23:53 UTC (rev 1169)
@@ -409,38 +409,38 @@
 	return ret;
 }
 
-/* This function needs to be filled out.  Essentially, it should be
- * calling a function in chainalloc.c.  Something like
- * "ocfs2_chain_alloc_range()".  The difference between that and
- * ocfs2_chain_alloc() is that the range can return a number of bits.
- * That function should take a 'required' number of bits, and return
- * the biggest chunk available.  It will need some sort of
- * "find_clear_bit_range()" function for the bitmaps.
- *
- * XXX what to do about local allocs?
+/* XXX what to do about local allocs?
  * XXX Well, we shouldn't use local allocs to allocate, as we are
  *     userspace and we have the entire bitmap in memory.  However, this
  *     doesn't solve the issue of "is space still in dirty local
  *     allocs?"
  */
 errcode_t ocfs2_new_clusters(ocfs2_filesys *fs,
+			     uint32_t min,
 			     uint32_t requested,
-			     uint64_t *start_blkno)
+			     uint64_t *start_blkno,
+			     uint32_t *clusters_found)
+
 {
 	errcode_t ret;
 	uint64_t start_bit;
+	uint64_t found;
 
 	ret = ocfs2_load_allocator(fs, GLOBAL_BITMAP_SYSTEM_INODE,
 				   0, &fs->fs_cluster_alloc);
 	if (ret)
 		goto out;
 
-	ret = ocfs2_chain_alloc_range(fs, fs->fs_cluster_alloc, requested,
-				      &start_bit);
+	ret = ocfs2_chain_alloc_range(fs, fs->fs_cluster_alloc, min, requested,
+				      &start_bit, &found);
 	if (ret)
 		goto out;
 
 	*start_blkno = ocfs2_clusters_to_blocks(fs, start_bit);
+	/* We never have enough bits that can be allocated
+	 * contiguously to overflow this. The lower level API needs
+	 * fixing. */
+	*clusters_found = (uint32_t) found;
 
 	ret = ocfs2_write_chain_allocator(fs, fs->fs_cluster_alloc);
 	if (ret)

Modified: trunk/libocfs2/bitmap.c
===================================================================
--- trunk/libocfs2/bitmap.c	2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/bitmap.c	2006-02-27 23:23:53 UTC (rev 1169)
@@ -138,13 +138,21 @@
 }
 
 /* kind of poorly named, but I couldn't come up with something nicer */
-errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t len, 
-				   uint64_t *first_bit)
+errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t min,
+				   uint64_t len, uint64_t *first_bit,
+				   uint64_t *bits_found)
 {
-	if (len == 0 || len >= bitmap->b_total_bits)
+	errcode_t ret;
+
+	if (min == 0 || len == 0 || len >= bitmap->b_total_bits || min > len)
 		return OCFS2_ET_INVALID_ARGUMENT;
 
-	return (*bitmap->b_ops->alloc_range)(bitmap, len, first_bit);
+	ret = (*bitmap->b_ops->alloc_range)(bitmap, min, len, first_bit,
+					    bits_found);
+	if (ret == 0 && *bits_found < min)
+		abort();
+
+	return ret;
 }
 
 errcode_t ocfs2_bitmap_clear_range(ocfs2_bitmap *bitmap, uint64_t len, 
@@ -631,62 +639,85 @@
 
 struct alloc_range_args {
 	ocfs2_bitmap	*ar_bitmap;
+	uint64_t	ar_min_len;
 	uint64_t	ar_len;
 	uint64_t	ar_first_bit;
+	uint64_t	ar_bits_found;
 	errcode_t	ar_ret;
 };
 
+/* Our strategy here to aid discontiguous allocation is to track the
+ * largest free regions (which still fit within ar_min_len) and if the
+ * max allocation fails, fall back to returning one of those. */
 static errcode_t alloc_range_func(struct ocfs2_bitmap_region *br,
 				  void *private_data)
 {
 	struct alloc_range_args *ar = private_data;
 	errcode_t ret = 0;
+	uint64_t best_start, best_len = 0;
 	int start, end;
 
-	if ((br->br_total_bits - br->br_set_bits) < ar->ar_len)
+	if ((br->br_total_bits - br->br_set_bits) < ar->ar_min_len)
 		goto out;
 
-	for (start = 0; start + ar->ar_len <= br->br_total_bits; ) {
+	for (start = 0; start + ar->ar_min_len <= br->br_total_bits; ) {
 		start = ocfs2_find_next_bit_clear(br->br_bitmap,
 						  br->br_total_bits,
 						  start);
 		if (start == br->br_total_bits)
-			goto out;
+			break;
 
 		/* avoiding start + 1 here so that start at total_bits - 1
 		 * just works out */
 		end = ocfs2_find_next_bit_set(br->br_bitmap,
 					      br->br_total_bits,
 					      start);
-		if ((end - start) < ar->ar_len) {
-			start = end + 1;
-			continue;
-		}
 
-		if ((end - start) > ar->ar_len)
+		/* We've found a region large enough to hold our max. */
+		if ((end - start) >= ar->ar_len) {
 			end = start + ar->ar_len;
+			goto found;
+		}
 
-		ar->ar_first_bit = br->br_start_bit + start;
-		for (; start < end; start++)
-			set_generic_shared(ar->ar_bitmap, br,
-					   start + br->br_start_bit);
+		if ((end - start) > best_len) {
+			best_len = end - start;
+			best_start = start;
+		}
 
-		ar->ar_ret = 0;
-		ret = OCFS2_ET_ITERATION_COMPLETE;
-		break;
+		start = end + 1;
 	}
 
+	/* Nothing found at all */
+	if (best_len < ar->ar_min_len)
+		goto out;
+
+	/* Best fit works */
+	start = best_start;
+	end = best_start + best_len;
+found:
+	ar->ar_first_bit = br->br_start_bit + start;
+	ar->ar_bits_found = end - start;
+
+	for (; start < end; start++)
+		set_generic_shared(ar->ar_bitmap, br,
+				   start + br->br_start_bit);
+
+	ar->ar_ret = 0;
+	ret = OCFS2_ET_ITERATION_COMPLETE;
 out:
 	return ret;
 }
 
 errcode_t ocfs2_bitmap_alloc_range_generic(ocfs2_bitmap *bitmap,
+					   uint64_t min_len,
 					   uint64_t len,
-					   uint64_t *first_bit)
+					   uint64_t *first_bit,
+					   uint64_t *bits_found)
 {
 	errcode_t ret;
 	struct alloc_range_args ar = { 
 		.ar_bitmap = bitmap,
+		.ar_min_len = min_len,
 		.ar_len = len,
 		.ar_ret = OCFS2_ET_BIT_NOT_FOUND,
 	};
@@ -696,8 +727,10 @@
 	if (ret == 0)
 		ret = ar.ar_ret;
 
-	if (ret == 0)
+	if (ret == 0) {
 		*first_bit = ar.ar_first_bit;
+		*bits_found = ar.ar_bits_found;
+	}
 
 	return ret;
 }

Modified: trunk/libocfs2/chainalloc.c
===================================================================
--- trunk/libocfs2/chainalloc.c	2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/chainalloc.c	2006-02-27 23:23:53 UTC (rev 1169)
@@ -342,14 +342,16 @@
 /* FIXME: Better name, too */
 errcode_t ocfs2_chain_alloc_range(ocfs2_filesys *fs,
 				  ocfs2_cached_inode *cinode,
+				  uint64_t min,
 				  uint64_t requested,
-				  uint64_t *start_bit)
+				  uint64_t *start_bit,
+				  uint64_t *bits_found)
 {
 	if (!cinode->ci_chains)
 		return OCFS2_ET_INVALID_ARGUMENT;
 
-	return ocfs2_bitmap_alloc_range(cinode->ci_chains, requested,
-				        start_bit);
+	return ocfs2_bitmap_alloc_range(cinode->ci_chains, min, requested,
+				        start_bit, bits_found);
 }
 
 errcode_t ocfs2_chain_free_range(ocfs2_filesys *fs,
@@ -502,6 +504,7 @@
 {
 	errcode_t ret;
 	uint64_t blkno = 0, old_blkno = 0;
+	uint32_t found;
 	struct ocfs2_group_desc *gd;
 	char *buf = NULL;
 	struct ocfs2_chain_rec *rec = NULL;
@@ -513,10 +516,14 @@
 	gd = (struct ocfs2_group_desc *)buf;
 
 	ret = ocfs2_new_clusters(fs, cinode->ci_inode->id2.i_chain.cl_cpg,
-				 &blkno);
+				 cinode->ci_inode->id2.i_chain.cl_cpg,
+				 &blkno, &found);
 	if (ret)
 		goto out;
 
+	if (found != cinode->ci_inode->id2.i_chain.cl_cpg)
+		abort();
+
 	ocfs2_init_group_desc(fs, gd, blkno, fs->fs_super->i_fs_generation,
 			      cinode->ci_inode->i_blkno,
 			      cinode->ci_inode->id2.i_chain.cl_cpg *

Modified: trunk/libocfs2/extend_file.c
===================================================================
--- trunk/libocfs2/extend_file.c	2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/extend_file.c	2006-02-27 23:23:53 UTC (rev 1169)
@@ -357,7 +357,8 @@
 
 	while (new_clusters) {
 		n_clusters = 1;
-		ret = ocfs2_new_clusters(fs, n_clusters, &blkno);
+		ret = ocfs2_new_clusters(fs, 1, new_clusters, &blkno,
+			&n_clusters);
 		if (ret)
 			break;
 

Modified: trunk/libocfs2/include/bitmap.h
===================================================================
--- trunk/libocfs2/include/bitmap.h	2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/include/bitmap.h	2006-02-27 23:23:53 UTC (rev 1169)
@@ -65,8 +65,9 @@
 				  struct ocfs2_bitmap_region *br,
 				  uint64_t bitno,
 				  int new_val);
-	errcode_t (*alloc_range)(ocfs2_bitmap *bitmap, uint64_t len, 
-				 uint64_t *first_bit);
+	errcode_t (*alloc_range)(ocfs2_bitmap *bitmap, uint64_t min_len,
+				 uint64_t len, uint64_t *first_bit,
+				 uint64_t *bits_found);
 	errcode_t (*clear_range)(ocfs2_bitmap *bitmap, uint64_t len, 
 				 uint64_t first_bit);
 };
@@ -116,8 +117,10 @@
 					       uint64_t start,
 					       uint64_t *found);
 errcode_t ocfs2_bitmap_alloc_range_generic(ocfs2_bitmap *bitmap,
+					   uint64_t min_len,
 					   uint64_t len,
-					   uint64_t *first_bit);
+					   uint64_t *first_bit,
+					   uint64_t *bits_found);
 errcode_t ocfs2_bitmap_clear_range_generic(ocfs2_bitmap *bitmap,
 					   uint64_t len,
 					   uint64_t first_bit);

Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h	2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/include/ocfs2.h	2006-02-27 23:23:53 UTC (rev 1169)
@@ -430,8 +430,9 @@
 errcode_t ocfs2_bitmap_read(ocfs2_bitmap *bitmap);
 errcode_t ocfs2_bitmap_write(ocfs2_bitmap *bitmap);
 uint64_t ocfs2_bitmap_get_set_bits(ocfs2_bitmap *bitmap);
-errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t len, 
-				   uint64_t *first_bit);
+errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t min,
+				   uint64_t len, uint64_t *first_bit,
+				   uint64_t *bits_found);
 errcode_t ocfs2_bitmap_clear_range(ocfs2_bitmap *bitmap, uint64_t len, 
 				   uint64_t first_bit);
 
@@ -484,8 +485,10 @@
 			   uint64_t bitno);
 errcode_t ocfs2_chain_alloc_range(ocfs2_filesys *fs,
 				  ocfs2_cached_inode *cinode,
+				  uint64_t min,
 				  uint64_t requested,
-				  uint64_t *start_bit);
+				  uint64_t *start_bit,
+				  uint64_t *bits_found);
 errcode_t ocfs2_chain_free_range(ocfs2_filesys *fs,
 				 ocfs2_cached_inode *cinode,
 				 uint64_t len,
@@ -531,8 +534,10 @@
 				  uint32_t new_clusters);
 errcode_t ocfs2_truncate(ocfs2_filesys *fs, uint64_t ino, uint64_t new_i_size);
 errcode_t ocfs2_new_clusters(ocfs2_filesys *fs,
+			     uint32_t min,
 			     uint32_t requested,
-			     uint64_t *start_blkno);
+			     uint64_t *start_blkno,
+			     uint32_t *clusters_found);
 errcode_t ocfs2_free_clusters(ocfs2_filesys *fs,
 			      uint32_t len,
 			      uint64_t start_blkno);




More information about the Ocfs2-tools-commits mailing list