]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - fs/udf/partition.c
5 * Partition handling routines for the OSTA-UDF(tm) filesystem.
8 * This file is distributed under the terms of the GNU General Public
9 * License (GPL). Copies of the GPL can be obtained from:
10 * ftp://prep.ai.mit.edu/pub/gnu/GPL
11 * Each contributing author retains all rights to their own work.
13 * (C) 1998-2001 Ben Fennema
17 * 12/06/98 blf Created file.
26 #include <linux/string.h>
27 #include <linux/udf_fs.h>
28 #include <linux/slab.h>
29 #include <linux/buffer_head.h>
31 inline uint32_t udf_get_pblock(struct super_block
*sb
, uint32_t block
,
32 uint16_t partition
, uint32_t offset
)
34 if (partition
>= UDF_SB_NUMPARTS(sb
)) {
36 ("block=%d, partition=%d, offset=%d: invalid partition\n",
37 block
, partition
, offset
);
40 if (UDF_SB_PARTFUNC(sb
, partition
))
41 return UDF_SB_PARTFUNC(sb
, partition
) (sb
, block
, partition
,
44 return UDF_SB_PARTROOT(sb
, partition
) + block
+ offset
;
47 uint32_t udf_get_pblock_virt15(struct super_block
* sb
, uint32_t block
,
48 uint16_t partition
, uint32_t offset
)
50 struct buffer_head
*bh
= NULL
;
57 UDF_SB_TYPEVIRT(sb
, partition
).s_start_offset
) / sizeof(uint32_t);
59 if (block
> UDF_SB_TYPEVIRT(sb
, partition
).s_num_entries
) {
61 ("Trying to access block beyond end of VAT (%d max %d)\n",
62 block
, UDF_SB_TYPEVIRT(sb
, partition
).s_num_entries
);
68 newblock
= 1 + (block
/ (sb
->s_blocksize
/ sizeof(uint32_t)));
69 index
= block
% (sb
->s_blocksize
/ sizeof(uint32_t));
74 partition
).s_start_offset
/
75 sizeof(uint32_t) + block
;
78 loc
= udf_block_map(UDF_SB_VAT(sb
), newblock
);
80 if (!(bh
= sb_bread(sb
, loc
))) {
81 udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
82 sb
, block
, partition
, loc
, index
);
86 loc
= le32_to_cpu(((__le32
*) bh
->b_data
)[index
]);
90 if (UDF_I_LOCATION(UDF_SB_VAT(sb
)).partitionReferenceNum
== partition
) {
91 udf_debug("recursive call to udf_get_pblock!\n");
95 return udf_get_pblock(sb
, loc
,
96 UDF_I_LOCATION(UDF_SB_VAT(sb
)).
97 partitionReferenceNum
, offset
);
100 inline uint32_t udf_get_pblock_virt20(struct super_block
* sb
, uint32_t block
,
101 uint16_t partition
, uint32_t offset
)
103 return udf_get_pblock_virt15(sb
, block
, partition
, offset
);
106 uint32_t udf_get_pblock_spar15(struct super_block
* sb
, uint32_t block
,
107 uint16_t partition
, uint32_t offset
)
110 struct sparingTable
*st
= NULL
;
112 (block
+ offset
) & ~(UDF_SB_TYPESPAR(sb
, partition
).s_packet_len
-
115 for (i
= 0; i
< 4; i
++) {
116 if (UDF_SB_TYPESPAR(sb
, partition
).s_spar_map
[i
] != NULL
) {
117 st
= (struct sparingTable
*)UDF_SB_TYPESPAR(sb
,
119 s_spar_map
[i
]->b_data
;
125 for (i
= 0; i
< le16_to_cpu(st
->reallocationTableLen
); i
++) {
126 if (le32_to_cpu(st
->mapEntry
[i
].origLocation
) >=
129 else if (le32_to_cpu(st
->mapEntry
[i
].origLocation
) ==
131 return le32_to_cpu(st
->mapEntry
[i
].
132 mappedLocation
) + ((block
+
139 } else if (le32_to_cpu(st
->mapEntry
[i
].origLocation
) >
144 return UDF_SB_PARTROOT(sb
, partition
) + block
+ offset
;
147 int udf_relocate_blocks(struct super_block
*sb
, long old_block
, long *new_block
)
149 struct udf_sparing_data
*sdata
;
150 struct sparingTable
*st
= NULL
;
151 struct sparingEntry mapEntry
;
155 for (i
= 0; i
< UDF_SB_NUMPARTS(sb
); i
++) {
156 if (old_block
> UDF_SB_PARTROOT(sb
, i
) &&
157 old_block
< UDF_SB_PARTROOT(sb
, i
) + UDF_SB_PARTLEN(sb
, i
))
159 sdata
= &UDF_SB_TYPESPAR(sb
, i
);
163 i
)) & ~(sdata
->s_packet_len
- 1);
165 for (j
= 0; j
< 4; j
++) {
166 if (UDF_SB_TYPESPAR(sb
, i
).s_spar_map
[j
] !=
168 st
= (struct sparingTable
*)sdata
->
169 s_spar_map
[j
]->b_data
;
177 for (k
= 0; k
< le16_to_cpu(st
->reallocationTableLen
);
179 if (le32_to_cpu(st
->mapEntry
[k
].origLocation
) ==
182 if (sdata
->s_spar_map
[j
]) {
191 udf_update_tag((char *)
199 reallocationTableLen
)
210 le32_to_cpu(st
->mapEntry
[k
].
220 (st
->mapEntry
[k
].origLocation
) ==
223 le32_to_cpu(st
->mapEntry
[k
].
233 (st
->mapEntry
[k
].origLocation
) > packet
)
236 for (l
= k
; l
< le16_to_cpu(st
->reallocationTableLen
);
238 if (le32_to_cpu(st
->mapEntry
[l
].origLocation
) ==
241 if (sdata
->s_spar_map
[j
]) {
249 mapEntry
.origLocation
=
261 udf_update_tag((char *)
269 reallocationTableLen
)
280 le32_to_cpu(st
->mapEntry
[k
].
293 if (i
== UDF_SB_NUMPARTS(sb
)) {
294 /* outside of partitions */
295 /* for now, fail =) */