From f6fb99cadcd44660c68e13f6eab28333653621e6 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 30 Jun 2012 19:14:57 -0400 Subject: ext4: pass a char * to ext4_count_free() instead of a buffer_head ptr Make it possible for ext4_count_free to operate on buffers and not just data in buffer_heads. Signed-off-by: "Theodore Ts'o" Cc: stable@kernel.org --- fs/ext4/bitmap.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'fs/ext4/bitmap.c') diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index b319721da26..7e86a6d28c6 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c @@ -15,15 +15,13 @@ static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; -unsigned int ext4_count_free(struct buffer_head *map, unsigned int numchars) +unsigned int ext4_count_free(char *bitmap, unsigned int numchars) { unsigned int i, sum = 0; - if (!map) - return 0; for (i = 0; i < numchars; i++) - sum += nibblemap[map->b_data[i] & 0xf] + - nibblemap[(map->b_data[i] >> 4) & 0xf]; + sum += nibblemap[bitmap[i] & 0xf] + + nibblemap[(bitmap[i] >> 4) & 0xf]; return sum; } -- cgit v1.2.3 From 952fc18ef9ec707ebdc16c0786ec360295e5ff15 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 9 Jul 2012 16:27:05 -0400 Subject: ext4: fix overhead calculation used by ext4_statfs() Commit f975d6bcc7a introduced bug which caused ext4_statfs() to miscalculate the number of file system overhead blocks. This causes the f_blocks field in the statfs structure to be larger than it should be. This would in turn cause the "df" output to show the number of data blocks in the file system and the number of data blocks used to be larger than they should be. Signed-off-by: "Theodore Ts'o" Cc: stable@kernel.org --- fs/ext4/bitmap.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'fs/ext4/bitmap.c') diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index 7e86a6d28c6..a94b9c63ee5 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c @@ -11,8 +11,6 @@ #include #include "ext4.h" -#ifdef EXT4FS_DEBUG - static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; unsigned int ext4_count_free(char *bitmap, unsigned int numchars) @@ -25,8 +23,6 @@ unsigned int ext4_count_free(char *bitmap, unsigned int numchars) return sum; } -#endif /* EXT4FS_DEBUG */ - int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, struct ext4_group_desc *gdp, struct buffer_head *bh, int sz) -- cgit v1.2.3 From 6017b485caeae5915956190b4f3d8307021e785d Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 30 Jul 2012 14:41:08 -0700 Subject: ext4: use memweight() Convert ext4_count_free() to use memweight() instead of table lookup based counting clear bits implementation. This change only affects the code segments enabled by EXT4FS_DEBUG. Note that this memweight() call can't be replaced with a single bitmap_weight() call, although the pointer to the memory area is aligned to long-word boundary. Because the size of the memory area may not be a multiple of BITS_PER_LONG, then it returns wrong value on big-endian architecture. This also includes the following change. - Remove unnecessary map == NULL check in ext4_count_free() which always takes non-null pointer as the memory area. Signed-off-by: Akinobu Mita Cc: "Theodore Ts'o" Cc: Andreas Dilger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ext4/bitmap.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'fs/ext4/bitmap.c') diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index a94b9c63ee5..f8716eab999 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c @@ -11,16 +11,9 @@ #include #include "ext4.h" -static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; - unsigned int ext4_count_free(char *bitmap, unsigned int numchars) { - unsigned int i, sum = 0; - - for (i = 0; i < numchars; i++) - sum += nibblemap[bitmap[i] & 0xf] + - nibblemap[(bitmap[i] >> 4) & 0xf]; - return sum; + return numchars * BITS_PER_BYTE - memweight(bitmap, numchars); } int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, -- cgit v1.2.3 From 7a4c5de27efa4c2ecca87af0a3deea63446367e2 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 10 Aug 2012 13:57:52 -0400 Subject: ext4: don't call ext4_error while block group is locked While in ext4_validate_block_bitmap(), if an block allocation bitmap is found to be invalid, we call ext4_error() while the block group is still locked. This causes ext4_commit_super() to call a function which might sleep while in an atomic context. There's no need to keep the block group locked at this point, so hoist the ext4_error() call up to ext4_validate_block_bitmap() and release the block group spinlock before calling ext4_error(). The reported stack trace can be found at: http://article.gmane.org/gmane.comp.file-systems.ext4/33731 Reported-by: Dave Jones Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/bitmap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/ext4/bitmap.c') diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index f8716eab999..5c2d1813ebe 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c @@ -79,7 +79,6 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, if (provided == calculated) return 1; - ext4_error(sb, "Bad block bitmap checksum: block_group = %u", group); return 0; } -- cgit v1.2.3 From 79f1ba49569e5aec919b653c55b03274c2331701 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Mon, 22 Oct 2012 00:34:32 -0400 Subject: ext4: Checksum the block bitmap properly with bigalloc enabled In mke2fs, we only checksum the whole bitmap block and it is right. While in the kernel, we use EXT4_BLOCKS_PER_GROUP to indicate the size of the checksumed bitmap which is wrong when we enable bigalloc. The right size should be EXT4_CLUSTERS_PER_GROUP and this patch fixes it. Also as every caller of ext4_block_bitmap_csum_set and ext4_block_bitmap_csum_verify pass in EXT4_BLOCKS_PER_GROUP(sb)/8, we'd better removes this parameter and sets it in the function itself. Signed-off-by: Tao Ma Signed-off-by: "Theodore Ts'o" Reviewed-by: Lukas Czerner Cc: stable@vger.kernel.org --- fs/ext4/bitmap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'fs/ext4/bitmap.c') diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index 5c2d1813ebe..3285aa5a706 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c @@ -58,11 +58,12 @@ void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group, int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, struct ext4_group_desc *gdp, - struct buffer_head *bh, int sz) + struct buffer_head *bh) { __u32 hi; __u32 provided, calculated; struct ext4_sb_info *sbi = EXT4_SB(sb); + int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) @@ -84,8 +85,9 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, struct ext4_group_desc *gdp, - struct buffer_head *bh, int sz) + struct buffer_head *bh) { + int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; __u32 csum; struct ext4_sb_info *sbi = EXT4_SB(sb); -- cgit v1.2.3