/*
 *  linux/fs/hfsplus/wrapper.c
 *
 * Copyright (C) 2001
 * Brad Boyer (flar@allandria.com)
 * (C) 2003 Ardis Technologies <roman@ardistech.com>
 *
 * Handling of HFS wrappers around HFS+ volumes
 */

#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/cdrom.h>
#include <linux/genhd.h>
#include <linux/version.h>
#include <asm/unaligned.h>

#include "hfsplus_fs.h"
#include "hfsplus_raw.h"

struct hfsplus_wd {
	u32 ablk_size;
	u16 ablk_start;
	u16 embed_start;
	u16 embed_count;
};

static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd)
{
	u32 extent;
	u16 attrib;

	if (be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_EMBEDSIG)) != HFSPLUS_VOLHEAD_SIG)
		return 0;

	attrib = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ATTRIB));
	if (!(attrib & HFSP_WRAP_ATTRIB_SLOCK) ||
	   !(attrib & HFSP_WRAP_ATTRIB_SPARED))
		return 0;

	wd->ablk_size = be32_to_cpu(*(__be32 *)(bufptr + HFSP_WRAPOFF_ABLKSIZE));
	if (wd->ablk_size < HFSPLUS_SECTOR_SIZE)
		return 0;
	if (wd->ablk_size % HFSPLUS_SECTOR_SIZE)
		return 0;
	wd->ablk_start = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART));

	extent = be32_to_cpu(get_unaligned((__be32 *)(bufptr + HFSP_WRAPOFF_EMBEDEXT)));
	wd->embed_start = (extent >> 16) & 0xFFFF;
	wd->embed_count = extent & 0xFFFF;

	return 1;
}

static int hfsplus_get_last_session(struct super_block *sb,
				    sector_t *start, sector_t *size)
{
	struct cdrom_multisession ms_info;
	struct cdrom_tocentry te;
	int res;

	/* default values */
	*start = 0;
	*size = sb->s_bdev->bd_inode->i_size >> 9;

	if (HFSPLUS_SB(sb).session >= 0) {
		te.cdte_track = HFSPLUS_SB(sb).session;
		te.cdte_format = CDROM_LBA;
		res = ioctl_by_bdev(sb->s_bdev, CDROMREADTOCENTRY, (unsigned long)&te);
		if (!res && (te.cdte_ctrl & CDROM_DATA_TRACK) == 4) {
			*start = (sector_t)te.cdte_addr.lba << 2;
			return 0;
		}
		printk(KERN_ERR "HFS: Invalid session number or type of track\n");
		return -EINVAL;
	}
	ms_info.addr_format = CDROM_LBA;
	res = ioctl_by_bdev(sb->s_bdev, CDROMMULTISESSION, (unsigned long)&ms_info);
	if (!res && ms_info.xa_flag)
		*start = (sector_t)ms_info.addr.lba << 2;
	return 0;
}

/* Find the volume header and fill in some minimum bits in superblock */
/* Takes in super block, returns true if good data read */
int hfsplus_read_wrapper(struct super_block *sb)
{
	struct buffer_head *bh;
	struct hfsplus_vh *vhdr;
	struct hfsplus_wd wd;
	sector_t part_start, part_size;
	u32 blocksize;

	blocksize = sb_min_blocksize(sb, HFSPLUS_SECTOR_SIZE);
	if (!blocksize)
		return -EINVAL;

	if (hfsplus_get_last_session(sb, &part_start, &part_size))
		return -EINVAL;
	while (1) {
		bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
		if (!bh)
			return -EIO;

		if (vhdr->signature == cpu_to_be16(HFSP_WRAP_MAGIC)) {
			if (!hfsplus_read_mdb(vhdr, &wd))
				goto error;
			wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT;
			part_start += wd.ablk_start + wd.embed_start * wd.ablk_size;
			part_size = wd.embed_count * wd.ablk_size;
			brelse(bh);
			bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
			if (!bh)
				return -EIO;
		}
		if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG))
			break;
		brelse(bh);

		/* check for a partition block
		 * (should do this only for cdrom/loop though)
		 */
		if (hfs_part_find(sb, &part_start, &part_size))
			return -EINVAL;
	}

	blocksize = be32_to_cpu(vhdr->blocksize);
	brelse(bh);

	/* block size must be at least as large as a sector
	 * and a multiple of 2
	 */
	if (blocksize < HFSPLUS_SECTOR_SIZE ||
	    ((blocksize - 1) & blocksize))
		return -EINVAL;
	HFSPLUS_SB(sb).alloc_blksz = blocksize;
	HFSPLUS_SB(sb).alloc_blksz_shift = 0;
	while ((blocksize >>= 1) != 0)
		HFSPLUS_SB(sb).alloc_blksz_shift++;
	blocksize = min(HFSPLUS_SB(sb).alloc_blksz, (u32)PAGE_SIZE);

	/* align block size to block offset */
	while (part_start & ((blocksize >> HFSPLUS_SECTOR_SHIFT) - 1))
		blocksize >>= 1;

	if (sb_set_blocksize(sb, blocksize) != blocksize) {
		printk("HFS+: unable to blocksize to %u!\n", blocksize);
		return -EINVAL;
	}

	HFSPLUS_SB(sb).blockoffset = part_start >>
			(sb->s_blocksize_bits - HFSPLUS_SECTOR_SHIFT);
	HFSPLUS_SB(sb).sect_count = part_size;
	HFSPLUS_SB(sb).fs_shift = HFSPLUS_SB(sb).alloc_blksz_shift -
			sb->s_blocksize_bits;

	bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
	if (!bh)
		return -EIO;

	/* should still be the same... */
	if (be16_to_cpu(vhdr->signature) != HFSPLUS_VOLHEAD_SIG)
		goto error;
	HFSPLUS_SB(sb).s_vhbh = bh;
	HFSPLUS_SB(sb).s_vhdr = vhdr;

	return 0;
 error:
	brelse(bh);
	return -EINVAL;
}
