This source file includes following definitions.
- find_first_zero_bit
- find_next_zero_bit
- find_first_zero_byte
- get_group_desc
- read_block_bitmap
- load__block_bitmap
- load_block_bitmap
- ext2_free_blocks
- ext2_new_block
- ext2_count_free_blocks
- block_in_use
- ext2_check_blocks_bitmap
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 #include <linux/fs.h>
27 #include <linux/ext2_fs.h>
28 #include <linux/stat.h>
29 #include <linux/sched.h>
30 #include <linux/string.h>
31 #include <linux/locks.h>
32
33 #include <asm/bitops.h>
34
35 #define clear_block(addr,size) \
36 __asm__("cld\n\t" \
37 "rep\n\t" \
38 "stosl" \
39 : \
40 :"a" (0), "c" (size / 4), "D" ((long) (addr)) \
41 :"cx", "di")
42
43 #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
44
45 static inline int find_first_zero_bit (unsigned long * addr, unsigned size)
46 {
47 int res;
48
49 if (!size)
50 return 0;
51 __asm__("
52 cld
53 movl $-1,%%eax
54 repe; scasl
55 je 1f
56 subl $4,%%edi
57 movl (%%edi),%%eax
58 notl %%eax
59 bsfl %%eax,%%edx
60 jmp 2f
61 1: xorl %%edx,%%edx
62 2: subl %%ebx,%%edi
63 shll $3,%%edi
64 addl %%edi,%%edx"
65 :"=d" (res)
66 :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
67 :"ax", "bx", "cx", "di");
68 return res;
69 }
70
71 static inline int find_next_zero_bit (unsigned long * addr, int size,
72 int offset)
73 {
74 unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
75 int set = 0, bit = offset & 31, res;
76
77 if (bit) {
78
79
80
81 __asm__("
82 bsfl %1,%0
83 jne 1f
84 movl $32, %0
85 1: "
86 : "=r" (set)
87 : "r" (~(*p >> bit)));
88 if (set < (32 - bit))
89 return set + offset;
90 set = 32 - bit;
91 p++;
92 }
93
94
95
96 res = find_first_zero_bit (p, size - 32 * (p - addr));
97 return (offset + set + res);
98 }
99
100 static inline char * find_first_zero_byte (char * addr, int size)
101 {
102 char *res;
103
104 if (!size)
105 return 0;
106 __asm__("
107 cld
108 mov $0,%%eax
109 repnz; scasb
110 jnz 1f
111 dec %%edi
112 1: "
113 : "=D" (res)
114 : "0" (addr), "c" (size)
115 : "ax");
116 return res;
117 }
118
119 static struct ext2_group_desc * get_group_desc (struct super_block * sb,
120 unsigned int block_group,
121 struct buffer_head ** bh)
122 {
123 unsigned long group_desc;
124 unsigned long desc;
125 struct ext2_group_desc * gdp;
126
127 if (block_group >= sb->u.ext2_sb.s_groups_count)
128 ext2_panic (sb, "get_group_desc",
129 "block_group >= groups_count\n"
130 "block_group = %d, groups_count = %lu",
131 block_group, sb->u.ext2_sb.s_groups_count);
132
133 group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
134 desc = block_group % EXT2_DESC_PER_BLOCK(sb);
135 if (!sb->u.ext2_sb.s_group_desc[group_desc])
136 ext2_panic (sb, "get_group_desc",
137 "Group descriptor not loaded\n"
138 "block_group = %d, group_desc = %lu, desc = %lu",
139 block_group, group_desc, desc);
140 gdp = (struct ext2_group_desc *)
141 sb->u.ext2_sb.s_group_desc[group_desc]->b_data;
142 if (bh)
143 *bh = sb->u.ext2_sb.s_group_desc[group_desc];
144 return gdp + desc;
145 }
146
147 static void read_block_bitmap (struct super_block * sb,
148 unsigned int block_group,
149 unsigned long bitmap_nr)
150 {
151 struct ext2_group_desc * gdp;
152 struct buffer_head * bh;
153
154 gdp = get_group_desc (sb, block_group, NULL);
155 bh = bread (sb->s_dev, gdp->bg_block_bitmap, sb->s_blocksize);
156 if (!bh)
157 ext2_panic (sb, "read_block_bitmap",
158 "Cannot read block bitmap\n"
159 "block_group = %d, block_bitmap = %lu",
160 block_group, gdp->bg_block_bitmap);
161 sb->u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group;
162 sb->u.ext2_sb.s_block_bitmap[bitmap_nr] = bh;
163 }
164
165
166
167
168
169
170
171
172
173
174
175
176 static int load__block_bitmap (struct super_block * sb,
177 unsigned int block_group)
178 {
179 int i, j;
180 unsigned long block_bitmap_number;
181 struct buffer_head * block_bitmap;
182
183 if (block_group >= sb->u.ext2_sb.s_groups_count)
184 ext2_panic (sb, "load_block_bitmap",
185 "block_group >= groups_count\n"
186 "block_group = %d, groups_count = %lu",
187 block_group, sb->u.ext2_sb.s_groups_count);
188
189 if (sb->u.ext2_sb.s_groups_count <= EXT2_MAX_GROUP_LOADED) {
190 if (sb->u.ext2_sb.s_block_bitmap[block_group]) {
191 if (sb->u.ext2_sb.s_block_bitmap_number[block_group] !=
192 block_group)
193 ext2_panic (sb, "load_block_bitmap",
194 "block_group != block_bitmap_number");
195 else
196 return block_group;
197 } else {
198 read_block_bitmap (sb, block_group, block_group);
199 return block_group;
200 }
201 }
202
203 for (i = 0; i < sb->u.ext2_sb.s_loaded_block_bitmaps &&
204 sb->u.ext2_sb.s_block_bitmap_number[i] != block_group; i++)
205 ;
206 if (i < sb->u.ext2_sb.s_loaded_block_bitmaps &&
207 sb->u.ext2_sb.s_block_bitmap_number[i] == block_group) {
208 block_bitmap_number = sb->u.ext2_sb.s_block_bitmap_number[i];
209 block_bitmap = sb->u.ext2_sb.s_block_bitmap[i];
210 for (j = i; j > 0; j--) {
211 sb->u.ext2_sb.s_block_bitmap_number[j] =
212 sb->u.ext2_sb.s_block_bitmap_number[j - 1];
213 sb->u.ext2_sb.s_block_bitmap[j] =
214 sb->u.ext2_sb.s_block_bitmap[j - 1];
215 }
216 sb->u.ext2_sb.s_block_bitmap_number[0] = block_bitmap_number;
217 sb->u.ext2_sb.s_block_bitmap[0] = block_bitmap;
218 } else {
219 if (sb->u.ext2_sb.s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED)
220 sb->u.ext2_sb.s_loaded_block_bitmaps++;
221 else
222 brelse (sb->u.ext2_sb.s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1]);
223 for (j = sb->u.ext2_sb.s_loaded_block_bitmaps - 1; j > 0; j--) {
224 sb->u.ext2_sb.s_block_bitmap_number[j] =
225 sb->u.ext2_sb.s_block_bitmap_number[j - 1];
226 sb->u.ext2_sb.s_block_bitmap[j] =
227 sb->u.ext2_sb.s_block_bitmap[j - 1];
228 }
229 read_block_bitmap (sb, block_group, 0);
230 }
231 return 0;
232 }
233
234 static inline int load_block_bitmap (struct super_block * sb,
235 unsigned int block_group)
236 {
237 if (sb->u.ext2_sb.s_loaded_block_bitmaps > 0 &&
238 sb->u.ext2_sb.s_block_bitmap_number[0] == block_group)
239 return 0;
240
241 if (sb->u.ext2_sb.s_groups_count <= EXT2_MAX_GROUP_LOADED &&
242 sb->u.ext2_sb.s_block_bitmap_number[block_group] == block_group &&
243 sb->u.ext2_sb.s_block_bitmap[block_group])
244 return block_group;
245
246 return load__block_bitmap (sb, block_group);
247 }
248
249 void ext2_free_blocks (struct super_block * sb, unsigned long block,
250 unsigned long count)
251 {
252 struct buffer_head * bh;
253 struct buffer_head * bh2;
254 unsigned long block_group;
255 unsigned long bit;
256 unsigned long i;
257 int bitmap_nr;
258 struct ext2_group_desc * gdp;
259 struct ext2_super_block * es;
260
261 if (!sb) {
262 printk ("ext2_free_blocks: nonexistent device");
263 return;
264 }
265 lock_super (sb);
266 es = sb->u.ext2_sb.s_es;
267 if (block < es->s_first_data_block ||
268 (block + count) > es->s_blocks_count) {
269 ext2_error (sb, "ext2_free_blocks",
270 "Freeing blocks not in datazone\n"
271 "block = %lu, count = %lu", block, count);
272 unlock_super (sb);
273 return;
274 }
275
276 ext2_debug ("freeing block %lu\n", block);
277
278 block_group = (block - es->s_first_data_block) /
279 EXT2_BLOCKS_PER_GROUP(sb);
280 bit = (block - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb);
281 if (bit + count > EXT2_BLOCKS_PER_GROUP(sb))
282 ext2_panic (sb, "ext2_free_blocks",
283 "Freeing blocks across group boundary\n"
284 "Block = %lu, count = %lu",
285 block, count);
286 bitmap_nr = load_block_bitmap (sb, block_group);
287 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
288 gdp = get_group_desc (sb, block_group, &bh2);
289
290 if (test_opt (sb, CHECK_STRICT) &&
291 (in_range (gdp->bg_block_bitmap, block, count) ||
292 in_range (gdp->bg_inode_bitmap, block, count) ||
293 in_range (block, gdp->bg_inode_table,
294 sb->u.ext2_sb.s_itb_per_group) ||
295 in_range (block + count - 1, gdp->bg_inode_table,
296 sb->u.ext2_sb.s_itb_per_group)))
297 ext2_panic (sb, "ext2_free_blocks",
298 "Freeing blocks in system zones\n"
299 "Block = %lu, count = %lu",
300 block, count);
301
302 for (i = 0; i < count; i++) {
303 if (!clear_bit (bit + i, bh->b_data))
304 ext2_warning (sb, "ext2_free_blocks",
305 "bit already cleared for block %lu",
306 block);
307 else {
308 gdp->bg_free_blocks_count++;
309 es->s_free_blocks_count++;
310 }
311 }
312
313 bh2->b_dirt = 1;
314 sb->u.ext2_sb.s_sbh->b_dirt = 1;
315
316 bh->b_dirt = 1;
317 if (sb->s_flags & MS_SYNC) {
318 ll_rw_block (WRITE, 1, &bh);
319 wait_on_buffer (bh);
320 }
321 sb->s_dirt = 1;
322 unlock_super (sb);
323 return;
324 }
325
326
327
328
329
330
331
332
333 int ext2_new_block (struct super_block * sb, unsigned long goal,
334 unsigned long * prealloc_count,
335 unsigned long * prealloc_block)
336 {
337 struct buffer_head * bh;
338 struct buffer_head * bh2;
339 char * p, * r;
340 int i, j, k, tmp;
341 unsigned long lmap;
342 int bitmap_nr;
343 struct ext2_group_desc * gdp;
344 struct ext2_super_block * es;
345
346 #ifdef EXT2FS_DEBUG
347 static int goal_hits = 0, goal_attempts = 0;
348 #endif
349 if (!sb) {
350 printk ("ext2_new_block: nonexistent device");
351 return 0;
352 }
353 lock_super (sb);
354 es = sb->u.ext2_sb.s_es;
355 if (es->s_free_blocks_count <= es->s_r_blocks_count && !suser()) {
356 unlock_super (sb);
357 return 0;
358 }
359
360 ext2_debug ("goal=%lu.\n", goal);
361
362 if (goal < es->s_first_data_block || goal >= es->s_blocks_count) {
363 ext2_warning (sb, "ext2_new_block",
364 "Goal out of bounds: %lu", goal);
365 goal = es->s_first_data_block;
366 }
367 repeat:
368
369
370
371 i = ((goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb));
372 gdp = get_group_desc (sb, i, &bh2);
373 if (gdp->bg_free_blocks_count > 0) {
374 j = ((goal - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb));
375 #ifdef EXT2FS_DEBUG
376 if (j)
377 goal_attempts++;
378 #endif
379 bitmap_nr = load_block_bitmap (sb, i);
380 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
381
382 ext2_debug ("goal is at %d:%d.\n", i, j);
383
384 if (!test_bit(j, bh->b_data)) {
385 #ifdef EXT2FS_DEBUG
386 goal_hits++;
387 ext2_debug ("goal bit allocated.\n");
388 #endif
389 goto got_block;
390 }
391 if (j) {
392
393
394
395
396 lmap = ((((unsigned long *) bh->b_data)[j >> 5]) >>
397 ((j & 31) + 1));
398 if (j < EXT2_BLOCKS_PER_GROUP(sb) - 32)
399 lmap |= (((unsigned long *) bh->b_data)[(j >> 5) + 1]) <<
400 (31 - (j & 31));
401 else
402 lmap |= 0xffffffff << (31 - (j & 31));
403 if (lmap != 0xffffffffl) {
404 __asm__ ("bsfl %1,%0"
405 : "=r" (k)
406 : "r" (~lmap));
407 k++;
408 if ((j + k) < EXT2_BLOCKS_PER_GROUP(sb)) {
409 j += k;
410 goto got_block;
411 }
412 }
413 }
414
415 ext2_debug ("Bit not found near goal\n");
416
417
418
419
420
421
422
423
424
425
426 p = ((char *) bh->b_data) + (j >> 3);
427 r = find_first_zero_byte (p,
428 (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
429 k = (r - ((char *) bh->b_data)) << 3;
430 if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
431 j = k;
432 goto search_back;
433 }
434 k = find_next_zero_bit ((unsigned long *) bh->b_data,
435 EXT2_BLOCKS_PER_GROUP(sb),
436 j);
437 if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
438 j = k;
439 goto got_block;
440 }
441 }
442
443 ext2_debug ("Bit not found in block group %d.\n", i);
444
445
446
447
448
449 for (k = 0; k < sb->u.ext2_sb.s_groups_count; k++) {
450 i++;
451 if (i >= sb->u.ext2_sb.s_groups_count)
452 i = 0;
453 gdp = get_group_desc (sb, i, &bh2);
454 if (gdp->bg_free_blocks_count > 0)
455 break;
456 }
457 if (k >= sb->u.ext2_sb.s_groups_count) {
458 unlock_super (sb);
459 return 0;
460 }
461 bitmap_nr = load_block_bitmap (sb, i);
462 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
463 r = find_first_zero_byte (bh->b_data,
464 EXT2_BLOCKS_PER_GROUP(sb) >> 3);
465 j = (r - bh->b_data) << 3;
466 if (j < EXT2_BLOCKS_PER_GROUP(sb))
467 goto search_back;
468 else
469 j = find_first_zero_bit ((unsigned long *) bh->b_data,
470 EXT2_BLOCKS_PER_GROUP(sb));
471 if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
472 ext2_error (sb, "ext2_new_block",
473 "Free blocks count corrupted for block group %d", i);
474 unlock_super (sb);
475 return 0;
476 }
477
478 search_back:
479
480
481
482
483
484 for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh->b_data); k++, j--);
485
486 got_block:
487
488 ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count);
489
490 tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + es->s_first_data_block;
491
492 if (test_opt (sb, CHECK_STRICT) &&
493 (tmp == gdp->bg_block_bitmap ||
494 tmp == gdp->bg_inode_bitmap ||
495 in_range (tmp, gdp->bg_inode_table, sb->u.ext2_sb.s_itb_per_group)))
496 ext2_panic (sb, "ext2_new_block",
497 "Allocating block in system zone\n"
498 "block = %u", tmp);
499
500 if (set_bit (j, bh->b_data)) {
501 ext2_warning (sb, "ext2_new_block",
502 "bit already set for block %d", j);
503 goto repeat;
504 }
505
506 ext2_debug ("found bit %d\n", j);
507
508
509
510
511 #ifdef EXT2_PREALLOCATE
512 if (prealloc_block) {
513 *prealloc_count = 0;
514 *prealloc_block = tmp + 1;
515 for (k = 1;
516 k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) {
517 if (set_bit (j + k, bh->b_data))
518 break;
519 (*prealloc_count)++;
520 }
521 gdp->bg_free_blocks_count -= *prealloc_count;
522 es->s_free_blocks_count -= *prealloc_count;
523 ext2_debug ("Preallocated a further %lu bits.\n",
524 *prealloc_count);
525 }
526 #endif
527
528 j = tmp;
529
530 bh->b_dirt = 1;
531 if (sb->s_flags & MS_SYNC) {
532 ll_rw_block (WRITE, 1, &bh);
533 wait_on_buffer (bh);
534 }
535
536 if (j >= es->s_blocks_count) {
537 ext2_error (sb, "ext2_new_block",
538 "block >= blocks count\n"
539 "block_group = %d, block=%d", i, j);
540 unlock_super (sb);
541 return 0;
542 }
543 if (!(bh = getblk (sb->s_dev, j, sb->s_blocksize))) {
544 ext2_error (sb, "ext2_new_block", "cannot get block %d", j);
545 unlock_super (sb);
546 return 0;
547 }
548 clear_block (bh->b_data, sb->s_blocksize);
549 bh->b_uptodate = 1;
550 bh->b_dirt = 1;
551 brelse (bh);
552
553 ext2_debug ("allocating block %d. "
554 "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
555
556 gdp->bg_free_blocks_count--;
557 bh2->b_dirt = 1;
558 es->s_free_blocks_count--;
559 sb->u.ext2_sb.s_sbh->b_dirt = 1;
560 sb->s_dirt = 1;
561 unlock_super (sb);
562 return j;
563 }
564
565 unsigned long ext2_count_free_blocks (struct super_block * sb)
566 {
567 #ifdef EXT2FS_DEBUG
568 struct ext2_super_block * es;
569 unsigned long desc_count, bitmap_count, x;
570 int bitmap_nr;
571 struct ext2_group_desc * gdp;
572 int i;
573
574 lock_super (sb);
575 es = sb->u.ext2_sb.s_es;
576 desc_count = 0;
577 bitmap_count = 0;
578 gdp = NULL;
579 for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
580 gdp = get_group_desc (sb, i, NULL);
581 desc_count += gdp->bg_free_blocks_count;
582 bitmap_nr = load_block_bitmap (sb, i);
583 x = ext2_count_free (sb->u.ext2_sb.s_block_bitmap[bitmap_nr],
584 sb->s_blocksize);
585 printk ("group %d: stored = %d, counted = %lu\n",
586 i, gdp->bg_free_blocks_count, x);
587 bitmap_count += x;
588 }
589 printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",
590 es->s_free_blocks_count, desc_count, bitmap_count);
591 unlock_super (sb);
592 return bitmap_count;
593 #else
594 return sb->u.ext2_sb.s_es->s_free_blocks_count;
595 #endif
596 }
597
598 static inline int block_in_use (unsigned long block,
599 struct super_block * sb,
600 unsigned char * map)
601 {
602 return test_bit ((block - sb->u.ext2_sb.s_es->s_first_data_block) %
603 EXT2_BLOCKS_PER_GROUP(sb), map);
604 }
605
606 void ext2_check_blocks_bitmap (struct super_block * sb)
607 {
608 struct buffer_head * bh;
609 struct ext2_super_block * es;
610 unsigned long desc_count, bitmap_count, x;
611 int bitmap_nr;
612 struct ext2_group_desc * gdp;
613 int i, j;
614
615 lock_super (sb);
616 es = sb->u.ext2_sb.s_es;
617 desc_count = 0;
618 bitmap_count = 0;
619 gdp = NULL;
620 for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
621 gdp = get_group_desc (sb, i, NULL);
622 desc_count += gdp->bg_free_blocks_count;
623 bitmap_nr = load_block_bitmap (sb, i);
624 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
625
626 if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data))
627 ext2_error (sb, "ext2_check_blocks_bitmap",
628 "Block bitmap for group %d is marked free",
629 i);
630
631 if (!block_in_use (gdp->bg_inode_bitmap, sb, bh->b_data))
632 ext2_error (sb, "ext2_check_blocks_bitmap",
633 "Inode bitmap for group %d is marked free",
634 i);
635
636 for (j = 0; j < sb->u.ext2_sb.s_itb_per_group; j++)
637 if (!block_in_use (gdp->bg_inode_table + j, sb, bh->b_data))
638 ext2_error (sb, "ext2_check_blocks_bitmap",
639 "Block #%d of the inode table in group %d "
640 "is marked free", j, i);
641
642 x = ext2_count_free (bh, sb->s_blocksize);
643 if (gdp->bg_free_blocks_count != x)
644 ext2_error (sb, "ext2_check_blocks_bitmap",
645 "Wrong free blocks count for group %d, "
646 "stored = %d, counted = %lu", i,
647 gdp->bg_free_blocks_count, x);
648 bitmap_count += x;
649 }
650 if (es->s_free_blocks_count != bitmap_count)
651 ext2_error (sb, "ext2_check_blocks_bitmap",
652 "Wrong free blocks count in super block, "
653 "stored = %lu, counted = %lu",
654 es->s_free_blocks_count, bitmap_count);
655 unlock_super (sb);
656 }