Linux Audio

Check our new training course

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