// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */

#include "libxfs.h"
#include "block.h"
#include "bmap.h"
#include "command.h"
#include "type.h"
#include "faddr.h"
#include "fprint.h"
#include "field.h"
#include "inode.h"
#include "io.h"
#include "output.h"
#include "init.h"

static int	ablock_f(int argc, char **argv);
static void     ablock_help(void);
static int	daddr_f(int argc, char **argv);
static void     daddr_help(void);
static int	dblock_f(int argc, char **argv);
static void     dblock_help(void);
static int	fsblock_f(int argc, char **argv);
static void     fsblock_help(void);
static int	rtblock_f(int argc, char **argv);
static void	rtblock_help(void);
static int	rtextent_f(int argc, char **argv);
static void	rtextent_help(void);
static int	logblock_f(int argc, char **argv);
static void	logblock_help(void);
static void	print_rawdata(void *data, int len);

static const cmdinfo_t	ablock_cmd =
	{ "ablock", NULL, ablock_f, 1, 1, 1, N_("filoff"),
	  N_("set address to file offset (attr fork)"), ablock_help };
static const cmdinfo_t	daddr_cmd =
	{ "daddr", NULL, daddr_f, 0, -1, 1, N_("[d]"),
	  N_("set address to daddr value"), daddr_help };
static const cmdinfo_t	dblock_cmd =
	{ "dblock", NULL, dblock_f, 1, 1, 1, N_("filoff"),
	  N_("set address to file offset (data fork)"), dblock_help };
static const cmdinfo_t	fsblock_cmd =
	{ "fsblock", "fsb", fsblock_f, 0, 1, 1, N_("[fsb]"),
	  N_("set address to fsblock value"), fsblock_help };
static const cmdinfo_t	rtblock_cmd =
	{ "rtblock", "rtbno", rtblock_f, 0, 1, 1, N_("[rtbno]"),
	  N_("set address to rtblock value"), rtblock_help };
static const cmdinfo_t	rtextent_cmd =
	{ "rtextent", "rtx", rtextent_f, 0, 1, 1, N_("[rtxno]"),
	  N_("set address to rtextent value"), rtextent_help };
static const cmdinfo_t	logblock_cmd =
	{ "logblock", "lsb", logblock_f, 0, 1, 1, N_("[logbno]"),
	  N_("set address to logblock value"), logblock_help };

static void
ablock_help(void)
{
	dbprintf(_(
"\n Example:\n"
"\n"
" 'ablock 23' - sets the file position to the 23rd filesystem block in\n"
" the inode's attribute fork.  The filesystem block size is specified in\n"
" the superblock.\n\n"
));
}

/*ARGSUSED*/
static int
ablock_f(
	int			argc,
	char			**argv)
{
	bmap_ext_t		bm;
	xfs_fileoff_t		bno;
	xfs_fsblock_t		dfsbno;
	int			haveattr;
	xfs_extnum_t		nex;
	char			*p;
	struct xfs_dinode	*dip = iocur_top->data;

	bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0);
	if (*p != '\0') {
		dbprintf(_("bad block number %s\n"), argv[1]);
		return 0;
	}
	push_cur();
	set_cur_inode(iocur_top->ino);
	if (!dip) {
		pop_cur();
		dbprintf(_("no current inode\n"));
		return 0;
	}
	haveattr = dip->di_forkoff;
	pop_cur();
	if (!haveattr) {
		dbprintf(_("no attribute data for file\n"));
		return 0;
	}
	nex = 1;
	bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm);
	if (nex == 0) {
		dbprintf(_("file attr block is unmapped\n"));
		return 0;
	}
	dfsbno = bm.startblock + (bno - bm.startoff);
	ASSERT(typtab[TYP_ATTR].typnm == TYP_ATTR);
	set_cur(&typtab[TYP_ATTR], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
		blkbb, DB_RING_ADD, NULL);
	return 0;
}

void
block_init(void)
{
	add_command(&ablock_cmd);
	add_command(&daddr_cmd);
	add_command(&dblock_cmd);
	add_command(&fsblock_cmd);
	add_command(&rtblock_cmd);
	add_command(&rtextent_cmd);
	add_command(&logblock_cmd);
}

static void
daddr_help(void)
{
	dbprintf(_(
"\n Example:\n"
"\n"
" 'daddr 102' - sets position to the 102nd absolute disk block\n"
" (512 byte block).\n"
));
}

enum daddr_target {
	DT_DATA,
	DT_RT,
	DT_LOG,
};

static int
daddr_f(
	int		argc,
	char		**argv)
{
	xfs_rfsblock_t	max_daddrs = mp->m_sb.sb_dblocks;
	int64_t		d;
	char		*p;
	int		bb_count = BTOBB(mp->m_sb.sb_sectsize);
	int		c;
	enum daddr_target tgt = DT_DATA;

	while ((c = getopt(argc, argv, "rl")) != -1) {
		switch (c) {
		case 'r':
			tgt = DT_RT;
			max_daddrs = mp->m_sb.sb_rblocks;
			break;
		case 'l':
			tgt = DT_LOG;
			max_daddrs = mp->m_sb.sb_logblocks;
			break;
		default:
			daddr_help();
			return 0;
		}
	}

	if (tgt == DT_LOG && mp->m_sb.sb_logstart > 0) {
		dbprintf(_("filesystem has internal log\n"));
		return 0;
	}

	if (optind == argc) {
		xfs_daddr_t	daddr = iocur_top->off >> BBSHIFT;

		if (iocur_is_ddev(iocur_top))
			dbprintf(_("datadev daddr is %lld\n"), daddr);
		else if (iocur_is_extlogdev(iocur_top))
			dbprintf(_("logdev daddr is %lld\n"), daddr);
		else if (iocur_is_rtdev(iocur_top))
			dbprintf(_("rtdev daddr is %lld\n"), daddr);
		else
			dbprintf(_("current daddr is %lld\n"), daddr);

		return 0;
	}

	if (optind != argc - 1) {
		daddr_help();
		return 0;
	}

	d = (int64_t)strtoull(argv[optind], &p, 0);
	if (*p != '\0' ||
	    d >= max_daddrs << (mp->m_sb.sb_blocklog - BBSHIFT)) {
		dbprintf(_("bad daddr %s\n"), argv[1]);
		return 0;
	}
	ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
	switch (tgt) {
	case DT_DATA:
		set_cur(&typtab[TYP_DATA], d, bb_count, DB_RING_ADD, NULL);
		break;
	case DT_RT:
		set_rt_cur(&typtab[TYP_DATA], d, bb_count, DB_RING_ADD, NULL);
		break;
	case DT_LOG:
		set_log_cur(&typtab[TYP_DATA], d, bb_count, DB_RING_ADD, NULL);
		break;
	}
	return 0;
}

static void
dblock_help(void)
{
	dbprintf(_(
"\n Example:\n"
"\n"
" 'dblock 23' - sets the file position to the 23rd filesystem block in\n"
" the inode's data fork.  The filesystem block size is specified in the\n"
" superblock.\n\n"
));
}

static inline bool
is_rtfile(
	struct xfs_dinode	*dip)
{
	return dip->di_flags & cpu_to_be16(XFS_DIFLAG_REALTIME);
}

static int
dblock_f(
	int		argc,
	char		**argv)
{
	bbmap_t		bbmap;
	bmap_ext_t	*bmp;
	xfs_fileoff_t	bno;
	xfs_fsblock_t	dfsbno;
	int		nb;
	xfs_extnum_t	nex;
	char		*p;
	typnm_t		type;

	bno = (xfs_fileoff_t)strtoull(argv[1], &p, 0);
	if (*p != '\0') {
		dbprintf(_("bad block number %s\n"), argv[1]);
		return 0;
	}
	push_cur();
	set_cur_inode(iocur_top->ino);
	type = inode_next_type();
	pop_cur();
	if (type == TYP_NONE) {
		dbprintf(_("no type for file data\n"));
		return 0;
	}
	nex = nb = type == TYP_DIR2 ? mp->m_dir_geo->fsbcount : 1;
	bmp = malloc(nb * sizeof(*bmp));
	bmap(bno, nb, XFS_DATA_FORK, &nex, bmp);
	if (nex == 0) {
		dbprintf(_("file data block is unmapped\n"));
		free(bmp);
		return 0;
	}
	dfsbno = bmp->startblock + (bno - bmp->startoff);
	ASSERT(typtab[type].typnm == type);
	if (nex > 1)
		make_bbmap(&bbmap, nex, bmp);
	if (is_rtfile(iocur_top->data))
		set_rt_cur(&typtab[type], xfs_rtb_to_daddr(mp, dfsbno),
				nb * blkbb, DB_RING_ADD,
				nex > 1 ? &bbmap : NULL);
	else
		set_cur(&typtab[type], (int64_t)XFS_FSB_TO_DADDR(mp, dfsbno),
				nb * blkbb, DB_RING_ADD,
				nex > 1 ? &bbmap : NULL);
	free(bmp);
	return 0;
}

static void
fsblock_help(void)
{
	dbprintf(_(
"\n Example:\n"
"\n"
" 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n"
" The filesystem block size is specified in the superblock and set during\n"
" mkfs time.  Offset is absolute (not AG relative).\n\n"
));
}

static int
fsblock_f(
	int		argc,
	char		**argv)
{
	xfs_agblock_t	agbno;
	xfs_agnumber_t	agno;
	xfs_fsblock_t	d;
	char		*p;

	if (argc == 1) {
		if (!iocur_is_ddev(iocur_top)) {
			dbprintf(_("cursor does not point to data device\n"));
			return 0;
		}
		dbprintf(_("current fsblock is %lld\n"),
			XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT));
		return 0;
	}
	d = strtoull(argv[1], &p, 0);
	if (*p != '\0') {
		dbprintf(_("bad fsblock %s\n"), argv[1]);
		return 0;
	}
	agno = XFS_FSB_TO_AGNO(mp, d);
	agbno = XFS_FSB_TO_AGBNO(mp, d);
	if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks) {
		dbprintf(_("bad fsblock %s\n"), argv[1]);
		return 0;
	}
	ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
	set_cur(&typtab[TYP_DATA], XFS_AGB_TO_DADDR(mp, agno, agbno),
		blkbb, DB_RING_ADD, NULL);
	return 0;
}

static void
rtblock_help(void)
{
	dbprintf(_(
"\n Example:\n"
"\n"
" 'rtblock 1023' - sets the file position to the 1023rd block on the realtime\n"
" volume. The filesystem block size is specified in the superblock and set\n"
" during mkfs time.\n\n"
));
}

static int
rtblock_f(
	int		argc,
	char		**argv)
{
	xfs_rtblock_t	rtbno;
	char		*p;

	if (argc == 1) {
		if (!iocur_is_rtdev(iocur_top)) {
			dbprintf(_("cursor does not point to rt device\n"));
			return 0;
		}
		dbprintf(_("current rtblock is %lld\n"),
			xfs_daddr_to_rtb(mp, iocur_top->off >> BBSHIFT));
		return 0;
	}
	rtbno = strtoull(argv[1], &p, 0);
	if (*p != '\0') {
		dbprintf(_("bad rtblock %s\n"), argv[1]);
		return 0;
	}

	if (xfs_has_rtgroups(mp)) {
		xfs_rgnumber_t	rgno = xfs_rtb_to_rgno(mp, rtbno);
		xfs_rgblock_t	rgbno = xfs_rtb_to_rgbno(mp, rtbno);

		if (rgno >= mp->m_sb.sb_rgcount ||
		    rgbno >= mp->m_sb.sb_rgextents * mp->m_sb.sb_rextsize) {
			dbprintf(_("bad rtblock %s\n"), argv[1]);
			return 0;
		}
	} else {
		if (rtbno >= mp->m_sb.sb_rblocks) {
			dbprintf(_("bad rtblock %s\n"), argv[1]);
			return 0;
		}
	}

	ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
	set_rt_cur(&typtab[TYP_DATA], xfs_rtb_to_daddr(mp, rtbno), blkbb,
			DB_RING_ADD, NULL);
	return 0;
}

static void
rtextent_help(void)
{
	dbprintf(_(
"\n Example:\n"
"\n"
" 'rtextent 10' - sets the file position to the 10th extent on the realtime\n"
" volume. The realtime extent size is specified in the superblock and set\n"
" during mkfs or growfs time.\n\n"
));
}

/*
 * Move the cursor to a specific location on the realtime block device given
 * a linear address in units of realtime extents.
 *
 * NOTE: The user interface assumes a global RT extent number, while the
 * in-kernel rtx is per-RTG now, thus the odd conversions here.
 */
static int
rtextent_f(
	int		argc,
	char		**argv)
{
	uint64_t	rfsbno;
	uint64_t	rtx;
	char		*p;

	if (argc == 1) {
		if (!iocur_is_rtdev(iocur_top)) {
			dbprintf(_("cursor does not point to rt device\n"));
			return 0;
		}

		rfsbno = XFS_BB_TO_FSB(mp, iocur_top->off >> BBSHIFT);
		dbprintf(_("current rtextent is %lld\n"),
				xfs_blen_to_rtbxlen(mp, rfsbno));
		return 0;
	}
	rtx = strtoull(argv[1], &p, 0);
	if (*p != '\0') {
		dbprintf(_("bad rtextent %s\n"), argv[1]);
		return 0;
	}
	if (rtx >= mp->m_sb.sb_rextents) {
		dbprintf(_("bad rtextent %s\n"), argv[1]);
		return 0;
	}

	rfsbno = xfs_rtbxlen_to_blen(mp, rtx);
	ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);
	set_rt_cur(&typtab[TYP_DATA], XFS_FSB_TO_BB(mp, rfsbno),
			mp->m_sb.sb_rextsize * blkbb, DB_RING_ADD, NULL);
	return 0;
}

static void
logblock_help(void)
{
	dbprintf(_(
"\n Example:\n"
"\n"
" 'logblock 1023' - sets the file position to the 1023rd log block.\n"
" The external log device or the block offset within the internal log will be\n"
" chosen as appropriate.\n"
));
}

static int
logblock_f(
	int		argc,
	char		**argv)
{
	xfs_fsblock_t	logblock;
	char		*p;

	if (argc == 1) {
		if (mp->m_sb.sb_logstart > 0 && iocur_is_ddev(iocur_top)) {
			logblock = XFS_DADDR_TO_FSB(mp,
						iocur_top->off >> BBSHIFT);

			if (logblock < mp->m_sb.sb_logstart ||
			    logblock >= mp->m_sb.sb_logstart +
					mp->m_sb.sb_logblocks) {
				dbprintf(
 _("current address not within internal log\n"));
				return 0;
			}

			dbprintf(_("current logblock is %lld\n"),
					logblock - mp->m_sb.sb_logstart);
			return 0;
		}

		if (mp->m_sb.sb_logstart == 0 &&
		    iocur_is_extlogdev(iocur_top)) {
			logblock = XFS_BB_TO_FSB(mp,
						iocur_top->off >> BBSHIFT);

			if (logblock >= mp->m_sb.sb_logblocks) {
				dbprintf(
 _("current address not within external log\n"));
				return 0;
			}

			dbprintf(_("current logblock is %lld\n"), logblock);
			return 0;
		}

		dbprintf(_("current address does not point to log\n"));
		return 0;
	}

	logblock = strtoull(argv[1], &p, 0);
	if (*p != '\0') {
		dbprintf(_("bad logblock %s\n"), argv[1]);
		return 0;
	}

	if (logblock >= mp->m_sb.sb_logblocks) {
		dbprintf(_("bad logblock %s\n"), argv[1]);
		return 0;
	}

	ASSERT(typtab[TYP_DATA].typnm == TYP_DATA);

	if (mp->m_sb.sb_logstart) {
		logblock += mp->m_sb.sb_logstart;
		set_cur(&typtab[TYP_DATA], XFS_FSB_TO_DADDR(mp, logblock),
				blkbb, DB_RING_ADD, NULL);
	} else {
		set_log_cur(&typtab[TYP_DATA], XFS_FSB_TO_BB(mp, logblock),
				blkbb, DB_RING_ADD, NULL);
	}

	return 0;
}

void
print_block(
	const field_t	*fields,
	int		argc,
	char		**argv)
{
	print_rawdata(iocur_top->data, iocur_top->len);
}

static void
print_rawdata(
	void	*data,
	int	len)
{
	int	i;
	int	j;
	int	lastaddr;
	int	offchars;
	unsigned char	*p;

	lastaddr = (len - 1) & ~(32 - 1);
	if (lastaddr < 0x10)
		offchars = 1;
	else if (lastaddr < 0x100)
		offchars = 2;
	else if (lastaddr < 0x1000)
		offchars = 3;
	else
		offchars = 4;
	for (i = 0, p = data; i < len; i += 32) {
		dbprintf("%-0*.*x:", offchars, offchars, i);
		for (j = 0; j < 32 && i + j < len; j++, p++) {
			if ((j & 3) == 0)
				dbprintf(" ");
			dbprintf("%02x", *p);
		}
		dbprintf("\n");
	}
}
