[Ocfs2-commits] mfasheh commits r1551 - trunk/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Oct 7 15:38:47 CDT 2004


Author: mfasheh
Date: 2004-10-07 15:38:45 -0500 (Thu, 07 Oct 2004)
New Revision: 1551

Modified:
   trunk/src/journal.c
   trunk/src/localalloc.c
   trunk/src/localalloc.h
   trunk/src/super.c
Log:
* fix up local alloc shutdown and recovery to just delete main bitmaps
  bits inside of their own transaction instead of using the
  bitmap_free_head junk.



Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c	2004-10-07 16:04:20 UTC (rev 1550)
+++ trunk/src/journal.c	2004-10-07 20:38:45 UTC (rev 1551)
@@ -1567,6 +1567,7 @@
 	int status = -1;
 	int tmpstat;
 	ocfs2_dinode *fe;
+	ocfs2_dinode *local_alloc = NULL;
 	struct inode *inode = NULL;
 	journal_t *k_journal = NULL;
 	struct buffer_head *bh = NULL;
@@ -1685,7 +1686,7 @@
 	journal_destroy(k_journal);
 
 	/* recover his local alloc file, AFTER recovering his journal... */
-	status = ocfs_recover_local_alloc(osb, node_num, &bits_to_free);
+	status = ocfs_begin_local_alloc_recovery(osb, node_num, &local_alloc);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto done;
@@ -1720,6 +1721,15 @@
 	if (bh)
 		brelse(bh);
 
+	if (local_alloc && !status) {
+		tmpstat = ocfs_complete_local_alloc_recovery(osb, local_alloc);
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS(tmpstat);
+	}
+
+	if (local_alloc)
+		kfree(local_alloc);
+
 	if (clean_orphans && !status) {
 		tmpstat = ocfs_recover_orphans(osb);
 		if (tmpstat < 0)

Modified: trunk/src/localalloc.c
===================================================================
--- trunk/src/localalloc.c	2004-10-07 16:04:20 UTC (rev 1550)
+++ trunk/src/localalloc.c	2004-10-07 20:38:45 UTC (rev 1551)
@@ -69,11 +69,6 @@
 
 static void ocfs_clear_local_alloc(ocfs2_dinode *alloc);
 
-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 int ocfs_sync_local_to_main(ocfs_super *osb, 
 				   ocfs_journal_handle *handle, 
 				   ocfs2_dinode *alloc,
@@ -228,12 +223,14 @@
 void ocfs_shutdown_local_alloc(ocfs_super *osb)
 {
 	int status;
-	ocfs2_dinode *alloc = NULL;
-	ocfs_bitmap_free_head *f = NULL;
-	struct buffer_head *bh = NULL;
 	ocfs_journal_handle *handle = NULL;
 	struct inode *local_alloc_inode = NULL;
 	ocfs_inode_private *oip;
+	struct buffer_head *bh = NULL;
+	struct buffer_head *main_bm_bh = NULL;
+	struct inode *main_bm_inode = NULL;
+	ocfs2_dinode *alloc_copy = NULL;
+	ocfs2_dinode *alloc = NULL;
 
 	LOG_ENTRY();
 
@@ -258,26 +255,57 @@
 	osb->have_local_alloc = 0;
 	up_write(&oip->ip_io_sem);
 
-	bh = osb->local_alloc_bh;
+	handle = ocfs_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		LOG_ERROR_STATUS (status);
+		goto bail;
+	}
 
-	status = ocfs_sync_local_from_shutdown(osb, &f, bh, 0);
-	if (status < 0)
-		LOG_ERROR_STATUS(status);
+	main_bm_inode = ocfs_get_system_file_inode(osb, 
+						   GLOBAL_BITMAP_SYSTEM_INODE, 
+						   -1);
+	if (!main_bm_inode) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS (status);
+		goto bail;
+	}
 
-	handle = ocfs_start_trans(osb, NULL, 1);
+	status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, 
+				   0, &main_bm_bh, main_bm_inode);
+	if (status < 0) {
+		if (status != -EINTR)
+			LOG_ERROR_STATUS (status);
+		goto bail;
+	}
+	ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, 
+			     0, main_bm_inode);
+	ocfs_handle_add_inode(handle, main_bm_inode);
+
+	/* WINDOW_MOVE_CREDITS is a bit heavy... */
+	handle = ocfs_start_trans(osb, handle, OCFS_WINDOW_MOVE_CREDITS);
 	if (!handle) {
 		LOG_ERROR_STATUS(-ENOMEM);
 		goto bail;
 	}
 	ocfs_handle_set_always_commits(handle, 1);
 
+	bh = osb->local_alloc_bh;
+	alloc = (ocfs2_dinode *) bh->b_data;
+
+	alloc_copy = kmalloc(bh->b_size, GFP_KERNEL);
+	if (!alloc_copy) {
+		status = -ENOMEM;
+		goto bail;
+	}
+	memcpy(alloc_copy, alloc, bh->b_size);
+
 	status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
 
-	alloc = (ocfs2_dinode *) bh->b_data;
 	ocfs_clear_local_alloc(alloc);
 
 	status = ocfs_journal_dirty(handle, bh);
@@ -287,39 +315,45 @@
 	}
 
 	brelse(bh);
-
-	ocfs_commit_trans(handle);
-	handle = NULL;
-
 	osb->local_alloc_bh = NULL;
-	osb->have_local_alloc = 0;
 
-	if (f)
-		ocfs_process_bitmap_free_head(osb, f);
+	status = ocfs_sync_local_to_main(osb, handle, alloc_copy, 
+					 main_bm_inode, main_bm_bh);
+	if (status < 0)
+		LOG_ERROR_STATUS(status);
 
 bail:
 	if (handle)
 		ocfs_commit_trans(handle);
 
-	if (f)
-		ocfs_free_bitmap_free_head(f);
+	if (main_bm_bh)
+		brelse(main_bm_bh);
 
+	if (main_bm_inode)
+		iput(main_bm_inode);
+
 	if (local_alloc_inode)
 		iput(local_alloc_inode);
 
+	if (alloc_copy)
+		kfree(alloc_copy);
+
 	LOG_EXIT();
 	return;
 } /* ocfs_shutdown_local_alloc */
 
 /*
- * ocfs_recover_local_alloc
+ * ocfs_begin_local_alloc_recovery
  *
- * We want to free the bitmap bits outside of any recovery context, so
- * it's allocated and passed back for you.
+ * We want to free the bitmap bits outside of any recovery context as
+ * we'll need a cluster lock to do so, but we must clear the local
+ * alloc before giving up the recovered nodes journal. To solve this,
+ * we kmalloc a copy of the local alloc before it's change for the
+ * caller to process with ocfs_complete_local_alloc_recovery
  */
-int ocfs_recover_local_alloc(ocfs_super *osb, 
-			     int node_num, 
-			     ocfs_bitmap_free_head **bits_to_free)
+int ocfs_begin_local_alloc_recovery(ocfs_super *osb, 
+				    int node_num, 
+				    ocfs2_dinode **alloc_copy)
 {
 	int status = 0;
 	struct buffer_head *alloc_bh = NULL;
@@ -328,6 +362,8 @@
 
 	LOG_ENTRY_ARGS("(node_num = %d)\n", node_num);
 
+	*alloc_copy = NULL;
+
 	inode = ocfs_get_system_file_inode(osb, 
 					   LOCAL_ALLOC_SYSTEM_INODE, 
 					   node_num);
@@ -343,14 +379,12 @@
 		goto bail;
 	}
 
-	status = ocfs_sync_local_from_shutdown(osb, 
-					       bits_to_free, 
-					       alloc_bh, 
-					       1);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
+	*alloc_copy = kmalloc(alloc_bh->b_size, GFP_KERNEL);
+	if (!(*alloc_copy)) {
+		status = -ENOMEM;
 		goto bail;
 	}
+	memcpy((*alloc_copy), alloc_bh->b_data, alloc_bh->b_size);
 
 	alloc = (ocfs2_dinode *) alloc_bh->b_data;
 	ocfs_clear_local_alloc(alloc);
@@ -360,6 +394,11 @@
 		LOG_ERROR_STATUS(status);
 
 bail:
+	if ((status < 0) && (*alloc_copy)) {
+		kfree(*alloc_copy);
+		*alloc_copy = NULL;
+	}
+
 	if (alloc_bh)
 		brelse(alloc_bh);
 
@@ -368,8 +407,79 @@
 
 	LOG_EXIT_STATUS(status);
 	return(status);
-} /* ocfs_recover_local_alloc */
+} /* ocfs_begin_local_alloc_recovery */
 
+/*
+ * Step 2: By now, we've completed the journal recovery, we've stamped
+ * a clean local alloc on disk and dropped the node out of the
+ * recovery map. Dlm locks will no longer stall, so lets clear out the
+ * main bitmap.
+ */
+int ocfs_complete_local_alloc_recovery(ocfs_super *osb, 
+				       ocfs2_dinode *alloc)
+{
+	int status;
+	ocfs_journal_handle *handle = NULL;
+	struct buffer_head *main_bm_bh = NULL;
+	struct inode *main_bm_inode = NULL;
+
+	LOG_ENTRY();
+
+	handle = ocfs_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		LOG_ERROR_STATUS (status);
+		goto bail;
+	}
+
+	main_bm_inode = ocfs_get_system_file_inode(osb, 
+						   GLOBAL_BITMAP_SYSTEM_INODE, 
+						   -1);
+	if (!main_bm_inode) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS (status);
+		goto bail;
+	}
+
+	status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, 
+				   0, &main_bm_bh, main_bm_inode);
+	if (status < 0) {
+		if (status != -EINTR)
+			LOG_ERROR_STATUS (status);
+		goto bail;
+	}
+	ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, 
+			     0, main_bm_inode);
+	ocfs_handle_add_inode(handle, main_bm_inode);
+
+	handle = ocfs_start_trans(osb, handle, OCFS_WINDOW_MOVE_CREDITS);
+	if (!handle) {
+		LOG_ERROR_STATUS(status = -ENOMEM);
+		goto bail;
+	}
+	ocfs_handle_set_always_commits(handle, 1);
+	/* we want the bitmap change to be recorded on disk asap */
+	ocfs_handle_set_sync(handle, 1);
+
+	status = ocfs_sync_local_to_main(osb, handle, alloc, 
+					 main_bm_inode, main_bm_bh);
+	if (status < 0)
+		LOG_ERROR_STATUS(status);
+
+bail:
+	if (handle)
+		ocfs_commit_trans(handle);
+
+	if (main_bm_bh)
+		brelse(main_bm_bh);
+
+	if (main_bm_inode)
+		iput(main_bm_inode);
+
+	LOG_EXIT_STATUS(status);
+	return status;
+}
+
 /* 
  * ocfs_reserve_local_alloc_bits
  *
@@ -614,74 +724,6 @@
 	return;
 } /* ocfs_clear_local_alloc */
 
-/*
- * 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;
-	ocfs2_dinode *alloc = NULL;
-	void *bitmap;
-
-	LOG_ENTRY();
-
-	if (!local_alloc_bh)
-		BUG();
-
-	alloc = (ocfs2_dinode *) local_alloc_bh->b_data;
-	if (LOCAL_ALLOC(alloc)->la_bm_bits == 0) {
-		LOG_TRACE_STR("nothing to sync!");
-		goto bail;
-	}
-
-	if (!(*f)) {
-		*f = ocfs_alloc_bitmap_free_head();
-		if (*f == NULL) {
-			LOG_ERROR_STATUS(-ENOMEM);
-			goto bail;
-		}
-	}
-
-	alloc = (ocfs2_dinode *) local_alloc_bh->b_data;
-
-	LOG_TRACE_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);
-
-	bitmap = LOCAL_ALLOC(alloc)->la_bitmap;
-
-	/* any unset bits in local alloc need to be unset in bitmap. */
-	bit_off = 0;
-	left = LOCAL_ALLOC(alloc)->la_bm_bits;
-	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);*/
-		status = ocfs_add_to_bitmap_free_head(osb, 
-						 *f, 1, 
-						 bit_off + LOCAL_ALLOC(alloc)->la_bm_off,
-						 -1, 0, DISK_ALLOC_VOLUME);
-		if (status < 0) {
-			ocfs_free_bitmap_free_head(*f);
-			*f = NULL;
-		}
-		bit_off++;
-	}
-
-bail:
-	LOG_EXIT_STATUS(status);
-	return(status);
-} /* ocfs_sync_local_from_shutdown */
-
 /* 
  * ocfs_sync_local_to_main
  *
@@ -905,15 +947,6 @@
 
 	LOG_ENTRY();
 
-	main_bm_inode = ocfs_get_system_file_inode(osb, 
-						   GLOBAL_BITMAP_SYSTEM_INODE, 
-						   -1);
-	if (!main_bm_inode) {
-		status = -EINVAL;
-		LOG_ERROR_STATUS (status);
-		goto bail;
-	}
-
 	handle = ocfs_alloc_handle(osb);
 	if (!handle) {
 		status = -ENOMEM;
@@ -951,6 +984,7 @@
 	alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_KERNEL);
 	if (!alloc_copy) {
 		status = -ENOMEM;
+		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
 	memcpy(alloc_copy, alloc, osb->local_alloc_bh->b_size);

Modified: trunk/src/localalloc.h
===================================================================
--- trunk/src/localalloc.h	2004-10-07 16:04:20 UTC (rev 1550)
+++ trunk/src/localalloc.h	2004-10-07 20:38:45 UTC (rev 1551)
@@ -33,10 +33,13 @@
 
 void ocfs_shutdown_local_alloc(ocfs_super *osb);
 
-int ocfs_recover_local_alloc(ocfs_super *osb, 
-			     int node_num, 
-			     ocfs_bitmap_free_head **bits_to_free);
+int ocfs_begin_local_alloc_recovery(ocfs_super *osb, 
+				    int node_num, 
+				    ocfs2_dinode **alloc_copy);
 
+int ocfs_complete_local_alloc_recovery(ocfs_super *osb, 
+				       ocfs2_dinode *alloc);
+
 int ocfs_alloc_should_use_local(ocfs_super *osb, 
 				u64 bits);
 

Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c	2004-10-07 16:04:20 UTC (rev 1550)
+++ trunk/src/super.c	2004-10-07 20:38:45 UTC (rev 1551)
@@ -1830,9 +1830,9 @@
 	int node_num = osb->node_num;
 	struct buffer_head * publish_bh = NULL;
 	int mounted;
-	ocfs_bitmap_free_head *bits_to_free = NULL; /* only used if we
-						     * recover
-						     * ourselves. */
+	ocfs2_dinode *local_alloc = NULL; /* only used if we
+					   * recover
+					   * ourselves. */
 
 	LOG_ENTRY ();
 
@@ -1876,13 +1876,15 @@
 
 	if (mounted) {
 		/* recover my local alloc if we didn't unmount cleanly. */
-		status = ocfs_recover_local_alloc(osb, 
-						  node_num, 
-						  &bits_to_free);
+		status = ocfs_begin_local_alloc_recovery(osb,
+							 node_num,
+							 &local_alloc);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			goto finally;
 		}
+		/* we complete the recovery process after we've marked
+		 * ourselves as mounted. */
 	}
 
 	/* 'mounted' flag in publish sector should not be set until
@@ -1897,21 +1899,24 @@
 		LOG_ERROR_STATUS(status);
 
 	if (mounted) {
+		status = ocfs_complete_local_alloc_recovery(osb, local_alloc);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto finally;
+		}
+
 		status = ocfs_recover_orphans(osb);
 		if (status < 0)
 			LOG_ERROR_STATUS(status);
 	}
 
 finally:
+	if (local_alloc)
+		kfree(local_alloc);
+
 	if (publish_bh)
 		brelse(publish_bh);
 
-	if (bits_to_free) {
-		if (!status)
-			ocfs_process_bitmap_free_head(osb, bits_to_free);
-		ocfs_free_bitmap_free_head(bits_to_free);
-	}
-
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_check_volume */



More information about the Ocfs2-commits mailing list