| .. | .. |
|---|
| 36 | 36 | unsigned long bitmap_nr) |
|---|
| 37 | 37 | { |
|---|
| 38 | 38 | struct buffer_head *bh = NULL; |
|---|
| 39 | | - int retval = 0; |
|---|
| 39 | + int i; |
|---|
| 40 | + int max_bits, off, count; |
|---|
| 40 | 41 | struct kernel_lb_addr loc; |
|---|
| 41 | 42 | |
|---|
| 42 | 43 | loc.logicalBlockNum = bitmap->s_extPosition; |
|---|
| 43 | 44 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; |
|---|
| 44 | 45 | |
|---|
| 45 | 46 | bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block)); |
|---|
| 46 | | - if (!bh) |
|---|
| 47 | | - retval = -EIO; |
|---|
| 48 | | - |
|---|
| 49 | 47 | bitmap->s_block_bitmap[bitmap_nr] = bh; |
|---|
| 50 | | - return retval; |
|---|
| 48 | + if (!bh) |
|---|
| 49 | + return -EIO; |
|---|
| 50 | + |
|---|
| 51 | + /* Check consistency of Space Bitmap buffer. */ |
|---|
| 52 | + max_bits = sb->s_blocksize * 8; |
|---|
| 53 | + if (!bitmap_nr) { |
|---|
| 54 | + off = sizeof(struct spaceBitmapDesc) << 3; |
|---|
| 55 | + count = min(max_bits - off, bitmap->s_nr_groups); |
|---|
| 56 | + } else { |
|---|
| 57 | + /* |
|---|
| 58 | + * Rough check if bitmap number is too big to have any bitmap |
|---|
| 59 | + * blocks reserved. |
|---|
| 60 | + */ |
|---|
| 61 | + if (bitmap_nr > |
|---|
| 62 | + (bitmap->s_nr_groups >> (sb->s_blocksize_bits + 3)) + 2) |
|---|
| 63 | + return 0; |
|---|
| 64 | + off = 0; |
|---|
| 65 | + count = bitmap->s_nr_groups - bitmap_nr * max_bits + |
|---|
| 66 | + (sizeof(struct spaceBitmapDesc) << 3); |
|---|
| 67 | + count = min(count, max_bits); |
|---|
| 68 | + } |
|---|
| 69 | + |
|---|
| 70 | + for (i = 0; i < count; i++) |
|---|
| 71 | + if (udf_test_bit(i + off, bh->b_data)) |
|---|
| 72 | + return -EFSCORRUPTED; |
|---|
| 73 | + return 0; |
|---|
| 51 | 74 | } |
|---|
| 52 | 75 | |
|---|
| 53 | 76 | static int __load_block_bitmap(struct super_block *sb, |
|---|
| .. | .. |
|---|
| 175 | 198 | { |
|---|
| 176 | 199 | struct udf_sb_info *sbi = UDF_SB(sb); |
|---|
| 177 | 200 | int alloc_count = 0; |
|---|
| 178 | | - int bit, block, block_group, group_start; |
|---|
| 179 | | - int nr_groups, bitmap_nr; |
|---|
| 201 | + int bit, block, block_group; |
|---|
| 202 | + int bitmap_nr; |
|---|
| 180 | 203 | struct buffer_head *bh; |
|---|
| 181 | 204 | __u32 part_len; |
|---|
| 182 | 205 | |
|---|
| .. | .. |
|---|
| 189 | 212 | block_count = part_len - first_block; |
|---|
| 190 | 213 | |
|---|
| 191 | 214 | do { |
|---|
| 192 | | - nr_groups = udf_compute_nr_groups(sb, partition); |
|---|
| 193 | 215 | block = first_block + (sizeof(struct spaceBitmapDesc) << 3); |
|---|
| 194 | 216 | block_group = block >> (sb->s_blocksize_bits + 3); |
|---|
| 195 | | - group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc); |
|---|
| 196 | 217 | |
|---|
| 197 | 218 | bitmap_nr = load_block_bitmap(sb, bitmap, block_group); |
|---|
| 198 | 219 | if (bitmap_nr < 0) |
|---|
| .. | .. |
|---|
| 326 | 347 | got_block: |
|---|
| 327 | 348 | newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - |
|---|
| 328 | 349 | (sizeof(struct spaceBitmapDesc) << 3); |
|---|
| 350 | + |
|---|
| 351 | + if (newblock >= sbi->s_partmaps[partition].s_partition_len) { |
|---|
| 352 | + /* |
|---|
| 353 | + * Ran off the end of the bitmap, and bits following are |
|---|
| 354 | + * non-compliant (not all zero) |
|---|
| 355 | + */ |
|---|
| 356 | + udf_err(sb, "bitmap for partition %d corrupted (block %u marked" |
|---|
| 357 | + " as free, partition length is %u)\n", partition, |
|---|
| 358 | + newblock, sbi->s_partmaps[partition].s_partition_len); |
|---|
| 359 | + goto error_return; |
|---|
| 360 | + } |
|---|
| 329 | 361 | |
|---|
| 330 | 362 | if (!udf_clear_bit(bit, bh->b_data)) { |
|---|
| 331 | 363 | udf_debug("bit already cleared for block %d\n", bit); |
|---|
| .. | .. |
|---|
| 555 | 587 | udf_pblk_t newblock = 0; |
|---|
| 556 | 588 | uint32_t adsize; |
|---|
| 557 | 589 | uint32_t elen, goal_elen = 0; |
|---|
| 558 | | - struct kernel_lb_addr eloc, uninitialized_var(goal_eloc); |
|---|
| 590 | + struct kernel_lb_addr eloc, goal_eloc; |
|---|
| 559 | 591 | struct extent_position epos, goal_epos; |
|---|
| 560 | 592 | int8_t etype; |
|---|
| 561 | 593 | struct udf_inode_info *iinfo = UDF_I(table); |
|---|
| .. | .. |
|---|
| 652 | 684 | } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { |
|---|
| 653 | 685 | udf_table_free_blocks(sb, map->s_uspace.s_table, |
|---|
| 654 | 686 | bloc, offset, count); |
|---|
| 655 | | - } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { |
|---|
| 656 | | - udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap, |
|---|
| 657 | | - bloc, offset, count); |
|---|
| 658 | | - } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { |
|---|
| 659 | | - udf_table_free_blocks(sb, map->s_fspace.s_table, |
|---|
| 660 | | - bloc, offset, count); |
|---|
| 661 | 687 | } |
|---|
| 662 | 688 | |
|---|
| 663 | 689 | if (inode) { |
|---|
| .. | .. |
|---|
| 684 | 710 | map->s_uspace.s_table, |
|---|
| 685 | 711 | partition, first_block, |
|---|
| 686 | 712 | block_count); |
|---|
| 687 | | - else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
|---|
| 688 | | - allocated = udf_bitmap_prealloc_blocks(sb, |
|---|
| 689 | | - map->s_fspace.s_bitmap, |
|---|
| 690 | | - partition, first_block, |
|---|
| 691 | | - block_count); |
|---|
| 692 | | - else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
|---|
| 693 | | - allocated = udf_table_prealloc_blocks(sb, |
|---|
| 694 | | - map->s_fspace.s_table, |
|---|
| 695 | | - partition, first_block, |
|---|
| 696 | | - block_count); |
|---|
| 697 | 713 | else |
|---|
| 698 | 714 | return 0; |
|---|
| 699 | 715 | |
|---|
| .. | .. |
|---|
| 716 | 732 | else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) |
|---|
| 717 | 733 | block = udf_table_new_block(sb, |
|---|
| 718 | 734 | map->s_uspace.s_table, |
|---|
| 719 | | - partition, goal, err); |
|---|
| 720 | | - else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
|---|
| 721 | | - block = udf_bitmap_new_block(sb, |
|---|
| 722 | | - map->s_fspace.s_bitmap, |
|---|
| 723 | | - partition, goal, err); |
|---|
| 724 | | - else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
|---|
| 725 | | - block = udf_table_new_block(sb, |
|---|
| 726 | | - map->s_fspace.s_table, |
|---|
| 727 | 735 | partition, goal, err); |
|---|
| 728 | 736 | else { |
|---|
| 729 | 737 | *err = -EIO; |
|---|