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