Skip to content

Commit

Permalink
hfsplus: use raw bio access for partition tables
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Christoph Hellwig committed Nov 23, 2010
1 parent 52399b1 commit 358f26d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 70 deletions.
17 changes: 0 additions & 17 deletions fs/hfsplus/hfsplus_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,23 +401,6 @@ static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode)
return list_entry(inode, struct hfsplus_inode_info, vfs_inode);
}

#define sb_bread512(sb, sec, data) ({ \
struct buffer_head *__bh; \
sector_t __block; \
loff_t __start; \
int __offset; \
\
__start = (loff_t)(sec) << HFSPLUS_SECTOR_SHIFT;\
__block = __start >> (sb)->s_blocksize_bits; \
__offset = __start & ((sb)->s_blocksize - 1); \
__bh = sb_bread((sb), __block); \
if (likely(__bh != NULL)) \
data = (void *)(__bh->b_data + __offset);\
else \
data = NULL; \
__bh; \
})

/* time macros */
#define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U)
#define __hfsp_ut2mt(t) (cpu_to_be32(t + 2082844800U))
Expand Down
124 changes: 71 additions & 53 deletions fs/hfsplus/part_tbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*
*/

#include <linux/slab.h>
#include "hfsplus_fs.h"

/* offsets to various blocks */
Expand Down Expand Up @@ -65,70 +66,87 @@ struct old_pmap {
} 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)/*"TFS1"*/ &&
(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, 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 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;

res = hfsplus_submit_bio(sb->s_bdev,
*part_start + HFS_PMAP_BLK + i,
pm, READ);
if (res)
return res;
} while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC));

return -ENOENT;
}

/*
* hfs_part_find()
*
* Parse the partition map looking for the
* start and length of the 'part'th HFS partition.
* Parse the partition map looking for the start and length of a
* HFS/HFS+ partition.
*/
int hfs_part_find(struct super_block *sb,
sector_t *part_start, sector_t *part_size)
sector_t *part_start, sector_t *part_size)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
struct buffer_head *bh;
__be16 *data;
int i, size, res;
void *data;
int res;

data = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;

res = -ENOENT;
bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data);
if (!bh)
return -EIO;
res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
data, READ);
if (res)
return res;

switch (be16_to_cpu(*data)) {
switch (be16_to_cpu(*((__be16 *)data))) {
case HFS_OLD_PMAP_MAGIC:
{
struct old_pmap *pm;
struct old_pmap_entry *p;

pm = (struct old_pmap *)bh->b_data;
p = pm->pdEntry;
size = 42;
for (i = 0; i < size; p++, i++) {
if (p->pdStart && p->pdSize &&
p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ &&
(sbi->part < 0 || sbi->part == i)) {
*part_start += be32_to_cpu(p->pdStart);
*part_size = be32_to_cpu(p->pdSize);
res = 0;
}
}
res = hfs_parse_old_pmap(sb, data, part_start, part_size);
break;
}
case HFS_NEW_PMAP_MAGIC:
{
struct new_pmap *pm;

pm = (struct new_pmap *)bh->b_data;
size = be32_to_cpu(pm->pmMapBlkCnt);
for (i = 0; i < size;) {
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);
res = 0;
break;
}
brelse(bh);
bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK + ++i, pm);
if (!bh)
return -EIO;
if (pm->pmSig != cpu_to_be16(HFS_NEW_PMAP_MAGIC))
break;
}
res = hfs_parse_new_pmap(sb, data, part_start, part_size);
break;
default:
res = -ENOENT;
break;
}
}
brelse(bh);

kfree(data);
return res;
}

0 comments on commit 358f26d

Please sign in to comment.