[Ocfs2-commits]
jlbec commits r1126 - in branches/format-changes: . src
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Jun 17 12:48:07 CDT 2004
Author: jlbec
Date: 2004-06-17 11:48:05 -0500 (Thu, 17 Jun 2004)
New Revision: 1126
Modified:
branches/format-changes/TODO
branches/format-changes/src/alloc.c
branches/format-changes/src/bitmap.c
branches/format-changes/src/inode.c
branches/format-changes/src/namei.c
branches/format-changes/src/ocfs.h
Log:
o Merge 1115:1122 from trunk.
- [1121] Order inode hash insertes some more.
- [1121] Remove some useless locking.
- [1122] Stop using commit_bits in local alloc.
Modified: branches/format-changes/TODO
===================================================================
--- branches/format-changes/TODO 2004-06-17 04:30:27 UTC (rev 1125)
+++ branches/format-changes/TODO 2004-06-17 16:48:05 UTC (rev 1126)
@@ -27,14 +27,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.
@@ -54,3 +46,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: branches/format-changes/src/alloc.c
===================================================================
--- branches/format-changes/src/alloc.c 2004-06-17 04:30:27 UTC (rev 1125)
+++ branches/format-changes/src/alloc.c 2004-06-17 16:48:05 UTC (rev 1126)
@@ -105,10 +105,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(ocfs2_dinode *alloc);
static void ocfs_clear_local_alloc(ocfs2_dinode *alloc);
static int ocfs_find_space_from_local(ocfs_super *osb, __u32 bitswanted,
@@ -3035,7 +3035,7 @@
/* Ok, somewhat lame, but we submit the whole bitmap for reading here*/
if (ocfs_read_bhs(osb, osb->bitmap_blkno << osb->sb->s_blocksize_bits,
bitmapblocks << osb->sb->s_blocksize_bits,
- osb->cluster_bitmap.chunk, 0, NULL)) {
+ osb->cluster_bitmap.chunk, 0, bitmap_inode)) {
LOG_ERROR_STATUS(-EIO);
goto leave;
}
@@ -3083,8 +3083,10 @@
/* Ok, write out the bitmap now. We optimize only by writing
* out the bitmap blocks which have changed, and not all of
* them like before. */
- startbh = OCFS_GLOBAL_OFF_TO_CHUNK(osb->sb, bitoffset);
- numblocks = OCFS_GLOBAL_OFF_TO_CHUNK(osb->sb, bitoffset + ClusterCount - 1) - startbh + 1;
+ numblocks = ocfs_bitmap_blocks_affected(osb->sb,
+ bitoffset,
+ ClusterCount,
+ &startbh);
LOG_TRACE_ARGS("bitoffset = %u, ClusterCount = %u, startbh = %u, numblocks = %u\n", bitoffset, ClusterCount, startbh, numblocks);
@@ -3329,8 +3331,10 @@
ocfs_set_bits(osb->sb, handle, &bitmap, foundBit, numBits);
/* only write out what has changed... */
- startbh = OCFS_GLOBAL_OFF_TO_CHUNK(osb->sb, foundBit);
- numblocks = OCFS_GLOBAL_OFF_TO_CHUNK(osb->sb, foundBit + numBits - 1) - startbh + 1;
+ numblocks = ocfs_bitmap_blocks_affected(osb->sb,
+ foundBit,
+ numBits,
+ &startbh);
LOG_TRACE_ARGS ("offset=%u, type=%x, blksz=%u, foundbit=%u, fileid=%u\n",
foundBit * blockSize, Type, blockSize, foundBit, alloc_file);
@@ -3546,27 +3550,110 @@
*
* 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,
+ ocfs2_dinode *alloc,
+ struct inode *main_bm_inode)
{
int status = 0;
int bit_off, left;
+ void *bitmap;
+ unsigned int start, numblocks, bitmapblocks;
+
+ LOG_ENTRY_ARGS("alloc->la_bm_bits = %u, COUNT = %u, la_bits_set = %u\n",
+ LOCAL_ALLOC(alloc)->la_bm_bits,
+ ocfs_alloc_count_bits(alloc),
+ LOCAL_ALLOC(alloc)->la_bits_set);
+
+ if (LOCAL_ALLOC(alloc)->la_bm_bits == 0) {
+ LOG_TRACE_STR("nothing to sync!");
+ goto bail;
+ }
+
+ bitmapblocks =
+ ocfs_blocks_for_bits(osb->sb,
+ osb->cluster_bitmap.validbits);
+
+ /* 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... */
+ numblocks = ocfs_bitmap_blocks_affected(osb->sb,
+ LOCAL_ALLOC(alloc)->la_bm_off,
+ LOCAL_ALLOC(alloc)->la_bits_set,
+ &start);
+
+ if ((start + numblocks) > bitmapblocks)
+ numblocks--;
+ if ((start + numblocks) > bitmapblocks) {
+ printk("uhoh, bitmap calculation is bad!\n");
+ printk("alloc->la_bm_bits = %u, COUNT = %u, alloc->la_bits_set = %u"
+ "start=%u, alloc->la_bm_off = %u, numblocks=%u, "
+ "bitmapblocks = %u\n",
+ LOCAL_ALLOC(alloc)->la_bm_bits, ocfs_alloc_count_bits(alloc),
+ LOCAL_ALLOC(alloc)->la_bits_set, start, LOCAL_ALLOC(alloc)->la_bm_off, numblocks,
+ bitmapblocks);
+
+ BUG();
+ }
+
+ LOG_TRACE_ARGS("start=%u, alloc->la_bm_off = %u, numblocks=%u\n", start,
+ LOCAL_ALLOC(alloc)->la_bm_off, numblocks);
+ status = ocfs_read_bhs(osb,
+ (osb->bitmap_blkno + start) << osb->sb->s_blocksize_bits,
+ numblocks << osb->sb->s_blocksize_bits,
+ &osb->cluster_bitmap.chunk[start], 0,
+ main_bm_inode);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+
+ 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 + LOCAL_ALLOC(alloc)->la_bm_off);
+ ocfs_clear_bits(osb->sb, handle, &osb->cluster_bitmap,
+ bit_off + LOCAL_ALLOC(alloc)->la_bm_off,
+ 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;
ocfs2_dinode *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 (LOCAL_ALLOC(alloc)->la_bm_bits == 0) {
@@ -3620,7 +3707,7 @@
LOG_EXIT_STATUS(status);
return(status);
-} /* ocfs_sync_local_to_main */
+} /* ocfs_sync_local_from_shutdown */
/*
* ocfs_alloc_new_window
@@ -3742,13 +3829,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,
@@ -3852,27 +3932,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;
}
@@ -4082,7 +4156,6 @@
sync ? "true" : "false",
in_recovery ? "true" : "false");
-
if (!osb->have_local_alloc && (!in_recovery))
return;
@@ -4091,7 +4164,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)
Modified: branches/format-changes/src/bitmap.c
===================================================================
--- branches/format-changes/src/bitmap.c 2004-06-17 04:30:27 UTC (rev 1125)
+++ branches/format-changes/src/bitmap.c 2004-06-17 16:48:05 UTC (rev 1126)
@@ -186,8 +186,7 @@
lastbh = ocfs_blocks_for_bits(osb->sb, globalsize) - 1;
globaloff = offset;
- c = OCFS_GLOBAL_OFF_TO_CHUNK(osb->sb, globaloff);
- localstart = OCFS_GLOBAL_OFF_TO_LOCAL(osb->sb, globaloff);
+ ocfs_bitmap_block_for_off(osb->sb, globaloff, &c, &localstart);
if (lastbh == 0)
size = globalsize;
@@ -344,8 +343,7 @@
goto bail;
}
- i = OCFS_GLOBAL_OFF_TO_CHUNK(sb, start);
- local = OCFS_GLOBAL_OFF_TO_LOCAL(sb, start);
+ ocfs_bitmap_block_for_off(sb, start, &i, &local);
currbh = bitmap->chunk[i];
status = ocfs_journal_access(handle, currbh, OCFS_JOURNAL_ACCESS_UNDO);
@@ -415,8 +413,7 @@
goto bail;
}
- i = OCFS_GLOBAL_OFF_TO_CHUNK(sb, start);
- local = OCFS_GLOBAL_OFF_TO_LOCAL(sb, start);
+ ocfs_bitmap_block_for_off(sb, start, &i, &local);
currbh = bitmap->chunk[i];
status = ocfs_journal_access(handle, currbh, OCFS_JOURNAL_ACCESS_UNDO);
Modified: branches/format-changes/src/inode.c
===================================================================
--- branches/format-changes/src/inode.c 2004-06-17 04:30:27 UTC (rev 1125)
+++ branches/format-changes/src/inode.c 2004-06-17 16:48:05 UTC (rev 1126)
@@ -715,15 +715,10 @@
FLAG_FILE_CREATE | FLAG_DIR, orphan_dir_bh,
orphan_dir_inode, 1);
- /* take ip_io_sem on the inode, only to avoid a warning in
- * acquire_lockres. We can get rid of it when we get rid of
- * acquire_lockres */
- down_write(&OCFS_I(inode)->ip_io_sem);
if (S_ISDIR(inode->i_mode))
lock_flags |= FLAG_DIR;
status = ocfs_acquire_lock(osb, OCFS_DLM_EXCLUSIVE_LOCK, lock_flags,
&fe_bh, inode);
- up_write(&OCFS_I(inode)->ip_io_sem);
if (status < 0) {
/* EBUSY here is assumed to mean that other nodes are
* still using the inode. We're done here though, so
@@ -788,10 +783,8 @@
ocfs_abort_trans(handle);
if (release_disk_lock) {
- down_write(&OCFS_I(inode)->ip_io_sem);
status = ocfs_release_lock(osb, OCFS_DLM_EXCLUSIVE_LOCK,
lock_flags, fe_bh, inode);
- up_write(&OCFS_I(inode)->ip_io_sem);
if (status < 0)
LOG_ERROR_STATUS(status);
}
Modified: branches/format-changes/src/namei.c
===================================================================
--- branches/format-changes/src/namei.c 2004-06-17 04:30:27 UTC (rev 1125)
+++ branches/format-changes/src/namei.c 2004-06-17 16:48:05 UTC (rev 1126)
@@ -246,7 +246,6 @@
fe = OCFS_BH_GET_DATA_READ(new_fe_bh);
ocfs_populate_inode (inode, fe, 1);
- insert_inode_hash (inode);
file_off = fe->i_blkno << osb->sb->s_blocksize_bits;
handle->new_file_lockid =
@@ -256,7 +255,6 @@
ocfs_init_lockres (osb, inode);
- ocfs_handle_add_inode(handle, inode);
status = ocfs_update_lockres (osb, GET_INODE_FEOFF(inode),
&new_fe_bh, NULL, 0, inode, 0, 0);
if (S_ISDIR (mode)) {
@@ -316,6 +314,7 @@
dir->i_nlink++;
}
+ insert_inode_hash (inode);
d_instantiate (dentry, inode);
ocfs_commit_trans(handle);
@@ -1354,6 +1353,9 @@
if (status < 0) {
ocfs_abort_trans(handle);
} else {
+ insert_inode_hash (inode);
+ d_instantiate (dentry, inode);
+
ocfs_commit_trans(handle);
status = ocfs_block_symlink (inode, symname, l);
if (status < 0)
@@ -1371,12 +1373,6 @@
bail:
up_write(&OCFS_I(dir)->ip_io_sem);
- /* can we race with the nm threads iget() here? */
- if (status >= 0) {
- insert_inode_hash (inode);
- d_instantiate (dentry, inode);
- }
-
if (new_fe_bh) {
if (fe)
OCFS_BH_PUT_DATA(new_fe_bh);
Modified: branches/format-changes/src/ocfs.h
===================================================================
--- branches/format-changes/src/ocfs.h 2004-06-17 04:30:27 UTC (rev 1125)
+++ branches/format-changes/src/ocfs.h 2004-06-17 16:48:05 UTC (rev 1126)
@@ -1404,6 +1404,39 @@
return (num_bits + (bits_per_chunk - 1)) / bits_per_chunk;
}
+static inline void ocfs_bitmap_block_for_off(struct super_block *sb,
+ unsigned int bm_off,
+ unsigned int *block,
+ unsigned int *block_off)
+{
+ if (block)
+ *block = bm_off / OCFS_BITS_IN_CHUNK(sb);
+
+ if (block_off)
+ *block_off = bm_off % OCFS_BITS_IN_CHUNK(sb);
+}
+
+static inline int ocfs_bitmap_blocks_affected(struct super_block *sb,
+ unsigned int start_bit,
+ unsigned int num_bits,
+ unsigned int *start_blk)
+{
+ unsigned int start_tmp, end_tmp;
+
+ ocfs_bitmap_block_for_off(sb, start_bit, &start_tmp, NULL);
+ if (start_blk)
+ *start_blk = start_tmp;
+
+ if (!num_bits)
+ return 0;
+
+ ocfs_bitmap_block_for_off(sb, start_bit + num_bits - 1,
+ &end_tmp, NULL);
+
+ return (end_tmp - start_tmp + 1);
+}
+
+
typedef struct _ocfs_journal_handle ocfs_journal_handle;
#endif /* !OCFS_H */
More information about the Ocfs2-commits
mailing list