]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/fscounters.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
9 #include <sys/statvfs.h>
10 #include "platform_defs.h"
12 #include "xfs_format.h"
13 #include "libfrog/paths.h"
14 #include "libfrog/workqueue.h"
15 #include "xfs_scrub.h"
17 #include "fscounters.h"
18 #include "libfrog/bulkstat.h"
21 * Filesystem counter collection routines. We can count the number of
22 * inodes in the filesystem, and we can estimate the block counters.
25 /* Count the number of inodes in the filesystem. */
27 /* INUMBERS wrapper routines. */
34 * Count the number of inodes. Use INUMBERS to figure out how many inodes
35 * exist in the filesystem, assuming we've already scrubbed that.
43 struct count_inodes
*ci
= arg
;
44 struct scrub_ctx
*ctx
= (struct scrub_ctx
*)wq
->wq_ctx
;
45 struct xfs_inumbers_req
*ireq
;
50 ireq
= xfrog_inumbers_alloc_req(64, 0);
55 xfrog_inumbers_set_ag(ireq
, agno
);
57 while (!ci
->error
&& (error
= xfrog_inumbers(&ctx
->mnt
, ireq
)) == 0) {
58 if (ireq
->hdr
.ocount
== 0)
60 for (i
= 0; i
< ireq
->hdr
.ocount
; i
++)
61 nr
+= ireq
->inumbers
[i
].xi_alloccount
;
68 ci
->counters
[agno
] = nr
;
72 * Count all the inodes in a filesystem. Returns 0 or a positive error number.
75 scrub_count_all_inodes(
76 struct scrub_ctx
*ctx
,
79 struct count_inodes
*ci
;
84 ci
= calloc(1, sizeof(struct count_inodes
) +
85 (ctx
->mnt
.fsgeom
.agcount
* sizeof(uint64_t)));
89 ret
= workqueue_create(&wq
, (struct xfs_mount
*)ctx
,
90 scrub_nproc_workqueue(ctx
));
94 for (agno
= 0; agno
< ctx
->mnt
.fsgeom
.agcount
&& !ci
->error
; agno
++) {
95 ret
= workqueue_add(&wq
, count_ag_inodes
, agno
, ci
);
100 ret2
= workqueue_terminate(&wq
);
103 workqueue_destroy(&wq
);
110 for (agno
= 0; agno
< ctx
->mnt
.fsgeom
.agcount
; agno
++)
111 *count
+= ci
->counters
[agno
];
119 * Estimate the number of blocks and inodes in the filesystem. Returns 0
120 * or a positive error number.
123 scrub_scan_estimate_blocks(
124 struct scrub_ctx
*ctx
,
125 unsigned long long *d_blocks
,
126 unsigned long long *d_bfree
,
127 unsigned long long *r_blocks
,
128 unsigned long long *r_bfree
,
129 unsigned long long *f_files
,
130 unsigned long long *f_free
)
132 struct xfs_fsop_counts fc
;
133 struct xfs_fsop_resblks rb
;
137 /* Grab the fstatvfs counters, since it has to report accurately. */
138 error
= fstatvfs(ctx
->mnt
.fd
, &sfs
);
142 /* Fetch the filesystem counters. */
143 error
= ioctl(ctx
->mnt
.fd
, XFS_IOC_FSCOUNTS
, &fc
);
148 * XFS reserves some blocks to prevent hard ENOSPC, so add those
149 * blocks back to the free data counts.
151 error
= ioctl(ctx
->mnt
.fd
, XFS_IOC_GET_RESBLKS
, &rb
);
155 sfs
.f_bfree
+= rb
.resblks_avail
;
157 *d_blocks
= sfs
.f_blocks
;
158 if (ctx
->mnt
.fsgeom
.logstart
> 0)
159 *d_blocks
+= ctx
->mnt
.fsgeom
.logblocks
;
160 *d_bfree
= sfs
.f_bfree
;
161 *r_blocks
= ctx
->mnt
.fsgeom
.rtblocks
;
162 *r_bfree
= fc
.freertx
;
163 *f_files
= sfs
.f_files
;
164 *f_free
= sfs
.f_ffree
;