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 repeat:
363
364
365
366 i = ((goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb));
367 if (i >= EXT2_BLOCKS_PER_GROUP(sb) || i < 0) {
368 i = 0;
369 goal = es->s_first_data_block;
370 }
371 gdp = get_group_desc (sb, i, &bh2);
372 if (gdp->bg_free_blocks_count > 0) {
373 j = ((goal - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb));
374 #ifdef EXT2FS_DEBUG
375 if (j)
376 goal_attempts++;
377 #endif
378 bitmap_nr = load_block_bitmap (sb, i);
379 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
380
381 ext2_debug ("goal is at %d:%d.\n", i, j);
382
383 if (!test_bit(j, bh->b_data)) {
384 #ifdef EXT2FS_DEBUG
385 goal_hits++;
386 ext2_debug ("goal bit allocated.\n");
387 #endif
388 goto got_block;
389 }
390 if (j) {
391
392
393
394
395 lmap = ((((unsigned long *) bh->b_data)[j >> 5]) >>
396 ((j & 31) + 1));
397 if (j < EXT2_BLOCKS_PER_GROUP(sb) - 32)
398 lmap |= (((unsigned long *) bh->b_data)[(j >> 5) + 1]) <<
399 (31 - (j & 31));
400 else
401 lmap |= 0xffffffff << (31 - (j & 31));
402 if (lmap != 0xffffffffl) {
403 __asm__ ("bsfl %1,%0"
404 : "=r" (k)
405 : "r" (~lmap));
406 k++;
407 if ((j + k) < EXT2_BLOCKS_PER_GROUP(sb)) {
408 j += k;
409 goto got_block;
410 }
411 }
412 }
413
414 ext2_debug ("Bit not found near goal\n");
415
416
417
418
419
420
421
422
423
424
425 p = ((char *) bh->b_data) + (j >> 3);
426 r = find_first_zero_byte (p,
427 (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
428 k = (r - ((char *) bh->b_data)) << 3;
429 if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
430 j = k;
431 goto search_back;
432 }
433 k = find_next_zero_bit ((unsigned long *) bh->b_data,
434 EXT2_BLOCKS_PER_GROUP(sb),
435 j);
436 if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
437 j = k;
438 goto got_block;
439 }
440 }
441
442 ext2_debug ("Bit not found in block group %d.\n", i);
443
444
445
446
447
448 for (k = 0; k < sb->u.ext2_sb.s_groups_count; k++) {
449 i++;
450 if (i >= sb->u.ext2_sb.s_groups_count)
451 i = 0;
452 gdp = get_group_desc (sb, i, &bh2);
453 if (gdp->bg_free_blocks_count > 0)
454 break;
455 }
456 if (k >= sb->u.ext2_sb.s_groups_count) {
457 unlock_super (sb);
458 return 0;
459 }
460 bitmap_nr = load_block_bitmap (sb, i);
461 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
462 r = find_first_zero_byte (bh->b_data,
463 EXT2_BLOCKS_PER_GROUP(sb) >> 3);
464 j = (r - bh->b_data) << 3;
465 if (j < EXT2_BLOCKS_PER_GROUP(sb))
466 goto search_back;
467 else
468 j = find_first_zero_bit ((unsigned long *) bh->b_data,
469 EXT2_BLOCKS_PER_GROUP(sb));
470 if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
471 ext2_error (sb, "ext2_new_block",
472 "Free blocks count corrupted for block group %d", i);
473 unlock_super (sb);
474 return 0;
475 }
476
477 search_back:
478
479
480
481
482
483 for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh->b_data); k++, j--);
484
485 got_block:
486
487 ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count);
488
489 tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + es->s_first_data_block;
490
491 if (test_opt (sb, CHECK_STRICT) &&
492 (tmp == gdp->bg_block_bitmap ||
493 tmp == gdp->bg_inode_bitmap ||
494 in_range (tmp, gdp->bg_inode_table, sb->u.ext2_sb.s_itb_per_group)))
495 ext2_panic (sb, "ext2_new_block",
496 "Allocating block in system zone\n"
497 "block = %u", tmp);
498
499 if (set_bit (j, bh->b_data)) {
500 ext2_warning (sb, "ext2_new_block",
501 "bit already set for block %d", j);
502 goto repeat;
503 }
504
505 ext2_debug ("found bit %d\n", j);
506
507
508
509
510 #ifdef EXT2_PREALLOCATE
511 if (prealloc_block) {
512 *prealloc_count = 0;
513 *prealloc_block = tmp + 1;
514 for (k = 1;
515 k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) {
516 if (set_bit (j + k, bh->b_data))
517 break;
518 (*prealloc_count)++;
519 }
520 gdp->bg_free_blocks_count -= *prealloc_count;
521 es->s_free_blocks_count -= *prealloc_count;
522 ext2_debug ("Preallocated a further %lu bits.\n",
523 *prealloc_count);
524 }
525 #endif
526
527 j = tmp;
528
529 bh->b_dirt = 1;
530 if (sb->s_flags & MS_SYNC) {
531 ll_rw_block (WRITE, 1, &bh);
532 wait_on_buffer (bh);
533 }
534
535 if (j >= es->s_blocks_count) {
536 ext2_error (sb, "ext2_new_block",
537 "block >= blocks count\n"
538 "block_group = %d, block=%d", i, j);
539 unlock_super (sb);
540 return 0;
541 }
542 if (!(bh = getblk (sb->s_dev, j, sb->s_blocksize))) {
543 ext2_error (sb, "ext2_new_block", "cannot get block %d", j);
544 unlock_super (sb);
545 return 0;
546 }
547 clear_block (bh->b_data, sb->s_blocksize);
548 bh->b_uptodate = 1;
549 bh->b_dirt = 1;
550 brelse (bh);
551
552 ext2_debug ("allocating block %d. "
553 "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
554
555 gdp->bg_free_blocks_count--;
556 bh2->b_dirt = 1;
557 es->s_free_blocks_count--;
558 sb->u.ext2_sb.s_sbh->b_dirt = 1;
559 sb->s_dirt = 1;
560 unlock_super (sb);
561 return j;
562 }
563
564 unsigned long ext2_count_free_blocks (struct super_block * sb)
565 {
566 #ifdef EXT2FS_DEBUG
567 struct ext2_super_block * es;
568 unsigned long desc_count, bitmap_count, x;
569 int bitmap_nr;
570 struct ext2_group_desc * gdp;
571 int i;
572
573 lock_super (sb);
574 es = sb->u.ext2_sb.s_es;
575 desc_count = 0;
576 bitmap_count = 0;
577 gdp = NULL;
578 for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
579 gdp = get_group_desc (sb, i, NULL);
580 desc_count += gdp->bg_free_blocks_count;
581 bitmap_nr = load_block_bitmap (sb, i);
582 x = ext2_count_free (sb->u.ext2_sb.s_block_bitmap[bitmap_nr],
583 sb->s_blocksize);
584 printk ("group %d: stored = %d, counted = %lu\n",
585 i, gdp->bg_free_blocks_count, x);
586 bitmap_count += x;
587 }
588 printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",
589 es->s_free_blocks_count, desc_count, bitmap_count);
590 unlock_super (sb);
591 return bitmap_count;
592 #else
593 return sb->u.ext2_sb.s_es->s_free_blocks_count;
594 #endif
595 }
596
597 static inline int block_in_use (unsigned long block,
598 struct super_block * sb,
599 unsigned char * map)
600 {
601 return test_bit ((block - sb->u.ext2_sb.s_es->s_first_data_block) %
602 EXT2_BLOCKS_PER_GROUP(sb), map);
603 }
604
605 void ext2_check_blocks_bitmap (struct super_block * sb)
606 {
607 struct buffer_head * bh;
608 struct ext2_super_block * es;
609 unsigned long desc_count, bitmap_count, x;
610 int bitmap_nr;
611 struct ext2_group_desc * gdp;
612 int i, j;
613
614 lock_super (sb);
615 es = sb->u.ext2_sb.s_es;
616 desc_count = 0;
617 bitmap_count = 0;
618 gdp = NULL;
619 for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
620 gdp = get_group_desc (sb, i, NULL);
621 desc_count += gdp->bg_free_blocks_count;
622 bitmap_nr = load_block_bitmap (sb, i);
623 bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
624
625 if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data))
626 ext2_error (sb, "ext2_check_blocks_bitmap",
627 "Block bitmap for group %d is marked free",
628 i);
629
630 if (!block_in_use (gdp->bg_inode_bitmap, sb, bh->b_data))
631 ext2_error (sb, "ext2_check_blocks_bitmap",
632 "Inode bitmap for group %d is marked free",
633 i);
634
635 for (j = 0; j < sb->u.ext2_sb.s_itb_per_group; j++)
636 if (!block_in_use (gdp->bg_inode_table + j, sb, bh->b_data))
637 ext2_error (sb, "ext2_check_blocks_bitmap",
638 "Block #%d of the inode table in group %d "
639 "is marked free", j, i);
640
641 x = ext2_count_free (bh, sb->s_blocksize);
642 if (gdp->bg_free_blocks_count != x)
643 ext2_error (sb, "ext2_check_blocks_bitmap",
644 "Wrong free blocks count for group %d, "
645 "stored = %d, counted = %lu", i,
646 gdp->bg_free_blocks_count, x);
647 bitmap_count += x;
648 }
649 if (es->s_free_blocks_count != bitmap_count)
650 ext2_error (sb, "ext2_check_blocks_bitmap",
651 "Wrong free blocks count in super block, "
652 "stored = %lu, counted = %lu",
653 es->s_free_blocks_count, bitmap_count);
654 unlock_super (sb);
655 }