]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_db: add an rgresv command
authorDarrick J. Wong <djwong@kernel.org>
Mon, 24 Feb 2025 18:21:59 +0000 (10:21 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 25 Feb 2025 17:16:00 +0000 (09:16 -0800)
Create a command to dump rtgroup btree space reservations.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
db/info.c
libxfs/libxfs_api_defs.h
man/man8/xfs_db.8

index 9a86d247839f846c051d05a29c5ec394463abe32..ce6f358420a79d7c49dfd18b826608da854ee4f3 100644 (file)
--- a/db/info.c
+++ b/db/info.c
@@ -151,9 +151,128 @@ static const struct cmdinfo agresv_cmd = {
        .help =         agresv_help,
 };
 
+static void
+rgresv_help(void)
+{
+       dbprintf(_(
+"\n"
+" Print the size and per-rtgroup reservation information for some realtime allocation groups.\n"
+"\n"
+" Specific realtime allocation group numbers can be provided as command line\n"
+" arguments.  If no arguments are provided, all allocation groups are iterated.\n"
+"\n"
+));
+
+}
+
+static void
+print_rgresv_info(
+       struct xfs_rtgroup      *rtg)
+{
+       struct xfs_trans        *tp;
+       xfs_filblks_t           ask = 0;
+       xfs_filblks_t           used = 0;
+       int                     error;
+
+       error = -libxfs_trans_alloc_empty(mp, &tp);
+       if (error) {
+               dbprintf(
+ _("Cannot alloc transaction to look up rtgroup %u rmap inode\n"),
+                               rtg_rgno(rtg));
+               return;
+       }
+
+       error = -libxfs_rtginode_load_parent(tp);
+       if (error) {
+               dbprintf(_("Cannot load realtime metadir, error %d\n"),
+                       error);
+               goto out_trans;
+       }
+
+       /* rtrmapbt */
+       error = -libxfs_rtginode_load(rtg, XFS_RTGI_RMAP, tp);
+       if (error) {
+               dbprintf(_("Cannot load rtgroup %u rmap inode, error %d\n"),
+                       rtg_rgno(rtg), error);
+               goto out_rele_dp;
+       }
+       if (rtg_rmap(rtg))
+               used += rtg_rmap(rtg)->i_nblocks;
+       libxfs_rtginode_irele(&rtg->rtg_inodes[XFS_RTGI_RMAP]);
+
+       ask += libxfs_rtrmapbt_calc_reserves(mp);
+
+       printf(_("rtg %d: dblocks: %llu fdblocks: %llu reserved: %llu used: %llu"),
+                       rtg_rgno(rtg),
+                       (unsigned long long)mp->m_sb.sb_dblocks,
+                       (unsigned long long)mp->m_sb.sb_fdblocks,
+                       (unsigned long long)ask,
+                       (unsigned long long)used);
+       if (ask - used > mp->m_sb.sb_fdblocks)
+               printf(_(" <not enough space>"));
+       printf("\n");
+out_rele_dp:
+       libxfs_rtginode_irele(&mp->m_rtdirip);
+out_trans:
+       libxfs_trans_cancel(tp);
+}
+
+static int
+rgresv_f(
+       int                     argc,
+       char                    **argv)
+{
+       struct xfs_rtgroup      *rtg = NULL;
+       int                     i;
+
+       if (argc > 1) {
+               for (i = 1; i < argc; i++) {
+                       long    a;
+                       char    *p;
+
+                       errno = 0;
+                       a = strtol(argv[i], &p, 0);
+                       if (p == argv[i])
+                               errno = ERANGE;
+                       if (errno) {
+                               perror(argv[i]);
+                               continue;
+                       }
+
+                       if (a < 0 || a >= mp->m_sb.sb_rgcount) {
+                               fprintf(stderr, "%ld: Not a rtgroup.\n", a);
+                               continue;
+                       }
+
+                       rtg = libxfs_rtgroup_get(mp, a);
+                       print_rgresv_info(rtg);
+                       libxfs_rtgroup_put(rtg);
+               }
+               return 0;
+       }
+
+       while ((rtg = xfs_rtgroup_next(mp, rtg)))
+               print_rgresv_info(rtg);
+
+       return 0;
+}
+
+static const struct cmdinfo rgresv_cmd = {
+       .name =         "rgresv",
+       .altname =      NULL,
+       .cfunc =        rgresv_f,
+       .argmin =       0,
+       .argmax =       -1,
+       .canpush =      0,
+       .args =         NULL,
+       .oneline =      N_("print rtgroup reservation stats"),
+       .help =         rgresv_help,
+};
+
 void
 info_init(void)
 {
        add_command(&info_cmd);
        add_command(&agresv_cmd);
+       add_command(&rgresv_cmd);
 }
index 3e521cd0c76063cbbfca3ec2c119cab98358eaf4..9beea4f7ce85356fa3b8e1c67a979a52a8e56a57 100644 (file)
 #define xfs_rtfree_extent              libxfs_rtfree_extent
 #define xfs_rtfree_blocks              libxfs_rtfree_blocks
 #define xfs_update_rtsb                        libxfs_update_rtsb
+#define xfs_rtgroup_get                        libxfs_rtgroup_get
 #define xfs_rtgroup_put                        libxfs_rtgroup_put
+#define xfs_rtrmapbt_calc_reserves     libxfs_rtrmapbt_calc_reserves
 #define xfs_rtrmapbt_droot_maxrecs     libxfs_rtrmapbt_droot_maxrecs
 #define xfs_rtrmapbt_maxlevels_ondisk  libxfs_rtrmapbt_maxlevels_ondisk
 #define xfs_rtrmapbt_init_cursor       libxfs_rtrmapbt_init_cursor
index 83a8734d3c0b476cf6dbdbd7a53772c46c17bacd..784aa3cb46c588287bb726ae2c35b460a23fda86 100644 (file)
@@ -1131,6 +1131,11 @@ command.
 Exit
 .BR xfs_db .
 .TP
+.BI "rgresv [" rgno ]
+Displays the per-rtgroup reservation size, and per-rtgroup
+reservation usage for a given realtime allocation group.
+If no argument is given, display information for all rtgroups.
+.TP
 .BI "rtblock [" rtbno ]
 Set current address to the location on the realtime device given by
 .IR rtbno .