[Ocfs2-commits] mfasheh commits r1630 - branches/cluster-groups/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Nov 9 22:09:12 CST 2004


Author: mfasheh
Date: 2004-11-09 22:09:10 -0600 (Tue, 09 Nov 2004)
New Revision: 1630

Modified:
   branches/cluster-groups/src/localalloc.c
   branches/cluster-groups/src/suballoc.c
   branches/cluster-groups/src/suballoc.h
Log:
* rename ocfs_search_suballoc_chain to ocfs_search_chain         

* simplify some of the code for doing group descriptor searches

* factor out the cluster bitmap setup code into it's own function so local  
  alloc can call that when sliding windows.

* some of our cluster group calculations for delete were off

* la_set_bits wasn't being updated properly. Update it correctly, and rely  
  on that in ocfs_reserve_local_alloc_bits instead of a bitmap search.

* fix an inode leak in ocfs_reserve_local_alloc_bits       

* add some code to help debug window shifts 

* lots of debugging printks. these will be removed when we sync back to
  trunk.



Modified: branches/cluster-groups/src/localalloc.c
===================================================================
--- branches/cluster-groups/src/localalloc.c	2004-11-10 04:02:40 UTC (rev 1629)
+++ branches/cluster-groups/src/localalloc.c	2004-11-10 04:09:10 UTC (rev 1630)
@@ -124,8 +124,8 @@
 	if (osb->have_local_alloc 
 	    && (ocfs2_clusters_to_bytes(osb->sb, bits) <= OCFS_LOCAL_ALLOC_MAX_ALLOC)
 	    && (bits <= ocfs_local_alloc_window_bits(osb)))
-		return(1);
-	return(0);
+		return 1;
+	return 0;
 }
 
 /* 
@@ -491,9 +491,9 @@
 				  ocfs2_alloc_context *ac)
 {
 	int status;
-	int startoff;
 	ocfs2_dinode *alloc;
 	struct inode *local_alloc_inode;
+	int free_bits;
 
 	LOG_ENTRY();
 
@@ -531,8 +531,13 @@
 	}
 
 	alloc = (ocfs2_dinode *) osb->local_alloc_bh->b_data;
-	startoff = ocfs_local_alloc_find_clear_bits(osb, alloc, bits_wanted);
-	if (startoff == -1) {
+
+	OCFS_ASSERT(LOCAL_ALLOC(alloc)->la_bits_set == 
+		    ocfs_local_alloc_count_bits(alloc));
+
+	free_bits = le16_to_cpu(LOCAL_ALLOC(alloc)->la_bm_bits) - 
+		le16_to_cpu(LOCAL_ALLOC(alloc)->la_bits_set);
+	if (bits_wanted > free_bits) {
 		/* uhoh, window change time. */
 		status = 
 			ocfs_local_alloc_slide_window(osb, local_alloc_inode);
@@ -549,6 +554,8 @@
 	ac->ac_which = OCFS_AC_USE_LOCAL;
 	status = 0;
 bail:
+	if (local_alloc_inode)
+		iput(local_alloc_inode);
 
 	LOG_EXIT_STATUS(status);
 	return(status);
@@ -599,6 +606,8 @@
 	while(bits_wanted--)
 		ocfs2_set_bit(start++, bitmap);
 
+	LOCAL_ALLOC(alloc)->la_bits_set += *num_bits;
+
 	status = ocfs_journal_dirty(handle, osb->local_alloc_bh);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
@@ -714,6 +723,25 @@
 	return;
 } /* ocfs_clear_local_alloc */
 
+#if 0
+/* turn this on and uncomment below to aid debugging window shifts. */
+static void ocfs2_verify_zero_bits(unsigned long *bitmap,
+				   unsigned int start,
+				   unsigned int count)
+{
+	unsigned int tmp = count;
+	while(tmp--) {
+		if (ocfs2_test_bit(start + tmp, bitmap)) {
+			printk("ocfs2_verify_zero_bits: start = %u, count = "
+			       "%u\n", start, count);
+			printk("ocfs2_verify_zero_bits: bit %u is set!",
+			       start + tmp);
+			BUG();
+		}
+	}
+}
+#endif
+
 /* 
  * ocfs_sync_local_to_main
  *
@@ -734,8 +762,8 @@
 	u64 blkno;
 	void *bitmap;
 
-	LOG_ENTRY_ARGS("alloc->la_bm_bits = %u, COUNT = %u, la_bits_set = %u\n", 
-		       LOCAL_ALLOC(alloc)->la_bm_bits,
+	LOG_ENTRY_ARGS("alloc->la_bm_bits = %u, COUNT = %u, "
+		       "la_bits_set = %u\n", LOCAL_ALLOC(alloc)->la_bm_bits,
 		       ocfs_local_alloc_count_bits(alloc), 
 		       LOCAL_ALLOC(alloc)->la_bits_set);
 
@@ -750,6 +778,11 @@
 		goto bail;
 	}
 
+	printk("sync_local_to_main: alloc->la_bm_bits = %u, COUNT = %u, "
+	       "la_bits_set = %u\n", LOCAL_ALLOC(alloc)->la_bm_bits,
+	       ocfs_local_alloc_count_bits(alloc), 
+	       LOCAL_ALLOC(alloc)->la_bits_set);
+
 	la_start_blk = ocfs2_clusters_to_blocks(osb->sb,
 						LOCAL_ALLOC(alloc)->la_bm_off);
 	bitmap = LOCAL_ALLOC(alloc)->la_bitmap;
@@ -764,19 +797,23 @@
 			continue;
 		} 
 		if (count) {
-			blkno = la_start_blk + (u64) (start - count);
+//			ocfs2_verify_zero_bits(bitmap, start, count);
 
-			printk("freeing %u bits starting at local alloc bit "
-			       "%u (la_start_blk = %llu, blkno = %llu)\n", 
-			       count, start, la_start_blk, blkno);
+			blkno = la_start_blk + 
+				ocfs2_clusters_to_blocks(osb->sb, 
+							 start - count);
 
+			printk("sync_local_to_main: freeing %u bits starting "
+			       "at local alloc bit %u (la_start_blk = %llu, "
+			       "blkno = %llu)\n", count, start - count,
+			       la_start_blk, blkno);
+
 			status = ocfs_free_clusters(handle, main_bm_inode,
 						    main_bm_bh, blkno, count);
 			if (status < 0) {
 				LOG_ERROR_STATUS(status);
 				goto bail;
 			}
-
 		}
 		if (bit_off >= left)
 			break;
@@ -806,17 +843,8 @@
 	memset(*ac, 0, sizeof(ocfs2_alloc_context));
 	(*ac)->ac_handle = handle;
 	(*ac)->ac_bits_wanted = ocfs_local_alloc_window_bits(osb);
-	(*ac)->ac_inode = ocfs_get_system_file_inode(osb, 
-						     GLOBAL_BITMAP_SYSTEM_INODE, 
-						     -1);
-	if (!(*ac)->ac_inode) {
-		status = -EINVAL;
-		LOG_ERROR_STR("Could not get bitmap inode!");
-		goto bail;
-	}
-	(*ac)->ac_which = OCFS_AC_USE_MAIN;
 
-	status = ocfs_reserve_suballoc_bits(osb, *ac);
+	status = ocfs_reserve_cluster_bitmap_bits(osb, *ac);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto bail;

Modified: branches/cluster-groups/src/suballoc.c
===================================================================
--- branches/cluster-groups/src/suballoc.c	2004-11-10 04:02:40 UTC (rev 1629)
+++ branches/cluster-groups/src/suballoc.c	2004-11-10 04:09:10 UTC (rev 1630)
@@ -59,6 +59,10 @@
 static int ocfs_block_group_alloc(ocfs_super *osb, 
 				  struct inode *alloc_inode,
 				  struct buffer_head *bh);
+
+static int ocfs_reserve_suballoc_bits(ocfs_super *osb, 
+				      ocfs2_alloc_context *ac);
+
 static int ocfs2_cluster_group_search(struct inode *inode,
 				      struct buffer_head *group_bh,
 				      u32 bits_wanted, u32 min_bits,
@@ -67,12 +71,12 @@
 				    struct buffer_head *group_bh,
 				    u32 bits_wanted, u32 min_bits,
 				    u16 *bit_off, u16 *bits_found);
-static int ocfs_search_suballoc_chain(ocfs2_alloc_context *ac,
-				      u32 bits_wanted,
-				      u32 min_bits,
-				      u16 *bit_off,
-				      unsigned int *num_bits,
-				      u64 *bg_blkno);
+static int ocfs_search_chain(ocfs2_alloc_context *ac,
+			     u32 bits_wanted,
+			     u32 min_bits,
+			     u16 *bit_off,
+			     unsigned int *num_bits,
+			     u64 *bg_blkno);
 static int ocfs_claim_suballoc_bits(ocfs_super *osb,
 				    ocfs2_alloc_context *ac,
 				    u32 bits_wanted,
@@ -407,8 +411,8 @@
 	return status;
 }
 
-int ocfs_reserve_suballoc_bits(ocfs_super *osb, 
-			       ocfs2_alloc_context *ac)
+static int ocfs_reserve_suballoc_bits(ocfs_super *osb, 
+				      ocfs2_alloc_context *ac)
 {
 	int status;
 	u32 bits_wanted = ac->ac_bits_wanted;
@@ -571,6 +575,31 @@
 	return status;
 }
 
+/* local alloc code has to do the same thing, so rather than do this
+ * twice.. */
+int ocfs_reserve_cluster_bitmap_bits(ocfs_super *osb,
+				     ocfs2_alloc_context *ac)
+{
+	int status;
+
+	ac->ac_inode = ocfs_get_system_file_inode(osb, 
+						     GLOBAL_BITMAP_SYSTEM_INODE, 
+						     -1);
+	if (!ac->ac_inode) {
+		status = -EINVAL;
+		LOG_ERROR_STR("Could not get bitmap inode!");
+		goto bail;
+	}
+	ac->ac_which = OCFS_AC_USE_MAIN;
+	ac->ac_group_search = &ocfs2_cluster_group_search;
+
+	status = ocfs_reserve_suballoc_bits(osb, ac);
+	if (status < 0)
+		LOG_ERROR_STATUS(status);
+bail:
+	return status;
+}
+
 /* Callers don't need to care which bitmap (local alloc or main) to
  * use so we figure it out for them, but unfortunately this clutters
  * things a bit. */
@@ -580,7 +609,6 @@
 			  ocfs2_alloc_context **ac)
 {
 	int status;
-	struct inode *main_bitmap_inode = NULL;
 
 	LOG_ENTRY();
 
@@ -617,18 +645,7 @@
 	}
 
 	if (status == -ENOSPC) {
-		main_bitmap_inode = ocfs_get_system_file_inode(osb, 
-							       GLOBAL_BITMAP_SYSTEM_INODE, 
-							       -1);
-		if (!main_bitmap_inode) {
-			status = -EINVAL;
-			LOG_ERROR_STR("Could not get bitmap inode!");
-			goto bail;
-		}
-		(*ac)->ac_which = OCFS_AC_USE_MAIN;
-		(*ac)->ac_inode = igrab(main_bitmap_inode);
-		(*ac)->ac_group_search = &ocfs2_cluster_group_search;
-		status = ocfs_reserve_suballoc_bits(osb, *ac);
+		status = ocfs_reserve_cluster_bitmap_bits(osb, *ac);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			goto bail;
@@ -641,8 +658,6 @@
 		ocfs_free_alloc_context(*ac);
 		*ac = NULL;
 	}
-	if (main_bitmap_inode)
-		iput(main_bitmap_inode);
 
 	LOG_EXIT_STATUS(status);
 	return(status);
@@ -901,15 +916,15 @@
 	return bg->bg_free_bits_count > wanted;
 }
 
-/* return 0 to keep searching, > 0 on succes (and populate the return
- * values) and < 0 on failure. -ENOSPC means that we hit the end of
- * the chain without finding anything. */
+/* return 0 on success, -ENOSPC to keep searching and any other < 0
+ * value on error. */
 static int ocfs2_cluster_group_search(struct inode *inode,
 				      struct buffer_head *group_bh,
 				      u32 bits_wanted, u32 min_bits,
 				      u16 *bit_off, u16 *bits_found)
 {
-	int ret = 0;
+	int search = -ENOSPC;
+	int ret;
 	ocfs2_group_desc *bg = (ocfs2_group_desc *) group_bh->b_data;
 	u16 tmp_off, tmp_found;
 
@@ -919,20 +934,16 @@
 		ret = ocfs_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
 						       group_bh, bits_wanted,
 						       &tmp_off, &tmp_found);
-		if (ret == -ENOSPC)
-			ret = 0;
-		else if (!ret) {
+		if (!ret) {
 			if (min_bits <= tmp_found) {
 				*bit_off = tmp_off;
 				*bits_found = tmp_found;
-				ret = 1; /* success */
+				search = 0; /* success */
 			}
 		}
 	}
 
-	if (!ret && !bg->bg_next_group)
-		ret = -ENOSPC;
-	return ret;
+	return search;
 }
 
 static int ocfs2_block_group_search(struct inode *inode,
@@ -940,55 +951,45 @@
 				    u32 bits_wanted, u32 min_bits,
 				    u16 *bit_off, u16 *bits_found)
 {
-	int ret = 0;
+	int ret = -ENOSPC;
 	ocfs2_group_desc *bg = (ocfs2_group_desc *) group_bh->b_data;
 
 	OCFS_ASSERT(min_bits == 1);
 	OCFS_ASSERT(!ocfs2_is_cluster_bitmap(inode));
 
-	if (bg->bg_free_bits_count) {
+	if (bg->bg_free_bits_count)
 		ret = ocfs_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
 						       group_bh, bits_wanted,
 						       bit_off, bits_found);
-		if (ret == -ENOSPC)
-			ret = 0;
-		else if (!ret)
-			ret = 1; /* success */
-	} else if (!bg->bg_next_group) {
-		/* This really shouldn't happen... */
-		LOG_ERROR_ARGS("Failure to find free space in suballoc "
-			       "chain!\n");
-		ret = -ENOSPC;
-	}
+
 	return ret;
 }
 
-static int ocfs_search_suballoc_chain(ocfs2_alloc_context *ac,
-				      u32 bits_wanted,
-				      u32 min_bits,
-				      u16 *bit_off,
-				      unsigned int *num_bits,
-				      u64 *bg_blkno)
+static int ocfs_search_chain(ocfs2_alloc_context *ac,
+			     u32 bits_wanted,
+			     u32 min_bits,
+			     u16 *bit_off,
+			     unsigned int *num_bits,
+			     u64 *bg_blkno)
 {
 	int status;
+	u16 chain, tmp_bits;
+	u64 next_group;
 	ocfs_journal_handle *handle = ac->ac_handle;
 	struct inode *alloc_inode = ac->ac_inode;
-	ocfs_super *osb = OCFS2_SB(alloc_inode->i_sb);
 	struct buffer_head *group_bh = NULL;
 	struct buffer_head *prev_group_bh = NULL;
 	ocfs2_dinode *fe = (ocfs2_dinode *) ac->ac_bh->b_data;
 	ocfs2_chain_list *cl = (ocfs2_chain_list *) &fe->id2.i_chain;
 	ocfs2_group_desc *bg;
-	u16 chain, tmp_bits;
-	u64 next_group;
 
-
 	chain = ac->ac_chain;
-	LOG_TRACE_ARGS("trying to alloc %u bits from chain %u, inode %llu\n",
-		       bits_wanted, chain, OCFS_I(alloc_inode)->ip_blkno);
+	printk("trying to alloc %u bits from chain %u, inode %llu\n",
+	       bits_wanted, chain, OCFS_I(alloc_inode)->ip_blkno);
 
-	status = ocfs_read_block(osb, cl->cl_recs[chain].c_blkno, 
-				 &group_bh, OCFS_BH_CACHED, alloc_inode);
+	status = ocfs_read_block(OCFS2_SB(alloc_inode->i_sb),
+				 cl->cl_recs[chain].c_blkno, &group_bh,
+				 OCFS_BH_CACHED, alloc_inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto bail;
@@ -996,18 +997,14 @@
 	bg = (ocfs2_group_desc *) group_bh->b_data;
 	OCFS_ASSERT_RO(IS_VALID_GROUP_DESC(bg));
 
+	status = -ENOSPC;
 	/* for now, the chain search is a bit simplistic. We just use
 	 * the 1st group with any empty bits. */
 	while ((status = ac->ac_group_search(alloc_inode, group_bh, 
 					     bits_wanted, min_bits, bit_off, 
-					     &tmp_bits)) == 0) {
-		/*
-		 * This means we've walked off the end of a chain that
-		 * we thought had bits, but didn't.  While this
-		 * _could_ be a code error, it is more likely to be
-		 * corruption on disk.
-		 */
-		OCFS_ASSERT_RO(bg->bg_next_group);
+					     &tmp_bits)) == -ENOSPC) {
+		if (!bg->bg_next_group)
+			break;
 
 		if (prev_group_bh) {
 			brelse(prev_group_bh);
@@ -1016,7 +1013,8 @@
 		next_group = bg->bg_next_group;
 		prev_group_bh = group_bh;
 		group_bh = NULL;
-		status = ocfs_read_block(osb, next_group, &group_bh, 
+		status = ocfs_read_block(OCFS2_SB(alloc_inode->i_sb), 
+					 next_group, &group_bh, 
 					 OCFS_BH_CACHED, alloc_inode);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
@@ -1031,6 +1029,9 @@
 		goto bail;
 	}
 
+	printk("alloc succeeds: we give %u bits from block group %llu\n",
+	       tmp_bits, bg->bg_blkno);
+
 	*num_bits = tmp_bits;
 
 	OCFS_ASSERT(*num_bits);
@@ -1140,7 +1141,7 @@
 	ac->ac_chain = victim;
 	ac->ac_allow_chain_relink = 1;
 
-	status = ocfs_search_suballoc_chain(ac, bits_wanted, min_bits, bit_off,
+	status = ocfs_search_chain(ac, bits_wanted, min_bits, bit_off,
 					    num_bits, bg_blkno);
 	if (!status)
 		goto bail;
@@ -1161,9 +1162,9 @@
 			continue;
 
 		ac->ac_chain = i;
-		status = ocfs_search_suballoc_chain(ac, bits_wanted, min_bits, 
-						    bit_off, num_bits, 
-						    bg_blkno);
+		status = ocfs_search_chain(ac, bits_wanted, min_bits, 
+					   bit_off, num_bits, 
+					   bg_blkno);
 		if (!status)
 			break;
 		if (status < 0 && status != -ENOSPC) {
@@ -1507,15 +1508,15 @@
 					    u32 cluster)
 {
 	ocfs_super *osb = OCFS2_SB(inode->i_sb);
-	u32 group_cluster_off;
+	u32 group_no;
 
 	OCFS_ASSERT(ocfs2_is_cluster_bitmap(inode));
 
-	/* align us to the cluster groups 1st cluster */
-	group_cluster_off = cluster / osb->bitmap_cpg;
-	if (!group_cluster_off)
+	group_no = cluster / osb->bitmap_cpg;
+	if (!group_no)
 		return osb->first_cluster_group_blkno;
-	return ocfs2_clusters_to_blocks(inode->i_sb, group_cluster_off);
+	return ocfs2_clusters_to_blocks(inode->i_sb,
+					group_no * osb->bitmap_cpg);
 }
 
 /* given the block number of a cluster start, calculate which cluster

Modified: branches/cluster-groups/src/suballoc.h
===================================================================
--- branches/cluster-groups/src/suballoc.h	2004-11-10 04:02:40 UTC (rev 1629)
+++ branches/cluster-groups/src/suballoc.h	2004-11-10 04:09:10 UTC (rev 1630)
@@ -126,7 +126,7 @@
 
 /* This is for local alloc ONLY. Others should use the task-specific
  * apis above. */
-int ocfs_reserve_suballoc_bits(ocfs_super *osb, 
-			       ocfs2_alloc_context *ac);
+int ocfs_reserve_cluster_bitmap_bits(ocfs_super *osb,
+				     ocfs2_alloc_context *ac);
 
 #endif /* _CHAINALLOC_H_ */



More information about the Ocfs2-commits mailing list