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