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 610 : xqcheck_dqacct_free(
70 : void *ptr,
71 : void *arg)
72 : {
73 2995464 : struct xqcheck_dqacct *dqa = ptr;
74 :
75 610 : kfree(dqa);
76 2994854 : }
77 :
78 : /* Set us up to scrub quota counters. */
79 : int
80 11570 : xchk_setup_quotacheck(
81 : struct xfs_scrub *sc)
82 : {
83 11570 : if (!XFS_IS_QUOTA_ON(sc->mp))
84 : return -ENOENT;
85 :
86 11554 : xchk_fsgates_enable(sc, XCHK_FSGATES_QUOTA);
87 :
88 11554 : sc->buf = kzalloc(sizeof(struct xqcheck), XCHK_GFP_FLAGS);
89 11554 : if (!sc->buf)
90 : return -ENOMEM;
91 :
92 11554 : 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 250966805 : 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 250966805 : struct xqcheck_dquot xcdq;
136 250966805 : int error;
137 :
138 250966805 : error = xfarray_load_sparse(counts, id, &xcdq);
139 250966805 : if (error)
140 : return error;
141 :
142 250966805 : xcdq.flags |= XQCHECK_DQUOT_WRITTEN;
143 250966805 : xcdq.icount += inodes;
144 250966805 : xcdq.bcount += nblks;
145 250966805 : xcdq.rtbcount += rtblks;
146 :
147 250966805 : error = xfarray_store(counts, id, &xcdq);
148 250966805 : 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 17098323 : xqcheck_dqacct_obj_cmpfn(
162 : struct rhashtable_compare_arg *arg,
163 : const void *obj)
164 : {
165 17098323 : const uintptr_t *tx_idp = arg->key;
166 17098323 : const struct xqcheck_dqacct *dqa = obj;
167 :
168 17098323 : if (dqa->tx_id != *tx_idp)
169 141449 : 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 19952338 : xqcheck_get_dqtrx(
185 : struct xqcheck_dqacct *dqa,
186 : xfs_dqtype_t q_type,
187 : xfs_dqid_t q_id)
188 : {
189 19952338 : int i;
190 :
191 40808489 : for (i = 0; i < XQCHECK_MAX_NR_DQTRXS; i++) {
192 40808489 : if (dqa->dqtrx[i].q_type == 0 ||
193 11876722 : (dqa->dqtrx[i].q_type == q_type &&
194 11876722 : dqa->dqtrx[i].q_id == q_id))
195 19952338 : 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 11897672 : xqcheck_mod_live_ino_dqtrx(
207 : struct notifier_block *nb,
208 : unsigned long action,
209 : void *data)
210 : {
211 11897672 : struct xfs_mod_ino_dqtrx_params *p = data;
212 11897672 : struct xqcheck *xqc;
213 11897672 : struct xqcheck_dqacct *dqa;
214 11897672 : struct xqcheck_dqtrx *dqtrx;
215 11897672 : int error;
216 :
217 11897672 : xqc = container_of(nb, struct xqcheck, hooks.mod_hook.nb);
218 :
219 : /* Skip quota reservation fields. */
220 11897672 : 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 11874813 : break;
227 : default:
228 : return NOTIFY_DONE;
229 : }
230 :
231 : /* Ignore dqtrx updates for quota types we don't care about. */
232 11874813 : switch (p->q_type) {
233 4184072 : case XFS_DQTYPE_USER:
234 4184072 : if (!xqc->ucounts)
235 : return NOTIFY_DONE;
236 : break;
237 4183793 : case XFS_DQTYPE_GROUP:
238 4183793 : if (!xqc->gcounts)
239 : return NOTIFY_DONE;
240 : break;
241 3506948 : case XFS_DQTYPE_PROJ:
242 3506948 : 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 11874813 : 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 10854449 : mutex_lock(&xqc->lock);
255 10854569 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
256 : xqcheck_dqacct_hash_params);
257 10854569 : if (!dqa) {
258 2995464 : dqa = kzalloc(sizeof(struct xqcheck_dqacct), XCHK_GFP_FLAGS);
259 2995464 : if (!dqa)
260 0 : goto out_abort;
261 :
262 2995464 : dqa->tx_id = p->tx_id;
263 2995464 : error = rhashtable_insert_fast(&xqc->shadow_dquot_acct,
264 : &dqa->hash, xqcheck_dqacct_hash_params);
265 2995464 : if (error)
266 0 : goto out_abort;
267 : }
268 :
269 : /* Find the shadow dqtrx (or an empty slot) here. */
270 10854569 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
271 10854569 : if (!dqtrx)
272 0 : goto out_abort;
273 10854569 : if (dqtrx->q_type == 0) {
274 9089002 : dqtrx->q_type = p->q_type;
275 9089002 : dqtrx->q_id = p->q_id;
276 9089002 : dqa->refcount++;
277 : }
278 :
279 : /* Update counter */
280 10854569 : switch (action) {
281 2545911 : case XFS_TRANS_DQ_BCOUNT:
282 2545911 : dqtrx->bcount_delta += p->delta;
283 2545911 : break;
284 1428708 : case XFS_TRANS_DQ_DELBCOUNT:
285 1428708 : dqtrx->delbcnt_delta += p->delta;
286 1428708 : break;
287 1907692 : case XFS_TRANS_DQ_ICOUNT:
288 1907692 : dqtrx->icount_delta += p->delta;
289 1907692 : break;
290 4901364 : case XFS_TRANS_DQ_RTBCOUNT:
291 4901364 : dqtrx->rtbcount_delta += p->delta;
292 4901364 : break;
293 70894 : case XFS_TRANS_DQ_DELRTBCOUNT:
294 70894 : dqtrx->delrtb_delta += p->delta;
295 70894 : break;
296 : }
297 :
298 10854569 : mutex_unlock(&xqc->lock);
299 10854569 : 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 60464900 : xqcheck_apply_live_dqtrx(
313 : struct notifier_block *nb,
314 : unsigned long action,
315 : void *data)
316 : {
317 60464900 : struct xfs_apply_dqtrx_params *p = data;
318 60464900 : struct xqcheck *xqc;
319 60464900 : struct xqcheck_dqacct *dqa;
320 60464900 : struct xqcheck_dqtrx *dqtrx;
321 60464900 : struct xfarray *counts;
322 60464900 : int error;
323 :
324 60464900 : xqc = container_of(nb, struct xqcheck, hooks.apply_hook.nb);
325 :
326 : /* Map the dquot type to an incore counter object. */
327 60464900 : switch (p->q_type) {
328 20239492 : case XFS_DQTYPE_USER:
329 20239492 : counts = xqc->ucounts;
330 20239492 : break;
331 20240041 : case XFS_DQTYPE_GROUP:
332 20240041 : counts = xqc->gcounts;
333 20240041 : break;
334 19985367 : case XFS_DQTYPE_PROJ:
335 19985367 : counts = xqc->pcounts;
336 19985367 : break;
337 : default:
338 : return NOTIFY_DONE;
339 : }
340 :
341 60464900 : 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 60427231 : mutex_lock(&xqc->lock);
349 60431010 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
350 : xqcheck_dqacct_hash_params);
351 60431010 : if (!dqa)
352 51333241 : goto out_unlock;
353 9097769 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
354 9097769 : if (!dqtrx || dqtrx->q_type == 0)
355 10081 : goto out_unlock;
356 :
357 : /* Update our shadow dquot if we're committing. */
358 9087688 : if (action == XFS_APPLY_DQTRX_COMMIT) {
359 8418512 : error = xqcheck_update_incore_counts(xqc, counts, p->q_id,
360 : dqtrx->icount_delta,
361 8418512 : dqtrx->bcount_delta + dqtrx->delbcnt_delta,
362 8418512 : dqtrx->rtbcount_delta + dqtrx->delrtb_delta);
363 8418512 : if (error)
364 0 : goto out_abort;
365 : }
366 :
367 : /* Free the shadow accounting structure if that was the last user. */
368 9087688 : dqa->refcount--;
369 9087688 : if (dqa->refcount == 0) {
370 2994854 : error = rhashtable_remove_fast(&xqc->shadow_dquot_acct,
371 : &dqa->hash, xqcheck_dqacct_hash_params);
372 2994854 : if (error)
373 0 : goto out_abort;
374 2994854 : xqcheck_dqacct_free(dqa, NULL);
375 : }
376 :
377 9087688 : mutex_unlock(&xqc->lock);
378 9087688 : return NOTIFY_DONE;
379 :
380 0 : out_abort:
381 0 : xchk_iscan_abort(&xqc->iscan);
382 51343322 : out_unlock:
383 51343322 : mutex_unlock(&xqc->lock);
384 51343322 : return NOTIFY_DONE;
385 : }
386 :
387 : /* Record this inode's quota usage in our shadow quota counter data. */
388 : STATIC int
389 80980449 : xqcheck_collect_inode(
390 : struct xqcheck *xqc,
391 : struct xfs_inode *ip)
392 : {
393 80980449 : struct xfs_trans *tp = xqc->sc->tp;
394 80980449 : xfs_filblks_t nblks, rtblks;
395 80980449 : uint ilock_flags = 0;
396 80980449 : xfs_dqid_t id;
397 80980449 : bool isreg = S_ISREG(VFS_I(ip)->i_mode);
398 80980449 : int error = 0;
399 :
400 161830430 : if (xfs_is_metadir_inode(ip) ||
401 80849981 : 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 130612 : xchk_iscan_mark_visited(&xqc->iscan, ip);
409 130612 : return 0;
410 : }
411 :
412 : /* Figure out the data / rt device block counts. */
413 80849837 : xfs_ilock(ip, XFS_IOLOCK_SHARED);
414 80849837 : if (isreg)
415 35726343 : xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
416 80849837 : if (XFS_IS_REALTIME_INODE(ip)) {
417 12576727 : ilock_flags = xfs_ilock_data_map_shared(ip);
418 12576727 : error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
419 12576727 : if (error)
420 0 : goto out_abort;
421 : } else {
422 68273110 : ilock_flags = XFS_ILOCK_SHARED;
423 68273110 : xfs_ilock(ip, XFS_ILOCK_SHARED);
424 : }
425 80849837 : xfs_inode_count_blocks(tp, ip, &nblks, &rtblks);
426 :
427 80849837 : if (xchk_iscan_aborted(&xqc->iscan)) {
428 0 : error = -ECANCELED;
429 0 : goto out_incomplete;
430 : }
431 :
432 : /* Update the shadow dquot counters. */
433 80849837 : mutex_lock(&xqc->lock);
434 80849837 : if (xqc->ucounts) {
435 80849613 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_USER);
436 80849613 : error = xqcheck_update_incore_counts(xqc, xqc->ucounts, id, 1,
437 : nblks, rtblks);
438 80849613 : if (error)
439 0 : goto out_mutex;
440 : }
441 :
442 80849837 : if (xqc->gcounts) {
443 80849125 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_GROUP);
444 80849125 : error = xqcheck_update_incore_counts(xqc, xqc->gcounts, id, 1,
445 : nblks, rtblks);
446 80849125 : if (error)
447 0 : goto out_mutex;
448 : }
449 :
450 80849837 : if (xqc->pcounts) {
451 80849555 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_PROJ);
452 80849555 : error = xqcheck_update_incore_counts(xqc, xqc->pcounts, id, 1,
453 : nblks, rtblks);
454 80849555 : if (error)
455 0 : goto out_mutex;
456 : }
457 80849837 : mutex_unlock(&xqc->lock);
458 :
459 80849837 : xchk_iscan_mark_visited(&xqc->iscan, ip);
460 80849837 : 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 80849837 : out_ilock:
469 80849837 : xfs_iunlock(ip, ilock_flags);
470 80849837 : if (isreg)
471 35726343 : xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
472 80849837 : xfs_iunlock(ip, XFS_IOLOCK_SHARED);
473 80849837 : return error;
474 : }
475 :
476 : /* Walk all the allocated inodes and run a quota scan on them. */
477 : STATIC int
478 11554 : xqcheck_collect_counts(
479 : struct xqcheck *xqc)
480 : {
481 11554 : struct xfs_scrub *sc = xqc->sc;
482 11554 : struct xfs_inode *ip;
483 11554 : 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 11554 : xchk_trans_cancel(sc);
502 11554 : error = xchk_trans_alloc_empty(sc);
503 11554 : if (error)
504 : return error;
505 :
506 80992002 : while ((error = xchk_iscan_iter(&xqc->iscan, &ip)) == 1) {
507 80980449 : error = xqcheck_collect_inode(xqc, ip);
508 80980449 : xchk_irele(sc, ip);
509 80980449 : if (error)
510 : break;
511 :
512 80980449 : if (xchk_should_terminate(sc, &error))
513 : break;
514 : }
515 11554 : xchk_iscan_iter_finish(&xqc->iscan);
516 11554 : if (error) {
517 1 : 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 1 : if (error == -EBUSY)
524 : return -ECANCELED;
525 1 : return error;
526 : }
527 :
528 : /*
529 : * Switch out for a real transaction in preparation for building a new
530 : * tree.
531 : */
532 11553 : xchk_trans_cancel(sc);
533 11553 : 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 16738386 : xqcheck_compare_dquot(
549 : struct xfs_dquot *dqp,
550 : xfs_dqtype_t dqtype,
551 : void *priv)
552 : {
553 16738386 : struct xqcheck_dquot xcdq;
554 16738386 : struct xqcheck *xqc = priv;
555 16738386 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
556 16738386 : int error;
557 :
558 16738386 : if (xchk_iscan_aborted(&xqc->iscan)) {
559 0 : xchk_set_incomplete(xqc->sc);
560 0 : return -ECANCELED;
561 : }
562 :
563 16738386 : mutex_lock(&xqc->lock);
564 16738386 : error = xfarray_load_sparse(counts, dqp->q_id, &xcdq);
565 16738386 : if (error)
566 0 : goto out_unlock;
567 :
568 16738386 : if (xcdq.icount != dqp->q_ino.count)
569 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
570 :
571 16738386 : if (xcdq.bcount != dqp->q_blk.count)
572 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
573 :
574 16738386 : if (xcdq.rtbcount != dqp->q_rtb.count)
575 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
576 :
577 16738386 : xcdq.flags |= (XQCHECK_DQUOT_COMPARE_SCANNED | XQCHECK_DQUOT_WRITTEN);
578 16738386 : error = xfarray_store(counts, dqp->q_id, &xcdq);
579 16738386 : 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 16738386 : mutex_unlock(&xqc->lock);
590 16738386 : if (error)
591 : return error;
592 :
593 16738386 : 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 34572 : xqcheck_walk_observations(
609 : struct xqcheck *xqc,
610 : xfs_dqtype_t dqtype)
611 : {
612 34572 : struct xqcheck_dquot xcdq;
613 34572 : struct xfs_dquot *dqp;
614 34572 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
615 34572 : xfarray_idx_t cur = XFARRAY_CURSOR_INIT;
616 34572 : int error;
617 :
618 34572 : mutex_lock(&xqc->lock);
619 16772953 : while ((error = xfarray_iter(counts, &cur, &xcdq)) == 1) {
620 16738386 : xfs_dqid_t id = cur - 1;
621 :
622 16738386 : if (xcdq.flags & XQCHECK_DQUOT_COMPARE_SCANNED)
623 34572 : continue;
624 :
625 16703814 : mutex_unlock(&xqc->lock);
626 :
627 16703814 : error = xfs_qm_dqget(xqc->sc->mp, id, dqtype, false, &dqp);
628 16703814 : if (error == -ENOENT) {
629 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, id);
630 0 : return 0;
631 : }
632 16703814 : if (error)
633 0 : return error;
634 :
635 16703814 : error = xqcheck_compare_dquot(dqp, dqtype, xqc);
636 16703814 : xfs_qm_dqput(dqp);
637 16703814 : if (error)
638 0 : return error;
639 :
640 16703814 : if (xchk_should_terminate(xqc->sc, &error))
641 5 : return error;
642 :
643 16703809 : mutex_lock(&xqc->lock);
644 : }
645 34567 : mutex_unlock(&xqc->lock);
646 :
647 34567 : return error;
648 : }
649 :
650 : /* Compare the quota counters we observed against the live dquots. */
651 : STATIC int
652 34572 : xqcheck_compare_dqtype(
653 : struct xqcheck *xqc,
654 : xfs_dqtype_t dqtype)
655 : {
656 34572 : struct xfs_scrub *sc = xqc->sc;
657 34572 : int error;
658 :
659 34572 : 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 69144 : 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 34572 : error = xfs_qm_dqiterate(sc->mp, dqtype, xqcheck_compare_dquot, xqc);
670 34572 : if (error)
671 : return error;
672 :
673 : /* Walk all the observed dquots and compare to the incore ones. */
674 34572 : return xqcheck_walk_observations(xqc, dqtype);
675 : }
676 :
677 : /* Tear down everything associated with a quotacheck. */
678 : static void
679 11554 : xqcheck_teardown_scan(
680 : void *priv)
681 : {
682 11554 : struct xqcheck *xqc = priv;
683 11554 : struct xfs_quotainfo *qi = xqc->sc->mp->m_quotainfo;
684 :
685 : /* Discourage any hook functions that might be running. */
686 11554 : 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 11554 : xfs_dqtrx_hook_del(qi, &xqc->hooks);
697 :
698 11554 : if (xqc->shadow_dquot_acct.key_len) {
699 11554 : rhashtable_free_and_destroy(&xqc->shadow_dquot_acct,
700 : xqcheck_dqacct_free, NULL);
701 11554 : xqc->shadow_dquot_acct.key_len = 0;
702 : }
703 :
704 11554 : if (xqc->pcounts) {
705 11518 : xfarray_destroy(xqc->pcounts);
706 11518 : xqc->pcounts = NULL;
707 : }
708 :
709 11554 : if (xqc->gcounts) {
710 11524 : xfarray_destroy(xqc->gcounts);
711 11524 : xqc->gcounts = NULL;
712 : }
713 :
714 11554 : if (xqc->ucounts) {
715 11542 : xfarray_destroy(xqc->ucounts);
716 11542 : xqc->ucounts = NULL;
717 : }
718 :
719 11554 : xchk_iscan_teardown(&xqc->iscan);
720 11554 : mutex_destroy(&xqc->lock);
721 11554 : xqc->sc = NULL;
722 11554 : }
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 11554 : xqcheck_setup_scan(
731 : struct xfs_scrub *sc,
732 : struct xqcheck *xqc)
733 : {
734 11554 : char *descr;
735 11554 : struct xfs_quotainfo *qi = sc->mp->m_quotainfo;
736 11554 : unsigned long long max_dquots = ((xfs_dqid_t)-1) + 1;
737 11554 : int error;
738 :
739 11554 : ASSERT(xqc->sc == NULL);
740 11554 : xqc->sc = sc;
741 :
742 11554 : mutex_init(&xqc->lock);
743 :
744 : /* Retry iget every tenth of a second for up to 30 seconds. */
745 11554 : xchk_iscan_start(sc, 30000, 100, &xqc->iscan);
746 :
747 11554 : error = -ENOMEM;
748 11554 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_USER)) {
749 11542 : descr = xchk_xfile_descr(sc, "user dquot records");
750 11542 : error = xfarray_create(descr, max_dquots,
751 : sizeof(struct xqcheck_dquot), &xqc->ucounts);
752 11542 : kfree(descr);
753 11542 : if (error)
754 0 : goto out_teardown;
755 : }
756 :
757 11554 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_GROUP)) {
758 11524 : descr = xchk_xfile_descr(sc, "group dquot records");
759 11524 : error = xfarray_create(descr, max_dquots,
760 : sizeof(struct xqcheck_dquot), &xqc->gcounts);
761 11524 : kfree(descr);
762 11524 : if (error)
763 0 : goto out_teardown;
764 : }
765 :
766 11554 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_PROJ)) {
767 11518 : descr = xchk_xfile_descr(sc, "project dquot records");
768 11518 : error = xfarray_create(descr, max_dquots,
769 : sizeof(struct xqcheck_dquot), &xqc->pcounts);
770 11518 : kfree(descr);
771 11518 : 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 11554 : error = rhashtable_init(&xqc->shadow_dquot_acct,
780 : &xqcheck_dqacct_hash_params);
781 11554 : 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 11554 : ASSERT(sc->flags & XCHK_FSGATES_QUOTA);
795 11554 : xfs_hook_setup(&xqc->hooks.mod_hook, xqcheck_mod_live_ino_dqtrx);
796 11554 : xfs_hook_setup(&xqc->hooks.apply_hook, xqcheck_apply_live_dqtrx);
797 :
798 11554 : error = xfs_dqtrx_hook_add(qi, &xqc->hooks);
799 11554 : if (error)
800 0 : goto out_teardown;
801 :
802 : /* Use deferred cleanup to pass the quota count data to repair. */
803 11554 : sc->buf_cleanup = xqcheck_teardown_scan;
804 11554 : 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 11554 : xchk_quotacheck(
814 : struct xfs_scrub *sc)
815 : {
816 11554 : struct xqcheck *xqc = sc->buf;
817 11554 : int error = 0;
818 :
819 : /* Check quota counters on the live filesystem. */
820 11554 : error = xqcheck_setup_scan(sc, xqc);
821 11554 : if (error)
822 : return error;
823 :
824 : /* Walk all inodes, picking up quota information. */
825 11554 : error = xqcheck_collect_counts(xqc);
826 11554 : if (!xchk_xref_process_error(sc, 0, 0, &error))
827 1 : return error;
828 :
829 : /* Fail fast if we're not playing with a full dataset. */
830 11553 : if (xchk_iscan_aborted(&xqc->iscan))
831 0 : xchk_set_incomplete(sc);
832 11553 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
833 : return 0;
834 :
835 : /* Compare quota counters. */
836 11553 : if (xqc->ucounts) {
837 11541 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_USER);
838 11541 : if (!xchk_xref_process_error(sc, 0, 0, &error))
839 4 : return error;
840 : }
841 11549 : if (xqc->gcounts) {
842 11519 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_GROUP);
843 11519 : if (!xchk_xref_process_error(sc, 0, 0, &error))
844 1 : return error;
845 : }
846 11548 : if (xqc->pcounts) {
847 11512 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_PROJ);
848 11512 : 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 11548 : if (xchk_iscan_aborted(&xqc->iscan))
854 0 : xchk_set_incomplete(sc);
855 :
856 : return 0;
857 : }
|