aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/udf/super.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 68d57b61f3af..6f515651a2c2 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1510,10 +1510,16 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_
1510 */ 1510 */
1511#define PART_DESC_ALLOC_STEP 32 1511#define PART_DESC_ALLOC_STEP 32
1512 1512
1513struct part_desc_seq_scan_data {
1514 struct udf_vds_record rec;
1515 u32 partnum;
1516};
1517
1513struct desc_seq_scan_data { 1518struct desc_seq_scan_data {
1514 struct udf_vds_record vds[VDS_POS_LENGTH]; 1519 struct udf_vds_record vds[VDS_POS_LENGTH];
1515 unsigned int size_part_descs; 1520 unsigned int size_part_descs;
1516 struct udf_vds_record *part_descs_loc; 1521 unsigned int num_part_descs;
1522 struct part_desc_seq_scan_data *part_descs_loc;
1517}; 1523};
1518 1524
1519static struct udf_vds_record *handle_partition_descriptor( 1525static struct udf_vds_record *handle_partition_descriptor(
@@ -1522,10 +1528,14 @@ static struct udf_vds_record *handle_partition_descriptor(
1522{ 1528{
1523 struct partitionDesc *desc = (struct partitionDesc *)bh->b_data; 1529 struct partitionDesc *desc = (struct partitionDesc *)bh->b_data;
1524 int partnum; 1530 int partnum;
1531 int i;
1525 1532
1526 partnum = le16_to_cpu(desc->partitionNumber); 1533 partnum = le16_to_cpu(desc->partitionNumber);
1527 if (partnum >= data->size_part_descs) { 1534 for (i = 0; i < data->num_part_descs; i++)
1528 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;
1529 unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP); 1539 unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
1530 1540
1531 new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL); 1541 new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
@@ -1537,7 +1547,7 @@ static struct udf_vds_record *handle_partition_descriptor(
1537 data->part_descs_loc = new_loc; 1547 data->part_descs_loc = new_loc;
1538 data->size_part_descs = new_size; 1548 data->size_part_descs = new_size;
1539 } 1549 }
1540 return &(data->part_descs_loc[partnum]); 1550 return &(data->part_descs_loc[data->num_part_descs++].rec);
1541} 1551}
1542 1552
1543 1553
@@ -1587,6 +1597,7 @@ static noinline int udf_process_sequence(
1587 1597
1588 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);
1589 data.size_part_descs = PART_DESC_ALLOC_STEP; 1599 data.size_part_descs = PART_DESC_ALLOC_STEP;
1600 data.num_part_descs = 0;
1590 data.part_descs_loc = kcalloc(data.size_part_descs, 1601 data.part_descs_loc = kcalloc(data.size_part_descs,
1591 sizeof(*data.part_descs_loc), 1602 sizeof(*data.part_descs_loc),
1592 GFP_KERNEL); 1603 GFP_KERNEL);
@@ -1598,7 +1609,6 @@ static noinline int udf_process_sequence(
1598 * are in it. 1609 * are in it.
1599 */ 1610 */
1600 for (; (!done && block <= lastblock); block++) { 1611 for (; (!done && block <= lastblock); block++) {
1601
1602 bh = udf_read_tagged(sb, block, block, &ident); 1612 bh = udf_read_tagged(sb, block, block, &ident);
1603 if (!bh) 1613 if (!bh)
1604 break; 1614 break;
@@ -1670,13 +1680,10 @@ static noinline int udf_process_sequence(
1670 } 1680 }
1671 1681
1672 /* Now handle prevailing Partition Descriptors */ 1682 /* Now handle prevailing Partition Descriptors */
1673 for (i = 0; i < data.size_part_descs; i++) { 1683 for (i = 0; i < data.num_part_descs; i++) {
1674 if (data.part_descs_loc[i].block) { 1684 ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block);
1675 ret = udf_load_partdesc(sb, 1685 if (ret < 0)
1676 data.part_descs_loc[i].block); 1686 return ret;
1677 if (ret < 0)
1678 return ret;
1679 }
1680 } 1687 }
1681 1688
1682 return 0; 1689 return 0;