Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Copyright (C) 2020-2023 Oracle. All Rights Reserved.
4 : * Author: Darrick J. Wong <djwong@kernel.org>
5 : */
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_log_format.h"
13 : #include "xfs_trans.h"
14 : #include "xfs_inode.h"
15 : #include "xfs_quota.h"
16 : #include "xfs_qm.h"
17 : #include "xfs_icache.h"
18 : #include "xfs_bmap_util.h"
19 : #include "xfs_ialloc.h"
20 : #include "xfs_ag.h"
21 : #include "scrub/scrub.h"
22 : #include "scrub/common.h"
23 : #include "scrub/repair.h"
24 : #include "scrub/xfile.h"
25 : #include "scrub/xfarray.h"
26 : #include "scrub/iscan.h"
27 : #include "scrub/quotacheck.h"
28 : #include "scrub/trace.h"
29 :
30 : /*
31 : * Live Quotacheck
32 : * ===============
33 : *
34 : * Quota counters are "summary" metadata, in the sense that they are computed
35 : * as the summation of the block usage counts for every file on the filesystem.
36 : * Therefore, we compute the correct icount, bcount, and rtbcount values by
37 : * creating a shadow quota counter structure and walking every inode.
38 : */
39 :
40 : /* Track the quota deltas for a dquot in a transaction. */
41 : struct xqcheck_dqtrx {
42 : xfs_dqtype_t q_type;
43 : xfs_dqid_t q_id;
44 :
45 : int64_t icount_delta;
46 :
47 : int64_t bcount_delta;
48 : int64_t delbcnt_delta;
49 :
50 : int64_t rtbcount_delta;
51 : int64_t delrtb_delta;
52 : };
53 :
54 : #define XQCHECK_MAX_NR_DQTRXS (XFS_QM_TRANS_DQTYPES * XFS_QM_TRANS_MAXDQS)
55 :
56 : /*
57 : * Track the quota deltas for all dquots attached to a transaction if the
58 : * quota deltas are being applied to an inode that we already scanned.
59 : */
60 : struct xqcheck_dqacct {
61 : struct rhash_head hash;
62 : uintptr_t tx_id;
63 : struct xqcheck_dqtrx dqtrx[XQCHECK_MAX_NR_DQTRXS];
64 : unsigned int refcount;
65 : };
66 :
67 : /* Free a shadow dquot accounting structure. */
68 : static void
69 2267 : xqcheck_dqacct_free(
70 : void *ptr,
71 : void *arg)
72 : {
73 5144704 : struct xqcheck_dqacct *dqa = ptr;
74 :
75 2267 : kfree(dqa);
76 5142437 : }
77 :
78 : /* Set us up to scrub quota counters. */
79 : int
80 35770 : xchk_setup_quotacheck(
81 : struct xfs_scrub *sc)
82 : {
83 35770 : if (!XFS_IS_QUOTA_ON(sc->mp))
84 : return -ENOENT;
85 :
86 34637 : xchk_fsgates_enable(sc, XCHK_FSGATES_QUOTA);
87 :
88 34637 : sc->buf = kzalloc(sizeof(struct xqcheck), XCHK_GFP_FLAGS);
89 34637 : if (!sc->buf)
90 : return -ENOMEM;
91 :
92 34637 : return xchk_setup_fs(sc);
93 : }
94 :
95 : /*
96 : * Part 1: Collecting dquot resource usage counts. For each xfs_dquot attached
97 : * to each inode, we create a shadow dquot, and compute the inode count and add
98 : * the data/rt block usage from what we see.
99 : *
100 : * To avoid false corruption reports in part 2, any failure in this part must
101 : * set the INCOMPLETE flag even when a negative errno is returned. This care
102 : * must be taken with certain errno values (i.e. EFSBADCRC, EFSCORRUPTED,
103 : * ECANCELED) that are absorbed into a scrub state flag update by
104 : * xchk_*_process_error. Scrub and repair share the same incore data
105 : * structures, so the INCOMPLETE flag is critical to prevent a repair based on
106 : * insufficient information.
107 : *
108 : * Because we are scanning a live filesystem, it's possible that another thread
109 : * will try to update the quota counters for an inode that we've already
110 : * scanned. This will cause our counts to be incorrect. Therefore, we hook
111 : * the live transaction code in two places: (1) when the callers update the
112 : * per-transaction dqtrx structure to log quota counter updates; and (2) when
113 : * transaction commit actually logs those updates to the incore dquot. By
114 : * shadowing transaction updates in this manner, live quotacheck can ensure
115 : * by locking the dquot and the shadow structure that its own copies are not
116 : * out of date. Because the hook code runs in a different process context from
117 : * the scrub code and the scrub state flags are not accessed atomically,
118 : * failures in the hook code must abort the iscan and the scrubber must notice
119 : * the aborted scan and set the incomplete flag.
120 : *
121 : * Note that we use srcu notifier hooks to minimize the overhead when live
122 : * quotacheck is /not/ running.
123 : */
124 :
125 : /* Update an incore dquot counter information from a live update. */
126 : static int
127 1161397579 : xqcheck_update_incore_counts(
128 : struct xqcheck *xqc,
129 : struct xfarray *counts,
130 : xfs_dqid_t id,
131 : int64_t inodes,
132 : int64_t nblks,
133 : int64_t rtblks)
134 : {
135 1161397579 : struct xqcheck_dquot xcdq;
136 1161397579 : int error;
137 :
138 1161397579 : error = xfarray_load_sparse(counts, id, &xcdq);
139 1161397579 : if (error)
140 : return error;
141 :
142 1161397579 : xcdq.flags |= XQCHECK_DQUOT_WRITTEN;
143 1161397579 : xcdq.icount += inodes;
144 1161397579 : xcdq.bcount += nblks;
145 1161397579 : xcdq.rtbcount += rtblks;
146 :
147 1161397579 : error = xfarray_store(counts, id, &xcdq);
148 1161397579 : if (error == -EFBIG) {
149 : /*
150 : * EFBIG means we tried to store data at too high a byte offset
151 : * in the sparse array. IOWs, we cannot complete the check and
152 : * must notify userspace that the check was incomplete.
153 : */
154 0 : error = -ECANCELED;
155 : }
156 : return error;
157 : }
158 :
159 : /* Decide if this is the shadow dquot accounting structure for a transaction. */
160 : static int
161 28843055 : xqcheck_dqacct_obj_cmpfn(
162 : struct rhashtable_compare_arg *arg,
163 : const void *obj)
164 : {
165 28843055 : const uintptr_t *tx_idp = arg->key;
166 28843055 : const struct xqcheck_dqacct *dqa = obj;
167 :
168 28843055 : if (dqa->tx_id != *tx_idp)
169 294847 : return 1;
170 : return 0;
171 : }
172 :
173 : static const struct rhashtable_params xqcheck_dqacct_hash_params = {
174 : .min_size = 32,
175 : .key_len = sizeof(uintptr_t),
176 : .key_offset = offsetof(struct xqcheck_dqacct, tx_id),
177 : .head_offset = offsetof(struct xqcheck_dqacct, hash),
178 : .automatic_shrinking = true,
179 : .obj_cmpfn = xqcheck_dqacct_obj_cmpfn,
180 : };
181 :
182 : /* Find a shadow dqtrx slot for the given dquot. */
183 : STATIC struct xqcheck_dqtrx *
184 33692912 : xqcheck_get_dqtrx(
185 : struct xqcheck_dqacct *dqa,
186 : xfs_dqtype_t q_type,
187 : xfs_dqid_t q_id)
188 : {
189 33692912 : int i;
190 :
191 68562887 : for (i = 0; i < XQCHECK_MAX_NR_DQTRXS; i++) {
192 121543469 : if (dqa->dqtrx[i].q_type == 0 ||
193 52980582 : (dqa->dqtrx[i].q_type == q_type &&
194 19439200 : dqa->dqtrx[i].q_id == q_id))
195 33692912 : return &dqa->dqtrx[i];
196 : }
197 :
198 : return NULL;
199 : }
200 :
201 : /*
202 : * Create and fill out a quota delta tracking structure to shadow the updates
203 : * going on in the regular quota code.
204 : */
205 : static int
206 23958139 : xqcheck_mod_live_ino_dqtrx(
207 : struct notifier_block *nb,
208 : unsigned long action,
209 : void *data)
210 : {
211 23958139 : struct xfs_mod_ino_dqtrx_params *p = data;
212 23958139 : struct xqcheck *xqc;
213 23958139 : struct xqcheck_dqacct *dqa;
214 23958139 : struct xqcheck_dqtrx *dqtrx;
215 23958139 : int error;
216 :
217 23958139 : xqc = container_of(nb, struct xqcheck, hooks.mod_hook.nb);
218 :
219 : /* Skip quota reservation fields. */
220 23958139 : switch (action) {
221 : case XFS_TRANS_DQ_BCOUNT:
222 : case XFS_TRANS_DQ_DELBCOUNT:
223 : case XFS_TRANS_DQ_ICOUNT:
224 : case XFS_TRANS_DQ_RTBCOUNT:
225 : case XFS_TRANS_DQ_DELRTBCOUNT:
226 23918639 : break;
227 : default:
228 : return NOTIFY_DONE;
229 : }
230 :
231 : /* Ignore dqtrx updates for quota types we don't care about. */
232 23918639 : switch (p->q_type) {
233 8328754 : case XFS_DQTYPE_USER:
234 8328754 : if (!xqc->ucounts)
235 : return NOTIFY_DONE;
236 : break;
237 8329139 : case XFS_DQTYPE_GROUP:
238 8329139 : if (!xqc->gcounts)
239 : return NOTIFY_DONE;
240 : break;
241 7260746 : case XFS_DQTYPE_PROJ:
242 7260746 : if (!xqc->pcounts)
243 : return NOTIFY_DONE;
244 : break;
245 : default:
246 : return NOTIFY_DONE;
247 : }
248 :
249 : /* Skip inodes that haven't been scanned yet. */
250 23918639 : if (!xchk_iscan_want_live_update(&xqc->iscan, p->ino))
251 : return NOTIFY_DONE;
252 :
253 : /* Make a shadow quota accounting tracker for this transaction. */
254 18116081 : mutex_lock(&xqc->lock);
255 18116184 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
256 : xqcheck_dqacct_hash_params);
257 18116184 : if (!dqa) {
258 5144704 : dqa = kzalloc(sizeof(struct xqcheck_dqacct), XCHK_GFP_FLAGS);
259 5144704 : if (!dqa)
260 0 : goto out_abort;
261 :
262 5144704 : dqa->tx_id = p->tx_id;
263 5144704 : error = rhashtable_insert_fast(&xqc->shadow_dquot_acct,
264 : &dqa->hash, xqcheck_dqacct_hash_params);
265 5144704 : if (error)
266 0 : goto out_abort;
267 : }
268 :
269 : /* Find the shadow dqtrx (or an empty slot) here. */
270 18116184 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
271 18116184 : if (!dqtrx)
272 0 : goto out_abort;
273 18116184 : if (dqtrx->q_type == 0) {
274 15567325 : dqtrx->q_type = p->q_type;
275 15567325 : dqtrx->q_id = p->q_id;
276 15567325 : dqa->refcount++;
277 : }
278 :
279 : /* Update counter */
280 18116184 : switch (action) {
281 5402212 : case XFS_TRANS_DQ_BCOUNT:
282 5402212 : dqtrx->bcount_delta += p->delta;
283 5402212 : break;
284 1509928 : case XFS_TRANS_DQ_DELBCOUNT:
285 1509928 : dqtrx->delbcnt_delta += p->delta;
286 1509928 : break;
287 2415727 : case XFS_TRANS_DQ_ICOUNT:
288 2415727 : dqtrx->icount_delta += p->delta;
289 2415727 : break;
290 8689187 : case XFS_TRANS_DQ_RTBCOUNT:
291 8689187 : dqtrx->rtbcount_delta += p->delta;
292 8689187 : break;
293 99130 : case XFS_TRANS_DQ_DELRTBCOUNT:
294 99130 : dqtrx->delrtb_delta += p->delta;
295 99130 : break;
296 : }
297 :
298 18116184 : mutex_unlock(&xqc->lock);
299 18116184 : return NOTIFY_DONE;
300 :
301 0 : out_abort:
302 0 : xchk_iscan_abort(&xqc->iscan);
303 0 : mutex_unlock(&xqc->lock);
304 0 : return NOTIFY_DONE;
305 : }
306 :
307 : /*
308 : * Apply the transaction quota deltas to our shadow quota accounting info when
309 : * the regular quota code are doing the same.
310 : */
311 : static int
312 108791951 : xqcheck_apply_live_dqtrx(
313 : struct notifier_block *nb,
314 : unsigned long action,
315 : void *data)
316 : {
317 108791951 : struct xfs_apply_dqtrx_params *p = data;
318 108791951 : struct xqcheck *xqc;
319 108791951 : struct xqcheck_dqacct *dqa;
320 108791951 : struct xqcheck_dqtrx *dqtrx;
321 108791951 : struct xfarray *counts;
322 108791951 : int error;
323 :
324 108791951 : xqc = container_of(nb, struct xqcheck, hooks.apply_hook.nb);
325 :
326 : /* Map the dquot type to an incore counter object. */
327 108791951 : switch (p->q_type) {
328 36403159 : case XFS_DQTYPE_USER:
329 36403159 : counts = xqc->ucounts;
330 36403159 : break;
331 36396150 : case XFS_DQTYPE_GROUP:
332 36396150 : counts = xqc->gcounts;
333 36396150 : break;
334 35992642 : case XFS_DQTYPE_PROJ:
335 35992642 : counts = xqc->pcounts;
336 35992642 : break;
337 : default:
338 : return NOTIFY_DONE;
339 : }
340 :
341 108791951 : if (xchk_iscan_aborted(&xqc->iscan) || counts == NULL)
342 : return NOTIFY_DONE;
343 :
344 : /*
345 : * Find the shadow dqtrx for this transaction and dquot, if any deltas
346 : * need to be applied here. If not, we're finished early.
347 : */
348 108703316 : mutex_lock(&xqc->lock);
349 108773683 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
350 : xqcheck_dqacct_hash_params);
351 108773683 : if (!dqa)
352 93196955 : goto out_unlock;
353 15576728 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
354 15576728 : if (!dqtrx || dqtrx->q_type == 0)
355 14980 : goto out_unlock;
356 :
357 : /* Update our shadow dquot if we're committing. */
358 15561748 : if (action == XFS_APPLY_DQTRX_COMMIT) {
359 14048302 : error = xqcheck_update_incore_counts(xqc, counts, p->q_id,
360 : dqtrx->icount_delta,
361 14048302 : dqtrx->bcount_delta + dqtrx->delbcnt_delta,
362 14048302 : dqtrx->rtbcount_delta + dqtrx->delrtb_delta);
363 14048302 : if (error)
364 0 : goto out_abort;
365 : }
366 :
367 : /* Free the shadow accounting structure if that was the last user. */
368 15561748 : dqa->refcount--;
369 15561748 : if (dqa->refcount == 0) {
370 5142437 : error = rhashtable_remove_fast(&xqc->shadow_dquot_acct,
371 : &dqa->hash, xqcheck_dqacct_hash_params);
372 5142437 : if (error)
373 0 : goto out_abort;
374 5142437 : xqcheck_dqacct_free(dqa, NULL);
375 : }
376 :
377 15561748 : mutex_unlock(&xqc->lock);
378 15561748 : return NOTIFY_DONE;
379 :
380 0 : out_abort:
381 0 : xchk_iscan_abort(&xqc->iscan);
382 93211935 : out_unlock:
383 93211935 : mutex_unlock(&xqc->lock);
384 93211935 : return NOTIFY_DONE;
385 : }
386 :
387 : /* Record this inode's quota usage in our shadow quota counter data. */
388 : STATIC int
389 382877238 : xqcheck_collect_inode(
390 : struct xqcheck *xqc,
391 : struct xfs_inode *ip)
392 : {
393 382877238 : struct xfs_trans *tp = xqc->sc->tp;
394 382877238 : xfs_filblks_t nblks, rtblks;
395 382877238 : uint ilock_flags = 0;
396 382877238 : xfs_dqid_t id;
397 382877238 : bool isreg = S_ISREG(VFS_I(ip)->i_mode);
398 382877238 : int error = 0;
399 :
400 765334439 : if (xfs_is_metadir_inode(ip) ||
401 382457201 : xfs_is_quota_inode(&tp->t_mountp->m_sb, ip->i_ino)) {
402 : /*
403 : * Quota files are never counted towards quota, so we do not
404 : * need to take the lock. Files do not switch between the
405 : * metadata and regular directory trees without a reallocation,
406 : * so we do not need to ILOCK them either.
407 : */
408 425282 : xchk_iscan_mark_visited(&xqc->iscan, ip);
409 425282 : return 0;
410 : }
411 :
412 : /* Figure out the data / rt device block counts. */
413 382451956 : xfs_ilock(ip, XFS_IOLOCK_SHARED);
414 382451956 : if (isreg)
415 168696742 : xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
416 382451956 : if (XFS_IS_REALTIME_INODE(ip)) {
417 78668650 : ilock_flags = xfs_ilock_data_map_shared(ip);
418 78668650 : error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
419 78668650 : if (error)
420 0 : goto out_abort;
421 : } else {
422 303783306 : ilock_flags = XFS_ILOCK_SHARED;
423 303783306 : xfs_ilock(ip, XFS_ILOCK_SHARED);
424 : }
425 382451956 : xfs_inode_count_blocks(tp, ip, &nblks, &rtblks);
426 :
427 382451956 : if (xchk_iscan_aborted(&xqc->iscan)) {
428 0 : error = -ECANCELED;
429 0 : goto out_incomplete;
430 : }
431 :
432 : /* Update the shadow dquot counters. */
433 382451956 : mutex_lock(&xqc->lock);
434 382451956 : if (xqc->ucounts) {
435 382450726 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_USER);
436 382450726 : error = xqcheck_update_incore_counts(xqc, xqc->ucounts, id, 1,
437 : nblks, rtblks);
438 382450726 : if (error)
439 0 : goto out_mutex;
440 : }
441 :
442 382451956 : if (xqc->gcounts) {
443 382448257 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_GROUP);
444 382448257 : error = xqcheck_update_incore_counts(xqc, xqc->gcounts, id, 1,
445 : nblks, rtblks);
446 382448257 : if (error)
447 0 : goto out_mutex;
448 : }
449 :
450 382451956 : if (xqc->pcounts) {
451 382450294 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_PROJ);
452 382450294 : error = xqcheck_update_incore_counts(xqc, xqc->pcounts, id, 1,
453 : nblks, rtblks);
454 382450294 : if (error)
455 0 : goto out_mutex;
456 : }
457 382451956 : mutex_unlock(&xqc->lock);
458 :
459 382451956 : xchk_iscan_mark_visited(&xqc->iscan, ip);
460 382451956 : goto out_ilock;
461 :
462 0 : out_mutex:
463 0 : mutex_unlock(&xqc->lock);
464 0 : out_abort:
465 0 : xchk_iscan_abort(&xqc->iscan);
466 0 : out_incomplete:
467 0 : xchk_set_incomplete(xqc->sc);
468 382451956 : out_ilock:
469 382451956 : xfs_iunlock(ip, ilock_flags);
470 382451956 : if (isreg)
471 168696742 : xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
472 382451956 : xfs_iunlock(ip, XFS_IOLOCK_SHARED);
473 382451956 : return error;
474 : }
475 :
476 : /* Walk all the allocated inodes and run a quota scan on them. */
477 : STATIC int
478 34618 : xqcheck_collect_counts(
479 : struct xqcheck *xqc)
480 : {
481 34618 : struct xfs_scrub *sc = xqc->sc;
482 34618 : struct xfs_inode *ip;
483 34618 : int error;
484 :
485 : /*
486 : * Set up for a potentially lengthy filesystem scan by reducing our
487 : * transaction resource usage for the duration. Specifically:
488 : *
489 : * Cancel the transaction to release the log grant space while we scan
490 : * the filesystem.
491 : *
492 : * Create a new empty transaction to eliminate the possibility of the
493 : * inode scan deadlocking on cyclical metadata.
494 : *
495 : * We pass the empty transaction to the file scanning function to avoid
496 : * repeatedly cycling empty transactions. This can be done without
497 : * risk of deadlock between sb_internal and the IOLOCK (we take the
498 : * IOLOCK to quiesce the file before scanning) because empty
499 : * transactions do not take sb_internal.
500 : */
501 34618 : xchk_trans_cancel(sc);
502 34618 : error = xchk_trans_alloc_empty(sc);
503 34618 : if (error)
504 : return error;
505 :
506 382911854 : while ((error = xchk_iscan_iter(&xqc->iscan, &ip)) == 1) {
507 382877238 : error = xqcheck_collect_inode(xqc, ip);
508 382877238 : xchk_irele(sc, ip);
509 382877238 : if (error)
510 : break;
511 :
512 382877238 : if (xchk_should_terminate(sc, &error))
513 : break;
514 : }
515 34618 : xchk_iscan_iter_finish(&xqc->iscan);
516 34618 : if (error) {
517 2 : xchk_set_incomplete(sc);
518 : /*
519 : * If we couldn't grab an inode that was busy with a state
520 : * change, change the error code so that we exit to userspace
521 : * as quickly as possible.
522 : */
523 2 : if (error == -EBUSY)
524 : return -ECANCELED;
525 2 : return error;
526 : }
527 :
528 : /*
529 : * Switch out for a real transaction in preparation for building a new
530 : * tree.
531 : */
532 34616 : xchk_trans_cancel(sc);
533 34616 : return xchk_setup_fs(sc);
534 : }
535 :
536 : /*
537 : * Part 2: Comparing dquot resource counters. Walk each xfs_dquot, comparing
538 : * the resource usage counters against our shadow dquots; and then walk each
539 : * shadow dquot (that wasn't covered in the first part), comparing it against
540 : * the xfs_dquot.
541 : */
542 :
543 : /*
544 : * Check the dquot data against what we observed. Caller must hold the dquot
545 : * lock.
546 : */
547 : STATIC int
548 94110563 : xqcheck_compare_dquot(
549 : struct xfs_dquot *dqp,
550 : xfs_dqtype_t dqtype,
551 : void *priv)
552 : {
553 94110563 : struct xqcheck_dquot xcdq;
554 94110563 : struct xqcheck *xqc = priv;
555 94110563 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
556 94110563 : int error;
557 :
558 94110563 : if (xchk_iscan_aborted(&xqc->iscan)) {
559 0 : xchk_set_incomplete(xqc->sc);
560 0 : return -ECANCELED;
561 : }
562 :
563 94110563 : mutex_lock(&xqc->lock);
564 94110563 : error = xfarray_load_sparse(counts, dqp->q_id, &xcdq);
565 94110563 : if (error)
566 0 : goto out_unlock;
567 :
568 94110563 : if (xcdq.icount != dqp->q_ino.count)
569 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
570 :
571 94110563 : if (xcdq.bcount != dqp->q_blk.count)
572 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
573 :
574 94110563 : if (xcdq.rtbcount != dqp->q_rtb.count)
575 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
576 :
577 94110563 : xcdq.flags |= (XQCHECK_DQUOT_COMPARE_SCANNED | XQCHECK_DQUOT_WRITTEN);
578 94110563 : error = xfarray_store(counts, dqp->q_id, &xcdq);
579 94110563 : if (error == -EFBIG) {
580 : /*
581 : * EFBIG means we tried to store data at too high a byte offset
582 : * in the sparse array. IOWs, we cannot complete the check and
583 : * must notify userspace that the check was incomplete. This
584 : * should never happen outside of the collection phase.
585 : */
586 0 : xchk_set_incomplete(xqc->sc);
587 0 : error = -ECANCELED;
588 : }
589 94110563 : mutex_unlock(&xqc->lock);
590 94110563 : if (error)
591 : return error;
592 :
593 94110563 : if (xqc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
594 0 : return -ECANCELED;
595 :
596 : return 0;
597 :
598 : out_unlock:
599 0 : mutex_unlock(&xqc->lock);
600 0 : return error;
601 : }
602 :
603 : /*
604 : * Walk all the observed dquots, and make sure there's a matching incore
605 : * dquot and that its counts match ours.
606 : */
607 : STATIC int
608 103416 : xqcheck_walk_observations(
609 : struct xqcheck *xqc,
610 : xfs_dqtype_t dqtype)
611 : {
612 103416 : struct xqcheck_dquot xcdq;
613 103416 : struct xfs_dquot *dqp;
614 103416 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
615 103416 : xfarray_idx_t cur = XFARRAY_CURSOR_INIT;
616 103416 : int error;
617 :
618 103416 : mutex_lock(&xqc->lock);
619 94213976 : while ((error = xfarray_iter(counts, &cur, &xcdq)) == 1) {
620 94110563 : xfs_dqid_t id = cur - 1;
621 :
622 94110563 : if (xcdq.flags & XQCHECK_DQUOT_COMPARE_SCANNED)
623 103416 : continue;
624 :
625 94007147 : mutex_unlock(&xqc->lock);
626 :
627 94007147 : error = xfs_qm_dqget(xqc->sc->mp, id, dqtype, false, &dqp);
628 94007147 : if (error == -ENOENT) {
629 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, id);
630 0 : return 0;
631 : }
632 94007147 : if (error)
633 0 : return error;
634 :
635 94007147 : error = xqcheck_compare_dquot(dqp, dqtype, xqc);
636 94007147 : xfs_qm_dqput(dqp);
637 94007147 : if (error)
638 0 : return error;
639 :
640 94007147 : if (xchk_should_terminate(xqc->sc, &error))
641 3 : return error;
642 :
643 94007144 : mutex_lock(&xqc->lock);
644 : }
645 103413 : mutex_unlock(&xqc->lock);
646 :
647 103413 : return error;
648 : }
649 :
650 : /* Compare the quota counters we observed against the live dquots. */
651 : STATIC int
652 103416 : xqcheck_compare_dqtype(
653 : struct xqcheck *xqc,
654 : xfs_dqtype_t dqtype)
655 : {
656 103416 : struct xfs_scrub *sc = xqc->sc;
657 103416 : int error;
658 :
659 103416 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
660 : return 0;
661 :
662 : /* If the quota CHKD flag is cleared, we need to repair this quota. */
663 206832 : if (!(xfs_quota_chkd_flag(dqtype) & sc->mp->m_qflags)) {
664 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, 0);
665 0 : return 0;
666 : }
667 :
668 : /* Compare what we observed against the actual dquots. */
669 103416 : error = xfs_qm_dqiterate(sc->mp, dqtype, xqcheck_compare_dquot, xqc);
670 103416 : if (error)
671 : return error;
672 :
673 : /* Walk all the observed dquots and compare to the incore ones. */
674 103416 : return xqcheck_walk_observations(xqc, dqtype);
675 : }
676 :
677 : /* Tear down everything associated with a quotacheck. */
678 : static void
679 34618 : xqcheck_teardown_scan(
680 : void *priv)
681 : {
682 34618 : struct xqcheck *xqc = priv;
683 34618 : struct xfs_quotainfo *qi = xqc->sc->mp->m_quotainfo;
684 :
685 : /* Discourage any hook functions that might be running. */
686 34618 : xchk_iscan_abort(&xqc->iscan);
687 :
688 : /*
689 : * As noted above, the apply hook is responsible for cleaning up the
690 : * shadow dquot accounting data when a transaction completes. The mod
691 : * hook must be removed before the apply hook so that we don't
692 : * mistakenly leave an active shadow account for the mod hook to get
693 : * its hands on. No hooks should be running after these functions
694 : * return.
695 : */
696 34618 : xfs_dqtrx_hook_del(qi, &xqc->hooks);
697 :
698 34618 : if (xqc->shadow_dquot_acct.key_len) {
699 34618 : rhashtable_free_and_destroy(&xqc->shadow_dquot_acct,
700 : xqcheck_dqacct_free, NULL);
701 34618 : xqc->shadow_dquot_acct.key_len = 0;
702 : }
703 :
704 34618 : if (xqc->pcounts) {
705 34408 : xfarray_destroy(xqc->pcounts);
706 34408 : xqc->pcounts = NULL;
707 : }
708 :
709 34618 : if (xqc->gcounts) {
710 34460 : xfarray_destroy(xqc->gcounts);
711 34460 : xqc->gcounts = NULL;
712 : }
713 :
714 34618 : if (xqc->ucounts) {
715 34558 : xfarray_destroy(xqc->ucounts);
716 34558 : xqc->ucounts = NULL;
717 : }
718 :
719 34618 : xchk_iscan_teardown(&xqc->iscan);
720 34618 : mutex_destroy(&xqc->lock);
721 34618 : xqc->sc = NULL;
722 34618 : }
723 :
724 : /*
725 : * Scan all inodes in the entire filesystem to generate quota counter data.
726 : * If the scan is successful, the quota data will be left alive for a repair.
727 : * If any error occurs, we'll tear everything down.
728 : */
729 : STATIC int
730 34618 : xqcheck_setup_scan(
731 : struct xfs_scrub *sc,
732 : struct xqcheck *xqc)
733 : {
734 34618 : char *descr;
735 34618 : struct xfs_quotainfo *qi = sc->mp->m_quotainfo;
736 34618 : unsigned long long max_dquots = ((xfs_dqid_t)-1) + 1;
737 34618 : int error;
738 :
739 34618 : ASSERT(xqc->sc == NULL);
740 34618 : xqc->sc = sc;
741 :
742 34618 : mutex_init(&xqc->lock);
743 :
744 : /* Retry iget every tenth of a second for up to 30 seconds. */
745 34618 : xchk_iscan_start(sc, 30000, 100, &xqc->iscan);
746 :
747 34618 : error = -ENOMEM;
748 34618 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_USER)) {
749 34558 : descr = xchk_xfile_descr(sc, "user dquot records");
750 34558 : error = xfarray_create(descr, max_dquots,
751 : sizeof(struct xqcheck_dquot), &xqc->ucounts);
752 34558 : kfree(descr);
753 34558 : if (error)
754 0 : goto out_teardown;
755 : }
756 :
757 34618 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_GROUP)) {
758 34460 : descr = xchk_xfile_descr(sc, "group dquot records");
759 34460 : error = xfarray_create(descr, max_dquots,
760 : sizeof(struct xqcheck_dquot), &xqc->gcounts);
761 34460 : kfree(descr);
762 34460 : if (error)
763 0 : goto out_teardown;
764 : }
765 :
766 34618 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_PROJ)) {
767 34408 : descr = xchk_xfile_descr(sc, "project dquot records");
768 34408 : error = xfarray_create(descr, max_dquots,
769 : sizeof(struct xqcheck_dquot), &xqc->pcounts);
770 34408 : kfree(descr);
771 34408 : if (error)
772 0 : goto out_teardown;
773 : }
774 :
775 : /*
776 : * Set up hash table to map transactions to our internal shadow dqtrx
777 : * structures.
778 : */
779 34618 : error = rhashtable_init(&xqc->shadow_dquot_acct,
780 : &xqcheck_dqacct_hash_params);
781 34618 : if (error)
782 0 : goto out_teardown;
783 :
784 : /*
785 : * Hook into the quota code. The hook only triggers for inodes that
786 : * were already scanned, and the scanner thread takes each inode's
787 : * ILOCK, which means that any in-progress inode updates will finish
788 : * before we can scan the inode.
789 : *
790 : * The apply hook (which removes the shadow dquot accounting struct)
791 : * must be installed before the mod hook so that we never fail to catch
792 : * the end of a quota update sequence and leave stale shadow data.
793 : */
794 34618 : ASSERT(sc->flags & XCHK_FSGATES_QUOTA);
795 34618 : xfs_hook_setup(&xqc->hooks.mod_hook, xqcheck_mod_live_ino_dqtrx);
796 34618 : xfs_hook_setup(&xqc->hooks.apply_hook, xqcheck_apply_live_dqtrx);
797 :
798 34618 : error = xfs_dqtrx_hook_add(qi, &xqc->hooks);
799 34618 : if (error)
800 0 : goto out_teardown;
801 :
802 : /* Use deferred cleanup to pass the quota count data to repair. */
803 34618 : sc->buf_cleanup = xqcheck_teardown_scan;
804 34618 : return 0;
805 :
806 0 : out_teardown:
807 0 : xqcheck_teardown_scan(xqc);
808 0 : return error;
809 : }
810 :
811 : /* Scrub all counters for a given quota type. */
812 : int
813 34618 : xchk_quotacheck(
814 : struct xfs_scrub *sc)
815 : {
816 34618 : struct xqcheck *xqc = sc->buf;
817 34618 : int error = 0;
818 :
819 : /* Check quota counters on the live filesystem. */
820 34618 : error = xqcheck_setup_scan(sc, xqc);
821 34618 : if (error)
822 : return error;
823 :
824 : /* Walk all inodes, picking up quota information. */
825 34618 : error = xqcheck_collect_counts(xqc);
826 34618 : if (!xchk_xref_process_error(sc, 0, 0, &error))
827 2 : return error;
828 :
829 : /* Fail fast if we're not playing with a full dataset. */
830 34616 : if (xchk_iscan_aborted(&xqc->iscan))
831 0 : xchk_set_incomplete(sc);
832 34616 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
833 : return 0;
834 :
835 : /* Compare quota counters. */
836 34616 : if (xqc->ucounts) {
837 34556 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_USER);
838 34556 : if (!xchk_xref_process_error(sc, 0, 0, &error))
839 1 : return error;
840 : }
841 34615 : if (xqc->gcounts) {
842 34457 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_GROUP);
843 34457 : if (!xchk_xref_process_error(sc, 0, 0, &error))
844 2 : return error;
845 : }
846 34613 : if (xqc->pcounts) {
847 34403 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_PROJ);
848 34403 : if (!xchk_xref_process_error(sc, 0, 0, &error))
849 0 : return error;
850 : }
851 :
852 : /* Check one last time for an incomplete dataset. */
853 34613 : if (xchk_iscan_aborted(&xqc->iscan))
854 0 : xchk_set_incomplete(sc);
855 :
856 : return 0;
857 : }
|