summaryrefslogtreecommitdiffstats
path: root/e2fsprogs-1.42.2-32-bit-ffz-fix.patch
blob: ef7298ea3200b33020a09d707e3db9f02b746b38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
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@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@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@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