.. | .. |
---|
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; |
---|