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