/*
 * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "libxfs.h"
#include "libxlog.h"

int print_exit;
int print_skip_uuid;
int print_record_header;
libxfs_init_t x;

/*
 * Return 1 for dirty, 0 for clean, -1 for errors
 */
int
xlog_is_dirty(
	struct xfs_mount	*mp,
	struct xlog		*log,
	libxfs_init_t		*x,
	int			verbose)
{
	int			error;
	xfs_daddr_t		head_blk, tail_blk;

	memset(log, 0, sizeof(*log));

	/* We (re-)init members of libxfs_init_t here?  really? */
	x->logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
	x->logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
	x->lbsize = BBSIZE;
	if (xfs_sb_version_hassector(&mp->m_sb))
		x->lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT);

	log->l_dev = mp->m_logdev_targp;
	log->l_logBBsize = x->logBBsize;
	log->l_logBBstart = x->logBBstart;
	log->l_sectBBsize = BTOBB(x->lbsize);
	log->l_mp = mp;
	if (xfs_sb_version_hassector(&mp->m_sb)) {
		log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
		ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
		/* for larger sector sizes, must have v2 or external log */
		ASSERT(log->l_sectbb_log == 0 ||
			log->l_logBBstart == 0 ||
			xfs_sb_version_haslogv2(&mp->m_sb));
		ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
	}
	log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1;

	error = xlog_find_tail(log, &head_blk, &tail_blk);
	if (error) {
		xlog_warn(_("%s: cannot find log head/tail "
			  "(xlog_find_tail=%d)\n"),
			__func__, error);
		return -1;
	}

	if (verbose)
		xlog_warn(
	_("%s: head block %" PRId64 " tail block %" PRId64 "\n"),
			__func__, head_blk, tail_blk);

	if (head_blk != tail_blk)
		return 1;

	return 0;
}

static int
header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head)
{
    char uu_log[64], uu_sb[64];

    if (print_skip_uuid)
		return 0;
    if (!platform_uuid_compare(&mp->m_sb.sb_uuid, &head->h_fs_uuid))
		return 0;

    platform_uuid_unparse(&mp->m_sb.sb_uuid, uu_sb);
    platform_uuid_unparse(&head->h_fs_uuid, uu_log);

    printf(_("* ERROR: mismatched uuid in log\n"
	     "*            SB : %s\n*            log: %s\n"),
	    uu_sb, uu_log);

    memcpy(&mp->m_sb.sb_uuid, &head->h_fs_uuid, sizeof(uuid_t));

    return 0;
}

int
xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head)
{
    if (print_record_header)
	printf(_("\nLOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n"),
	       CYCLE_LSN(be64_to_cpu(head->h_lsn)),
	       BLOCK_LSN(be64_to_cpu(head->h_lsn)),
	       CYCLE_LSN(be64_to_cpu(head->h_lsn)),
	       BLOCK_LSN(be64_to_cpu(head->h_lsn)));

    if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) {

	printf(_("* ERROR: bad magic number in log header: 0x%x\n"),
		be32_to_cpu(head->h_magicno));

    } else if (header_check_uuid(mp, head)) {

	/* failed - fall through */

    } else if (be32_to_cpu(head->h_fmt) != XLOG_FMT) {

	printf(_("* ERROR: log format incompatible (log=%d, ours=%d)\n"),
		be32_to_cpu(head->h_fmt), XLOG_FMT);

    } else {
	/* everything is ok */
	return 0;
    }

    /* bail out now or just carry on regardless */
    if (print_exit)
	xlog_exit(_("Bad log"));

    return 0;
}

int
xlog_header_check_mount(xfs_mount_t *mp, xlog_rec_header_t *head)
{
    if (platform_uuid_is_null(&head->h_fs_uuid)) return 0;
    if (header_check_uuid(mp, head)) {
	/* bail out now or just carry on regardless */
	if (print_exit)
	    xlog_exit(_("Bad log"));
    }
    return 0;
}

/*
 * Userspace versions of common diagnostic routines (varargs fun).
 */
void
xlog_warn(char *fmt, ...)
{
	va_list	ap;

	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	fputs("\n", stderr);
	va_end(ap);
}

void
xlog_exit(char *fmt, ...)
{
	va_list	ap;

	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	fputs("\n", stderr);
	va_end(ap);
	exit(1);
}

void
xlog_panic(char *fmt, ...)
{
	va_list	ap;

	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	fputs("\n", stderr);
	va_end(ap);
	abort();
}
