6b13f685e
김민수
BSP 최초 추가
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#include <linux/slab.h>
#include "hfsplus_fs.h"
#define HFS_DD_BLK 0 /* Driver Descriptor block */
#define HFS_PMAP_BLK 1 /* First block of partition map */
#define HFS_MDB_BLK 2 /* Block (w/i partition) of MDB */
#define HFS_DRVR_DESC_MAGIC 0x4552 /* "ER": driver descriptor map */
#define HFS_OLD_PMAP_MAGIC 0x5453 /* "TS": old-type partition map */
#define HFS_NEW_PMAP_MAGIC 0x504D /* "PM": new-type partition map */
#define HFS_SUPER_MAGIC 0x4244 /* "BD": HFS MDB (super block) */
#define HFS_MFS_SUPER_MAGIC 0xD2D7 /* MFS MDB (super block) */
struct new_pmap {
__be16 pmSig;
__be16 reSigPad;
__be32 pmMapBlkCnt;
__be32 pmPyPartStart;
__be32 pmPartBlkCnt;
u8 pmPartName[32];
u8 pmPartType[32];
} __packed;
struct old_pmap {
__be16 pdSig;
struct old_pmap_entry {
__be32 pdStart;
__be32 pdSize;
__be32 pdFSID;
} pdEntry[42];
} __packed;
static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm,
sector_t *part_start, sector_t *part_size)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
int i;
for (i = 0; i < 42; i++) {
struct old_pmap_entry *p = &pm->pdEntry[i];
if (p->pdStart && p->pdSize &&
p->pdFSID == cpu_to_be32(0x54465331) &&
(sbi->part < 0 || sbi->part == i)) {
*part_start += be32_to_cpu(p->pdStart);
*part_size = be32_to_cpu(p->pdSize);
return 0;
}
}
return -ENOENT;
}
static int hfs_parse_new_pmap(struct super_block *sb, void *buf,
struct new_pmap *pm, sector_t *part_start, sector_t *part_size)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
int size = be32_to_cpu(pm->pmMapBlkCnt);
int buf_size = hfsplus_min_io_size(sb);
int res;
int i = 0;
do {
if (!memcmp(pm->pmPartType, "Apple_HFS", 9) &&
(sbi->part < 0 || sbi->part == i)) {
*part_start += be32_to_cpu(pm->pmPyPartStart);
*part_size = be32_to_cpu(pm->pmPartBlkCnt);
return 0;
}
if (++i >= size)
return -ENOENT;
pm = (struct new_pmap *)((u8 *)pm + HFSPLUS_SECTOR_SIZE);
if ((u8 *)pm - (u8 *)buf >= buf_size) {
res = hfsplus_submit_bio(sb,
*part_start + HFS_PMAP_BLK + i,
buf, (void **)&pm, READ);
if (res)
return res;
}
} while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC));
return -ENOENT;
}
int hfs_part_find(struct super_block *sb,
sector_t *part_start, sector_t *part_size)
{
void *buf, *data;
int res;
buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
if (!buf)
return -ENOMEM;
res = hfsplus_submit_bio(sb, *part_start + HFS_PMAP_BLK,
buf, &data, READ);
if (res)
goto out;
switch (be16_to_cpu(*((__be16 *)data))) {
case HFS_OLD_PMAP_MAGIC:
res = hfs_parse_old_pmap(sb, data, part_start, part_size);
break;
case HFS_NEW_PMAP_MAGIC:
res = hfs_parse_new_pmap(sb, buf, data, part_start, part_size);
break;
default:
res = -ENOENT;
break;
}
out:
kfree(buf);
return res;
}
|