]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/udf/partition.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / fs / udf / partition.c
index eeb4714b36410f9da676d905bcd3b7f23d2e667a..fc533345ab89198a12fb472765f7c9073a356970 100644 (file)
@@ -34,8 +34,8 @@ inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
        struct udf_sb_info *sbi = UDF_SB(sb);
        struct udf_part_map *map;
        if (partition >= sbi->s_partitions) {
-               udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n",
-                         block, partition, offset);
+               udf_debug("block=%d, partition=%d, offset=%d: "
+                         "invalid partition\n", block, partition, offset);
                return 0xFFFFFFFF;
        }
        map = &sbi->s_partmaps[partition];
@@ -54,13 +54,16 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
        uint32_t loc;
        struct udf_sb_info *sbi = UDF_SB(sb);
        struct udf_part_map *map;
+       struct udf_virtual_data *vdata;
+       struct udf_inode_info *iinfo;
 
        map = &sbi->s_partmaps[partition];
-       index = (sb->s_blocksize - map->s_type_specific.s_virtual.s_start_offset) / sizeof(uint32_t);
+       vdata = &map->s_type_specific.s_virtual;
+       index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
 
-       if (block > map->s_type_specific.s_virtual.s_num_entries) {
-               udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
-                         block, map->s_type_specific.s_virtual.s_num_entries);
+       if (block > vdata->s_num_entries) {
+               udf_debug("Trying to access block beyond end of VAT "
+                         "(%d max %d)\n", block, vdata->s_num_entries);
                return 0xFFFFFFFF;
        }
 
@@ -70,12 +73,13 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
                index = block % (sb->s_blocksize / sizeof(uint32_t));
        } else {
                newblock = 0;
-               index = map->s_type_specific.s_virtual.s_start_offset / sizeof(uint32_t) + block;
+               index = vdata->s_start_offset / sizeof(uint32_t) + block;
        }
 
        loc = udf_block_map(sbi->s_vat_inode, newblock);
 
-       if (!(bh = sb_bread(sb, loc))) {
+       bh = sb_bread(sb, loc);
+       if (!bh) {
                udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
                          sb, block, partition, loc, index);
                return 0xFFFFFFFF;
@@ -85,17 +89,18 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
 
        brelse(bh);
 
-       if (UDF_I_LOCATION(sbi->s_vat_inode).partitionReferenceNum == partition) {
+       iinfo = UDF_I(sbi->s_vat_inode);
+       if (iinfo->i_location.partitionReferenceNum == partition) {
                udf_debug("recursive call to udf_get_pblock!\n");
                return 0xFFFFFFFF;
        }
 
        return udf_get_pblock(sb, loc,
-                             UDF_I_LOCATION(sbi->s_vat_inode).partitionReferenceNum,
+                             iinfo->i_location.partitionReferenceNum,
                              offset);
 }
 
-inline uint32_t udf_get_pblock_virt20(struct super_block * sb, uint32_t block,
+inline uint32_t udf_get_pblock_virt20(struct super_block *sb, uint32_t block,
                                      uint16_t partition, uint32_t offset)
 {
        return udf_get_pblock_virt15(sb, block, partition, offset);
@@ -109,27 +114,32 @@ uint32_t udf_get_pblock_spar15(struct super_block *sb, uint32_t block,
        struct udf_sb_info *sbi = UDF_SB(sb);
        struct udf_part_map *map;
        uint32_t packet;
+       struct udf_sparing_data *sdata;
 
        map = &sbi->s_partmaps[partition];
-       packet = (block + offset) & ~(map->s_type_specific.s_sparing.s_packet_len - 1);
+       sdata = &map->s_type_specific.s_sparing;
+       packet = (block + offset) & ~(sdata->s_packet_len - 1);
 
        for (i = 0; i < 4; i++) {
-               if (map->s_type_specific.s_sparing.s_spar_map[i] != NULL) {
-                       st = (struct sparingTable *)map->s_type_specific.s_sparing.s_spar_map[i]->b_data;
+               if (sdata->s_spar_map[i] != NULL) {
+                       st = (struct sparingTable *)
+                                       sdata->s_spar_map[i]->b_data;
                        break;
                }
        }
 
        if (st) {
                for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) {
-                       if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0) {
+                       struct sparingEntry *entry = &st->mapEntry[i];
+                       u32 origLoc = le32_to_cpu(entry->origLocation);
+                       if (origLoc >= 0xFFFFFFF0)
                                break;
-                       } else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet) {
-                               return le32_to_cpu(st->mapEntry[i].mappedLocation) +
-                                       ((block + offset) & (map->s_type_specific.s_sparing.s_packet_len - 1));
-                       } else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet) {
+                       else if (origLoc == packet)
+                               return le32_to_cpu(entry->mappedLocation) +
+                                       ((block + offset) &
+                                               (sdata->s_packet_len - 1));
+                       else if (origLoc > packet)
                                break;
-                       }
                }
        }
 
@@ -144,63 +154,101 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
        uint32_t packet;
        int i, j, k, l;
        struct udf_sb_info *sbi = UDF_SB(sb);
+       u16 reallocationTableLen;
+       struct buffer_head *bh;
 
        for (i = 0; i < sbi->s_partitions; i++) {
                struct udf_part_map *map = &sbi->s_partmaps[i];
                if (old_block > map->s_partition_root &&
                    old_block < map->s_partition_root + map->s_partition_len) {
                        sdata = &map->s_type_specific.s_sparing;
-                       packet = (old_block - map->s_partition_root) & ~(sdata->s_packet_len - 1);
+                       packet = (old_block - map->s_partition_root) &
+                                               ~(sdata->s_packet_len - 1);
 
-                       for (j = 0; j < 4; j++) {
-                               if (map->s_type_specific.s_sparing.s_spar_map[j] != NULL) {
-                                       st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
+                       for (j = 0; j < 4; j++)
+                               if (sdata->s_spar_map[j] != NULL) {
+                                       st = (struct sparingTable *)
+                                               sdata->s_spar_map[j]->b_data;
                                        break;
                                }
-                       }
 
                        if (!st)
                                return 1;
 
-                       for (k = 0; k < le16_to_cpu(st->reallocationTableLen); k++) {
-                               if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF) {
+                       reallocationTableLen =
+                                       le16_to_cpu(st->reallocationTableLen);
+                       for (k = 0; k < reallocationTableLen; k++) {
+                               struct sparingEntry *entry = &st->mapEntry[k];
+                               u32 origLoc = le32_to_cpu(entry->origLocation);
+
+                               if (origLoc == 0xFFFFFFFF) {
                                        for (; j < 4; j++) {
-                                               if (sdata->s_spar_map[j]) {
-                                                       st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
-                                                       st->mapEntry[k].origLocation = cpu_to_le32(packet);
-                                                       udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
-                                                       mark_buffer_dirty(sdata->s_spar_map[j]);
-                                               }
+                                               int len;
+                                               bh = sdata->s_spar_map[j];
+                                               if (!bh)
+                                                       continue;
+
+                                               st = (struct sparingTable *)
+                                                               bh->b_data;
+                                               entry->origLocation =
+                                                       cpu_to_le32(packet);
+                                               len =
+                                                 sizeof(struct sparingTable) +
+                                                 reallocationTableLen *
+                                                 sizeof(struct sparingEntry);
+                                               udf_update_tag((char *)st, len);
+                                               mark_buffer_dirty(bh);
                                        }
-                                       *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
-                                               ((old_block - map->s_partition_root) & (sdata->s_packet_len - 1));
+                                       *new_block = le32_to_cpu(
+                                                       entry->mappedLocation) +
+                                                    ((old_block -
+                                                       map->s_partition_root) &
+                                                    (sdata->s_packet_len - 1));
                                        return 0;
-                               } else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet) {
-                                       *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
-                                               ((old_block - map->s_partition_root) & (sdata->s_packet_len - 1));
+                               } else if (origLoc == packet) {
+                                       *new_block = le32_to_cpu(
+                                                       entry->mappedLocation) +
+                                                    ((old_block -
+                                                       map->s_partition_root) &
+                                                    (sdata->s_packet_len - 1));
                                        return 0;
-                               } else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet) {
+                               } else if (origLoc > packet)
                                        break;
-                               }
                        }
 
-                       for (l = k; l < le16_to_cpu(st->reallocationTableLen); l++) {
-                               if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF) {
-                                       for (; j < 4; j++) {
-                                               if (sdata->s_spar_map[j]) {
-                                                       st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
-                                                       mapEntry = st->mapEntry[l];
-                                                       mapEntry.origLocation = cpu_to_le32(packet);
-                                                       memmove(&st->mapEntry[k + 1], &st->mapEntry[k], (l - k) * sizeof(struct sparingEntry));
-                                                       st->mapEntry[k] = mapEntry;
-                                                       udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
-                                                       mark_buffer_dirty(sdata->s_spar_map[j]);
-                                               }
-                                       }
-                                       *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
-                                               ((old_block - map->s_partition_root) & (sdata->s_packet_len - 1));
-                                       return 0;
+                       for (l = k; l < reallocationTableLen; l++) {
+                               struct sparingEntry *entry = &st->mapEntry[l];
+                               u32 origLoc = le32_to_cpu(entry->origLocation);
+
+                               if (origLoc != 0xFFFFFFFF)
+                                       continue;
+
+                               for (; j < 4; j++) {
+                                       bh = sdata->s_spar_map[j];
+                                       if (!bh)
+                                               continue;
+
+                                       st = (struct sparingTable *)bh->b_data;
+                                       mapEntry = st->mapEntry[l];
+                                       mapEntry.origLocation =
+                                                       cpu_to_le32(packet);
+                                       memmove(&st->mapEntry[k + 1],
+                                               &st->mapEntry[k],
+                                               (l - k) *
+                                               sizeof(struct sparingEntry));
+                                       st->mapEntry[k] = mapEntry;
+                                       udf_update_tag((char *)st,
+                                               sizeof(struct sparingTable) +
+                                               reallocationTableLen *
+                                               sizeof(struct sparingEntry));
+                                       mark_buffer_dirty(bh);
                                }
+                               *new_block =
+                                       le32_to_cpu(
+                                             st->mapEntry[k].mappedLocation) +
+                                       ((old_block - map->s_partition_root) &
+                                        (sdata->s_packet_len - 1));
+                               return 0;
                        }
 
                        return 1;