[e2fsprogs] Fix find_first_zero() functions for 32-bit bitmaps

Eric Sandeen sandeen at fedoraproject.org
Mon Apr 9 16:30:24 UTC 2012


commit b97ba6e05295b4352e07683f6bb120f65451499c
Author: Eric Sandeen <sandeen at redhat.com>
Date:   Mon Apr 9 11:30:11 2012 -0500

    Fix find_first_zero() functions for 32-bit bitmaps

 e2fsprogs-1.42.2-32-bit-ffz-fix.patch |  452 +++++++++++++++++++++++++++++++++
 e2fsprogs.spec                        |    9 +-
 2 files changed, 460 insertions(+), 1 deletions(-)
---
diff --git a/e2fsprogs-1.42.2-32-bit-ffz-fix.patch b/e2fsprogs-1.42.2-32-bit-ffz-fix.patch
new file mode 100644
index 0000000..ef7298e
--- /dev/null
+++ b/e2fsprogs-1.42.2-32-bit-ffz-fix.patch
@@ -0,0 +1,452 @@
+[PATCH 1/3] libext2fs: add 32-bit compat code for ext2fs_find_first_zero_generic_bmap()
+
+The lack of 32-bit support was causing febootstrap to crash since it
+wasn't passing EXT2_FLAG_64BITS when opening the file system, so we
+were still using the legacy bitmaps.
+
+Addresses-Red-Hat-Bugzilla: #808421
+
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+---
+
+[PATCH 2/3] libext2fs: use correct types in ext2fs_find_first_zero_block_bitmap2()
+
+Fortunately nothing was using this inline function, so we'll just fix
+the types in its function signature, which were nonsensical (this was
+caused by a cut-and-paste error).
+
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+---
+
+[PATCH 3/3] libext2fs: improve testing coverage of tst_bitmaps
+
+Improve the test coverage of tst_bitmaps by:
+
+   (a) adding the ability to test the legacy (32-bit) bitmap code
+   (b) adding tests for ext2fs_find_first_zero_inode_bitmap2() and
+       ext2fs_find_first_zero_block_bitmap2()
+
+The recent regressions caused by the addition (and use) of
+ext2fs_find_first_zero_inode_bitmap2() would have been caught if we
+had added these tests first.  (Another object lesson in why unit tests
+are critically important!)
+
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+---
+
+Index: e2fsprogs-1.42.2/lib/ext2fs/Makefile.in
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/Makefile.in
++++ e2fsprogs-1.42.2/lib/ext2fs/Makefile.in
+@@ -403,6 +403,9 @@ check:: tst_bitops tst_badblocks tst_isc
+ 	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) \
+ 		./tst_bitmaps -t 3 -f $(srcdir)/tst_bitmaps_cmds > tst_bitmaps_out
+ 	diff $(srcdir)/tst_bitmaps_exp tst_bitmaps_out
++	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) \
++		./tst_bitmaps -l -f $(srcdir)/tst_bitmaps_cmds > tst_bitmaps_out
++	diff $(srcdir)/tst_bitmaps_exp tst_bitmaps_out
+ 
+ installdirs::
+ 	$(E) "	MKINSTALLDIRS $(libdir) $(includedir)/ext2fs"
+Index: e2fsprogs-1.42.2/lib/ext2fs/bitops.h
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/bitops.h
++++ e2fsprogs-1.42.2/lib/ext2fs/bitops.h
+@@ -153,9 +153,9 @@ extern void ext2fs_fast_unmark_inode_bit
+ extern int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+ 					  ext2_ino_t inode);
+ extern errcode_t ext2fs_find_first_zero_block_bitmap2(ext2fs_block_bitmap bitmap,
+-						      ext2_ino_t start,
+-						      ext2_ino_t end,
+-						      ext2_ino_t *out);
++						      blk64_t start,
++						      blk64_t end,
++						      blk64_t *out);
+ extern errcode_t ext2fs_find_first_zero_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+ 						      ext2_ino_t start,
+ 						      ext2_ino_t end,
+@@ -605,9 +605,9 @@ _INLINE_ int ext2fs_fast_test_inode_bitm
+ }
+ 
+ _INLINE_ errcode_t ext2fs_find_first_zero_block_bitmap2(ext2fs_block_bitmap bitmap,
+-							ext2_ino_t start,
+-							ext2_ino_t end,
+-							ext2_ino_t *out)
++							blk64_t start,
++							blk64_t end,
++							blk64_t *out)
+ {
+ 	__u64 o;
+ 	errcode_t rv;
+Index: e2fsprogs-1.42.2/lib/ext2fs/ext2fs.h
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/ext2fs.h
++++ e2fsprogs-1.42.2/lib/ext2fs/ext2fs.h
+@@ -1168,6 +1168,9 @@ extern errcode_t ext2fs_set_generic_bitm
+ 						 errcode_t magic,
+ 						 __u32 start, __u32 num,
+ 						 void *in);
++extern errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
++						       __u32 start, __u32 end,
++						       __u32 *out);
+ 
+ /* gen_bitmap64.c */
+ 
+Index: e2fsprogs-1.42.2/lib/ext2fs/gen_bitmap.c
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/gen_bitmap.c
++++ e2fsprogs-1.42.2/lib/ext2fs/gen_bitmap.c
+@@ -504,6 +504,30 @@ static int ext2fs_test_clear_generic_bit
+ 	return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
+ }
+ 
++errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
++						__u32 start, __u32 end,
++						__u32 *out)
++{
++	blk_t b;
++
++	if (start < bitmap->start || end > bitmap->end || start > end) {
++		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
++		return EINVAL;
++	}
++
++	while (start <= end) {
++		b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
++		if (!b) {
++			*out = start;
++			return 0;
++		}
++		start++;
++	}
++
++	return ENOENT;
++}
++
++
+ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ 				   blk_t block, int num)
+ {
+@@ -558,3 +582,4 @@ void ext2fs_unmark_block_bitmap_range(ex
+ 		ext2fs_fast_clear_bit(block + i - bitmap->start,
+ 				      bitmap->bitmap);
+ }
++
+Index: e2fsprogs-1.42.2/lib/ext2fs/gen_bitmap64.c
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/gen_bitmap64.c
++++ e2fsprogs-1.42.2/lib/ext2fs/gen_bitmap64.c
+@@ -768,12 +768,36 @@ errcode_t ext2fs_find_first_zero_generic
+ {
+ 	int b;
+ 
+-	if (bitmap->bitmap_ops->find_first_zero)
+-		return bitmap->bitmap_ops->find_first_zero(bitmap, start, end, out);
++	if (!bitmap)
++		return EINVAL;
++
++	if (EXT2FS_IS_64_BITMAP(bitmap) && bitmap->bitmap_ops->find_first_zero)
++		return bitmap->bitmap_ops->find_first_zero(bitmap, start,
++							   end, out);
++
++	if (EXT2FS_IS_32_BITMAP(bitmap)) {
++		blk_t blk = 0;
++		errcode_t retval;
++
++		if (((start) & ~0xffffffffULL) ||
++		    ((end) & ~0xffffffffULL)) {
++			ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
++			return EINVAL;
++		}
++
++		retval = ext2fs_find_first_zero_generic_bitmap(bitmap, start,
++							       end, &blk);
++		if (retval == 0)
++			*out = blk;
++		return retval;
++	}
+ 
+-	if (!bitmap || !EXT2FS_IS_64_BITMAP(bitmap) || bitmap->cluster_bits)
++	if (!EXT2FS_IS_64_BITMAP(bitmap))
+ 		return EINVAL;
+ 
++	start >>= bitmap->cluster_bits;
++	end >>= bitmap->cluster_bits;
++
+ 	if (start < bitmap->start || end > bitmap->end || start > end) {
+ 		warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
+ 		return EINVAL;
+@@ -782,7 +806,7 @@ errcode_t ext2fs_find_first_zero_generic
+ 	while (start <= end) {
+ 		b = bitmap->bitmap_ops->test_bmap(bitmap, start);
+ 		if (!b) {
+-			*out = start;
++			*out = start << bitmap->cluster_bits;
+ 			return 0;
+ 		}
+ 		start++;
+Index: e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps.c
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/tst_bitmaps.c
++++ e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps.c
+@@ -151,7 +151,7 @@ int check_fs_open(char *name)
+ 
+ static void setup_filesystem(const char *name,
+ 			     unsigned int blocks, unsigned int inodes,
+-			     unsigned int type)
++			     unsigned int type, int flags)
+ {
+ 	struct ext2_super_block param;
+ 	errcode_t retval;
+@@ -160,7 +160,7 @@ static void setup_filesystem(const char 
+ 	ext2fs_blocks_count_set(&param, blocks);
+ 	param.s_inodes_count = inodes;
+ 
+-	retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, &param,
++	retval = ext2fs_initialize("test fs", flags, &param,
+ 				   test_io_manager, &test_fs);
+ 
+ 	if (retval) {
+@@ -198,6 +198,7 @@ void setup_cmd(int argc, char **argv)
+ 	unsigned int	blocks = 128;
+ 	unsigned int	inodes = 0;
+ 	unsigned int	type = EXT2FS_BMAP64_BITARRAY;
++	int		flags = EXT2_FLAG_64BITS;
+ 
+ 	if (test_fs) {
+ 		ext2fs_close(test_fs);
+@@ -205,7 +206,7 @@ void setup_cmd(int argc, char **argv)
+ 	}
+ 
+ 	reset_getopt();
+-	while ((c = getopt(argc, argv, "b:i:t:")) != EOF) {
++	while ((c = getopt(argc, argv, "b:i:lt:")) != EOF) {
+ 		switch (c) {
+ 		case 'b':
+ 			blocks = parse_ulong(optarg, argv[0],
+@@ -219,6 +220,9 @@ void setup_cmd(int argc, char **argv)
+ 			if (err)
+ 				return;
+ 			break;
++		case 'l':	/* Legacy bitmaps */
++			flags = 0;
++			break;
+ 		case 't':
+ 			type = parse_ulong(optarg, argv[0],
+ 					   "bitmap backend type", &err);
+@@ -231,7 +235,7 @@ void setup_cmd(int argc, char **argv)
+ 			return;
+ 		}
+ 	}
+-	setup_filesystem(argv[0], blocks, inodes, type);
++	setup_filesystem(argv[0], blocks, inodes, type, flags);
+ }
+ 
+ void close_cmd(int argc, char **argv)
+@@ -399,6 +403,40 @@ void do_testb(int argc, char *argv[])
+ 	printf("Block %u is %s\n", block, test_result ? "set" : "clear");
+ }
+ 
++void do_ffzb(int argc, char *argv[])
++{
++	unsigned int start, end;
++	int err;
++	errcode_t retval;
++	blk64_t out;
++
++	if (check_fs_open(argv[0]))
++		return;
++
++	if (argc != 3 && argc != 3) {
++		com_err(argv[0], 0, "Usage: ffzb <start> <end>");
++		return;
++	}
++
++	start = parse_ulong(argv[1], argv[0], "start", &err);
++	if (err)
++		return;
++
++	end = parse_ulong(argv[2], argv[0], "end", &err);
++	if (err)
++		return;
++
++	retval = ext2fs_find_first_zero_block_bitmap2(test_fs->block_map,
++						      start, end, &out);
++	if (retval) {
++		printf("ext2fs_find_first_zero_block_bitmap2() returned %s\n",
++		       error_message(retval));
++		return;
++	}
++	printf("First unmarked block is %llu\n", out);
++}
++
++
+ void do_zerob(int argc, char *argv[])
+ {
+ 	if (check_fs_open(argv[0]))
+@@ -488,6 +526,40 @@ void do_testi(int argc, char *argv[])
+ 	printf("Inode %u is %s\n", inode, test_result ? "set" : "clear");
+ }
+ 
++void do_ffzi(int argc, char *argv[])
++{
++	unsigned int start, end;
++	int err;
++	errcode_t retval;
++	ext2_ino_t out;
++
++	if (check_fs_open(argv[0]))
++		return;
++
++	if (argc != 3 && argc != 3) {
++		com_err(argv[0], 0, "Usage: ffzi <start> <end>");
++		return;
++	}
++
++	start = parse_ulong(argv[1], argv[0], "start", &err);
++	if (err)
++		return;
++
++	end = parse_ulong(argv[2], argv[0], "end", &err);
++	if (err)
++		return;
++
++	retval = ext2fs_find_first_zero_inode_bitmap2(test_fs->inode_map,
++						      start, end, &out);
++	if (retval) {
++		printf("ext2fs_find_first_zero_inode_bitmap2() returned %s\n",
++		       error_message(retval));
++		return;
++	}
++	printf("First unmarked inode is %u\n", out);
++}
++
++
+ void do_zeroi(int argc, char *argv[])
+ {
+ 	if (check_fs_open(argv[0]))
+@@ -506,10 +578,11 @@ int main(int argc, char **argv)
+ 	char		*request = (char *)NULL;
+ 	char		*cmd_file = 0;
+ 	int		sci_idx;
++	int		flags = EXT2_FLAG_64BITS;
+ 
+ 	add_error_table(&et_ss_error_table);
+ 	add_error_table(&et_ext2_error_table);
+-	while ((c = getopt (argc, argv, "b:i:t:R:f:")) != EOF) {
++	while ((c = getopt (argc, argv, "b:i:lt:R:f:")) != EOF) {
+ 		switch (c) {
+ 		case 'b':
+ 			blocks = parse_ulong(optarg, argv[0],
+@@ -523,6 +596,9 @@ int main(int argc, char **argv)
+ 			if (err)
+ 				return;
+ 			break;
++		case 'l':	/* Legacy bitmaps */
++			flags = 0;
++			break;
+ 		case 't':
+ 			type = parse_ulong(optarg, argv[0],
+ 					   "bitmap backend type", &err);
+@@ -558,7 +634,7 @@ int main(int argc, char **argv)
+ 	printf("%s %s.  Type '?' for a list of commands.\n\n",
+ 	       subsystem_name, version);
+ 
+-	setup_filesystem(argv[0], blocks, inodes, type);
++	setup_filesystem(argv[0], blocks, inodes, type, flags);
+ 
+ 	if (request) {
+ 		code = ss_execute_line(sci_idx, request);
+Index: e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps_cmd.ct
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/tst_bitmaps_cmd.ct
++++ e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps_cmd.ct
+@@ -21,6 +21,9 @@ request do_clearb, "Clear block",
+ request do_testb, "Test block",
+ 	test_block, testb;
+ 
++request do_ffzb, "Find first zero block",
++	find_first_zero_block, ffzb;
++
+ request do_zerob, "Clear block bitmap",
+ 	clear_block_bitmap, zerob;
+ 
+@@ -33,6 +36,9 @@ request do_cleari, "Clear inode",
+ request do_testi, "Test inode",
+ 	test_inode, testi;
+ 
++request do_ffzi, "Find first zero inode",
++	find_first_zero_inode, ffzi;
++
+ request do_zeroi, "Clear inode bitmap",
+ 	clear_inode_bitmap, zeroi;
+ 
+Index: e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps_cmds
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/tst_bitmaps_cmds
++++ e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps_cmds
+@@ -16,6 +16,12 @@ testb 11
+ testb 15
+ testb 16
+ dump_bb
++ffzb 11 16
++ffzb 12 16
++ffzb 12 20
++clearb 13
++ffzb 12 20
++setb 13
+ clearb 12 7
+ testb 12 7
+ setb 15
+@@ -33,6 +39,11 @@ seti 5
+ testi 6
+ testi 1
+ dump_ib
++ffzi 1 6
++ffzi 2 5
++ffzi 2 6
++cleari 4
++ffzi 2 6
+ zeroi
+ testi 5
+ seti 5
+Index: e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps_exp
+===================================================================
+--- e2fsprogs-1.42.2.orig/lib/ext2fs/tst_bitmaps_exp
++++ e2fsprogs-1.42.2/lib/ext2fs/tst_bitmaps_exp
+@@ -36,6 +36,18 @@ tst_bitmaps: testb 16
+ Block 16 is set
+ tst_bitmaps: dump_bb
+ block bitmap: 00f80000000000000000000000000000
++tst_bitmaps: ffzb 11 16
++First unmarked block is 11
++tst_bitmaps: ffzb 12 16
++ext2fs_find_first_zero_block_bitmap2() returned No such file or directory
++tst_bitmaps: ffzb 12 20
++First unmarked block is 17
++tst_bitmaps: clearb 13
++Clearing block 13, was set before
++tst_bitmaps: ffzb 12 20
++First unmarked block is 13
++tst_bitmaps: setb 13
++Setting block 13, was clear before
+ tst_bitmaps: clearb 12 7
+ Clearing blocks 12 to 18
+ tst_bitmaps: testb 12 7
+@@ -70,6 +82,16 @@ tst_bitmaps: testi 1
+ Inode 1 is clear
+ tst_bitmaps: dump_ib
+ inode bitmap: 1e000000
++tst_bitmaps: ffzi 1 6
++First unmarked inode is 1
++tst_bitmaps: ffzi 2 5
++ext2fs_find_first_zero_inode_bitmap2() returned No such file or directory
++tst_bitmaps: ffzi 2 6
++First unmarked inode is 6
++tst_bitmaps: cleari 4
++Clearing inode 4, was set before
++tst_bitmaps: ffzi 2 6
++First unmarked inode is 4
+ tst_bitmaps: zeroi
+ Clearing inode bitmap.
+ tst_bitmaps: testi 5
diff --git a/e2fsprogs.spec b/e2fsprogs.spec
index 00363e5..1a3f43c 100644
--- a/e2fsprogs.spec
+++ b/e2fsprogs.spec
@@ -1,7 +1,7 @@
 Summary: Utilities for managing ext2, ext3, and ext4 filesystems
 Name: e2fsprogs
 Version: 1.42.2
-Release: 3%{?dist}
+Release: 4%{?dist}
 
 # License tags based on COPYING file distinctions for various components
 License: GPLv2
@@ -10,6 +10,7 @@ Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz
 Source1: ext2_types-wrapper.h
 
 Patch1: e2fsprogs-1.40.4-sb_feature_check_ignore.patch
+Patch2: e2fsprogs-1.42.2-32-bit-ffz-fix.patch
 
 Url: http://e2fsprogs.sourceforge.net/
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -146,6 +147,9 @@ It was originally inspired by the Multics SubSystem library.
 # after an selinux install...
 %patch1 -p1 -b .featurecheck
 
+# Handle 32-bit bitmaps in new find_first_zero functions (upstream patch)
+%patch2 -p1
+
 %build
 %configure --enable-elf-shlibs --enable-nls --disable-uuidd --disable-fsck \
 	   --disable-e2initrd-helper --disable-libblkid --disable-libuuid \
@@ -315,6 +319,9 @@ exit 0
 %{_libdir}/pkgconfig/ss.pc
 
 %changelog
+* Mon Apr 09 2012 Eric Sandeen <sandeen@@redhat.com> 1.42.2-4
+- Handle 32-bit bitmaps in new find_first_zero functions
+
 * Fri Mar 30 2012 Richard W.M. Jones <rjones at redhat.com> 1.42.2-3
 - Rebuild against new RPM (RHBZ#808250).
 


More information about the scm-commits mailing list