[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