Skip to contentSkip to conversation

Remove ext2's buffer_head cache

PATCH In review Andrew Morton 1 participant 1 message Jul 4, 2002 ext2 file system

lore
Share & tools
lore
#0 lore raw

PATCH 4/27 Remove ext2's buffer_head cache

Remove ext2's open-coded bitmap LRUs. Core kernel does this for it now.

 fs/ext2/balloc.c           |  162 +++++++++++++------------------------------
 fs/ext2/ialloc.c           |  166 +++++++++++++++------------------------------
 fs/ext2/super.c            |   14 ---
 include/linux/ext2_fs_sb.h |   14 ---
 4 files changed, 107 insertions(+), 249 deletions(-)
fs/ext2/balloc.c renamed from fs/ext2/balloc.c~ext2-lrus +51 -111
@@ -75,9 +75,8 @@ struct ext2_group_desc * ext2_get_group_
  *
  * Return buffer_head on success or NULL in case of failure.
  */
-
-static struct buffer_head *read_block_bitmap(struct super_block *sb,
-						unsigned int block_group)
+static struct buffer_head *
+read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
 	struct ext2_group_desc * desc;
 	struct buffer_head * bh = NULL;
@@ -95,78 +94,6 @@ error_out:
 	return bh;
 }
 
-/*
- * load_block_bitmap loads the block bitmap for a blocks group
- *
- * It maintains a cache for the last bitmaps loaded.  This cache is managed
- * with a LRU algorithm.
- *
- * Notes:
- * 1/ There is one cache per mounted file system.
- * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
- *    this function reads the bitmap without maintaining a LRU cache.
- * 
- * Return the buffer_head of the bitmap or ERR_PTR(-ve).
- */
-static struct buffer_head *load_block_bitmap(struct super_block * sb,
-						unsigned int block_group)
-{
-	struct ext2_sb_info *sbi = EXT2_SB(sb);
-	int i, slot = 0;
-	struct buffer_head *bh = sbi->s_block_bitmap[0];
-
-	if (block_group >= sbi->s_groups_count)
-		ext2_panic (sb, "load_block_bitmap",
-			    "block_group >= groups_count - "
-			    "block_group = %d, groups_count = %lu",
-			    block_group, sbi->s_groups_count);
-	
-	/*
-	 * Do the lookup for the slot.  First of all, check if we're asking
-	 * for the same slot as last time, and did we succeed that last time?
-	 */
-	if (sbi->s_loaded_block_bitmaps > 0 &&
-	    sbi->s_block_bitmap_number[0] == block_group && bh)
-		goto found;
-
-	if (sbi->s_groups_count <= EXT2_MAX_GROUP_LOADED) {
-		slot = block_group;
-		bh = sbi->s_block_bitmap[slot];
-		if (!bh)
-			goto read_it;
-		if (sbi->s_block_bitmap_number[slot] == slot)
-			goto found;
-		ext2_panic (sb, "load_block_bitmap",
-			    "block_group != block_bitmap_number");
-	}
-
-	bh = NULL;
-	for (i = 0; i < sbi->s_loaded_block_bitmaps &&
-		    sbi->s_block_bitmap_number[i] != block_group; i++)
-		;
-	if (i < sbi->s_loaded_block_bitmaps)
-		bh = sbi->s_block_bitmap[i];
-	else if (sbi->s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED)
-		sbi->s_loaded_block_bitmaps++;
-	else
-		brelse (sbi->s_block_bitmap[--i]);
-
-	while (i--) {
-		sbi->s_block_bitmap_number[i+1] = sbi->s_block_bitmap_number[i];
-		sbi->s_block_bitmap[i+1] = sbi->s_block_bitmap[i];
-	}
-
-read_it:
-	if (!bh)
-		bh = read_block_bitmap(sb, block_group);
-	sbi->s_block_bitmap_number[slot] = block_group;
-	sbi->s_block_bitmap[slot] = bh;
-	if (!bh)
-		return ERR_PTR(-EIO);
-found:
-	return bh;
-}
-
 static inline int reserve_blocks(struct super_block *sb, int count)
 {
 	struct ext2_sb_info * sbi = EXT2_SB(sb);
@@ -238,7 +165,7 @@ static inline void group_release_blocks(
 void ext2_free_blocks (struct inode * inode, unsigned long block,
 		       unsigned long count)
 {
-	struct buffer_head * bh;
+	struct buffer_head *bitmap_bh = NULL;
 	struct buffer_head * bh2;
 	unsigned long block_group;
 	unsigned long bit;
@@ -275,8 +202,9 @@ do_more:
 		overflow = bit + count - EXT2_BLOCKS_PER_GROUP(sb);
 		count -= overflow;
 	}
-	bh = load_block_bitmap (sb, block_group);
-	if (IS_ERR(bh))
+	brelse(bitmap_bh);
+	bitmap_bh = read_block_bitmap(sb, block_group);
+	if (!bitmap_bh)
 		goto error_return;
 
 	desc = ext2_get_group_desc (sb, block_group, &bh2);
@@ -295,7 +223,7 @@ do_more:
 			    block, count);
 
 	for (i = 0, group_freed = 0; i < count; i++) {
-		if (!ext2_clear_bit (bit + i, bh->b_data))
+		if (!ext2_clear_bit(bit + i, bitmap_bh->b_data))
 			ext2_error (sb, "ext2_free_blocks",
 				      "bit already cleared for block %lu",
 				      block + i);
@@ -303,10 +231,10 @@ do_more:
 			group_freed++;
 	}
 
-	mark_buffer_dirty(bh);
+	mark_buffer_dirty(bitmap_bh);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
+		ll_rw_block(WRITE, 1, &bitmap_bh);
+		wait_on_buffer(bitmap_bh);
 	}
 
 	group_release_blocks(desc, bh2, group_freed);
@@ -318,6 +246,7 @@ do_more:
 		goto do_more;
 	}
 error_return:
+	brelse(bitmap_bh);
 	release_blocks(sb, freed);
 	unlock_super (sb);
 	DQUOT_FREE_BLOCK(inode, freed);
@@ -384,7 +313,7 @@ got_it:
 int ext2_new_block (struct inode * inode, unsigned long goal,
     u32 * prealloc_count, u32 * prealloc_block, int * err)
 {
-	struct buffer_head *bh;
+	struct buffer_head *bitmap_bh = NULL;
 	struct buffer_head *bh2;
 	struct ext2_group_desc *desc;
 	int i, j, k, tmp;
@@ -431,13 +360,14 @@ int ext2_new_block (struct inode * inode
 	group_alloc = group_reserve_blocks(desc, bh2, es_alloc);
 	if (group_alloc) {
 		j = ((goal - le32_to_cpu(es->s_first_data_block)) % group_size);
-		bh = load_block_bitmap (sb, i);
-		if (IS_ERR(bh))
+		brelse(bitmap_bh);
+		bitmap_bh = read_block_bitmap(sb, i);
+		if (!bitmap_bh)
 			goto io_error;
 		
 		ext2_debug ("goal is at %d:%d.\n", i, j);
 
-		j = grab_block(bh->b_data, group_size, j);
+		j = grab_block(bitmap_bh->b_data, group_size, j);
 		if (j >= 0)
 			goto got_block;
 		group_release_blocks(desc, bh2, group_alloc);
@@ -461,11 +391,12 @@ int ext2_new_block (struct inode * inode
 	}
 	if (k >= sbi->s_groups_count)
 		goto out_release;
-	bh = load_block_bitmap (sb, i);
-	if (IS_ERR(bh))
+	brelse(bitmap_bh);
+	bitmap_bh = read_block_bitmap(sb, i);
+	if (!bitmap_bh)
 		goto io_error;
 	
-	j = grab_block(bh->b_data, group_size, 0);
+	j = grab_block(bitmap_bh->b_data, group_size, 0);
 	if (j < 0) {
 		ext2_error (sb, "ext2_new_block",
 			    "Free blocks count corrupted for block group %d", i);
@@ -510,7 +441,7 @@ got_block:
 		unsigned n;
 
 		for (n = 0; n < group_alloc && ++j < group_size; n++) {
-			if (ext2_set_bit (j, bh->b_data))
+			if (ext2_set_bit(j, bitmap_bh->b_data))
  				break;
 		}
 		*prealloc_block = block + 1;
@@ -521,10 +452,10 @@ got_block:
 	}
 	write_unlock(&EXT2_I(inode)->i_meta_lock);
 
-	mark_buffer_dirty(bh);
+	mark_buffer_dirty(bitmap_bh);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
+		ll_rw_block(WRITE, 1, &bitmap_bh);
+		wait_on_buffer(bitmap_bh);
 	}
 
 	ext2_debug ("allocating block %d. ", block);
@@ -537,6 +468,7 @@ out_unlock:
 	unlock_super (sb);
 	DQUOT_FREE_BLOCK(inode, dq_alloc);
 out:
+	brelse(bitmap_bh);
 	return block;
 
 io_error:
@@ -558,19 +490,20 @@ unsigned long ext2_count_free_blocks (st
 	bitmap_count = 0;
 	desc = NULL;
 	for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
-		struct buffer_head *bh;
+		struct buffer_head *bitmap_bh;
 		desc = ext2_get_group_desc (sb, i, NULL);
 		if (!desc)
 			continue;
 		desc_count += le16_to_cpu(desc->bg_free_blocks_count);
-		bh = load_block_bitmap (sb, i);
-		if (IS_ERR(bh))
+		bitmap_bh = read_block_bitmap(sb, i);
+		if (!bitmap_bh)
 			continue;
 		
-		x = ext2_count_free (bh, sb->s_blocksize);
+		x = ext2_count_free(bitmap_bh, sb->s_blocksize);
 		printk ("group %d: stored = %d, counted = %lu\n",
 			i, le16_to_cpu(desc->bg_free_blocks_count), x);
 		bitmap_count += x;
+		brelse(bitmap_bh);
 	}
 	printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",
 	       le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count);
@@ -645,7 +578,7 @@ unsigned long ext2_bg_num_gdb(struct sup
 /* Called at mount-time, super-block is locked */
 void ext2_check_blocks_bitmap (struct super_block * sb)
 {
-	struct buffer_head * bh;
+	struct buffer_head *bitmap_bh = NULL;
 	struct ext2_super_block * es;
 	unsigned long desc_count, bitmap_count, x, j;
 	unsigned long desc_blocks;
@@ -661,38 +594,43 @@ void ext2_check_blocks_bitmap (struct su
 		if (!desc)
 			continue;
 		desc_count += le16_to_cpu(desc->bg_free_blocks_count);
-		bh = load_block_bitmap (sb, i);
-		if (IS_ERR(bh))
+		brelse(bitmap_bh);
+		bitmap_bh = read_block_bitmap(sb, i);
+		if (!bitmap_bh)
 			continue;
 
-		if (ext2_bg_has_super(sb, i) && !ext2_test_bit(0, bh->b_data))
+		if (ext2_bg_has_super(sb, i) &&
+				!ext2_test_bit(0, bitmap_bh->b_data))
 			ext2_error(sb, __FUNCTION__,
 				   "Superblock in group %d is marked free", i);
 
 		desc_blocks = ext2_bg_num_gdb(sb, i);
 		for (j = 0; j < desc_blocks; j++)
-			if (!ext2_test_bit(j + 1, bh->b_data))
+			if (!ext2_test_bit(j + 1, bitmap_bh->b_data))
 				ext2_error(sb, __FUNCTION__,
 					   "Descriptor block #%ld in group "
 					   "%d is marked free", j, i);
 
-		if (!block_in_use (le32_to_cpu(desc->bg_block_bitmap), sb, bh->b_data))
-			ext2_error (sb, "ext2_check_blocks_bitmap",
+		if (!block_in_use(le32_to_cpu(desc->bg_block_bitmap),
+					sb, bitmap_bh->b_data))
+			ext2_error(sb, "ext2_check_blocks_bitmap",
 				    "Block bitmap for group %d is marked free",
 				    i);
 
-		if (!block_in_use (le32_to_cpu(desc->bg_inode_bitmap), sb, bh->b_data))
-			ext2_error (sb, "ext2_check_blocks_bitmap",
+		if (!block_in_use(le32_to_cpu(desc->bg_inode_bitmap),
+					sb, bitmap_bh->b_data))
+			ext2_error(sb, "ext2_check_blocks_bitmap",
 				    "Inode bitmap for group %d is marked free",
 				    i);
 
 		for (j = 0; j < EXT2_SB(sb)->s_itb_per_group; j++)
-			if (!block_in_use (le32_to_cpu(desc->bg_inode_table) + j, sb, bh->b_data))
+			if (!block_in_use(le32_to_cpu(desc->bg_inode_table) + j,
+						sb, bitmap_bh->b_data))
 				ext2_error (sb, "ext2_check_blocks_bitmap",
 					    "Block #%ld of the inode table in "
 					    "group %d is marked free", j, i);
 
-		x = ext2_count_free (bh, sb->s_blocksize);
+		x = ext2_count_free(bitmap_bh, sb->s_blocksize);
 		if (le16_to_cpu(desc->bg_free_blocks_count) != x)
 			ext2_error (sb, "ext2_check_blocks_bitmap",
 				    "Wrong free blocks count for group %d, "
@@ -702,8 +640,10 @@ void ext2_check_blocks_bitmap (struct su
 	}
 	if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
 		ext2_error (sb, "ext2_check_blocks_bitmap",
-			    "Wrong free blocks count in super block, "
-			    "stored = %lu, counted = %lu",
-			    (unsigned long) le32_to_cpu(es->s_free_blocks_count), bitmap_count);
+			"Wrong free blocks count in super block, "
+			"stored = %lu, counted = %lu",
+			(unsigned long)le32_to_cpu(es->s_free_blocks_count),
+			bitmap_count);
+	brelse(bitmap_bh);
 }
 #endif
include/linux/ext2_fs_sb.h renamed from include/linux/ext2_fs_sb.h~ext2-lrus +0 -14
@@ -17,14 +17,6 @@
 #define _LINUX_EXT2_FS_SB
 
 /*
- * The following is not needed anymore since the descriptors buffer
- * heads are now dynamically allocated
- */
-/* #define EXT2_MAX_GROUP_DESC	8 */
-
-#define EXT2_MAX_GROUP_LOADED	8
-
-/*
  * second extended-fs super-block data in memory
  */
 struct ext2_sb_info {
@@ -41,12 +33,6 @@ struct ext2_sb_info {
 	struct buffer_head * s_sbh;	/* Buffer containing the super block */
 	struct ext2_super_block * s_es;	/* Pointer to the super block in the buffer */
 	struct buffer_head ** s_group_desc;
-	unsigned short s_loaded_inode_bitmaps;
-	unsigned short s_loaded_block_bitmaps;
-	unsigned long s_inode_bitmap_number[EXT2_MAX_GROUP_LOADED];
-	struct buffer_head * s_inode_bitmap[EXT2_MAX_GROUP_LOADED];
-	unsigned long s_block_bitmap_number[EXT2_MAX_GROUP_LOADED];
-	struct buffer_head * s_block_bitmap[EXT2_MAX_GROUP_LOADED];
 	unsigned long  s_mount_opt;
 	uid_t s_resuid;
 	gid_t s_resgid;
fs/ext2/super.c renamed from fs/ext2/super.c~ext2-lrus +0 -14
@@ -142,12 +142,6 @@ static void ext2_put_super (struct super
 		if (sbi->s_group_desc[i])
 			brelse (sbi->s_group_desc[i]);
 	kfree(sbi->s_group_desc);
-	for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
-		if (sbi->s_inode_bitmap[i])
-			brelse (sbi->s_inode_bitmap[i]);
-	for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
-		if (sbi->s_block_bitmap[i])
-			brelse (sbi->s_block_bitmap[i]);
 	brelse (sbi->s_sbh);
 	sb->u.generic_sbp = NULL;
 	kfree(sbi);
@@ -686,14 +680,6 @@ static int ext2_fill_super(struct super_
 		db_count = i;
 		goto failed_mount2;
 	}
-	for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
-		sbi->s_inode_bitmap_number[i] = 0;
-		sbi->s_inode_bitmap[i] = NULL;
-		sbi->s_block_bitmap_number[i] = 0;
-		sbi->s_block_bitmap[i] = NULL;
-	}
-	sbi->s_loaded_inode_bitmaps = 0;
-	sbi->s_loaded_block_bitmaps = 0;
 	sbi->s_gdb_count = db_count;
 	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
 	/*
fs/ext2/ialloc.c renamed from fs/ext2/ialloc.c~ext2-lrus +56 -110

311 lines not on this page · raw message

-