]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/freesp.c
43520481d5e038251f740167f37279f35d01dd89
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
15 #include "libfrog/histogram.h"
17 static void addhistent(int h
);
18 static void addtohist(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
20 static int freesp_f(int argc
, char **argv
);
21 static void histinit(int maxlen
);
22 static int init(int argc
, char **argv
);
23 static void printhist(void);
24 static void scan_ag(xfs_agnumber_t agno
);
25 static void scanfunc_bno(struct xfs_btree_block
*block
, typnm_t typ
, int level
,
27 static void scanfunc_cnt(struct xfs_btree_block
*block
, typnm_t typ
, int level
,
29 static void scan_freelist(xfs_agf_t
*agf
);
30 static void scan_sbtree(xfs_agf_t
*agf
, xfs_agblock_t root
, typnm_t typ
,
32 void (*func
)(struct xfs_btree_block
*block
, typnm_t typ
,
33 int level
, xfs_agf_t
*agf
));
34 static int usage(void);
37 static xfs_agnumber_t
*aglist
;
42 static struct histogram freesp_hist
;
45 static int summaryflag
;
47 static const cmdinfo_t freesp_cmd
=
48 { "freesp", NULL
, freesp_f
, 0, -1, 0,
49 "[-bcdfs] [-A alignment] [-a agno]... [-e binsize] [-h h1]... [-m binmult]",
50 "summarize free space for filesystem", NULL
};
60 for (i
= 0; i
< agcount
; i
++)
61 if (aglist
[i
] == agno
)
67 * Report on freespace usage in xfs filesystem.
76 if (!init(argc
, argv
))
80 dbprintf("%8s %8s %8s\n", "agno", "agbno", "len");
82 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
86 if (hist_buckets(&freesp_hist
))
89 struct histogram_strings hstr
= {
90 .sum
= _("total free blocks"),
91 .observations
= _("total free extents"),
92 .averages
= _("average free extent size"),
95 hist_summarize(&freesp_hist
, &hstr
);
99 hist_free(&freesp_hist
);
106 add_command(&freesp_cmd
);
113 aglist
= xrealloc(aglist
, (agcount
+ 1) * sizeof(*aglist
));
114 aglist
[agcount
] = (xfs_agnumber_t
)atoi(a
);
126 agcount
= countflag
= dumpflag
= equalsize
= multsize
= optind
= 0;
127 seen1
= summaryflag
= 0;
130 while ((c
= getopt(argc
, argv
, "A:a:bcde:h:m:s")) != EOF
) {
133 alignment
= atoi(optarg
);
153 equalsize
= atoi(optarg
);
157 if (speced
&& hist_buckets(&freesp_hist
) == 0)
159 addhistent(atoi(optarg
));
165 multsize
= atoi(optarg
);
179 histinit((int)mp
->m_sb
.sb_agblocks
);
186 dbprintf(_("freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... "
198 set_cur(&typtab
[TYP_AGF
], XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
199 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
200 agf
= iocur_top
->data
;
203 scan_sbtree(agf
, be32_to_cpu(agf
->agf_cnt_root
),
204 TYP_CNTBT
, be32_to_cpu(agf
->agf_cnt_level
),
207 scan_sbtree(agf
, be32_to_cpu(agf
->agf_bno_root
),
208 TYP_BNOBT
, be32_to_cpu(agf
->agf_bno_level
),
215 struct xfs_mount
*mp
,
219 addtohist(*(xfs_agnumber_t
*)priv
, bno
, 1);
227 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
229 if (be32_to_cpu(agf
->agf_flcount
) == 0)
232 set_cur(&typtab
[TYP_AGFL
], XFS_AG_DADDR(mp
, seqno
, XFS_AGFL_DADDR(mp
)),
233 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
235 /* verify agf values before proceeding */
236 if (be32_to_cpu(agf
->agf_flfirst
) >= libxfs_agfl_size(mp
) ||
237 be32_to_cpu(agf
->agf_fllast
) >= libxfs_agfl_size(mp
)) {
238 dbprintf(_("agf %d freelist blocks bad, skipping "
239 "freelist scan\n"), seqno
);
244 libxfs_agfl_walk(mp
, agf
, iocur_top
->bp
, scan_agfl
, &seqno
);
254 void (*func
)(struct xfs_btree_block
*block
,
259 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
262 set_cur(&typtab
[typ
], XFS_AGB_TO_DADDR(mp
, seqno
, root
),
263 blkbb
, DB_RING_IGN
, NULL
);
264 if (iocur_top
->data
== NULL
) {
265 dbprintf(_("can't read btree block %u/%u\n"), seqno
, root
);
268 (*func
)(iocur_top
->data
, typ
, nlevels
- 1, agf
);
275 struct xfs_btree_block
*block
,
284 if (!(be32_to_cpu(block
->bb_magic
) == XFS_ABTB_MAGIC
||
285 be32_to_cpu(block
->bb_magic
) == XFS_ABTB_CRC_MAGIC
))
289 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
290 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
291 addtohist(be32_to_cpu(agf
->agf_seqno
),
292 be32_to_cpu(rp
[i
].ar_startblock
),
293 be32_to_cpu(rp
[i
].ar_blockcount
));
296 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
297 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
298 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), typ
, level
, scanfunc_bno
);
303 struct xfs_btree_block
*block
,
312 if (!(be32_to_cpu(block
->bb_magic
) == XFS_ABTC_MAGIC
||
313 be32_to_cpu(block
->bb_magic
) == XFS_ABTC_CRC_MAGIC
))
317 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
318 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
319 addtohist(be32_to_cpu(agf
->agf_seqno
),
320 be32_to_cpu(rp
[i
].ar_startblock
),
321 be32_to_cpu(rp
[i
].ar_blockcount
));
324 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
325 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
326 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), typ
, level
, scanfunc_cnt
);
333 hist_add_bucket(&freesp_hist
, h
);
342 if (alignment
&& (XFS_AGB_TO_FSB(mp
,agno
,agbno
) % alignment
))
346 dbprintf("%8d %8d %8d\n", agno
, agbno
, len
);
347 hist_add(&freesp_hist
, len
);
356 hist_init(&freesp_hist
);
358 for (i
= 1; i
< maxlen
; i
+= equalsize
)
360 } else if (multsize
) {
361 for (i
= 1; i
< maxlen
; i
*= multsize
)
367 hist_prepare(&freesp_hist
, maxlen
);
373 struct histogram_strings hstr
= {
375 .observations
= _("extents"),
378 hist_print(&freesp_hist
, &hstr
);