Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
fs
hfsplus
part_tbl.c
Go to the documentation of this file.
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 (
[email protected]
).
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,
READ
);
116
if
(res)
117
return
res
;
118
}
119
}
while
(pm->
pmSig
==
cpu_to_be16
(
HFS_NEW_PMAP_MAGIC
));
120
121
return
-
ENOENT
;
122
}
123
124
/*
125
* Parse the partition map looking for the start and length of a
126
* HFS/HFS+ partition.
127
*/
128
int
hfs_part_find
(
struct
super_block
*sb,
129
sector_t
*part_start,
sector_t
*part_size)
130
{
131
void
*
buf
, *
data
;
132
int
res
;
133
134
buf =
kmalloc
(hfsplus_min_io_size(sb),
GFP_KERNEL
);
135
if
(!buf)
136
return
-
ENOMEM
;
137
138
res =
hfsplus_submit_bio
(sb, *part_start +
HFS_PMAP_BLK
,
139
buf, &data,
READ
);
140
if
(res)
141
goto
out
;
142
143
switch
(
be16_to_cpu
(*((
__be16
*)data))) {
144
case
HFS_OLD_PMAP_MAGIC
:
145
res = hfs_parse_old_pmap(sb, data, part_start, part_size);
146
break
;
147
case
HFS_NEW_PMAP_MAGIC
:
148
res = hfs_parse_new_pmap(sb, buf, data, part_start, part_size);
149
break
;
150
default
:
151
res = -
ENOENT
;
152
break
;
153
}
154
out
:
155
kfree
(buf);
156
return
res
;
157
}
Generated on Thu Jan 10 2013 14:47:22 for Linux Kernel by
1.8.2