part_tbl.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * linux/fs/hfsplus/part_tbl.c
  3. *
  4. * Copyright (C) 1996-1997 Paul H. Hargrove
  5. * This file may be distributed under the terms of the GNU General Public License.
  6. *
  7. * Original code to handle the new style Mac partition table based on
  8. * a patch contributed by Holger Schemel (aeglos@valinor.owl.de).
  9. *
  10. * In function preconditions the term "valid" applied to a pointer to
  11. * a structure means that the pointer is non-NULL and the structure it
  12. * points to has all fields initialized to consistent values.
  13. *
  14. */
  15. #include "hfsplus_fs.h"
  16. /* offsets to various blocks */
  17. #define HFS_DD_BLK 0 /* Driver Descriptor block */
  18. #define HFS_PMAP_BLK 1 /* First block of partition map */
  19. #define HFS_MDB_BLK 2 /* Block (w/i partition) of MDB */
  20. /* magic numbers for various disk blocks */
  21. #define HFS_DRVR_DESC_MAGIC 0x4552 /* "ER": driver descriptor map */
  22. #define HFS_OLD_PMAP_MAGIC 0x5453 /* "TS": old-type partition map */
  23. #define HFS_NEW_PMAP_MAGIC 0x504D /* "PM": new-type partition map */
  24. #define HFS_SUPER_MAGIC 0x4244 /* "BD": HFS MDB (super block) */
  25. #define HFS_MFS_SUPER_MAGIC 0xD2D7 /* MFS MDB (super block) */
  26. /*
  27. * The new style Mac partition map
  28. *
  29. * For each partition on the media there is a physical block (512-byte
  30. * block) containing one of these structures. These blocks are
  31. * contiguous starting at block 1.
  32. */
  33. struct new_pmap {
  34. __be16 pmSig; /* signature */
  35. __be16 reSigPad; /* padding */
  36. __be32 pmMapBlkCnt; /* partition blocks count */
  37. __be32 pmPyPartStart; /* physical block start of partition */
  38. __be32 pmPartBlkCnt; /* physical block count of partition */
  39. u8 pmPartName[32]; /* (null terminated?) string
  40. giving the name of this
  41. partition */
  42. u8 pmPartType[32]; /* (null terminated?) string
  43. giving the type of this
  44. partition */
  45. /* a bunch more stuff we don't need */
  46. } __packed;
  47. /*
  48. * The old style Mac partition map
  49. *
  50. * The partition map consists for a 2-byte signature followed by an
  51. * array of these structures. The map is terminated with an all-zero
  52. * one of these.
  53. */
  54. struct old_pmap {
  55. __be16 pdSig; /* Signature bytes */
  56. struct old_pmap_entry {
  57. __be32 pdStart;
  58. __be32 pdSize;
  59. __be32 pdFSID;
  60. } pdEntry[42];
  61. } __packed;
  62. /*
  63. * hfs_part_find()
  64. *
  65. * Parse the partition map looking for the
  66. * start and length of the 'part'th HFS partition.
  67. */
  68. int hfs_part_find(struct super_block *sb,
  69. sector_t *part_start, sector_t *part_size)
  70. {
  71. struct buffer_head *bh;
  72. __be16 *data;
  73. int i, size, res;
  74. res = -ENOENT;
  75. bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data);
  76. if (!bh)
  77. return -EIO;
  78. switch (be16_to_cpu(*data)) {
  79. case HFS_OLD_PMAP_MAGIC:
  80. {
  81. struct old_pmap *pm;
  82. struct old_pmap_entry *p;
  83. pm = (struct old_pmap *)bh->b_data;
  84. p = pm->pdEntry;
  85. size = 42;
  86. for (i = 0; i < size; p++, i++) {
  87. if (p->pdStart && p->pdSize &&
  88. p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ &&
  89. (HFSPLUS_SB(sb).part < 0 || HFSPLUS_SB(sb).part == i)) {
  90. *part_start += be32_to_cpu(p->pdStart);
  91. *part_size = be32_to_cpu(p->pdSize);
  92. res = 0;
  93. }
  94. }
  95. break;
  96. }
  97. case HFS_NEW_PMAP_MAGIC:
  98. {
  99. struct new_pmap *pm;
  100. pm = (struct new_pmap *)bh->b_data;
  101. size = be32_to_cpu(pm->pmMapBlkCnt);
  102. for (i = 0; i < size;) {
  103. if (!memcmp(pm->pmPartType,"Apple_HFS", 9) &&
  104. (HFSPLUS_SB(sb).part < 0 || HFSPLUS_SB(sb).part == i)) {
  105. *part_start += be32_to_cpu(pm->pmPyPartStart);
  106. *part_size = be32_to_cpu(pm->pmPartBlkCnt);
  107. res = 0;
  108. break;
  109. }
  110. brelse(bh);
  111. bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK + ++i, pm);
  112. if (!bh)
  113. return -EIO;
  114. if (pm->pmSig != cpu_to_be16(HFS_NEW_PMAP_MAGIC))
  115. break;
  116. }
  117. break;
  118. }
  119. }
  120. brelse(bh);
  121. return res;
  122. }