blob: d40bba9e75968c4a382b2061052fc68f8635759c [file] [log] [blame]
Dave Chinner0b61f8a2018-06-05 19:42:14 -07001// SPDX-License-Identifier: GPL-2.0+
Darrick J. Wongdcb660f2017-10-17 21:37:36 -07002/*
3 * Copyright (C) 2017 Oracle. All Rights Reserved.
Darrick J. Wongdcb660f2017-10-17 21:37:36 -07004 * Author: Darrick J. Wong <darrick.wong@oracle.com>
Darrick J. Wongdcb660f2017-10-17 21:37:36 -07005 */
6#include "xfs.h"
7#include "xfs_fs.h"
8#include "xfs_shared.h"
9#include "xfs_format.h"
10#include "xfs_trans_resv.h"
11#include "xfs_mount.h"
12#include "xfs_defer.h"
13#include "xfs_btree.h"
14#include "xfs_bit.h"
15#include "xfs_log_format.h"
16#include "xfs_trans.h"
17#include "xfs_sb.h"
18#include "xfs_inode.h"
Darrick J. Wong80e4e122017-10-17 21:37:42 -070019#include "xfs_icache.h"
20#include "xfs_itable.h"
Darrick J. Wongdcb660f2017-10-17 21:37:36 -070021#include "xfs_alloc.h"
22#include "xfs_alloc_btree.h"
23#include "xfs_bmap.h"
24#include "xfs_bmap_btree.h"
25#include "xfs_ialloc.h"
26#include "xfs_ialloc_btree.h"
27#include "xfs_refcount.h"
28#include "xfs_refcount_btree.h"
29#include "xfs_rmap.h"
30#include "xfs_rmap_btree.h"
Darrick J. Wong3daa6642017-10-17 21:37:40 -070031#include "xfs_log.h"
32#include "xfs_trans_priv.h"
Darrick J. Wong87d9d602018-05-14 06:34:33 -070033#include "xfs_attr.h"
34#include "xfs_reflink.h"
Darrick J. Wongdcb660f2017-10-17 21:37:36 -070035#include "scrub/xfs_scrub.h"
36#include "scrub/scrub.h"
37#include "scrub/common.h"
38#include "scrub/trace.h"
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -070039#include "scrub/btree.h"
Darrick J. Wong0a9633f2018-05-29 22:18:08 -070040#include "scrub/repair.h"
Darrick J. Wongdcb660f2017-10-17 21:37:36 -070041
42/* Common code for the metadata scrubbers. */
43
Darrick J. Wong4700d222017-10-17 21:37:36 -070044/*
45 * Handling operational errors.
46 *
47 * The *_process_error() family of functions are used to process error return
48 * codes from functions called as part of a scrub operation.
49 *
50 * If there's no error, we return true to tell the caller that it's ok
51 * to move on to the next check in its list.
52 *
53 * For non-verifier errors (e.g. ENOMEM) we return false to tell the
54 * caller that something bad happened, and we preserve *error so that
55 * the caller can return the *error up the stack to userspace.
56 *
57 * Verifier errors (EFSBADCRC/EFSCORRUPTED) are recorded by setting
58 * OFLAG_CORRUPT in sm_flags and the *error is cleared. In other words,
59 * we track verifier errors (and failed scrub checks) via OFLAG_CORRUPT,
60 * not via return codes. We return false to tell the caller that
61 * something bad happened. Since the error has been cleared, the caller
62 * will (presumably) return that zero and scrubbing will move on to
63 * whatever's next.
64 *
65 * ftrace can be used to record the precise metadata location and the
66 * approximate code location of the failed operation.
67 */
68
69/* Check for operational errors. */
Darrick J. Wong64b12562018-01-16 18:52:14 -080070static bool
Darrick J. Wongc517b3a2018-07-19 12:29:11 -070071__xchk_process_error(
Darrick J. Wong64b12562018-01-16 18:52:14 -080072 struct xfs_scrub_context *sc,
73 xfs_agnumber_t agno,
74 xfs_agblock_t bno,
75 int *error,
76 __u32 errflag,
77 void *ret_ip)
78{
79 switch (*error) {
80 case 0:
81 return true;
82 case -EDEADLOCK:
83 /* Used to restart an op with deadlock avoidance. */
Darrick J. Wongc517b3a2018-07-19 12:29:11 -070084 trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
Darrick J. Wong64b12562018-01-16 18:52:14 -080085 break;
86 case -EFSBADCRC:
87 case -EFSCORRUPTED:
88 /* Note the badness but don't abort. */
89 sc->sm->sm_flags |= errflag;
90 *error = 0;
91 /* fall through */
92 default:
Darrick J. Wongc517b3a2018-07-19 12:29:11 -070093 trace_xchk_op_error(sc, agno, bno, *error,
Darrick J. Wong64b12562018-01-16 18:52:14 -080094 ret_ip);
95 break;
96 }
97 return false;
98}
99
Darrick J. Wong4700d222017-10-17 21:37:36 -0700100bool
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700101xchk_process_error(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700102 struct xfs_scrub_context *sc,
103 xfs_agnumber_t agno,
104 xfs_agblock_t bno,
105 int *error)
106{
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700107 return __xchk_process_error(sc, agno, bno, error,
Darrick J. Wong64b12562018-01-16 18:52:14 -0800108 XFS_SCRUB_OFLAG_CORRUPT, __return_address);
109}
110
111bool
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700112xchk_xref_process_error(
Darrick J. Wong64b12562018-01-16 18:52:14 -0800113 struct xfs_scrub_context *sc,
114 xfs_agnumber_t agno,
115 xfs_agblock_t bno,
116 int *error)
117{
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700118 return __xchk_process_error(sc, agno, bno, error,
Darrick J. Wong64b12562018-01-16 18:52:14 -0800119 XFS_SCRUB_OFLAG_XFAIL, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700120}
121
122/* Check for operational errors for a file offset. */
Darrick J. Wong64b12562018-01-16 18:52:14 -0800123static bool
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700124__xchk_fblock_process_error(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700125 struct xfs_scrub_context *sc,
126 int whichfork,
127 xfs_fileoff_t offset,
Darrick J. Wong64b12562018-01-16 18:52:14 -0800128 int *error,
129 __u32 errflag,
130 void *ret_ip)
Darrick J. Wong4700d222017-10-17 21:37:36 -0700131{
132 switch (*error) {
133 case 0:
134 return true;
135 case -EDEADLOCK:
136 /* Used to restart an op with deadlock avoidance. */
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700137 trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700138 break;
139 case -EFSBADCRC:
140 case -EFSCORRUPTED:
141 /* Note the badness but don't abort. */
Darrick J. Wong64b12562018-01-16 18:52:14 -0800142 sc->sm->sm_flags |= errflag;
Darrick J. Wong4700d222017-10-17 21:37:36 -0700143 *error = 0;
144 /* fall through */
145 default:
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700146 trace_xchk_file_op_error(sc, whichfork, offset, *error,
Darrick J. Wong64b12562018-01-16 18:52:14 -0800147 ret_ip);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700148 break;
149 }
150 return false;
151}
152
Darrick J. Wong64b12562018-01-16 18:52:14 -0800153bool
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700154xchk_fblock_process_error(
Darrick J. Wong64b12562018-01-16 18:52:14 -0800155 struct xfs_scrub_context *sc,
156 int whichfork,
157 xfs_fileoff_t offset,
158 int *error)
159{
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700160 return __xchk_fblock_process_error(sc, whichfork, offset, error,
Darrick J. Wong64b12562018-01-16 18:52:14 -0800161 XFS_SCRUB_OFLAG_CORRUPT, __return_address);
162}
163
164bool
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700165xchk_fblock_xref_process_error(
Darrick J. Wong64b12562018-01-16 18:52:14 -0800166 struct xfs_scrub_context *sc,
167 int whichfork,
168 xfs_fileoff_t offset,
169 int *error)
170{
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700171 return __xchk_fblock_process_error(sc, whichfork, offset, error,
Darrick J. Wong64b12562018-01-16 18:52:14 -0800172 XFS_SCRUB_OFLAG_XFAIL, __return_address);
173}
174
Darrick J. Wong4700d222017-10-17 21:37:36 -0700175/*
176 * Handling scrub corruption/optimization/warning checks.
177 *
178 * The *_set_{corrupt,preen,warning}() family of functions are used to
179 * record the presence of metadata that is incorrect (corrupt), could be
180 * optimized somehow (preen), or should be flagged for administrative
181 * review but is not incorrect (warn).
182 *
183 * ftrace can be used to record the precise metadata location and
184 * approximate code location of the failed check.
185 */
186
187/* Record a block which could be optimized. */
188void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700189xchk_block_set_preen(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700190 struct xfs_scrub_context *sc,
191 struct xfs_buf *bp)
192{
193 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700194 trace_xchk_block_preen(sc, bp->b_bn, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700195}
196
197/*
198 * Record an inode which could be optimized. The trace data will
199 * include the block given by bp if bp is given; otherwise it will use
200 * the block location of the inode record itself.
201 */
202void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700203xchk_ino_set_preen(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700204 struct xfs_scrub_context *sc,
Darrick J. Wong7e56d9e2018-03-23 10:06:54 -0700205 xfs_ino_t ino)
Darrick J. Wong4700d222017-10-17 21:37:36 -0700206{
207 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700208 trace_xchk_ino_preen(sc, ino, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700209}
210
211/* Record a corrupt block. */
212void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700213xchk_block_set_corrupt(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700214 struct xfs_scrub_context *sc,
215 struct xfs_buf *bp)
216{
217 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700218 trace_xchk_block_error(sc, bp->b_bn, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700219}
220
Darrick J. Wong64b12562018-01-16 18:52:14 -0800221/* Record a corruption while cross-referencing. */
222void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700223xchk_block_xref_set_corrupt(
Darrick J. Wong64b12562018-01-16 18:52:14 -0800224 struct xfs_scrub_context *sc,
225 struct xfs_buf *bp)
226{
227 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700228 trace_xchk_block_error(sc, bp->b_bn, __return_address);
Darrick J. Wong64b12562018-01-16 18:52:14 -0800229}
230
Darrick J. Wong4700d222017-10-17 21:37:36 -0700231/*
232 * Record a corrupt inode. The trace data will include the block given
233 * by bp if bp is given; otherwise it will use the block location of the
234 * inode record itself.
235 */
236void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700237xchk_ino_set_corrupt(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700238 struct xfs_scrub_context *sc,
Darrick J. Wong7e56d9e2018-03-23 10:06:54 -0700239 xfs_ino_t ino)
Darrick J. Wong4700d222017-10-17 21:37:36 -0700240{
241 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700242 trace_xchk_ino_error(sc, ino, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700243}
244
Darrick J. Wong64b12562018-01-16 18:52:14 -0800245/* Record a corruption while cross-referencing with an inode. */
246void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700247xchk_ino_xref_set_corrupt(
Darrick J. Wong64b12562018-01-16 18:52:14 -0800248 struct xfs_scrub_context *sc,
Darrick J. Wong7e56d9e2018-03-23 10:06:54 -0700249 xfs_ino_t ino)
Darrick J. Wong64b12562018-01-16 18:52:14 -0800250{
251 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700252 trace_xchk_ino_error(sc, ino, __return_address);
Darrick J. Wong64b12562018-01-16 18:52:14 -0800253}
254
Darrick J. Wong4700d222017-10-17 21:37:36 -0700255/* Record corruption in a block indexed by a file fork. */
256void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700257xchk_fblock_set_corrupt(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700258 struct xfs_scrub_context *sc,
259 int whichfork,
260 xfs_fileoff_t offset)
261{
262 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700263 trace_xchk_fblock_error(sc, whichfork, offset, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700264}
265
Darrick J. Wong64b12562018-01-16 18:52:14 -0800266/* Record a corruption while cross-referencing a fork block. */
267void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700268xchk_fblock_xref_set_corrupt(
Darrick J. Wong64b12562018-01-16 18:52:14 -0800269 struct xfs_scrub_context *sc,
270 int whichfork,
271 xfs_fileoff_t offset)
272{
273 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700274 trace_xchk_fblock_error(sc, whichfork, offset, __return_address);
Darrick J. Wong64b12562018-01-16 18:52:14 -0800275}
276
Darrick J. Wong4700d222017-10-17 21:37:36 -0700277/*
278 * Warn about inodes that need administrative review but is not
279 * incorrect.
280 */
281void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700282xchk_ino_set_warning(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700283 struct xfs_scrub_context *sc,
Darrick J. Wong7e56d9e2018-03-23 10:06:54 -0700284 xfs_ino_t ino)
Darrick J. Wong4700d222017-10-17 21:37:36 -0700285{
286 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700287 trace_xchk_ino_warning(sc, ino, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700288}
289
290/* Warn about a block indexed by a file fork that needs review. */
291void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700292xchk_fblock_set_warning(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700293 struct xfs_scrub_context *sc,
294 int whichfork,
295 xfs_fileoff_t offset)
296{
297 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700298 trace_xchk_fblock_warning(sc, whichfork, offset, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700299}
300
301/* Signal an incomplete scrub. */
302void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700303xchk_set_incomplete(
Darrick J. Wong4700d222017-10-17 21:37:36 -0700304 struct xfs_scrub_context *sc)
305{
306 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_INCOMPLETE;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700307 trace_xchk_incomplete(sc, __return_address);
Darrick J. Wong4700d222017-10-17 21:37:36 -0700308}
309
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700310/*
Darrick J. Wongd8526572018-01-16 18:53:08 -0800311 * rmap scrubbing -- compute the number of blocks with a given owner,
312 * at least according to the reverse mapping data.
313 */
314
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700315struct xchk_rmap_ownedby_info {
Darrick J. Wongd8526572018-01-16 18:53:08 -0800316 struct xfs_owner_info *oinfo;
317 xfs_filblks_t *blocks;
318};
319
320STATIC int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700321xchk_count_rmap_ownedby_irec(
Darrick J. Wongd8526572018-01-16 18:53:08 -0800322 struct xfs_btree_cur *cur,
323 struct xfs_rmap_irec *rec,
324 void *priv)
325{
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700326 struct xchk_rmap_ownedby_info *sroi = priv;
Darrick J. Wongd8526572018-01-16 18:53:08 -0800327 bool irec_attr;
328 bool oinfo_attr;
329
330 irec_attr = rec->rm_flags & XFS_RMAP_ATTR_FORK;
331 oinfo_attr = sroi->oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK;
332
333 if (rec->rm_owner != sroi->oinfo->oi_owner)
334 return 0;
335
336 if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) || irec_attr == oinfo_attr)
337 (*sroi->blocks) += rec->rm_blockcount;
338
339 return 0;
340}
341
342/*
343 * Calculate the number of blocks the rmap thinks are owned by something.
344 * The caller should pass us an rmapbt cursor.
345 */
346int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700347xchk_count_rmap_ownedby_ag(
Darrick J. Wongd8526572018-01-16 18:53:08 -0800348 struct xfs_scrub_context *sc,
349 struct xfs_btree_cur *cur,
350 struct xfs_owner_info *oinfo,
351 xfs_filblks_t *blocks)
352{
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700353 struct xchk_rmap_ownedby_info sroi;
Darrick J. Wongd8526572018-01-16 18:53:08 -0800354
355 sroi.oinfo = oinfo;
356 *blocks = 0;
357 sroi.blocks = blocks;
358
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700359 return xfs_rmap_query_all(cur, xchk_count_rmap_ownedby_irec,
Darrick J. Wongd8526572018-01-16 18:53:08 -0800360 &sroi);
361}
362
363/*
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700364 * AG scrubbing
365 *
366 * These helpers facilitate locking an allocation group's header
367 * buffers, setting up cursors for all btrees that are present, and
368 * cleaning everything up once we're through.
369 */
370
Darrick J. Wongab9d5dc2017-10-17 21:37:39 -0700371/* Decide if we want to return an AG header read failure. */
372static inline bool
373want_ag_read_header_failure(
374 struct xfs_scrub_context *sc,
375 unsigned int type)
376{
377 /* Return all AG header read failures when scanning btrees. */
378 if (sc->sm->sm_type != XFS_SCRUB_TYPE_AGF &&
Darrick J. Wonga12890a2017-10-17 21:37:39 -0700379 sc->sm->sm_type != XFS_SCRUB_TYPE_AGFL &&
380 sc->sm->sm_type != XFS_SCRUB_TYPE_AGI)
Darrick J. Wongab9d5dc2017-10-17 21:37:39 -0700381 return true;
382 /*
383 * If we're scanning a given type of AG header, we only want to
384 * see read failures from that specific header. We'd like the
385 * other headers to cross-check them, but this isn't required.
386 */
387 if (sc->sm->sm_type == type)
388 return true;
389 return false;
390}
391
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700392/*
393 * Grab all the headers for an AG.
394 *
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700395 * The headers should be released by xchk_ag_free, but as a fail
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700396 * safe we attach all the buffers we grab to the scrub transaction so
397 * they'll all be freed when we cancel it.
398 */
399int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700400xchk_ag_read_headers(
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700401 struct xfs_scrub_context *sc,
402 xfs_agnumber_t agno,
403 struct xfs_buf **agi,
404 struct xfs_buf **agf,
405 struct xfs_buf **agfl)
406{
407 struct xfs_mount *mp = sc->mp;
408 int error;
409
410 error = xfs_ialloc_read_agi(mp, sc->tp, agno, agi);
Darrick J. Wonga12890a2017-10-17 21:37:39 -0700411 if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI))
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700412 goto out;
413
414 error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, agf);
Darrick J. Wongab9d5dc2017-10-17 21:37:39 -0700415 if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGF))
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700416 goto out;
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700417
418 error = xfs_alloc_read_agfl(mp, sc->tp, agno, agfl);
Darrick J. Wongab9d5dc2017-10-17 21:37:39 -0700419 if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGFL))
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700420 goto out;
Darrick J. Wong5a0f4332018-01-08 10:49:02 -0800421 error = 0;
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700422out:
423 return error;
424}
425
426/* Release all the AG btree cursors. */
427void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700428xchk_ag_btcur_free(
429 struct xchk_ag *sa)
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700430{
431 if (sa->refc_cur)
432 xfs_btree_del_cursor(sa->refc_cur, XFS_BTREE_ERROR);
433 if (sa->rmap_cur)
434 xfs_btree_del_cursor(sa->rmap_cur, XFS_BTREE_ERROR);
435 if (sa->fino_cur)
436 xfs_btree_del_cursor(sa->fino_cur, XFS_BTREE_ERROR);
437 if (sa->ino_cur)
438 xfs_btree_del_cursor(sa->ino_cur, XFS_BTREE_ERROR);
439 if (sa->cnt_cur)
440 xfs_btree_del_cursor(sa->cnt_cur, XFS_BTREE_ERROR);
441 if (sa->bno_cur)
442 xfs_btree_del_cursor(sa->bno_cur, XFS_BTREE_ERROR);
443
444 sa->refc_cur = NULL;
445 sa->rmap_cur = NULL;
446 sa->fino_cur = NULL;
447 sa->ino_cur = NULL;
448 sa->bno_cur = NULL;
449 sa->cnt_cur = NULL;
450}
451
452/* Initialize all the btree cursors for an AG. */
453int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700454xchk_ag_btcur_init(
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700455 struct xfs_scrub_context *sc,
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700456 struct xchk_ag *sa)
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700457{
458 struct xfs_mount *mp = sc->mp;
459 xfs_agnumber_t agno = sa->agno;
460
461 if (sa->agf_bp) {
462 /* Set up a bnobt cursor for cross-referencing. */
463 sa->bno_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
464 agno, XFS_BTNUM_BNO);
465 if (!sa->bno_cur)
466 goto err;
467
468 /* Set up a cntbt cursor for cross-referencing. */
469 sa->cnt_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
470 agno, XFS_BTNUM_CNT);
471 if (!sa->cnt_cur)
472 goto err;
473 }
474
475 /* Set up a inobt cursor for cross-referencing. */
476 if (sa->agi_bp) {
477 sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp,
478 agno, XFS_BTNUM_INO);
479 if (!sa->ino_cur)
480 goto err;
481 }
482
483 /* Set up a finobt cursor for cross-referencing. */
484 if (sa->agi_bp && xfs_sb_version_hasfinobt(&mp->m_sb)) {
485 sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp,
486 agno, XFS_BTNUM_FINO);
487 if (!sa->fino_cur)
488 goto err;
489 }
490
491 /* Set up a rmapbt cursor for cross-referencing. */
492 if (sa->agf_bp && xfs_sb_version_hasrmapbt(&mp->m_sb)) {
493 sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp,
494 agno);
495 if (!sa->rmap_cur)
496 goto err;
497 }
498
499 /* Set up a refcountbt cursor for cross-referencing. */
500 if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb)) {
501 sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
Brian Fostered7ef8e2018-07-11 22:26:17 -0700502 sa->agf_bp, agno);
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700503 if (!sa->refc_cur)
504 goto err;
505 }
506
507 return 0;
508err:
509 return -ENOMEM;
510}
511
512/* Release the AG header context and btree cursors. */
513void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700514xchk_ag_free(
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700515 struct xfs_scrub_context *sc,
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700516 struct xchk_ag *sa)
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700517{
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700518 xchk_ag_btcur_free(sa);
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700519 if (sa->agfl_bp) {
520 xfs_trans_brelse(sc->tp, sa->agfl_bp);
521 sa->agfl_bp = NULL;
522 }
523 if (sa->agf_bp) {
524 xfs_trans_brelse(sc->tp, sa->agf_bp);
525 sa->agf_bp = NULL;
526 }
527 if (sa->agi_bp) {
528 xfs_trans_brelse(sc->tp, sa->agi_bp);
529 sa->agi_bp = NULL;
530 }
Darrick J. Wong51863d72018-05-29 22:24:44 -0700531 if (sa->pag) {
532 xfs_perag_put(sa->pag);
533 sa->pag = NULL;
534 }
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700535 sa->agno = NULLAGNUMBER;
536}
537
538/*
539 * For scrub, grab the AGI and the AGF headers, in that order. Locking
540 * order requires us to get the AGI before the AGF. We use the
541 * transaction to avoid deadlocking on crosslinked metadata buffers;
542 * either the caller passes one in (bmap scrub) or we have to create a
543 * transaction ourselves.
544 */
545int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700546xchk_ag_init(
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700547 struct xfs_scrub_context *sc,
548 xfs_agnumber_t agno,
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700549 struct xchk_ag *sa)
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700550{
551 int error;
552
553 sa->agno = agno;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700554 error = xchk_ag_read_headers(sc, agno, &sa->agi_bp,
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700555 &sa->agf_bp, &sa->agfl_bp);
556 if (error)
557 return error;
558
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700559 return xchk_ag_btcur_init(sc, sa);
Darrick J. Wongb6c1beb2017-10-17 21:37:38 -0700560}
561
Darrick J. Wong51863d72018-05-29 22:24:44 -0700562/*
563 * Grab the per-ag structure if we haven't already gotten it. Teardown of the
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700564 * xchk_ag will release it for us.
Darrick J. Wong51863d72018-05-29 22:24:44 -0700565 */
566void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700567xchk_perag_get(
Darrick J. Wong51863d72018-05-29 22:24:44 -0700568 struct xfs_mount *mp,
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700569 struct xchk_ag *sa)
Darrick J. Wong51863d72018-05-29 22:24:44 -0700570{
571 if (!sa->pag)
572 sa->pag = xfs_perag_get(mp, sa->agno);
573}
574
Darrick J. Wongdcb660f2017-10-17 21:37:36 -0700575/* Per-scrubber setup functions */
576
Darrick J. Wong9d9c9022018-05-09 10:02:01 -0700577/*
578 * Grab an empty transaction so that we can re-grab locked buffers if
579 * one of our btrees turns out to be cyclic.
Darrick J. Wong0a9633f2018-05-29 22:18:08 -0700580 *
581 * If we're going to repair something, we need to ask for the largest possible
582 * log reservation so that we can handle the worst case scenario for metadata
583 * updates while rebuilding a metadata item. We also need to reserve as many
584 * blocks in the head transaction as we think we're going to need to rebuild
585 * the metadata object.
Darrick J. Wong9d9c9022018-05-09 10:02:01 -0700586 */
587int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700588xchk_trans_alloc(
Darrick J. Wong0a9633f2018-05-29 22:18:08 -0700589 struct xfs_scrub_context *sc,
590 uint resblks)
Darrick J. Wong9d9c9022018-05-09 10:02:01 -0700591{
Darrick J. Wong0a9633f2018-05-29 22:18:08 -0700592 if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)
593 return xfs_trans_alloc(sc->mp, &M_RES(sc->mp)->tr_itruncate,
594 resblks, 0, 0, &sc->tp);
595
Darrick J. Wong9d9c9022018-05-09 10:02:01 -0700596 return xfs_trans_alloc_empty(sc->mp, &sc->tp);
597}
598
Darrick J. Wongdcb660f2017-10-17 21:37:36 -0700599/* Set us up with a transaction and an empty context. */
600int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700601xchk_setup_fs(
Darrick J. Wongdcb660f2017-10-17 21:37:36 -0700602 struct xfs_scrub_context *sc,
603 struct xfs_inode *ip)
604{
Darrick J. Wong0a9633f2018-05-29 22:18:08 -0700605 uint resblks;
606
Darrick J. Wongb5e21962018-07-19 12:29:11 -0700607 resblks = xrep_calc_ag_resblks(sc);
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700608 return xchk_trans_alloc(sc, resblks);
Darrick J. Wongdcb660f2017-10-17 21:37:36 -0700609}
Darrick J. Wongefa7a992017-10-17 21:37:40 -0700610
611/* Set us up with AG headers and btree cursors. */
612int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700613xchk_setup_ag_btree(
Darrick J. Wongefa7a992017-10-17 21:37:40 -0700614 struct xfs_scrub_context *sc,
615 struct xfs_inode *ip,
616 bool force_log)
617{
Darrick J. Wong3daa6642017-10-17 21:37:40 -0700618 struct xfs_mount *mp = sc->mp;
Darrick J. Wongefa7a992017-10-17 21:37:40 -0700619 int error;
620
Darrick J. Wong3daa6642017-10-17 21:37:40 -0700621 /*
622 * If the caller asks us to checkpont the log, do so. This
623 * expensive operation should be performed infrequently and only
624 * as a last resort. Any caller that sets force_log should
625 * document why they need to do so.
626 */
627 if (force_log) {
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700628 error = xchk_checkpoint_log(mp);
Darrick J. Wong3daa6642017-10-17 21:37:40 -0700629 if (error)
630 return error;
631 }
632
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700633 error = xchk_setup_fs(sc, ip);
Darrick J. Wongefa7a992017-10-17 21:37:40 -0700634 if (error)
635 return error;
636
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700637 return xchk_ag_init(sc, sc->sm->sm_agno, &sc->sa);
Darrick J. Wongefa7a992017-10-17 21:37:40 -0700638}
Darrick J. Wong3daa6642017-10-17 21:37:40 -0700639
640/* Push everything out of the log onto disk. */
641int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700642xchk_checkpoint_log(
Darrick J. Wong3daa6642017-10-17 21:37:40 -0700643 struct xfs_mount *mp)
644{
645 int error;
646
Christoph Hellwig60e5bb72018-03-13 23:15:28 -0700647 error = xfs_log_force(mp, XFS_LOG_SYNC);
Darrick J. Wong3daa6642017-10-17 21:37:40 -0700648 if (error)
649 return error;
650 xfs_ail_push_all_sync(mp->m_ail);
651 return 0;
652}
Darrick J. Wong80e4e122017-10-17 21:37:42 -0700653
654/*
655 * Given an inode and the scrub control structure, grab either the
656 * inode referenced in the control structure or the inode passed in.
657 * The inode is not locked.
658 */
659int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700660xchk_get_inode(
Darrick J. Wong80e4e122017-10-17 21:37:42 -0700661 struct xfs_scrub_context *sc,
662 struct xfs_inode *ip_in)
663{
Darrick J. Wongd658e722018-01-08 10:49:04 -0800664 struct xfs_imap imap;
Darrick J. Wong80e4e122017-10-17 21:37:42 -0700665 struct xfs_mount *mp = sc->mp;
666 struct xfs_inode *ip = NULL;
667 int error;
668
Darrick J. Wong80e4e122017-10-17 21:37:42 -0700669 /* We want to scan the inode we already had opened. */
670 if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) {
671 sc->ip = ip_in;
672 return 0;
673 }
674
675 /* Look up the inode, see if the generation number matches. */
676 if (xfs_internal_inum(mp, sc->sm->sm_ino))
677 return -ENOENT;
678 error = xfs_iget(mp, NULL, sc->sm->sm_ino,
679 XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE, 0, &ip);
Darrick J. Wongd658e722018-01-08 10:49:04 -0800680 switch (error) {
681 case -ENOENT:
682 /* Inode doesn't exist, just bail out. */
683 return error;
684 case 0:
685 /* Got an inode, continue. */
686 break;
687 case -EINVAL:
688 /*
689 * -EINVAL with IGET_UNTRUSTED could mean one of several
690 * things: userspace gave us an inode number that doesn't
691 * correspond to fs space, or doesn't have an inobt entry;
692 * or it could simply mean that the inode buffer failed the
693 * read verifiers.
694 *
695 * Try just the inode mapping lookup -- if it succeeds, then
696 * the inode buffer verifier failed and something needs fixing.
697 * Otherwise, we really couldn't find it so tell userspace
698 * that it no longer exists.
699 */
700 error = xfs_imap(sc->mp, sc->tp, sc->sm->sm_ino, &imap,
701 XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE);
702 if (error)
703 return -ENOENT;
704 error = -EFSCORRUPTED;
705 /* fall through */
706 default:
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700707 trace_xchk_op_error(sc,
Darrick J. Wong80e4e122017-10-17 21:37:42 -0700708 XFS_INO_TO_AGNO(mp, sc->sm->sm_ino),
709 XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino),
710 error, __return_address);
711 return error;
712 }
713 if (VFS_I(ip)->i_generation != sc->sm->sm_gen) {
714 iput(VFS_I(ip));
715 return -ENOENT;
716 }
717
718 sc->ip = ip;
719 return 0;
720}
Darrick J. Wonga5c46e52017-10-17 21:37:44 -0700721
722/* Set us up to scrub a file's contents. */
723int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700724xchk_setup_inode_contents(
Darrick J. Wonga5c46e52017-10-17 21:37:44 -0700725 struct xfs_scrub_context *sc,
726 struct xfs_inode *ip,
727 unsigned int resblks)
728{
Darrick J. Wonga5c46e52017-10-17 21:37:44 -0700729 int error;
730
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700731 error = xchk_get_inode(sc, ip);
Darrick J. Wonga5c46e52017-10-17 21:37:44 -0700732 if (error)
733 return error;
734
735 /* Got the inode, lock it and we're ready to go. */
736 sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
737 xfs_ilock(sc->ip, sc->ilock_flags);
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700738 error = xchk_trans_alloc(sc, resblks);
Darrick J. Wonga5c46e52017-10-17 21:37:44 -0700739 if (error)
740 goto out;
741 sc->ilock_flags |= XFS_ILOCK_EXCL;
742 xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
743
744out:
745 /* scrub teardown will unlock and release the inode for us */
746 return error;
747}
Darrick J. Wong64b12562018-01-16 18:52:14 -0800748
749/*
750 * Predicate that decides if we need to evaluate the cross-reference check.
751 * If there was an error accessing the cross-reference btree, just delete
752 * the cursor and skip the check.
753 */
754bool
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700755xchk_should_check_xref(
Darrick J. Wong64b12562018-01-16 18:52:14 -0800756 struct xfs_scrub_context *sc,
757 int *error,
758 struct xfs_btree_cur **curpp)
759{
Darrick J. Wong8389f3ff2018-05-14 06:34:31 -0700760 /* No point in xref if we already know we're corrupt. */
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700761 if (xchk_skip_xref(sc->sm))
Darrick J. Wong8389f3ff2018-05-14 06:34:31 -0700762 return false;
763
Darrick J. Wong64b12562018-01-16 18:52:14 -0800764 if (*error == 0)
765 return true;
766
767 if (curpp) {
768 /* If we've already given up on xref, just bail out. */
769 if (!*curpp)
770 return false;
771
772 /* xref error, delete cursor and bail out. */
773 xfs_btree_del_cursor(*curpp, XFS_BTREE_ERROR);
774 *curpp = NULL;
775 }
776
777 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XFAIL;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700778 trace_xchk_xref_error(sc, *error, __return_address);
Darrick J. Wong64b12562018-01-16 18:52:14 -0800779
780 /*
781 * Errors encountered during cross-referencing with another
782 * data structure should not cause this scrubber to abort.
783 */
784 *error = 0;
785 return false;
786}
Darrick J. Wongcf1b0b82018-01-16 18:53:11 -0800787
788/* Run the structure verifiers on in-memory buffers to detect bad memory. */
789void
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700790xchk_buffer_recheck(
Darrick J. Wongcf1b0b82018-01-16 18:53:11 -0800791 struct xfs_scrub_context *sc,
792 struct xfs_buf *bp)
793{
794 xfs_failaddr_t fa;
795
796 if (bp->b_ops == NULL) {
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700797 xchk_block_set_corrupt(sc, bp);
Darrick J. Wongcf1b0b82018-01-16 18:53:11 -0800798 return;
799 }
800 if (bp->b_ops->verify_struct == NULL) {
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700801 xchk_set_incomplete(sc);
Darrick J. Wongcf1b0b82018-01-16 18:53:11 -0800802 return;
803 }
804 fa = bp->b_ops->verify_struct(bp);
805 if (!fa)
806 return;
807 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700808 trace_xchk_block_error(sc, bp->b_bn, fa);
Darrick J. Wongcf1b0b82018-01-16 18:53:11 -0800809}
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700810
811/*
812 * Scrub the attr/data forks of a metadata inode. The metadata inode must be
813 * pointed to by sc->ip and the ILOCK must be held.
814 */
815int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700816xchk_metadata_inode_forks(
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700817 struct xfs_scrub_context *sc)
818{
819 __u32 smtype;
820 bool shared;
821 int error;
822
823 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
824 return 0;
825
826 /* Metadata inodes don't live on the rt device. */
827 if (sc->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) {
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700828 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700829 return 0;
830 }
831
832 /* They should never participate in reflink. */
833 if (xfs_is_reflink_inode(sc->ip)) {
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700834 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700835 return 0;
836 }
837
838 /* They also should never have extended attributes. */
839 if (xfs_inode_hasattr(sc->ip)) {
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700840 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700841 return 0;
842 }
843
844 /* Invoke the data fork scrubber. */
845 smtype = sc->sm->sm_type;
846 sc->sm->sm_type = XFS_SCRUB_TYPE_BMBTD;
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700847 error = xchk_bmap_data(sc);
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700848 sc->sm->sm_type = smtype;
849 if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
850 return error;
851
852 /* Look for incorrect shared blocks. */
853 if (xfs_sb_version_hasreflink(&sc->mp->m_sb)) {
854 error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip,
855 &shared);
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700856 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0,
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700857 &error))
858 return error;
859 if (shared)
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700860 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
Darrick J. Wong87d9d602018-05-14 06:34:33 -0700861 }
862
863 return error;
864}
Darrick J. Wongddd10c22018-05-14 06:34:34 -0700865
866/*
867 * Try to lock an inode in violation of the usual locking order rules. For
868 * example, trying to get the IOLOCK while in transaction context, or just
869 * plain breaking AG-order or inode-order inode locking rules. Either way,
870 * the only way to avoid an ABBA deadlock is to use trylock and back off if
871 * we can't.
872 */
873int
Darrick J. Wongc517b3a2018-07-19 12:29:11 -0700874xchk_ilock_inverted(
Darrick J. Wongddd10c22018-05-14 06:34:34 -0700875 struct xfs_inode *ip,
876 uint lock_mode)
877{
878 int i;
879
880 for (i = 0; i < 20; i++) {
881 if (xfs_ilock_nowait(ip, lock_mode))
882 return 0;
883 delay(1);
884 }
885 return -EDEADLOCK;
886}