/*
 * Copyright (C) 1999, 2001 by Andries Brouwer
 * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>

#include "superblocks.h"

struct reiserfs_super_block {
	uint32_t	rs_blocks_count;
	uint32_t	rs_free_blocks;
	uint32_t	rs_root_block;
	uint32_t	rs_journal_block;
	uint32_t	rs_journal_dev;
	uint32_t	rs_orig_journal_size;
	uint32_t	rs_dummy2[5];
	uint16_t	rs_blocksize;
	uint16_t	rs_dummy3[3];
	unsigned char	rs_magic[12];
	uint32_t	rs_dummy4[5];
	unsigned char	rs_uuid[16];
	char		rs_label[16];
} __attribute__((packed));

struct reiser4_super_block {
	unsigned char	rs4_magic[16];
	uint16_t	rs4_dummy[2];
	unsigned char	rs4_uuid[16];
	unsigned char	rs4_label[16];
	uint64_t	rs4_dummy2;
} __attribute__((packed));

static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct reiserfs_super_block *rs;
	unsigned int blocksize;

	rs = blkid_probe_get_sb(pr, mag, struct reiserfs_super_block);
	if (!rs)
		return -1;

	blocksize = le16_to_cpu(rs->rs_blocksize);

	/* The blocksize must be at least 512B */
	if ((blocksize >> 9) == 0)
		return -BLKID_ERR_PARAM;

	/* If the superblock is inside the journal, we have the wrong one */
	if (mag->kboff / (blocksize >> 9) > le32_to_cpu(rs->rs_journal_block) / 2)
		return -BLKID_ERR_BIG;

	/* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */
	if (mag->magic[6] == '2' || mag->magic[6] == '3') {
		if (*rs->rs_label)
			blkid_probe_set_label(pr,
					(unsigned char *) rs->rs_label,
					sizeof(rs->rs_label));
		blkid_probe_set_uuid(pr, rs->rs_uuid);
	}

	if (mag->magic[6] == '3')
		blkid_probe_set_version(pr, "JR");
	else if (mag->magic[6] == '2')
		blkid_probe_set_version(pr, "3.6");
	else
		blkid_probe_set_version(pr, "3.5");

	return 0;
}

static int probe_reiser4(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct reiser4_super_block *rs4;

	rs4 = blkid_probe_get_sb(pr, mag, struct reiser4_super_block);
	if (!rs4)
		return -1;

	if (*rs4->rs4_label)
		blkid_probe_set_label(pr, rs4->rs4_label, sizeof(rs4->rs4_label));
	blkid_probe_set_uuid(pr, rs4->rs4_uuid);
	blkid_probe_set_version(pr, "4");

	return 0;
}


const struct blkid_idinfo reiser_idinfo =
{
	.name		= "reiserfs",
	.usage		= BLKID_USAGE_FILESYSTEM,
	.probefunc	= probe_reiser,
	.minsz		= 128 * 1024,
	.magics		=
	{
		{ .magic = "ReIsErFs",  .len = 8, .kboff = 8,  .sboff = 0x34 },
		{ .magic = "ReIsEr2Fs", .len = 9, .kboff = 64, .sboff = 0x34 },
		{ .magic = "ReIsEr3Fs", .len = 9, .kboff = 64, .sboff = 0x34 },
		{ .magic = "ReIsErFs",  .len = 8, .kboff = 64, .sboff = 0x34 },
		{ .magic = "ReIsErFs",  .len = 8, .kboff =  8, .sboff = 20   },
		{ NULL }
	}
};

const struct blkid_idinfo reiser4_idinfo =
{
	.name		= "reiser4",
	.usage		= BLKID_USAGE_FILESYSTEM,
	.probefunc	= probe_reiser4,
	.minsz		= 128 * 1024,
	.magics		=
	{
		{ .magic = "ReIsEr4", .len = 7, .kboff = 64 },
		{ NULL }
	}
};




