diff options
author | Christoph Hellwig <hch@tuxera.com> | 2010-11-23 08:37:51 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2010-11-23 08:37:51 -0500 |
commit | 358f26d52680cb150907302d4334359de7dd2d59 (patch) | |
tree | 9348f861b49d5dd51049e31971cc09ab151388bc | |
parent | 52399b171dfaea02b6944cd6feba49b624147126 (diff) |
hfsplus: use raw bio access for partition tables
Switch the hfsplus partition table reding for cdroms to use our bio
helpers. Again we don't rely on any caching in the buffer_heads, and
this gets rid of the last buffer_head use in hfsplus.
Signed-off-by: Christoph Hellwig <hch@tuxera.com>
-rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 17 | ||||
-rw-r--r-- | fs/hfsplus/part_tbl.c | 124 |
2 files changed, 71 insertions, 70 deletions
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 276ddb0fd0fd..0d8532d96694 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -401,23 +401,6 @@ static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode) | |||
401 | return list_entry(inode, struct hfsplus_inode_info, vfs_inode); | 401 | return list_entry(inode, struct hfsplus_inode_info, vfs_inode); |
402 | } | 402 | } |
403 | 403 | ||
404 | #define sb_bread512(sb, sec, data) ({ \ | ||
405 | struct buffer_head *__bh; \ | ||
406 | sector_t __block; \ | ||
407 | loff_t __start; \ | ||
408 | int __offset; \ | ||
409 | \ | ||
410 | __start = (loff_t)(sec) << HFSPLUS_SECTOR_SHIFT;\ | ||
411 | __block = __start >> (sb)->s_blocksize_bits; \ | ||
412 | __offset = __start & ((sb)->s_blocksize - 1); \ | ||
413 | __bh = sb_bread((sb), __block); \ | ||
414 | if (likely(__bh != NULL)) \ | ||
415 | data = (void *)(__bh->b_data + __offset);\ | ||
416 | else \ | ||
417 | data = NULL; \ | ||
418 | __bh; \ | ||
419 | }) | ||
420 | |||
421 | /* time macros */ | 404 | /* time macros */ |
422 | #define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U) | 405 | #define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U) |
423 | #define __hfsp_ut2mt(t) (cpu_to_be32(t + 2082844800U)) | 406 | #define __hfsp_ut2mt(t) (cpu_to_be32(t + 2082844800U)) |
diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c index 208b16c645cc..58918222a604 100644 --- a/fs/hfsplus/part_tbl.c +++ b/fs/hfsplus/part_tbl.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/slab.h> | ||
16 | #include "hfsplus_fs.h" | 17 | #include "hfsplus_fs.h" |
17 | 18 | ||
18 | /* offsets to various blocks */ | 19 | /* offsets to various blocks */ |
@@ -65,70 +66,87 @@ struct old_pmap { | |||
65 | } pdEntry[42]; | 66 | } pdEntry[42]; |
66 | } __packed; | 67 | } __packed; |
67 | 68 | ||
69 | static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm, | ||
70 | sector_t *part_start, sector_t *part_size) | ||
71 | { | ||
72 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | ||
73 | int i; | ||
74 | |||
75 | for (i = 0; i < 42; i++) { | ||
76 | struct old_pmap_entry *p = &pm->pdEntry[i]; | ||
77 | |||
78 | if (p->pdStart && p->pdSize && | ||
79 | p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ && | ||
80 | (sbi->part < 0 || sbi->part == i)) { | ||
81 | *part_start += be32_to_cpu(p->pdStart); | ||
82 | *part_size = be32_to_cpu(p->pdSize); | ||
83 | return 0; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | return -ENOENT; | ||
88 | } | ||
89 | |||
90 | static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm, | ||
91 | sector_t *part_start, sector_t *part_size) | ||
92 | { | ||
93 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | ||
94 | int size = be32_to_cpu(pm->pmMapBlkCnt); | ||
95 | int res; | ||
96 | int i = 0; | ||
97 | |||
98 | do { | ||
99 | if (!memcmp(pm->pmPartType,"Apple_HFS", 9) && | ||
100 | (sbi->part < 0 || sbi->part == i)) { | ||
101 | *part_start += be32_to_cpu(pm->pmPyPartStart); | ||
102 | *part_size = be32_to_cpu(pm->pmPartBlkCnt); | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | if (++i >= size) | ||
107 | return -ENOENT; | ||
108 | |||
109 | res = hfsplus_submit_bio(sb->s_bdev, | ||
110 | *part_start + HFS_PMAP_BLK + i, | ||
111 | pm, READ); | ||
112 | if (res) | ||
113 | return res; | ||
114 | } while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC)); | ||
115 | |||
116 | return -ENOENT; | ||
117 | } | ||
118 | |||
68 | /* | 119 | /* |
69 | * hfs_part_find() | 120 | * Parse the partition map looking for the start and length of a |
70 | * | 121 | * HFS/HFS+ partition. |
71 | * Parse the partition map looking for the | ||
72 | * start and length of the 'part'th HFS partition. | ||
73 | */ | 122 | */ |
74 | int hfs_part_find(struct super_block *sb, | 123 | int hfs_part_find(struct super_block *sb, |
75 | sector_t *part_start, sector_t *part_size) | 124 | sector_t *part_start, sector_t *part_size) |
76 | { | 125 | { |
77 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | 126 | void *data; |
78 | struct buffer_head *bh; | 127 | int res; |
79 | __be16 *data; | 128 | |
80 | int i, size, res; | 129 | data = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL); |
130 | if (!data) | ||
131 | return -ENOMEM; | ||
81 | 132 | ||
82 | res = -ENOENT; | 133 | res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK, |
83 | bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data); | 134 | data, READ); |
84 | if (!bh) | 135 | if (res) |
85 | return -EIO; | 136 | return res; |
86 | 137 | ||
87 | switch (be16_to_cpu(*data)) { | 138 | switch (be16_to_cpu(*((__be16 *)data))) { |
88 | case HFS_OLD_PMAP_MAGIC: | 139 | case HFS_OLD_PMAP_MAGIC: |
89 | { | 140 | res = hfs_parse_old_pmap(sb, data, part_start, part_size); |
90 | struct old_pmap *pm; | ||
91 | struct old_pmap_entry *p; | ||
92 | |||
93 | pm = (struct old_pmap *)bh->b_data; | ||
94 | p = pm->pdEntry; | ||
95 | size = 42; | ||
96 | for (i = 0; i < size; p++, i++) { | ||
97 | if (p->pdStart && p->pdSize && | ||
98 | p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ && | ||
99 | (sbi->part < 0 || sbi->part == i)) { | ||
100 | *part_start += be32_to_cpu(p->pdStart); | ||
101 | *part_size = be32_to_cpu(p->pdSize); | ||
102 | res = 0; | ||
103 | } | ||
104 | } | ||
105 | break; | 141 | break; |
106 | } | ||
107 | case HFS_NEW_PMAP_MAGIC: | 142 | case HFS_NEW_PMAP_MAGIC: |
108 | { | 143 | res = hfs_parse_new_pmap(sb, data, part_start, part_size); |
109 | struct new_pmap *pm; | 144 | break; |
110 | 145 | default: | |
111 | pm = (struct new_pmap *)bh->b_data; | 146 | res = -ENOENT; |
112 | size = be32_to_cpu(pm->pmMapBlkCnt); | ||
113 | for (i = 0; i < size;) { | ||
114 | if (!memcmp(pm->pmPartType,"Apple_HFS", 9) && | ||
115 | (sbi->part < 0 || sbi->part == i)) { | ||
116 | *part_start += be32_to_cpu(pm->pmPyPartStart); | ||
117 | *part_size = be32_to_cpu(pm->pmPartBlkCnt); | ||
118 | res = 0; | ||
119 | break; | ||
120 | } | ||
121 | brelse(bh); | ||
122 | bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK + ++i, pm); | ||
123 | if (!bh) | ||
124 | return -EIO; | ||
125 | if (pm->pmSig != cpu_to_be16(HFS_NEW_PMAP_MAGIC)) | ||
126 | break; | ||
127 | } | ||
128 | break; | 147 | break; |
129 | } | ||
130 | } | 148 | } |
131 | brelse(bh); | ||
132 | 149 | ||
150 | kfree(data); | ||
133 | return res; | 151 | return res; |
134 | } | 152 | } |