diff options
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r-- | fs/udf/super.c | 93 |
1 files changed, 20 insertions, 73 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 3040dc2a32f6..6f515651a2c2 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -764,9 +764,7 @@ static int udf_find_fileset(struct super_block *sb, | |||
764 | struct kernel_lb_addr *root) | 764 | struct kernel_lb_addr *root) |
765 | { | 765 | { |
766 | struct buffer_head *bh = NULL; | 766 | struct buffer_head *bh = NULL; |
767 | long lastblock; | ||
768 | uint16_t ident; | 767 | uint16_t ident; |
769 | struct udf_sb_info *sbi; | ||
770 | 768 | ||
771 | if (fileset->logicalBlockNum != 0xFFFFFFFF || | 769 | if (fileset->logicalBlockNum != 0xFFFFFFFF || |
772 | fileset->partitionReferenceNum != 0xFFFF) { | 770 | fileset->partitionReferenceNum != 0xFFFF) { |
@@ -779,69 +777,11 @@ static int udf_find_fileset(struct super_block *sb, | |||
779 | return 1; | 777 | return 1; |
780 | } | 778 | } |
781 | 779 | ||
782 | } | ||
783 | |||
784 | sbi = UDF_SB(sb); | ||
785 | if (!bh) { | ||
786 | /* Search backwards through the partitions */ | ||
787 | struct kernel_lb_addr newfileset; | ||
788 | |||
789 | /* --> cvg: FIXME - is it reasonable? */ | ||
790 | return 1; | ||
791 | |||
792 | for (newfileset.partitionReferenceNum = sbi->s_partitions - 1; | ||
793 | (newfileset.partitionReferenceNum != 0xFFFF && | ||
794 | fileset->logicalBlockNum == 0xFFFFFFFF && | ||
795 | fileset->partitionReferenceNum == 0xFFFF); | ||
796 | newfileset.partitionReferenceNum--) { | ||
797 | lastblock = sbi->s_partmaps | ||
798 | [newfileset.partitionReferenceNum] | ||
799 | .s_partition_len; | ||
800 | newfileset.logicalBlockNum = 0; | ||
801 | |||
802 | do { | ||
803 | bh = udf_read_ptagged(sb, &newfileset, 0, | ||
804 | &ident); | ||
805 | if (!bh) { | ||
806 | newfileset.logicalBlockNum++; | ||
807 | continue; | ||
808 | } | ||
809 | |||
810 | switch (ident) { | ||
811 | case TAG_IDENT_SBD: | ||
812 | { | ||
813 | struct spaceBitmapDesc *sp; | ||
814 | sp = (struct spaceBitmapDesc *) | ||
815 | bh->b_data; | ||
816 | newfileset.logicalBlockNum += 1 + | ||
817 | ((le32_to_cpu(sp->numOfBytes) + | ||
818 | sizeof(struct spaceBitmapDesc) | ||
819 | - 1) >> sb->s_blocksize_bits); | ||
820 | brelse(bh); | ||
821 | break; | ||
822 | } | ||
823 | case TAG_IDENT_FSD: | ||
824 | *fileset = newfileset; | ||
825 | break; | ||
826 | default: | ||
827 | newfileset.logicalBlockNum++; | ||
828 | brelse(bh); | ||
829 | bh = NULL; | ||
830 | break; | ||
831 | } | ||
832 | } while (newfileset.logicalBlockNum < lastblock && | ||
833 | fileset->logicalBlockNum == 0xFFFFFFFF && | ||
834 | fileset->partitionReferenceNum == 0xFFFF); | ||
835 | } | ||
836 | } | ||
837 | |||
838 | if ((fileset->logicalBlockNum != 0xFFFFFFFF || | ||
839 | fileset->partitionReferenceNum != 0xFFFF) && bh) { | ||
840 | udf_debug("Fileset at block=%u, partition=%u\n", | 780 | udf_debug("Fileset at block=%u, partition=%u\n", |
841 | fileset->logicalBlockNum, | 781 | fileset->logicalBlockNum, |
842 | fileset->partitionReferenceNum); | 782 | fileset->partitionReferenceNum); |
843 | 783 | ||
844 | sbi->s_partition = fileset->partitionReferenceNum; | 784 | UDF_SB(sb)->s_partition = fileset->partitionReferenceNum; |
845 | udf_load_fileset(sb, bh, root); | 785 | udf_load_fileset(sb, bh, root); |
846 | brelse(bh); | 786 | brelse(bh); |
847 | return 0; | 787 | return 0; |
@@ -1570,10 +1510,16 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ | |||
1570 | */ | 1510 | */ |
1571 | #define PART_DESC_ALLOC_STEP 32 | 1511 | #define PART_DESC_ALLOC_STEP 32 |
1572 | 1512 | ||
1513 | struct part_desc_seq_scan_data { | ||
1514 | struct udf_vds_record rec; | ||
1515 | u32 partnum; | ||
1516 | }; | ||
1517 | |||
1573 | struct desc_seq_scan_data { | 1518 | struct desc_seq_scan_data { |
1574 | struct udf_vds_record vds[VDS_POS_LENGTH]; | 1519 | struct udf_vds_record vds[VDS_POS_LENGTH]; |
1575 | unsigned int size_part_descs; | 1520 | unsigned int size_part_descs; |
1576 | struct udf_vds_record *part_descs_loc; | 1521 | unsigned int num_part_descs; |
1522 | struct part_desc_seq_scan_data *part_descs_loc; | ||
1577 | }; | 1523 | }; |
1578 | 1524 | ||
1579 | static struct udf_vds_record *handle_partition_descriptor( | 1525 | static struct udf_vds_record *handle_partition_descriptor( |
@@ -1582,10 +1528,14 @@ static struct udf_vds_record *handle_partition_descriptor( | |||
1582 | { | 1528 | { |
1583 | struct partitionDesc *desc = (struct partitionDesc *)bh->b_data; | 1529 | struct partitionDesc *desc = (struct partitionDesc *)bh->b_data; |
1584 | int partnum; | 1530 | int partnum; |
1531 | int i; | ||
1585 | 1532 | ||
1586 | partnum = le16_to_cpu(desc->partitionNumber); | 1533 | partnum = le16_to_cpu(desc->partitionNumber); |
1587 | if (partnum >= data->size_part_descs) { | 1534 | for (i = 0; i < data->num_part_descs; i++) |
1588 | struct udf_vds_record *new_loc; | 1535 | if (partnum == data->part_descs_loc[i].partnum) |
1536 | return &(data->part_descs_loc[i].rec); | ||
1537 | if (data->num_part_descs >= data->size_part_descs) { | ||
1538 | struct part_desc_seq_scan_data *new_loc; | ||
1589 | unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP); | 1539 | unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP); |
1590 | 1540 | ||
1591 | new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL); | 1541 | new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL); |
@@ -1597,7 +1547,7 @@ static struct udf_vds_record *handle_partition_descriptor( | |||
1597 | data->part_descs_loc = new_loc; | 1547 | data->part_descs_loc = new_loc; |
1598 | data->size_part_descs = new_size; | 1548 | data->size_part_descs = new_size; |
1599 | } | 1549 | } |
1600 | return &(data->part_descs_loc[partnum]); | 1550 | return &(data->part_descs_loc[data->num_part_descs++].rec); |
1601 | } | 1551 | } |
1602 | 1552 | ||
1603 | 1553 | ||
@@ -1647,6 +1597,7 @@ static noinline int udf_process_sequence( | |||
1647 | 1597 | ||
1648 | memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); | 1598 | memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); |
1649 | data.size_part_descs = PART_DESC_ALLOC_STEP; | 1599 | data.size_part_descs = PART_DESC_ALLOC_STEP; |
1600 | data.num_part_descs = 0; | ||
1650 | data.part_descs_loc = kcalloc(data.size_part_descs, | 1601 | data.part_descs_loc = kcalloc(data.size_part_descs, |
1651 | sizeof(*data.part_descs_loc), | 1602 | sizeof(*data.part_descs_loc), |
1652 | GFP_KERNEL); | 1603 | GFP_KERNEL); |
@@ -1658,7 +1609,6 @@ static noinline int udf_process_sequence( | |||
1658 | * are in it. | 1609 | * are in it. |
1659 | */ | 1610 | */ |
1660 | for (; (!done && block <= lastblock); block++) { | 1611 | for (; (!done && block <= lastblock); block++) { |
1661 | |||
1662 | bh = udf_read_tagged(sb, block, block, &ident); | 1612 | bh = udf_read_tagged(sb, block, block, &ident); |
1663 | if (!bh) | 1613 | if (!bh) |
1664 | break; | 1614 | break; |
@@ -1730,13 +1680,10 @@ static noinline int udf_process_sequence( | |||
1730 | } | 1680 | } |
1731 | 1681 | ||
1732 | /* Now handle prevailing Partition Descriptors */ | 1682 | /* Now handle prevailing Partition Descriptors */ |
1733 | for (i = 0; i < data.size_part_descs; i++) { | 1683 | for (i = 0; i < data.num_part_descs; i++) { |
1734 | if (data.part_descs_loc[i].block) { | 1684 | ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block); |
1735 | ret = udf_load_partdesc(sb, | 1685 | if (ret < 0) |
1736 | data.part_descs_loc[i].block); | 1686 | return ret; |
1737 | if (ret < 0) | ||
1738 | return ret; | ||
1739 | } | ||
1740 | } | 1687 | } |
1741 | 1688 | ||
1742 | return 0; | 1689 | return 0; |