// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2017 Oracle.  All Rights Reserved.
 * Author: Darrick J. Wong <darrick.wong@oracle.com>
 */

#include <sys/uio.h>
#include <xfs/xfs.h>
#include "command.h"
#include "input.h"
#include "init.h"
#include "libfrog/paths.h"
#include "libfrog/fsgeom.h"
#include "libfrog/scrub.h"
#include "libfrog/logging.h"
#include "io.h"
#include "list.h"

static struct cmdinfo scrub_cmd;
static struct cmdinfo repair_cmd;
static const struct cmdinfo scrubv_cmd;

static void
scrub_help(void)
{
	const struct xfrog_scrub_descr	*d;
	int				i;

	printf(_(
"\n"
" Scrubs a piece of XFS filesystem metadata.  The first argument is the type\n"
" of metadata to examine.  Allocation group metadata types take one AG number\n"
" as the second parameter.  Inode metadata types act on the currently open file\n"
" or (optionally) take an inode number and generation number to act upon as\n"
" the second and third parameters.\n"
"\n"
" Example:\n"
" 'scrub inobt 3' - scrub the inode btree in AG 3.\n"
" 'scrub bmapbtd 128 13525' - scrubs the extent map of inode 128 gen 13525.\n"
"\n"
" Known metadata scrub types are:"));
	for (i = 0, d = xfrog_scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++)
		printf(" %s", d->name);
	printf("\n");
}

static bool
parse_inode(
	int		argc,
	char		**argv,
	int		optind,
	__u64		*ino,
	__u32		*gen)
{
	char		*p;
	unsigned long long control;
	unsigned long	control2;

	if (optind == argc) {
		*ino = 0;
		*gen = 0;
		return true;
	}

	if (optind != argc - 2) {
		fprintf(stderr,
 _("Must specify inode number and generation.\n"));
		return false;
	}

	control = strtoull(argv[optind], &p, 0);
	if (*p != '\0') {
		fprintf(stderr, _("Bad inode number '%s'.\n"),
				argv[optind]);
		return false;
	}
	control2 = strtoul(argv[optind + 1], &p, 0);
	if (*p != '\0') {
		fprintf(stderr, _("Bad generation number '%s'.\n"),
				argv[optind + 1]);
		return false;
	}

	*ino = control;
	*gen = control2;
	return true;
}

static bool
parse_agno(
	int		argc,
	char		**argv,
	int		optind,
	__u32		*agno)
{
	char		*p;
	unsigned long	control;

	if (optind != argc - 1) {
		fprintf(stderr, _("Must specify one AG number.\n"));
		return false;
	}

	control = strtoul(argv[optind], &p, 0);
	if (*p != '\0') {
		fprintf(stderr, _("Bad AG number '%s'.\n"), argv[optind]);
		return false;
	}

	*agno = control;
	return true;
}

static bool
parse_none(
	int		argc,
	int		optind)
{
	if (optind != argc) {
		fprintf(stderr, _("No parameters allowed.\n"));
		return false;
	}

	/* no control parameters */
	return true;
}

static int
parse_args(
	int				argc,
	char				**argv,
	const struct cmdinfo		*cmdinfo,
	struct xfs_scrub_metadata	*meta)
{
	int				type = -1;
	int				i, c;
	uint32_t			flags = 0;
	const struct xfrog_scrub_descr	*d = NULL;

	memset(meta, 0, sizeof(struct xfs_scrub_metadata));
	while ((c = getopt(argc, argv, "R")) != EOF) {
		switch (c) {
		case 'R':
			flags |= XFS_SCRUB_IFLAG_FORCE_REBUILD;
			break;
		default:
			exitcode = 1;
			return command_usage(cmdinfo);
		}
	}
	if (optind > argc - 1) {
		exitcode = 1;
		return command_usage(cmdinfo);
	}

	for (i = 0, d = xfrog_scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++) {
		if (strcmp(d->name, argv[optind]) == 0) {
			type = i;
			break;
		}
	}
	if (type < 0) {
		printf(_("Unknown type '%s'.\n"), argv[optind]);
		exitcode = 1;
		return command_usage(cmdinfo);
	}
	optind++;

	meta->sm_type = type;
	meta->sm_flags = flags;

	switch (d->group) {
	case XFROG_SCRUB_GROUP_INODE:
		if (!parse_inode(argc, argv, optind, &meta->sm_ino,
						     &meta->sm_gen)) {
			exitcode = 1;
			return command_usage(cmdinfo);
		}
		break;
	case XFROG_SCRUB_GROUP_AGHEADER:
	case XFROG_SCRUB_GROUP_PERAG:
		if (!parse_agno(argc, argv, optind, &meta->sm_agno)) {
			exitcode = 1;
			return command_usage(cmdinfo);
		}
		break;
	case XFROG_SCRUB_GROUP_FS:
	case XFROG_SCRUB_GROUP_NONE:
	case XFROG_SCRUB_GROUP_SUMMARY:
	case XFROG_SCRUB_GROUP_ISCAN:
		if (!parse_none(argc, optind)) {
			exitcode = 1;
			return command_usage(cmdinfo);
		}
		break;
	default:
		ASSERT(0);
		break;
	}
	return 0;
}

static void
report_scrub_outcome(
	uint32_t	flags)
{
	if (flags & XFS_SCRUB_OFLAG_CORRUPT)
		printf(_("Corruption detected.\n"));
	if (flags & XFS_SCRUB_OFLAG_PREEN)
		printf(_("Optimization possible.\n"));
	if (flags & XFS_SCRUB_OFLAG_XFAIL)
		printf(_("Cross-referencing failed.\n"));
	if (flags & XFS_SCRUB_OFLAG_XCORRUPT)
		printf(_("Corruption detected during cross-referencing.\n"));
	if (flags & XFS_SCRUB_OFLAG_INCOMPLETE)
		printf(_("Scan was not complete.\n"));
}

static int
scrub_f(
	int				argc,
	char				**argv)
{
	struct xfs_scrub_metadata	meta;
	int				error;

	error = parse_args(argc, argv, &scrub_cmd, &meta);
	if (error)
		return error;

	error = ioctl(file->fd, XFS_IOC_SCRUB_METADATA, &meta);
	if (error)
		perror("scrub");
	report_scrub_outcome(meta.sm_flags);
	return 0;
}

void
scrub_init(void)
{
	scrub_cmd.name = "scrub";
	scrub_cmd.altname = "sc";
	scrub_cmd.cfunc = scrub_f;
	scrub_cmd.argmin = 1;
	scrub_cmd.argmax = -1;
	scrub_cmd.flags = CMD_NOMAP_OK;
	scrub_cmd.args = _("type [agno|ino gen]");
	scrub_cmd.oneline = _("scrubs filesystem metadata");
	scrub_cmd.help = scrub_help;

	add_command(&scrub_cmd);
	add_command(&scrubv_cmd);
}

static void
repair_help(void)
{
	const struct xfrog_scrub_descr	*d;
	int				i;

	printf(_(
"\n"
" Repairs a piece of XFS filesystem metadata.  The first argument is the type\n"
" of metadata to examine.  Allocation group metadata types take one AG number\n"
" as the second parameter.  Inode metadata types act on the currently open file\n"
" or (optionally) take an inode number and generation number to act upon as\n"
" the second and third parameters.\n"
"\n"
" Flags are -R to force rebuilding metadata.\n"
"\n"
" Example:\n"
" 'repair inobt 3' - repairs the inode btree in AG 3.\n"
" 'repair bmapbtd 128 13525' - repairs the extent map of inode 128 gen 13525.\n"
"\n"
" Known metadata repair types are:"));
	for (i = 0, d = xfrog_scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++)
		printf(" %s", d->name);
	printf("\n");
}

static void
report_repair_outcome(
	uint32_t	flags)
{
	if (flags & XFS_SCRUB_OFLAG_CORRUPT)
		printf(_("Corruption remains.\n"));
	if (flags & XFS_SCRUB_OFLAG_PREEN)
		printf(_("Optimization possible.\n"));
	if (flags & XFS_SCRUB_OFLAG_XFAIL)
		printf(_("Cross-referencing failed.\n"));
	if (flags & XFS_SCRUB_OFLAG_XCORRUPT)
		printf(_("Corruption still detected during cross-referencing.\n"));
	if (flags & XFS_SCRUB_OFLAG_INCOMPLETE)
		printf(_("Repair was not complete.\n"));
	if (flags & XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED)
		printf(_("Metadata did not need repair or optimization.\n"));
}

static int
repair_f(
	int				argc,
	char				**argv)
{
	struct xfs_scrub_metadata	meta;
	int				error;

	error = parse_args(argc, argv, &repair_cmd, &meta);
	if (error)
		return error;
	meta.sm_flags |= XFS_SCRUB_IFLAG_REPAIR;

	error = ioctl(file->fd, XFS_IOC_SCRUB_METADATA, &meta);
	if (error)
		perror("repair");
	report_repair_outcome(meta.sm_flags);
	return 0;
}

void
repair_init(void)
{
	if (!expert)
		return;
	repair_cmd.name = "repair";
	repair_cmd.altname = "fix";
	repair_cmd.cfunc = repair_f;
	repair_cmd.argmin = 1;
	repair_cmd.argmax = -1;
	repair_cmd.flags = CMD_NOMAP_OK;
	repair_cmd.args = _("type [agno|ino gen]");
	repair_cmd.oneline = _("repairs filesystem metadata");
	repair_cmd.help = repair_help;

	add_command(&repair_cmd);
}

static void
scrubv_help(void)
{
	printf(_(
"\n"
" Scrubs pieces of XFS filesystem metadata.  The first argument is the group\n"
" of metadata to examine.  If the group is 'ag', the second parameter should\n"
" be the AG number.  If the group is 'inode', the second and third parameters\n"
" should be the inode number and generation number to act upon; if these are\n"
" omitted, the scrub is performed on the open file.  If the group is 'fs',\n"
" 'summary', or 'probe', there are no other parameters.\n"
"\n"
" Flags are -d for debug, and -r to allow repairs.\n"
" -b NN will insert a scrub barrier after every NN scrubs, and -m sets the\n"
" desired corruption mask in all barriers. -w pauses for some microseconds\n"
" after each scrub call.\n"
"\n"
" Example:\n"
" 'scrubv ag 3' - scrub all metadata in AG 3.\n"
" 'scrubv ag 3 -b 2 -m 0x4' - scrub all metadata in AG 3, and use barriers\n"
"            every third scrub to exit early if there are optimizations.\n"
" 'scrubv fs' - scrub all non-AG non-file metadata.\n"
" 'scrubv inode' - scrub all metadata for the open file.\n"
" 'scrubv inode 128 13525' - scrub all metadata for inode 128 gen 13525.\n"
" 'scrubv probe' - check for presence of online scrub.\n"
" 'scrubv summary' - scrub all summary metadata.\n"));
}

/* Fill out the scrub vectors for a group of scrubber (ag, ino, fs, summary) */
static void
scrubv_fill_group(
	struct xfrog_scrubv		*scrubv,
	int				barrier_interval,
	__u32				barrier_mask,
	enum xfrog_scrub_group		group)
{
	const struct xfrog_scrub_descr	*d;
	struct xfs_scrub_vec		*v;
	unsigned int			i;

	for (i = 0, d = xfrog_scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++) {
		if (d->group != group)
			continue;

		v = xfrog_scrubv_next_vector(scrubv);
		v->sv_type = i;

		if (barrier_interval &&
		    scrubv->head.svh_nr % (barrier_interval + 1) == 0) {
			v = xfrog_scrubv_next_vector(scrubv);
			v->sv_flags = barrier_mask;
			v->sv_type = XFS_SCRUB_TYPE_BARRIER;
		}
	}
}

static int
scrubv_f(
	int				argc,
	char				**argv)
{
	struct xfrog_scrubv		scrubv = { };
	struct xfs_fd			xfd = XFS_FD_INIT(file->fd);
	struct xfs_scrub_vec		*v;
	uint32_t			flags = 0;
	__u32				barrier_mask = XFS_SCRUB_OFLAG_CORRUPT;
	enum xfrog_scrub_group		group;
	bool				debug = false;
	int				version = -1;
	int				barrier_interval = 0;
	int				rest_us = 0;
	int				c;
	int				error;

	xfrog_scrubv_init(&scrubv);

	while ((c = getopt(argc, argv, "b:dm:rv:w:")) != EOF) {
		switch (c) {
		case 'b':
			barrier_interval = atoi(optarg);
			if (barrier_interval < 0) {
				fprintf(stderr,
 _("Negative barrier interval makes no sense.\n"));
				exitcode = 1;
				return command_usage(&scrubv_cmd);
			}
			break;
		case 'd':
			debug = true;
			break;
		case 'm':
			barrier_mask = strtoul(optarg, NULL, 0);
			break;
		case 'r':
			flags |= XFS_SCRUB_IFLAG_REPAIR;
			break;
		case 'v':
			if (!strcmp("single", optarg)) {
				version = 0;
			} else if (!strcmp("vector", optarg)) {
				version = 1;
			} else {
				fprintf(stderr,
 _("API version must be 'single' or 'vector'.\n"));
				exitcode = 1;
				return command_usage(&scrubv_cmd);
			}
			break;
		case 'w':
			rest_us = atoi(optarg);
			if (rest_us < 0) {
				fprintf(stderr,
 _("Rest time must be positive.\n"));
				exitcode = 1;
				return command_usage(&scrubv_cmd);
			}
			break;
		default:
			exitcode = 1;
			return command_usage(&scrubv_cmd);
		}
	}
	if (optind > argc - 1) {
		fprintf(stderr,
 _("Must have at least one positional argument.\n"));
		exitcode = 1;
		return command_usage(&scrubv_cmd);
	}

	if ((flags & XFS_SCRUB_IFLAG_REPAIR) && !expert) {
		printf(_("Repair flag requires expert mode.\n"));
		return 1;
	}

	scrubv.head.svh_rest_us = rest_us;
	foreach_xfrog_scrubv_vec(&scrubv, c, v)
		v->sv_flags = flags;

	/* Extract group and domain information from cmdline. */
	if (!strcmp(argv[optind], "probe"))
		group = XFROG_SCRUB_GROUP_NONE;
	else if (!strcmp(argv[optind], "agheader"))
		group = XFROG_SCRUB_GROUP_AGHEADER;
	else if (!strcmp(argv[optind], "ag"))
		group = XFROG_SCRUB_GROUP_PERAG;
	else if (!strcmp(argv[optind], "fs"))
		group = XFROG_SCRUB_GROUP_FS;
	else if (!strcmp(argv[optind], "inode"))
		group = XFROG_SCRUB_GROUP_INODE;
	else if (!strcmp(argv[optind], "iscan"))
		group = XFROG_SCRUB_GROUP_ISCAN;
	else if (!strcmp(argv[optind], "summary"))
		group = XFROG_SCRUB_GROUP_SUMMARY;
	else {
		printf(_("Unknown group '%s'.\n"), argv[optind]);
		exitcode = 1;
		return command_usage(&scrubv_cmd);
	}
	optind++;

	switch (group) {
	case XFROG_SCRUB_GROUP_INODE:
		if (!parse_inode(argc, argv, optind, &scrubv.head.svh_ino,
						     &scrubv.head.svh_gen)) {
			exitcode = 1;
			return command_usage(&scrubv_cmd);
		}
		break;
	case XFROG_SCRUB_GROUP_AGHEADER:
	case XFROG_SCRUB_GROUP_PERAG:
		if (!parse_agno(argc, argv, optind, &scrubv.head.svh_agno)) {
			exitcode = 1;
			return command_usage(&scrubv_cmd);
		}
		break;
	case XFROG_SCRUB_GROUP_FS:
	case XFROG_SCRUB_GROUP_SUMMARY:
	case XFROG_SCRUB_GROUP_ISCAN:
	case XFROG_SCRUB_GROUP_NONE:
		if (!parse_none(argc, optind)) {
			exitcode = 1;
			return command_usage(&scrubv_cmd);
		}
		break;
	default:
		ASSERT(0);
		break;
	}
	scrubv_fill_group(&scrubv, barrier_interval, barrier_mask, group);
	assert(scrubv.head.svh_nr <= XFROG_SCRUBV_MAX_VECTORS);

	error = -xfd_prepare_geometry(&xfd);
	if (error) {
		xfrog_perror(error, "xfd_prepare_geometry");
		exitcode = 1;
		return 0;
	}

	switch (version) {
	case 0:
		xfd.flags |= XFROG_FLAG_SCRUB_FORCE_SINGLE;
		break;
	case 1:
		xfd.flags |= XFROG_FLAG_SCRUB_FORCE_VECTOR;
		break;
	default:
		break;
	}

	error = -xfrog_scrubv_metadata(&xfd, &scrubv);
	if (error) {
		xfrog_perror(error, "xfrog_scrub_many");
		exitcode = 1;
		return 0;
	}

	/* Dump what happened. */
	if (debug) {
		foreach_xfrog_scrubv_vec(&scrubv, c, v) {
			const char	*type;

			if (v->sv_type == XFS_SCRUB_TYPE_BARRIER)
				type = _("barrier");
			else
				type = _(xfrog_scrubbers[v->sv_type].descr);
			printf(_("[%02u] %-25s: flags 0x%x ret %d\n"), c, type,
					v->sv_flags, v->sv_ret);
		}
	}

	/* Figure out what happened. */
	foreach_xfrog_scrubv_vec(&scrubv, c, v) {
		/* Report barrier failures. */
		if (v->sv_type == XFS_SCRUB_TYPE_BARRIER) {
			if (v->sv_ret) {
				printf(_("barrier: FAILED\n"));
				break;
			}
			continue;
		}

		printf("%s: ", _(xfrog_scrubbers[v->sv_type].descr));
		switch (v->sv_ret) {
		case 0:
			break;
		default:
			printf("%s\n", strerror(-v->sv_ret));
			continue;
		}
		if (!(v->sv_flags & XFS_SCRUB_FLAGS_OUT))
			printf(_("OK.\n"));
		else if (v->sv_flags & XFS_SCRUB_IFLAG_REPAIR)
			report_repair_outcome(v->sv_flags);
		else
			report_scrub_outcome(v->sv_flags);
	}

	return 0;
}

static const struct cmdinfo scrubv_cmd = {
	.name		= "scrubv",
	.cfunc		= scrubv_f,
	.argmin		= 1,
	.argmax		= -1,
	.flags		= CMD_NOMAP_OK,
	.oneline	= N_("vectored metadata scrub"),
	.help		= scrubv_help,
};
