[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