]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/phase3.c
2 * Copyright (C) 2018 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it would be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <sys/types.h>
25 #include <sys/statvfs.h>
28 #include "workqueue.h"
29 #include "xfs_scrub.h"
36 /* Phase 3: Scan all inodes. */
39 * Run a per-file metadata scanner. We use the ino/gen interface to
40 * ensure that the inode we're checking matches what the inode scan
45 struct scrub_ctx
*ctx
,
46 bool (*fn
)(struct scrub_ctx
*, uint64_t,
50 return fn(ctx
, bs
->bs_ino
, bs
->bs_gen
, ctx
->mnt_fd
);
53 struct scrub_inode_ctx
{
54 struct ptcounter
*icount
;
58 /* Verify the contents, xattrs, and extent maps of an inode. */
61 struct scrub_ctx
*ctx
,
62 struct xfs_handle
*handle
,
63 struct xfs_bstat
*bstat
,
66 struct scrub_inode_ctx
*ictx
= arg
;
67 struct ptcounter
*icount
= ictx
->icount
;
73 /* Try to open the inode to pin it. */
74 if (S_ISREG(bstat
->bs_mode
)) {
75 fd
= xfs_open_handle(handle
);
76 /* Stale inode means we scan the whole cluster again. */
77 if (fd
< 0 && errno
== ESTALE
)
81 /* Scrub the inode. */
82 moveon
= xfs_scrub_fd(ctx
, xfs_scrub_inode_fields
, bstat
);
86 /* Scrub all block mappings. */
87 moveon
= xfs_scrub_fd(ctx
, xfs_scrub_data_fork
, bstat
);
90 moveon
= xfs_scrub_fd(ctx
, xfs_scrub_attr_fork
, bstat
);
93 moveon
= xfs_scrub_fd(ctx
, xfs_scrub_cow_fork
, bstat
);
97 if (S_ISLNK(bstat
->bs_mode
)) {
98 /* Check symlink contents. */
99 moveon
= xfs_scrub_symlink(ctx
, bstat
->bs_ino
,
100 bstat
->bs_gen
, ctx
->mnt_fd
);
101 } else if (S_ISDIR(bstat
->bs_mode
)) {
102 /* Check the directory entries. */
103 moveon
= xfs_scrub_fd(ctx
, xfs_scrub_dir
, bstat
);
108 /* Check all the extended attributes. */
109 moveon
= xfs_scrub_fd(ctx
, xfs_scrub_attr
, bstat
);
113 /* Check parent pointers. */
114 moveon
= xfs_scrub_fd(ctx
, xfs_scrub_parent
, bstat
);
119 ptcounter_add(icount
, 1);
124 ictx
->moveon
= false;
125 return ictx
->moveon
? 0 : XFS_ITERATE_INODES_ABORT
;
128 /* Verify all the inodes in a filesystem. */
131 struct scrub_ctx
*ctx
)
133 struct scrub_inode_ctx ictx
;
137 ictx
.icount
= ptcounter_init(scrub_nproc(ctx
));
139 str_error(ctx
, ctx
->mntpoint
, _("Could not create counter."));
143 ret
= xfs_scan_all_inodes(ctx
, xfs_scrub_inode
, &ictx
);
148 xfs_scrub_report_preen_triggers(ctx
);
149 ctx
->inodes_checked
= ptcounter_value(ictx
.icount
);
152 ptcounter_free(ictx
.icount
);
156 /* Estimate how much work we're going to do. */
158 xfs_estimate_inodes_work(
159 struct scrub_ctx
*ctx
,
161 unsigned int *nr_threads
,
164 *items
= ctx
->mnt_sv
.f_files
- ctx
->mnt_sv
.f_ffree
;
165 *nr_threads
= scrub_nproc(ctx
);