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 16 #include "hfsplus_fs.h" 17 18 /* offsets to various blocks */ 19 #define HFS_DD_BLK 0 /* Driver Descriptor block */ 20 #define HFS_PMAP_BLK 1 /* First block of partition map */ 21 #define HFS_MDB_BLK 2 /* Block (w/i partition) of MDB */ 22 23 /* magic numbers for various disk blocks */ 24 #define HFS_DRVR_DESC_MAGIC 0x4552 /* "ER": driver descriptor map */ 25 #define HFS_OLD_PMAP_MAGIC 0x5453 /* "TS": old-type partition map */ 26 #define HFS_NEW_PMAP_MAGIC 0x504D /* "PM": new-type partition map */ 27 #define HFS_SUPER_MAGIC 0x4244 /* "BD": HFS MDB (super block) */ 28 #define HFS_MFS_SUPER_MAGIC 0xD2D7 /* MFS MDB (super block) */ 29 30 /* 31 * The new style Mac partition map 32 * 33 * For each partition on the media there is a physical block (512-byte 34 * block) containing one of these structures. These blocks are 35 * contiguous starting at block 1. 36 */ 37 struct new_pmap { 38 __be16 pmSig; /* signature */ 39 __be16 reSigPad; /* padding */ 40 __be32 pmMapBlkCnt; /* partition blocks count */ 41 __be32 pmPyPartStart; /* physical block start of partition */ 42 __be32 pmPartBlkCnt; /* physical block count of partition */ 43 u8 pmPartName[32]; /* (null terminated?) string 44 giving the name of this 45 partition */ 46 u8 pmPartType[32]; /* (null terminated?) string 47 giving the type of this 48 partition */ 49 /* a bunch more stuff we don't need */ 50 } __packed; 51 52 /* 53 * The old style Mac partition map 54 * 55 * The partition map consists for a 2-byte signature followed by an 56 * array of these structures. The map is terminated with an all-zero 57 * one of these. 58 */ 59 struct old_pmap { 60 __be16 pdSig; /* Signature bytes */ 61 struct old_pmap_entry { 62 __be32 pdStart; 63 __be32 pdSize; 64 __be32 pdFSID; 65 } pdEntry[42]; 66 } __packed; 67 68 /* 69 * hfs_part_find() 70 * 71 * Parse the partition map looking for the 72 * start and length of the 'part'th HFS partition. 73 */ 74 int hfs_part_find(struct super_block *sb, 75 sector_t *part_start, sector_t *part_size) 76 { 77 struct buffer_head *bh; 78 __be16 *data; 79 int i, size, res; 80 81 res = -ENOENT; 82 bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data); 83 if (!bh) 84 return -EIO; 85 86 switch (be16_to_cpu(*data)) { 87 case HFS_OLD_PMAP_MAGIC: 88 { 89 struct old_pmap *pm; 90 struct old_pmap_entry *p; 91 92 pm = (struct old_pmap *)bh->b_data; 93 p = pm->pdEntry; 94 size = 42; 95 for (i = 0; i < size; p++, i++) { 96 if (p->pdStart && p->pdSize && 97 p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ && 98 (HFSPLUS_SB(sb).part < 0 || HFSPLUS_SB(sb).part == i)) { 99 *part_start += be32_to_cpu(p->pdStart); 100 *part_size = be32_to_cpu(p->pdSize); 101 res = 0; 102 } 103 } 104 break; 105 } 106 case HFS_NEW_PMAP_MAGIC: 107 { 108 struct new_pmap *pm; 109 110 pm = (struct new_pmap *)bh->b_data; 111 size = be32_to_cpu(pm->pmMapBlkCnt); 112 for (i = 0; i < size;) { 113 if (!memcmp(pm->pmPartType,"Apple_HFS", 9) && 114 (HFSPLUS_SB(sb).part < 0 || HFSPLUS_SB(sb).part == i)) { 115 *part_start += be32_to_cpu(pm->pmPyPartStart); 116 *part_size = be32_to_cpu(pm->pmPartBlkCnt); 117 res = 0; 118 break; 119 } 120 brelse(bh); 121 bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK + ++i, pm); 122 if (!bh) 123 return -EIO; 124 if (pm->pmSig != cpu_to_be16(HFS_NEW_PMAP_MAGIC)) 125 break; 126 } 127 break; 128 } 129 } 130 brelse(bh); 131 132 return res; 133 } 134