|  | // SPDX-License-Identifier: GPL-2.0 | 
|  | /* | 
|  | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. | 
|  | * All Rights Reserved. | 
|  | */ | 
|  |  | 
|  | #include "libxfs.h" | 
|  | #include "command.h" | 
|  | #include "type.h" | 
|  | #include "faddr.h" | 
|  | #include "fprint.h" | 
|  | #include "field.h" | 
|  | #include "io.h" | 
|  | #include "bit.h" | 
|  | #include "output.h" | 
|  | #include "init.h" | 
|  | #include "agi.h" | 
|  |  | 
|  | static int agi_f(int argc, char **argv); | 
|  | static void agi_help(void); | 
|  |  | 
|  | static const cmdinfo_t agi_cmd = | 
|  | { "agi", NULL, agi_f, 0, 1, 1, N_("[agno]"), | 
|  | N_("set address to agi header"), agi_help }; | 
|  |  | 
|  | const field_t	agi_hfld[] = { | 
|  | { "", FLDT_AGI, OI(0), C1, 0, TYP_NONE }, | 
|  | { NULL } | 
|  | }; | 
|  |  | 
|  | #define	OFF(f)	bitize(offsetof(xfs_agi_t, agi_ ## f)) | 
|  | const field_t	agi_flds[] = { | 
|  | { "magicnum", FLDT_UINT32X, OI(OFF(magicnum)), C1, 0, TYP_NONE }, | 
|  | { "versionnum", FLDT_UINT32D, OI(OFF(versionnum)), C1, 0, TYP_NONE }, | 
|  | { "seqno", FLDT_AGNUMBER, OI(OFF(seqno)), C1, 0, TYP_NONE }, | 
|  | { "length", FLDT_AGBLOCK, OI(OFF(length)), C1, 0, TYP_NONE }, | 
|  | { "count", FLDT_AGINO, OI(OFF(count)), C1, 0, TYP_NONE }, | 
|  | { "root", FLDT_AGBLOCK, OI(OFF(root)), C1, 0, TYP_INOBT }, | 
|  | { "level", FLDT_UINT32D, OI(OFF(level)), C1, 0, TYP_NONE }, | 
|  | { "freecount", FLDT_AGINO, OI(OFF(freecount)), C1, 0, TYP_NONE }, | 
|  | { "newino", FLDT_AGINO, OI(OFF(newino)), C1, 0, TYP_INODE }, | 
|  | { "dirino", FLDT_AGINO, OI(OFF(dirino)), C1, 0, TYP_INODE }, | 
|  | { "unlinked", FLDT_AGINONN, OI(OFF(unlinked)), | 
|  | CI(XFS_AGI_UNLINKED_BUCKETS), FLD_ARRAY, TYP_NONE }, | 
|  | { "uuid", FLDT_UUID, OI(OFF(uuid)), C1, 0, TYP_NONE }, | 
|  | { "crc", FLDT_CRC, OI(OFF(crc)), C1, 0, TYP_NONE }, | 
|  | { "pad32", FLDT_UINT32X, OI(OFF(pad32)), C1, FLD_SKIPALL, TYP_NONE }, | 
|  | { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, | 
|  | { "free_root", FLDT_AGBLOCK, OI(OFF(free_root)), C1, 0, TYP_FINOBT }, | 
|  | { "free_level", FLDT_UINT32D, OI(OFF(free_level)), C1, 0, TYP_NONE }, | 
|  | { "ino_blocks", FLDT_UINT32D, OI(OFF(iblocks)), C1, 0, TYP_NONE }, | 
|  | { "fino_blocks", FLDT_UINT32D, OI(OFF(fblocks)), C1, 0, TYP_NONE }, | 
|  | { NULL } | 
|  | }; | 
|  |  | 
|  | static void | 
|  | agi_help(void) | 
|  | { | 
|  | dbprintf(_( | 
|  | "\n" | 
|  | " set allocation group inode btree\n" | 
|  | "\n" | 
|  | " Example:\n" | 
|  | "\n" | 
|  | " agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" | 
|  | "\n" | 
|  | " Located in the 3rd 512 byte block of each allocation group,\n" | 
|  | " the agi inode btree tracks all used/free inodes in the allocation group.\n" | 
|  | " Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" | 
|  | "\n" | 
|  | )); | 
|  | } | 
|  |  | 
|  | static int | 
|  | agi_f( | 
|  | int		argc, | 
|  | char		**argv) | 
|  | { | 
|  | xfs_agnumber_t	agno; | 
|  | char		*p; | 
|  |  | 
|  | if (argc > 1) { | 
|  | agno = (xfs_agnumber_t)strtoul(argv[1], &p, 0); | 
|  | if (*p != '\0' || agno >= mp->m_sb.sb_agcount) { | 
|  | dbprintf(_("bad allocation group number %s\n"), argv[1]); | 
|  | return 0; | 
|  | } | 
|  | cur_agno = agno; | 
|  | } else if (cur_agno == NULLAGNUMBER) | 
|  | cur_agno = 0; | 
|  | ASSERT(typtab[TYP_AGI].typnm == TYP_AGI); | 
|  | set_cur(&typtab[TYP_AGI], | 
|  | XFS_AG_DADDR(mp, cur_agno, XFS_AGI_DADDR(mp)), | 
|  | XFS_FSS_TO_BB(mp, 1), DB_RING_ADD, NULL); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | void | 
|  | agi_init(void) | 
|  | { | 
|  | add_command(&agi_cmd); | 
|  | } | 
|  |  | 
|  | /*ARGSUSED*/ | 
|  | int | 
|  | agi_size( | 
|  | void	*obj, | 
|  | int	startoff, | 
|  | int	idx) | 
|  | { | 
|  | return bitize(mp->m_sb.sb_sectsize); | 
|  | } |