~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/hfs/part_tbl.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 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 }
245 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.