From: Darrick J. Wong <djwong@xxxxxxxxxx> Create a command to dump rtgroup btree space reservations. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- db/info.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++ libxfs/libxfs_api_defs.h | 2 + man/man8/xfs_db.8 | 5 ++ 3 files changed, 126 insertions(+) diff --git a/db/info.c b/db/info.c index 9a86d247839f84..ce6f358420a79d 100644 --- 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); } diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 3e521cd0c76063..9beea4f7ce8535 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -311,7 +311,9 @@ #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 diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 83a8734d3c0b47..784aa3cb46c588 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -1131,6 +1131,11 @@ .SH COMMANDS 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 .