[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