[Ocfs2-commits] mfasheh commits r1122 - in trunk: . src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Jun 16 22:00:33 CDT 2004


Author: mfasheh
Date: 2004-06-16 21:00:31 -0500 (Wed, 16 Jun 2004)
New Revision: 1122

Modified:
   trunk/TODO
   trunk/src/alloc.c
Log:
* Local alloc code doesn't use the commit_bits on the journal handle
  any more. This gives us a performance boost, plus cleans up a few
  things.



Modified: trunk/TODO
===================================================================
--- trunk/TODO	2004-06-17 01:17:45 UTC (rev 1121)
+++ trunk/TODO	2004-06-17 02:00:31 UTC (rev 1122)
@@ -33,14 +33,6 @@
   values when the inode is passed in too (example: make acquire_lock not take
   an offset, as you get that off the inode which is passed in).
 
-* Clean up the local alloc path a bit. Specifically the part in
-  find_space_from_local where we take the main bitmap lock a bit early... We
-  can probably eliminate that and just let it get taken later...
-
-* Local alloc code can be slightly revamped to not use the commit_bits on
-  the journal handle any more. Also, investigate whether we can use the
-  "undo" access flag on that bitmap.
-
 * Local alloc structure needs to be turned into a file entry so creating an
   inode for it is trivial. This way we can use the inodes locking primitives
   instead of special casing stuff and using osb->local_alloc_sem.
@@ -58,3 +50,5 @@
 * change the dirent->inode to block number... it's in bytes currently
 
 * turn priv_sem into a spinlock
+
+* need to move the commit_bits stuff outside of the journalling code

Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c	2004-06-17 01:17:45 UTC (rev 1121)
+++ trunk/src/alloc.c	2004-06-17 02:00:31 UTC (rev 1122)
@@ -82,10 +82,10 @@
 static int ocfs_alloc_new_window(ocfs_super *osb, struct buffer_head *lock_bh,
 				 struct inode *bm_inode,
 				 ocfs_journal_handle *handle);
-static int ocfs_sync_local_to_main(ocfs_super *osb, 
-				   ocfs_bitmap_free_head **f, 
-				   struct buffer_head *local_alloc_bh, 
-				   int in_recovery);
+static int ocfs_sync_local_from_shutdown(ocfs_super *osb, 
+					 ocfs_bitmap_free_head **f, 
+					 struct buffer_head *local_alloc_bh, 
+					 int in_recovery);
 static __u32 ocfs_alloc_count_bits(ocfs_local_alloc *alloc);
 static void ocfs_clear_local_alloc(ocfs_local_alloc *alloc);
 static int ocfs_find_space_from_local(ocfs_super *osb, __u32 bitswanted, 
@@ -2817,7 +2817,7 @@
 	/* Ok, somewhat lame, but we submit the whole bitmap for reading here*/
 	if (ocfs_read_bhs(osb, osb->vol_layout.bitmap_off, 
 			  bitmapblocks * osb->sect_size, 
-			  osb->cluster_bitmap.chunk, 0, NULL)) {
+			  osb->cluster_bitmap.chunk, 0, bitmap_inode)) {
 		LOG_ERROR_STATUS(-EIO);
 		goto leave;
 	}
@@ -3282,27 +3282,103 @@
  *
  * sync the local alloc to main bitmap. 
  *
- * 'osb' and 'f' are always assumed to be valid (though they don't
- * have to be allocated)
- *
- * local_alloc_bh is optional. If not passed, we use the one off osb.
- *
- * bm_lock_bh should be passed in if you've already locked the main
- * bitmap, otherwise we'll do our own locking. */
+ * assumes you've already locked the main bitmap -- the bitmap inode
+ * passed is used for caching.
+ */
 static int ocfs_sync_local_to_main(ocfs_super *osb, 
-				   ocfs_bitmap_free_head **f, 
-				   struct buffer_head *local_alloc_bh, 
-				   int in_recovery)
+				   ocfs_journal_handle *handle, 
+				   ocfs_local_alloc *alloc,
+				   struct inode *main_bm_inode)
 {
 	int status = 0;
 	int bit_off, left;
+	void *bitmap;
+	unsigned int start, numblocks, bitmapblocks;
+
+	LOG_ENTRY_ARGS("alloc->alloc_size = %u, COUNT = %u, num_used = %u\n", 
+		       alloc->alloc_size, ocfs_alloc_count_bits(alloc), 
+		       alloc->num_used);
+
+	if (alloc->alloc_size == 0) {
+		LOG_TRACE_STR("nothing to sync!");
+		goto bail;
+	}
+
+	bitmapblocks = (OCFS_ALIGN(osb->cluster_bitmap.validbits, 
+				   OCFS_BITS_IN_CHUNK) / OCFS_BITS_IN_CHUNK);
+	/* figure out which block in the bitmap to start on and the
+	 * maximum number of blocks we can span over -- we don't need
+	 * to read any more as that's the most we'll be touching... */
+	start = OCFS_GLOBAL_OFF_TO_CHUNK(alloc->bitmap_start);
+	numblocks = 2 + OCFS_GLOBAL_OFF_TO_CHUNK(alloc->bitmap_start + alloc->alloc_size) - start;
+
+	if ((start + numblocks) > bitmapblocks)
+		numblocks--;
+	if ((start + numblocks) > bitmapblocks) {
+		printk("uhoh, bitmap calculation is bad!\n");
+		printk("alloc->alloc_size = %u, COUNT = %u, num_used = %u"
+		       "start=%u, bitmap_start = %u, numblocks=%u, "
+		       "bitmapblocks = %u\n",
+		       alloc->alloc_size, ocfs_alloc_count_bits(alloc), 
+		       alloc->num_used, start, alloc->bitmap_start, numblocks,
+		       bitmapblocks);
+
+		BUG();
+	}
+
+	LOG_TRACE_ARGS("start=%u, bitmap_start = %u, numblocks=%u\n", start, 
+		       alloc->bitmap_start, numblocks);
+	status = ocfs_read_bhs(osb, osb->vol_layout.bitmap_off,
+			       numblocks * osb->sect_size,
+			       &osb->cluster_bitmap.chunk[start], 0, 
+			       main_bm_inode);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	bitmap = alloc->bitmap;
+	/* any unset bits in local alloc need to be unset in bitmap. */
+	bit_off = 0;
+	left = alloc->alloc_size;
+	while ((bit_off = find_next_zero_bit(bitmap, left, bit_off)) 
+	       != -1) {
+		if (bit_off >= left) {
+			/*LOG_TRACE_ARGS("bit_off (%d) >= left\n", bit_off);*/
+			break;
+		}
+
+		LOG_TRACE_ARGS("Clearing bit %u in main bitmap\n", 
+			       bit_off + alloc->bitmap_start);
+		ocfs_clear_bits(handle, &osb->cluster_bitmap, 
+				bit_off + alloc->bitmap_start, 1);
+		bit_off++;
+	}
+
+bail:
+
+	LOG_EXIT_STATUS(status);
+	return(status);
+} /* ocfs_sync_local_to_main */
+
+/*
+ * This essentially does the same thing as sync_local_to_main, but
+ * without a journal handle -- used during shutdown and recovery.
+ */
+static int ocfs_sync_local_from_shutdown(ocfs_super *osb, 
+					   ocfs_bitmap_free_head **f, 
+					   struct buffer_head *local_alloc_bh, 
+					   int in_recovery)
+{
+	int status = 0;
+	int bit_off, left;
 	ocfs_local_alloc *alloc = NULL;
 	void *bitmap;
 
 	LOG_ENTRY();
 
 	if (!local_alloc_bh)
-		local_alloc_bh = osb->local_alloc_bh;
+		BUG();
 
 	alloc = OCFS_BH_GET_DATA_READ(local_alloc_bh);
 	if (alloc->alloc_size == 0) {
@@ -3355,7 +3431,7 @@
 
 	LOG_EXIT_STATUS(status);
 	return(status);
-} /* ocfs_sync_local_to_main */
+} /* ocfs_sync_local_from_shutdown */
 
 /*
  * ocfs_alloc_new_window
@@ -3473,13 +3549,6 @@
 
 /*
  * ocfs_find_space_from_local
- *
- * We're somewhat sensitive to aborts here. If we're moving our
- * window, or shutting down due to error, we skip our own journal
- * handling and send the buffer straight to jbd. This ensures that if
- * we abort_trans during one of those operations, it still gets
- * written out. This way, the code above us can always process our
- * bitmap free head, and our latest window will always hit disk.
  */
 static int ocfs_find_space_from_local(ocfs_super *osb, __u32 bitswanted, 
 				      __u64 * bitoff, __u64 * bitcount, 
@@ -3583,27 +3652,21 @@
 		ocfs_handle_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK, 0,
 				      main_bm_bh, main_bm_inode, 1);
 
-		status = ocfs_sync_local_to_main(osb, &(handle->commit_bits),
-						 NULL, 0);
+
+		alloc = OCFS_BH_GET_DATA_WRITE(osb->local_alloc_bh);
+
+		status = ocfs_sync_local_to_main(osb, handle, alloc,
+						 main_bm_inode);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			goto bail;
 		}
 
-		alloc = OCFS_BH_GET_DATA_WRITE(osb->local_alloc_bh);
-
 		ocfs_clear_local_alloc(alloc);
 
 		OCFS_BH_PUT_DATA(osb->local_alloc_bh);
 		alloc = NULL;
 
-		/* Ok, if we move our window, we have to make sure
-		 * that this transaction is a sync one, as we don't
-		 * want to crash after having free'd the main bitmap
-		 * bits and on replay have an old copy of the local
-		 * alloc put back! */
-		ocfs_handle_set_sync(handle, 1);
-
 		alloc = OCFS_BH_GET_DATA_WRITE(osb->local_alloc_bh);
 		goto tryagain;
 	}
@@ -3803,7 +3866,6 @@
 		       sync ? "true" : "false",
 		       in_recovery ? "true" : "false");
 
-
 	if (!osb->have_local_alloc && (!in_recovery))
 		return;
 
@@ -3812,7 +3874,7 @@
 	else
 		bh = osb->local_alloc_bh;
 
-	status = ocfs_sync_local_to_main(osb, &f, bh, in_recovery);
+	status = ocfs_sync_local_from_shutdown(osb, &f, bh, in_recovery);
 	if (status < 0)
 		LOG_ERROR_STATUS(status);
 	else if (f)



More information about the Ocfs2-commits mailing list