The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/hfs/part_tbl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * linux/fs/hfs/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  * "XXX" in a comment is a note to myself to consider changing something.
   11  *
   12  * In function preconditions the term "valid" applied to a pointer to
   13  * a structure means that the pointer is non-NULL and the structure it
   14  * points to has all fields initialized to consistent values.
   15  *
   16  * The code in this file initializes some structures which contain
   17  * pointers by calling memset(&foo, 0, sizeof(foo)).
   18  * This produces the desired behavior only due to the non-ANSI
   19  * assumption that the machine representation of NULL is all zeros.
   20  */
   21 
   22 #include "hfs.h"
   23 
   24 /*================ File-local data types ================*/
   25 
   26 /*
   27  * The Macintosh Driver Descriptor Block
   28  *
   29  * On partitioned Macintosh media this is block 0.
   30  * We really only need the "magic number" to check for partitioned media.
   31  */
   32 struct hfs_drvr_desc {
   33         hfs_word_t      ddSig;          /* The signature word */
   34         /* a bunch more stuff we don't need */
   35 };
   36 
   37 /* 
   38  * The new style Mac partition map
   39  *
   40  * For each partition on the media there is a physical block (512-byte
   41  * block) containing one of these structures.  These blocks are
   42  * contiguous starting at block 1.
   43  */
   44 struct new_pmap {
   45         hfs_word_t      pmSig;          /* Signature bytes to verify
   46                                            that this is a partition
   47                                            map block */
   48         hfs_word_t      reSigPad;       /* padding */
   49         hfs_lword_t     pmMapBlkCnt;    /* (At least in block 1) this
   50                                            is the number of partition
   51                                            map blocks */
   52         hfs_lword_t     pmPyPartStart;  /* The physical block number
   53                                            of the first block in this
   54                                            partition */
   55         hfs_lword_t     pmPartBlkCnt;   /* The number of physical
   56                                            blocks in this partition */
   57         hfs_byte_t      pmPartName[32]; /* (null terminated?) string
   58                                            giving the name of this
   59                                            partition */
   60         hfs_byte_t      pmPartType[32]; /* (null terminated?) string
   61                                            giving the type of this
   62                                            partition */
   63         /* a bunch more stuff we don't need */
   64 };
   65 
   66 /* 
   67  * The old style Mac partition map
   68  *
   69  * The partition map consists for a 2-byte signature followed by an
   70  * array of these structures.  The map is terminated with an all-zero
   71  * one of these.
   72  */
   73 struct old_pmap {
   74         hfs_word_t              pdSig;  /* Signature bytes */
   75         struct  old_pmap_entry {
   76                 hfs_lword_t     pdStart;
   77                 hfs_lword_t     pdSize;
   78                 hfs_lword_t     pdFSID;
   79         }       pdEntry[42];
   80 } __attribute__((packed));
   81 
   82 /*================ File-local functions ================*/
   83 
   84 /*
   85  * parse_new_part_table()
   86  *
   87  * Parse a new style partition map looking for the
   88  * start and length of the 'part'th HFS partition.
   89  */
   90 static int parse_new_part_table(hfs_sysmdb sys_mdb, hfs_buffer buf,
   91                                 int part, hfs_s32 *size, hfs_s32 *start)
   92 {
   93         struct new_pmap *pm = (struct new_pmap *)hfs_buffer_data(buf);
   94         hfs_u32 pmap_entries = hfs_get_hl(pm->pmMapBlkCnt);
   95         int hfs_part = 0;
   96         int entry;
   97 
   98         for (entry = 0; (entry < pmap_entries) && !(*start); ++entry) {
   99                 if (entry) {
  100                         /* read the next partition map entry */
  101                         buf = hfs_buffer_get(sys_mdb, HFS_PMAP_BLK + entry, 1);
  102                         if (!hfs_buffer_ok(buf)) {
  103                                 hfs_warn("hfs_fs: unable to "
  104                                          "read partition map.\n");
  105                                 goto bail;
  106                         }
  107                         pm = (struct new_pmap *)hfs_buffer_data(buf);
  108                         if (hfs_get_ns(pm->pmSig) !=
  109                                                 htons(HFS_NEW_PMAP_MAGIC)) {
  110                                 hfs_warn("hfs_fs: invalid "
  111                                          "entry in partition map\n");
  112                                 hfs_buffer_put(buf);
  113                                 goto bail;
  114                         }
  115                 }
  116 
  117                 /* look for an HFS partition */
  118                 if (!memcmp(pm->pmPartType,"Apple_HFS",9) && 
  119                     ((hfs_part++) == part)) {
  120                         /* Found it! */
  121                         *start = hfs_get_hl(pm->pmPyPartStart);
  122                         *size = hfs_get_hl(pm->pmPartBlkCnt);
  123                 }
  124 
  125                 hfs_buffer_put(buf);
  126         }
  127 
  128         return 0;
  129 
  130 bail:
  131         return 1;
  132 }
  133 
  134 /*
  135  * parse_old_part_table()
  136  *
  137  * Parse a old style partition map looking for the
  138  * start and length of the 'part'th HFS partition.
  139  */
  140 static int parse_old_part_table(hfs_sysmdb sys_mdb, hfs_buffer buf,
  141                                 int part, hfs_s32 *size, hfs_s32 *start)
  142 {
  143         struct old_pmap *pm = (struct old_pmap *)hfs_buffer_data(buf);
  144         struct old_pmap_entry *p = &pm->pdEntry[0];
  145         int hfs_part = 0;
  146 
  147         while ((p->pdStart || p->pdSize || p->pdFSID) && !(*start)) {
  148                 /* look for an HFS partition */
  149                 if ((hfs_get_nl(p->pdFSID) == htonl(0x54465331)/*"TFS1"*/) &&
  150                     ((hfs_part++) == part)) {
  151                         /* Found it! */
  152                         *start = hfs_get_hl(p->pdStart);
  153                         *size = hfs_get_hl(p->pdSize);
  154                 }
  155                 ++p;
  156         }
  157         hfs_buffer_put(buf);
  158 
  159         return 0;
  160 }
  161 
  162 /*================ Global functions ================*/
  163 
  164 /*
  165  * hfs_part_find()
  166  *
  167  * Parse the partition map looking for the
  168  * start and length of the 'part'th HFS partition.
  169  */
  170 int hfs_part_find(hfs_sysmdb sys_mdb, int part, int silent,
  171                   hfs_s32 *size, hfs_s32 *start)
  172 {
  173         hfs_buffer buf;
  174         hfs_u16 sig;
  175         int dd_found = 0;
  176         int retval = 1;
  177 
  178         /* Read block 0 to see if this media is partitioned */
  179         buf = hfs_buffer_get(sys_mdb, HFS_DD_BLK, 1);
  180         if (!hfs_buffer_ok(buf)) {
  181                 hfs_warn("hfs_fs: Unable to read block 0.\n");
  182                 goto done;
  183         }
  184         sig = hfs_get_ns(((struct hfs_drvr_desc *)hfs_buffer_data(buf))->ddSig);
  185         hfs_buffer_put(buf);
  186 
  187         if (sig == htons(HFS_DRVR_DESC_MAGIC)) {
  188                 /* We are definitely on partitioned media. */
  189                 dd_found = 1;
  190         }
  191 
  192         buf = hfs_buffer_get(sys_mdb, HFS_PMAP_BLK, 1);
  193         if (!hfs_buffer_ok(buf)) {
  194                 hfs_warn("hfs_fs: Unable to read block 1.\n");
  195                 goto done;
  196         }
  197 
  198         *size = *start = 0;
  199 
  200         switch (hfs_get_ns(hfs_buffer_data(buf))) {
  201         case __constant_htons(HFS_OLD_PMAP_MAGIC):
  202                 retval = parse_old_part_table(sys_mdb, buf, part, size, start);
  203                 break;
  204 
  205         case __constant_htons(HFS_NEW_PMAP_MAGIC):
  206                 retval = parse_new_part_table(sys_mdb, buf, part, size, start);
  207                 break;
  208 
  209         default:
  210                 if (dd_found) {
  211                         /* The media claimed to have a partition map */
  212                         if (!silent) {
  213                                 hfs_warn("hfs_fs: This disk has an "
  214                                          "unrecognized partition map type.\n");
  215                         }
  216                 } else {
  217                         /* Conclude that the media is not partitioned */
  218                         retval = 0;
  219                 }
  220                 goto done;
  221         }
  222 
  223         if (!retval) {
  224                 if (*start == 0) {
  225                         if (part) {
  226                                 hfs_warn("hfs_fs: unable to locate "
  227                                          "HFS partition number %d.\n", part);
  228                         } else {
  229                                 hfs_warn("hfs_fs: unable to locate any "
  230                                          "HFS partitions.\n");
  231                         }
  232                         retval = 1;
  233                 } else if (*size < 0) {
  234                         hfs_warn("hfs_fs: Partition size > 1 Terabyte.\n");
  235                         retval = 1;
  236                 } else if (*start < 0) {
  237                         hfs_warn("hfs_fs: Partition begins beyond 1 "
  238                                  "Terabyte.\n");
  239                         retval = 1;
  240                 }
  241         }
  242 done:
  243         return retval;
  244 }

Cache object: 4ca0440db2503f423961d3a97169ee3a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.