Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 358f26d5 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Christoph Hellwig
Browse files

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: default avatarChristoph Hellwig <hch@tuxera.com>
parent 52399b17
Loading
Loading
Loading
Loading
+0 −17
Original line number Diff line number Diff line
@@ -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))
+71 −53
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
 *
 */

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

/* offsets to various blocks */
@@ -65,70 +66,87 @@ struct old_pmap {
	}	pdEntry[42];
} __packed;

/*
 * hfs_part_find()
 *
 * Parse the partition map looking for the
 * start and length of the 'part'th HFS partition.
 */
int hfs_part_find(struct super_block *sb,
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);
	struct buffer_head *bh;
	__be16 *data;
	int i, size, res;
	int i;

	res = -ENOENT;
	bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data);
	if (!bh)
		return -EIO;
	for (i = 0; i < 42; i++) {
		struct old_pmap_entry *p = &pm->pdEntry[i];

	switch (be16_to_cpu(*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;
			return 0;
		}
	}
		break;

	return -ENOENT;
}
	case HFS_NEW_PMAP_MAGIC:

static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
		sector_t *part_start, sector_t *part_size)
{
		struct new_pmap *pm;
	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
	int size = be32_to_cpu(pm->pmMapBlkCnt);
	int res;
	int i = 0;

		pm = (struct new_pmap *)bh->b_data;
		size = be32_to_cpu(pm->pmMapBlkCnt);
		for (i = 0; i < size;) {
	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);
				res = 0;
				break;
			return 0;
		}
			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;

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

/*
 * 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)
{
	void *data;
	int res;

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

	res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
				 data, READ);
	if (res)
		return res;

	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, data, part_start, part_size);
		break;
	default:
		res = -ENOENT;
		break;
	}
	}
	brelse(bh);

	kfree(data);
	return res;
}