root/fs/hfsplus/part_tbl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hfs_parse_old_pmap
  2. hfs_parse_new_pmap
  3. hfs_part_find

   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
   6  * 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  * In function preconditions the term "valid" applied to a pointer to
  12  * a structure means that the pointer is non-NULL and the structure it
  13  * points to has all fields initialized to consistent values.
  14  *
  15  */
  16 
  17 #include <linux/slab.h>
  18 #include "hfsplus_fs.h"
  19 
  20 /* offsets to various blocks */
  21 #define HFS_DD_BLK              0 /* Driver Descriptor block */
  22 #define HFS_PMAP_BLK            1 /* First block of partition map */
  23 #define HFS_MDB_BLK             2 /* Block (w/i partition) of MDB */
  24 
  25 /* magic numbers for various disk blocks */
  26 #define HFS_DRVR_DESC_MAGIC     0x4552 /* "ER": driver descriptor map */
  27 #define HFS_OLD_PMAP_MAGIC      0x5453 /* "TS": old-type partition map */
  28 #define HFS_NEW_PMAP_MAGIC      0x504D /* "PM": new-type partition map */
  29 #define HFS_SUPER_MAGIC         0x4244 /* "BD": HFS MDB (super block) */
  30 #define HFS_MFS_SUPER_MAGIC     0xD2D7 /* MFS MDB (super block) */
  31 
  32 /*
  33  * The new style Mac partition map
  34  *
  35  * For each partition on the media there is a physical block (512-byte
  36  * block) containing one of these structures.  These blocks are
  37  * contiguous starting at block 1.
  38  */
  39 struct new_pmap {
  40         __be16  pmSig;          /* signature */
  41         __be16  reSigPad;       /* padding */
  42         __be32  pmMapBlkCnt;    /* partition blocks count */
  43         __be32  pmPyPartStart;  /* physical block start of partition */
  44         __be32  pmPartBlkCnt;   /* physical block count of partition */
  45         u8      pmPartName[32]; /* (null terminated?) string
  46                                    giving the name of this
  47                                    partition */
  48         u8      pmPartType[32]; /* (null terminated?) string
  49                                    giving the type of this
  50                                    partition */
  51         /* a bunch more stuff we don't need */
  52 } __packed;
  53 
  54 /*
  55  * The old style Mac partition map
  56  *
  57  * The partition map consists for a 2-byte signature followed by an
  58  * array of these structures.  The map is terminated with an all-zero
  59  * one of these.
  60  */
  61 struct old_pmap {
  62         __be16          pdSig;  /* Signature bytes */
  63         struct old_pmap_entry {
  64                 __be32  pdStart;
  65                 __be32  pdSize;
  66                 __be32  pdFSID;
  67         }       pdEntry[42];
  68 } __packed;
  69 
  70 static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm,
  71                 sector_t *part_start, sector_t *part_size)
  72 {
  73         struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
  74         int i;
  75 
  76         for (i = 0; i < 42; i++) {
  77                 struct old_pmap_entry *p = &pm->pdEntry[i];
  78 
  79                 if (p->pdStart && p->pdSize &&
  80                     p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ &&
  81                     (sbi->part < 0 || sbi->part == i)) {
  82                         *part_start += be32_to_cpu(p->pdStart);
  83                         *part_size = be32_to_cpu(p->pdSize);
  84                         return 0;
  85                 }
  86         }
  87 
  88         return -ENOENT;
  89 }
  90 
  91 static int hfs_parse_new_pmap(struct super_block *sb, void *buf,
  92                 struct new_pmap *pm, sector_t *part_start, sector_t *part_size)
  93 {
  94         struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
  95         int size = be32_to_cpu(pm->pmMapBlkCnt);
  96         int buf_size = hfsplus_min_io_size(sb);
  97         int res;
  98         int i = 0;
  99 
 100         do {
 101                 if (!memcmp(pm->pmPartType, "Apple_HFS", 9) &&
 102                     (sbi->part < 0 || sbi->part == i)) {
 103                         *part_start += be32_to_cpu(pm->pmPyPartStart);
 104                         *part_size = be32_to_cpu(pm->pmPartBlkCnt);
 105                         return 0;
 106                 }
 107 
 108                 if (++i >= size)
 109                         return -ENOENT;
 110 
 111                 pm = (struct new_pmap *)((u8 *)pm + HFSPLUS_SECTOR_SIZE);
 112                 if ((u8 *)pm - (u8 *)buf >= buf_size) {
 113                         res = hfsplus_submit_bio(sb,
 114                                                  *part_start + HFS_PMAP_BLK + i,
 115                                                  buf, (void **)&pm, REQ_OP_READ,
 116                                                  0);
 117                         if (res)
 118                                 return res;
 119                 }
 120         } while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC));
 121 
 122         return -ENOENT;
 123 }
 124 
 125 /*
 126  * Parse the partition map looking for the start and length of a
 127  * HFS/HFS+ partition.
 128  */
 129 int hfs_part_find(struct super_block *sb,
 130                 sector_t *part_start, sector_t *part_size)
 131 {
 132         void *buf, *data;
 133         int res;
 134 
 135         buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
 136         if (!buf)
 137                 return -ENOMEM;
 138 
 139         res = hfsplus_submit_bio(sb, *part_start + HFS_PMAP_BLK,
 140                                  buf, &data, REQ_OP_READ, 0);
 141         if (res)
 142                 goto out;
 143 
 144         switch (be16_to_cpu(*((__be16 *)data))) {
 145         case HFS_OLD_PMAP_MAGIC:
 146                 res = hfs_parse_old_pmap(sb, data, part_start, part_size);
 147                 break;
 148         case HFS_NEW_PMAP_MAGIC:
 149                 res = hfs_parse_new_pmap(sb, buf, data, part_start, part_size);
 150                 break;
 151         default:
 152                 res = -ENOENT;
 153                 break;
 154         }
 155 out:
 156         kfree(buf);
 157         return res;
 158 }

/* [<][>][^][v][top][bottom][index][help] */