Hi,
On Wed, Jul 12, 2000 at 07:12:39PM +0200, Juan J. Quintela wrote:
Hi
I have ported Stephen patch from 2.2.8 to 2.4, but now I have
contention in the inode bitmaps. Can I use the same trick
there that he used in the block bitmap???
I've attached the patch I did for 2.3.99-pre7. It uses a much simpler
trick for inodes: it just drops the lock while waiting in the
read_inode_bitmap functions and retakes it after IO. That means that
the lock is still held for the duration of the allocation of the
inode, but that's a much rarer and also a much more lightweight
operation than block allocation, so it should work fine.
Cheers,
Stephen
--- linux-2.3.99/fs/ext2/balloc.c.~1~ Wed Mar 29 22:35:22 2000
+++ linux-2.3.99/fs/ext2/balloc.c Wed May 3 16:49:04 2000
@@ -9,6 +9,13 @@
* Enhanced block allocation by Stephen Tweedie ([EMAIL PROTECTED]), 1993
* Big-endian to little-endian byte-swapping/bitmaps by
*David S. Miller ([EMAIL PROTECTED]), 1995
+ *
+ * Dropped use of the superblock lock.
+ * This means that we have to take extra care not to block between any
+ * operations on the bitmap and the corresponding update to the group
+ * descriptors.
+ * Stephen C. Tweedie ([EMAIL PROTECTED]), 1999
+ *
*/
#include linux/config.h
@@ -16,7 +23,6 @@
#include linux/locks.h
#include linux/quotaops.h
-
/*
* balloc.c contains the blocks allocation and deallocation routines
*/
@@ -70,42 +76,33 @@
}
/*
- * Read the bitmap for a given block_group, reading into the specified
- * slot in the superblock's bitmap cache.
+ * Read the bitmap for a given block_group.
*
- * Return =0 on success or a -ve error code.
+ * Return the buffer_head on success or NULL on IO error.
*/
-static int read_block_bitmap (struct super_block * sb,
- unsigned int block_group,
- unsigned long bitmap_nr)
+static struct buffer_head * read_block_bitmap (struct super_block * sb,
+unsigned int block_group)
{
struct ext2_group_desc * gdp;
struct buffer_head * bh = NULL;
- int retval = -EIO;
gdp = ext2_get_group_desc (sb, block_group, NULL);
if (!gdp)
- goto error_out;
- retval = 0;
+ return NULL;
+
bh = bread (sb-s_dev, le32_to_cpu(gdp-bg_block_bitmap), sb-s_blocksize);
if (!bh) {
ext2_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
"block_group = %d, block_bitmap = %lu",
block_group, (unsigned long) gdp-bg_block_bitmap);
- retval = -EIO;
+ return NULL;
}
- /*
-* On IO error, just leave a zero in the superblock's block pointer for
-* this group. The IO will be retried next time.
-*/
-error_out:
- sb-u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group;
- sb-u.ext2_sb.s_block_bitmap[bitmap_nr] = bh;
- return retval;
+ return bh;
}
+
/*
* load_block_bitmap loads the block bitmap for a blocks group
*
@@ -122,9 +119,9 @@
static int __load_block_bitmap (struct super_block * sb,
unsigned int block_group)
{
- int i, j, retval = 0;
+ int i, j;
unsigned long block_bitmap_number;
- struct buffer_head * block_bitmap;
+ struct buffer_head * block_bitmap, *cached_bitmap = NULL;
if (block_group = sb-u.ext2_sb.s_groups_count)
ext2_panic (sb, "load_block_bitmap",
@@ -132,27 +129,34 @@
"block_group = %d, groups_count = %lu",
block_group, sb-u.ext2_sb.s_groups_count);
+ retry:
if (sb-u.ext2_sb.s_groups_count = EXT2_MAX_GROUP_LOADED) {
if (sb-u.ext2_sb.s_block_bitmap[block_group]) {
if (sb-u.ext2_sb.s_block_bitmap_number[block_group] ==
- block_group)
+ block_group) {
+ brelse(cached_bitmap);
return block_group;
+ }
ext2_error (sb, "__load_block_bitmap",
"block_group != block_bitmap_number");
}
- retval = read_block_bitmap (sb, block_group, block_group);
- if (retval 0)
- return retval;
+ if (!cached_bitmap)
+ goto load;
+ sb-u.ext2_sb.s_block_bitmap_number[block_group] = block_group;
+ sb-u.ext2_sb.s_block_bitmap[block_group] = cached_bitmap;
return block_group;
}
for (i = 0; i sb-u.ext2_sb.s_loaded_block_bitmaps
sb-u.ext2_sb.s_block_bitmap_number[i] != block_group; i++)
;
+
+ /*