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