blob: 0320a98b12f981fb58411b2cfd6af44679d92fa0 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2021-2024 Oracle. All rights reserved.
* Author: Darrick J. Wong <djwong@kernel.org>
*/
#include "platform_defs.h"
#include "libxfs.h"
#include "command.h"
#include "input.h"
#include "init.h"
#include "io.h"
#include "libfrog/logging.h"
#include "libfrog/paths.h"
#include "libfrog/fsgeom.h"
static cmdinfo_t aginfo_cmd;
static cmdinfo_t rginfo_cmd;
static int
report_aginfo(
struct xfs_fd *xfd,
xfs_agnumber_t agno,
int oflag)
{
struct xfs_ag_geometry ageo = { 0 };
bool update = false;
int ret;
ret = -xfrog_ag_geometry(xfd->fd, agno, &ageo);
if (ret) {
xfrog_perror(ret, "aginfo");
return 1;
}
switch (oflag) {
case 0:
ageo.ag_flags |= XFS_AG_FLAG_UPDATE;
ageo.ag_flags &= ~XFS_AG_FLAG_NOALLOC;
update = true;
break;
case 1:
ageo.ag_flags |= (XFS_AG_FLAG_UPDATE | XFS_AG_FLAG_NOALLOC);
update = true;
break;
}
if (update) {
ret = -xfrog_ag_geometry(xfd->fd, agno, &ageo);
if (ret) {
xfrog_perror(ret, "aginfo update");
return 1;
}
}
printf(_("AG: %u\n"), ageo.ag_number);
printf(_("Blocks: %u\n"), ageo.ag_length);
printf(_("Free Blocks: %u\n"), ageo.ag_freeblks);
printf(_("Inodes: %u\n"), ageo.ag_icount);
printf(_("Free Inodes: %u\n"), ageo.ag_ifree);
printf(_("Sick: 0x%x\n"), ageo.ag_sick);
printf(_("Checked: 0x%x\n"), ageo.ag_checked);
printf(_("Flags: 0x%x\n"), ageo.ag_flags);
return 0;
}
/* Display AG status. */
static int
aginfo_f(
int argc,
char **argv)
{
struct xfs_fd xfd = XFS_FD_INIT(file->fd);
unsigned long long x;
xfs_agnumber_t agno = NULLAGNUMBER;
int oflag = -1;
int c;
int ret = 0;
ret = -xfd_prepare_geometry(&xfd);
if (ret) {
xfrog_perror(ret, "xfd_prepare_geometry");
exitcode = 1;
return 1;
}
while ((c = getopt(argc, argv, "a:o:")) != EOF) {
switch (c) {
case 'a':
errno = 0;
x = strtoll(optarg, NULL, 10);
if (!errno && x >= NULLAGNUMBER)
errno = ERANGE;
if (errno) {
perror("aginfo");
return 1;
}
agno = x;
break;
case 'o':
errno = 0;
x = strtoll(optarg, NULL, 10);
if (!errno && x != 0 && x != 1)
errno = ERANGE;
if (errno) {
perror("aginfo");
return 1;
}
oflag = x;
break;
default:
return command_usage(&aginfo_cmd);
}
}
if (agno != NULLAGNUMBER) {
ret = report_aginfo(&xfd, agno, oflag);
} else {
for (agno = 0; !ret && agno < xfd.fsgeom.agcount; agno++) {
ret = report_aginfo(&xfd, agno, oflag);
}
}
return ret;
}
static void
aginfo_help(void)
{
printf(_(
"\n"
"Report allocation group geometry.\n"
"\n"
" -a agno -- Report on the given allocation group.\n"
" -o state -- Change the NOALLOC state for this allocation group.\n"
"\n"));
}
static cmdinfo_t aginfo_cmd = {
.name = "aginfo",
.cfunc = aginfo_f,
.argmin = 0,
.argmax = -1,
.args = "[-a agno] [-o state]",
.flags = CMD_NOMAP_OK,
.help = aginfo_help,
};
static int
report_rginfo(
struct xfs_fd *xfd,
xfs_rgnumber_t rgno)
{
struct xfs_rtgroup_geometry rgeo = { 0 };
int ret;
ret = -xfrog_rtgroup_geometry(xfd->fd, rgno, &rgeo);
if (ret) {
xfrog_perror(ret, "rginfo");
return 1;
}
printf(_("RTG: %u\n"), rgeo.rg_number);
printf(_("Length: %u\n"), rgeo.rg_length);
printf(_("Sick: 0x%x\n"), rgeo.rg_sick);
printf(_("Checked: 0x%x\n"), rgeo.rg_checked);
printf(_("Flags: 0x%x\n"), rgeo.rg_flags);
return 0;
}
/* Display rtgroup status. */
static int
rginfo_f(
int argc,
char **argv)
{
struct xfs_fd xfd = XFS_FD_INIT(file->fd);
unsigned long long x;
xfs_rgnumber_t rgno = NULLRGNUMBER;
int c;
int ret = 0;
ret = -xfd_prepare_geometry(&xfd);
if (ret) {
xfrog_perror(ret, "xfd_prepare_geometry");
exitcode = 1;
return 1;
}
while ((c = getopt(argc, argv, "r:")) != EOF) {
switch (c) {
case 'r':
errno = 0;
x = strtoll(optarg, NULL, 10);
if (!errno && x >= NULLRGNUMBER)
errno = ERANGE;
if (errno) {
perror("rginfo");
return 1;
}
rgno = x;
break;
default:
return command_usage(&rginfo_cmd);
}
}
if (rgno != NULLRGNUMBER) {
ret = report_rginfo(&xfd, rgno);
} else {
for (rgno = 0; !ret && rgno < xfd.fsgeom.rgcount; rgno++) {
ret = report_rginfo(&xfd, rgno);
}
}
return ret;
}
static void
rginfo_help(void)
{
printf(_(
"\n"
"Report realtime group geometry.\n"
"\n"
" -r rgno -- Report on the given realtime group.\n"
"\n"));
}
static cmdinfo_t rginfo_cmd = {
.name = "rginfo",
.cfunc = rginfo_f,
.argmin = 0,
.argmax = -1,
.args = "[-r rgno]",
.flags = CMD_NOMAP_OK,
.help = rginfo_help,
};
void
aginfo_init(void)
{
aginfo_cmd.oneline = _("Get XFS allocation group state.");
add_command(&aginfo_cmd);
rginfo_cmd.oneline = _("Get XFS realtime group state.");
add_command(&rginfo_cmd);
}