/*
 * 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 errno ? -errno : 1;

	blocksize = le16_to_cpu(rs->rs_blocksize);

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

	/* 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 1;

	/* 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 errno ? -errno : 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 }
	}
};




