partition.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * partition.c
  4. *
  5. * PURPOSE
  6. * Partition handling routines for the OSTA-UDF(tm) filesystem.
  7. *
  8. * COPYRIGHT
  9. * (C) 1998-2001 Ben Fennema
  10. *
  11. * HISTORY
  12. *
  13. * 12/06/98 blf Created file.
  14. *
  15. */
  16. #include "udfdecl.h"
  17. #include "udf_sb.h"
  18. #include "udf_i.h"
  19. #include <linux/fs.h>
  20. #include <linux/string.h>
  21. #include <linux/mutex.h>
  22. uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
  23. uint16_t partition, uint32_t offset)
  24. {
  25. struct udf_sb_info *sbi = UDF_SB(sb);
  26. struct udf_part_map *map;
  27. if (partition >= sbi->s_partitions) {
  28. udf_debug("block=%u, partition=%u, offset=%u: invalid partition\n",
  29. block, partition, offset);
  30. return 0xFFFFFFFF;
  31. }
  32. map = &sbi->s_partmaps[partition];
  33. if (map->s_partition_func)
  34. return map->s_partition_func(sb, block, partition, offset);
  35. else
  36. return map->s_partition_root + block + offset;
  37. }
  38. uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
  39. uint16_t partition, uint32_t offset)
  40. {
  41. struct buffer_head *bh = NULL;
  42. uint32_t newblock;
  43. uint32_t index;
  44. uint32_t loc;
  45. struct udf_sb_info *sbi = UDF_SB(sb);
  46. struct udf_part_map *map;
  47. struct udf_virtual_data *vdata;
  48. struct udf_inode_info *iinfo = UDF_I(sbi->s_vat_inode);
  49. int err;
  50. map = &sbi->s_partmaps[partition];
  51. vdata = &map->s_type_specific.s_virtual;
  52. if (block > vdata->s_num_entries) {
  53. udf_debug("Trying to access block beyond end of VAT (%u max %u)\n",
  54. block, vdata->s_num_entries);
  55. return 0xFFFFFFFF;
  56. }
  57. if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
  58. loc = le32_to_cpu(((__le32 *)(iinfo->i_data +
  59. vdata->s_start_offset))[block]);
  60. goto translate;
  61. }
  62. index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
  63. if (block >= index) {
  64. block -= index;
  65. newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
  66. index = block % (sb->s_blocksize / sizeof(uint32_t));
  67. } else {
  68. newblock = 0;
  69. index = vdata->s_start_offset / sizeof(uint32_t) + block;
  70. }
  71. bh = udf_bread(sbi->s_vat_inode, newblock, 0, &err);
  72. if (!bh) {
  73. udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%u,%u)\n",
  74. sb, block, partition);
  75. return 0xFFFFFFFF;
  76. }
  77. loc = le32_to_cpu(((__le32 *)bh->b_data)[index]);
  78. brelse(bh);
  79. translate:
  80. if (iinfo->i_location.partitionReferenceNum == partition) {
  81. udf_debug("recursive call to udf_get_pblock!\n");
  82. return 0xFFFFFFFF;
  83. }
  84. return udf_get_pblock(sb, loc,
  85. iinfo->i_location.partitionReferenceNum,
  86. offset);
  87. }
  88. inline uint32_t udf_get_pblock_virt20(struct super_block *sb, uint32_t block,
  89. uint16_t partition, uint32_t offset)
  90. {
  91. return udf_get_pblock_virt15(sb, block, partition, offset);
  92. }
  93. uint32_t udf_get_pblock_spar15(struct super_block *sb, uint32_t block,
  94. uint16_t partition, uint32_t offset)
  95. {
  96. int i;
  97. struct sparingTable *st = NULL;
  98. struct udf_sb_info *sbi = UDF_SB(sb);
  99. struct udf_part_map *map;
  100. uint32_t packet;
  101. struct udf_sparing_data *sdata;
  102. map = &sbi->s_partmaps[partition];
  103. sdata = &map->s_type_specific.s_sparing;
  104. packet = (block + offset) & ~(sdata->s_packet_len - 1);
  105. for (i = 0; i < 4; i++) {
  106. if (sdata->s_spar_map[i] != NULL) {
  107. st = (struct sparingTable *)
  108. sdata->s_spar_map[i]->b_data;
  109. break;
  110. }
  111. }
  112. if (st) {
  113. for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) {
  114. struct sparingEntry *entry = &st->mapEntry[i];
  115. u32 origLoc = le32_to_cpu(entry->origLocation);
  116. if (origLoc >= 0xFFFFFFF0)
  117. break;
  118. else if (origLoc == packet)
  119. return le32_to_cpu(entry->mappedLocation) +
  120. ((block + offset) &
  121. (sdata->s_packet_len - 1));
  122. else if (origLoc > packet)
  123. break;
  124. }
  125. }
  126. return map->s_partition_root + block + offset;
  127. }
  128. int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
  129. {
  130. struct udf_sparing_data *sdata;
  131. struct sparingTable *st = NULL;
  132. struct sparingEntry mapEntry;
  133. uint32_t packet;
  134. int i, j, k, l;
  135. struct udf_sb_info *sbi = UDF_SB(sb);
  136. u16 reallocationTableLen;
  137. struct buffer_head *bh;
  138. int ret = 0;
  139. mutex_lock(&sbi->s_alloc_mutex);
  140. for (i = 0; i < sbi->s_partitions; i++) {
  141. struct udf_part_map *map = &sbi->s_partmaps[i];
  142. if (old_block > map->s_partition_root &&
  143. old_block < map->s_partition_root + map->s_partition_len) {
  144. sdata = &map->s_type_specific.s_sparing;
  145. packet = (old_block - map->s_partition_root) &
  146. ~(sdata->s_packet_len - 1);
  147. for (j = 0; j < 4; j++)
  148. if (sdata->s_spar_map[j] != NULL) {
  149. st = (struct sparingTable *)
  150. sdata->s_spar_map[j]->b_data;
  151. break;
  152. }
  153. if (!st) {
  154. ret = 1;
  155. goto out;
  156. }
  157. reallocationTableLen =
  158. le16_to_cpu(st->reallocationTableLen);
  159. for (k = 0; k < reallocationTableLen; k++) {
  160. struct sparingEntry *entry = &st->mapEntry[k];
  161. u32 origLoc = le32_to_cpu(entry->origLocation);
  162. if (origLoc == 0xFFFFFFFF) {
  163. for (; j < 4; j++) {
  164. int len;
  165. bh = sdata->s_spar_map[j];
  166. if (!bh)
  167. continue;
  168. st = (struct sparingTable *)
  169. bh->b_data;
  170. entry->origLocation =
  171. cpu_to_le32(packet);
  172. len =
  173. sizeof(struct sparingTable) +
  174. reallocationTableLen *
  175. sizeof(struct sparingEntry);
  176. udf_update_tag((char *)st, len);
  177. mark_buffer_dirty(bh);
  178. }
  179. *new_block = le32_to_cpu(
  180. entry->mappedLocation) +
  181. ((old_block -
  182. map->s_partition_root) &
  183. (sdata->s_packet_len - 1));
  184. ret = 0;
  185. goto out;
  186. } else if (origLoc == packet) {
  187. *new_block = le32_to_cpu(
  188. entry->mappedLocation) +
  189. ((old_block -
  190. map->s_partition_root) &
  191. (sdata->s_packet_len - 1));
  192. ret = 0;
  193. goto out;
  194. } else if (origLoc > packet)
  195. break;
  196. }
  197. for (l = k; l < reallocationTableLen; l++) {
  198. struct sparingEntry *entry = &st->mapEntry[l];
  199. u32 origLoc = le32_to_cpu(entry->origLocation);
  200. if (origLoc != 0xFFFFFFFF)
  201. continue;
  202. for (; j < 4; j++) {
  203. bh = sdata->s_spar_map[j];
  204. if (!bh)
  205. continue;
  206. st = (struct sparingTable *)bh->b_data;
  207. mapEntry = st->mapEntry[l];
  208. mapEntry.origLocation =
  209. cpu_to_le32(packet);
  210. memmove(&st->mapEntry[k + 1],
  211. &st->mapEntry[k],
  212. (l - k) *
  213. sizeof(struct sparingEntry));
  214. st->mapEntry[k] = mapEntry;
  215. udf_update_tag((char *)st,
  216. sizeof(struct sparingTable) +
  217. reallocationTableLen *
  218. sizeof(struct sparingEntry));
  219. mark_buffer_dirty(bh);
  220. }
  221. *new_block =
  222. le32_to_cpu(
  223. st->mapEntry[k].mappedLocation) +
  224. ((old_block - map->s_partition_root) &
  225. (sdata->s_packet_len - 1));
  226. ret = 0;
  227. goto out;
  228. }
  229. ret = 1;
  230. goto out;
  231. } /* if old_block */
  232. }
  233. if (i == sbi->s_partitions) {
  234. /* outside of partitions */
  235. /* for now, fail =) */
  236. ret = 1;
  237. }
  238. out:
  239. mutex_unlock(&sbi->s_alloc_mutex);
  240. return ret;
  241. }
  242. static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block,
  243. uint16_t partition, uint32_t offset)
  244. {
  245. struct super_block *sb = inode->i_sb;
  246. struct udf_part_map *map;
  247. struct kernel_lb_addr eloc;
  248. uint32_t elen;
  249. sector_t ext_offset;
  250. struct extent_position epos = {};
  251. uint32_t phyblock;
  252. int8_t etype;
  253. int err = 0;
  254. err = inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset, &etype);
  255. if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30))
  256. phyblock = 0xFFFFFFFF;
  257. else {
  258. map = &UDF_SB(sb)->s_partmaps[partition];
  259. /* map to sparable/physical partition desc */
  260. phyblock = udf_get_pblock(sb, eloc.logicalBlockNum,
  261. map->s_type_specific.s_metadata.s_phys_partition_ref,
  262. ext_offset + offset);
  263. }
  264. brelse(epos.bh);
  265. return phyblock;
  266. }
  267. uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block,
  268. uint16_t partition, uint32_t offset)
  269. {
  270. struct udf_sb_info *sbi = UDF_SB(sb);
  271. struct udf_part_map *map;
  272. struct udf_meta_data *mdata;
  273. uint32_t retblk;
  274. struct inode *inode;
  275. udf_debug("READING from METADATA\n");
  276. map = &sbi->s_partmaps[partition];
  277. mdata = &map->s_type_specific.s_metadata;
  278. inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe;
  279. if (!inode)
  280. return 0xFFFFFFFF;
  281. retblk = udf_try_read_meta(inode, block, partition, offset);
  282. if (retblk == 0xFFFFFFFF && mdata->s_metadata_fe) {
  283. udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n");
  284. if (!(mdata->s_flags & MF_MIRROR_FE_LOADED)) {
  285. mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb,
  286. mdata->s_mirror_file_loc,
  287. mdata->s_phys_partition_ref);
  288. if (IS_ERR(mdata->s_mirror_fe))
  289. mdata->s_mirror_fe = NULL;
  290. mdata->s_flags |= MF_MIRROR_FE_LOADED;
  291. }
  292. inode = mdata->s_mirror_fe;
  293. if (!inode)
  294. return 0xFFFFFFFF;
  295. retblk = udf_try_read_meta(inode, block, partition, offset);
  296. }
  297. return retblk;
  298. }