/*
 * volume_id - reads filesystem label and uuid
 *
 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
 * Copyright (C) 2005 Tobias Klauser <tklauser@access.unizh.ch>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include "volume_id_internal.h"

struct reiserfs_super_block {
	uint32_t	blocks_count;
	uint32_t	free_blocks;
	uint32_t	root_block;
	uint32_t	journal_block;
	uint32_t	journal_dev;
	uint32_t	orig_journal_size;
	uint32_t	dummy2[5];
	uint16_t	blocksize;
	uint16_t	dummy3[3];
	uint8_t		magic[12];
	uint32_t	dummy4[5];
	uint8_t		uuid[16];
	uint8_t		label[16];
} __attribute__((__packed__));

struct reiser4_super_block {
	uint8_t		magic[16];
	uint16_t	dummy[2];
	uint8_t		uuid[16];
	uint8_t		label[16];
	uint64_t	dummy2;
} __attribute__((__packed__));

#define REISERFS1_SUPERBLOCK_OFFSET		0x2000
#define REISERFS_SUPERBLOCK_OFFSET		0x10000

int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off)
{
	struct reiserfs_super_block *rs;
	struct reiser4_super_block *rs4;

	dbg("reiserfs: probing at offset 0x%llx", (unsigned long long) off);

	rs = volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200);
	if (rs == NULL)
		return -1;

	if (memcmp(rs->magic, "ReIsErFs", 8) == 0) {
		dbg("reiserfs: ReIsErFs, no label");
//		strcpy(id->type_version, "3.5");
		goto found;
	}
	if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) {
		dbg("reiserfs: ReIsEr2Fs");
//		strcpy(id->type_version, "3.6");
		goto found_label;
	}
	if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) {
		dbg("reiserfs: ReIsEr3Fs");
//		strcpy(id->type_version, "JR");
		goto found_label;
	}

	rs4 = (struct reiser4_super_block *) rs;
	if (memcmp(rs4->magic, "ReIsEr4", 7) == 0) {
//		strcpy(id->type_version, "4");
//		volume_id_set_label_raw(id, rs4->label, 16);
		volume_id_set_label_string(id, rs4->label, 16);
		volume_id_set_uuid(id, rs4->uuid, UUID_DCE);
		dbg("reiserfs: ReIsEr4, label '%s' uuid '%s'", id->label, id->uuid);
		goto found;
	}

	rs = volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200);
	if (rs == NULL)
		return -1;

	if (memcmp(rs->magic, "ReIsErFs", 8) == 0) {
		dbg("reiserfs: ReIsErFs, no label");
//		strcpy(id->type_version, "3.5");
		goto found;
	}

	dbg("reiserfs: no signature found");
	return -1;

 found_label:
//	volume_id_set_label_raw(id, rs->label, 16);
	volume_id_set_label_string(id, rs->label, 16);
	volume_id_set_uuid(id, rs->uuid, UUID_DCE);
	dbg("reiserfs: label '%s' uuid '%s'", id->label, id->uuid);

 found:
//	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
//	id->type = "reiserfs";

	return 0;
}
