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 1214 : xqcheck_dqacct_free(
70 : void *ptr,
71 : void *arg)
72 : {
73 2374643 : struct xqcheck_dqacct *dqa = ptr;
74 :
75 1214 : kfree(dqa);
76 2373429 : }
77 :
78 : /* Set us up to scrub quota counters. */
79 : int
80 27308 : xchk_setup_quotacheck(
81 : struct xfs_scrub *sc)
82 : {
83 27308 : if (!XFS_IS_QUOTA_ON(sc->mp))
84 : return -ENOENT;
85 :
86 18677 : xchk_fsgates_enable(sc, XCHK_FSGATES_QUOTA);
87 :
88 18677 : sc->buf = kzalloc(sizeof(struct xqcheck), XCHK_GFP_FLAGS);
89 18677 : if (!sc->buf)
90 : return -ENOMEM;
91 :
92 18677 : 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 694947191 : 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 694947191 : struct xqcheck_dquot xcdq;
136 694947191 : int error;
137 :
138 694947191 : error = xfarray_load_sparse(counts, id, &xcdq);
139 694947191 : if (error)
140 : return error;
141 :
142 694947191 : xcdq.flags |= XQCHECK_DQUOT_WRITTEN;
143 694947191 : xcdq.icount += inodes;
144 694947191 : xcdq.bcount += nblks;
145 694947191 : xcdq.rtbcount += rtblks;
146 :
147 694947191 : error = xfarray_store(counts, id, &xcdq);
148 694947191 : 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 13093331 : xqcheck_dqacct_obj_cmpfn(
162 : struct rhashtable_compare_arg *arg,
163 : const void *obj)
164 : {
165 13093331 : const uintptr_t *tx_idp = arg->key;
166 13093331 : const struct xqcheck_dqacct *dqa = obj;
167 :
168 13093331 : if (dqa->tx_id != *tx_idp)
169 123340 : 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 15344634 : xqcheck_get_dqtrx(
185 : struct xqcheck_dqacct *dqa,
186 : xfs_dqtype_t q_type,
187 : xfs_dqid_t q_id)
188 : {
189 15344634 : int i;
190 :
191 31194460 : for (i = 0; i < XQCHECK_MAX_NR_DQTRXS; i++) {
192 55182040 : if (dqa->dqtrx[i].q_type == 0 ||
193 23987580 : (dqa->dqtrx[i].q_type == q_type &&
194 8700566 : dqa->dqtrx[i].q_id == q_id))
195 15344634 : 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 10591343 : xqcheck_mod_live_ino_dqtrx(
207 : struct notifier_block *nb,
208 : unsigned long action,
209 : void *data)
210 : {
211 10591343 : struct xfs_mod_ino_dqtrx_params *p = data;
212 10591343 : struct xqcheck *xqc;
213 10591343 : struct xqcheck_dqacct *dqa;
214 10591343 : struct xqcheck_dqtrx *dqtrx;
215 10591343 : int error;
216 :
217 10591343 : xqc = container_of(nb, struct xqcheck, hooks.mod_hook.nb);
218 :
219 : /* Skip quota reservation fields. */
220 10591343 : 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 10591376 : break;
227 : default:
228 : return NOTIFY_DONE;
229 : }
230 :
231 : /* Ignore dqtrx updates for quota types we don't care about. */
232 10591376 : switch (p->q_type) {
233 3660527 : case XFS_DQTYPE_USER:
234 3660527 : if (!xqc->ucounts)
235 : return NOTIFY_DONE;
236 : break;
237 3660772 : case XFS_DQTYPE_GROUP:
238 3660772 : if (!xqc->gcounts)
239 : return NOTIFY_DONE;
240 : break;
241 3270077 : case XFS_DQTYPE_PROJ:
242 3270077 : 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 10591376 : 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 8140615 : mutex_lock(&xqc->lock);
255 8140693 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
256 : xqcheck_dqacct_hash_params);
257 8140693 : if (!dqa) {
258 2374643 : dqa = kzalloc(sizeof(struct xqcheck_dqacct), XCHK_GFP_FLAGS);
259 2374643 : if (!dqa)
260 0 : goto out_abort;
261 :
262 2374643 : dqa->tx_id = p->tx_id;
263 2374643 : error = rhashtable_insert_fast(&xqc->shadow_dquot_acct,
264 : &dqa->hash, xqcheck_dqacct_hash_params);
265 2374643 : if (error)
266 0 : goto out_abort;
267 : }
268 :
269 : /* Find the shadow dqtrx (or an empty slot) here. */
270 8140693 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
271 8140693 : if (!dqtrx)
272 0 : goto out_abort;
273 8140693 : if (dqtrx->q_type == 0) {
274 7198858 : dqtrx->q_type = p->q_type;
275 7198858 : dqtrx->q_id = p->q_id;
276 7198858 : dqa->refcount++;
277 : }
278 :
279 : /* Update counter */
280 8140693 : switch (action) {
281 5177251 : case XFS_TRANS_DQ_BCOUNT:
282 5177251 : dqtrx->bcount_delta += p->delta;
283 5177251 : break;
284 1581745 : case XFS_TRANS_DQ_DELBCOUNT:
285 1581745 : dqtrx->delbcnt_delta += p->delta;
286 1581745 : break;
287 1381697 : case XFS_TRANS_DQ_ICOUNT:
288 1381697 : dqtrx->icount_delta += p->delta;
289 1381697 : break;
290 0 : case XFS_TRANS_DQ_RTBCOUNT:
291 0 : dqtrx->rtbcount_delta += p->delta;
292 0 : break;
293 0 : case XFS_TRANS_DQ_DELRTBCOUNT:
294 0 : dqtrx->delrtb_delta += p->delta;
295 0 : break;
296 : }
297 :
298 8140693 : mutex_unlock(&xqc->lock);
299 8140693 : 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 52823226 : xqcheck_apply_live_dqtrx(
313 : struct notifier_block *nb,
314 : unsigned long action,
315 : void *data)
316 : {
317 52823226 : struct xfs_apply_dqtrx_params *p = data;
318 52823226 : struct xqcheck *xqc;
319 52823226 : struct xqcheck_dqacct *dqa;
320 52823226 : struct xqcheck_dqtrx *dqtrx;
321 52823226 : struct xfarray *counts;
322 52823226 : int error;
323 :
324 52823226 : xqc = container_of(nb, struct xqcheck, hooks.apply_hook.nb);
325 :
326 : /* Map the dquot type to an incore counter object. */
327 52823226 : switch (p->q_type) {
328 17684485 : case XFS_DQTYPE_USER:
329 17684485 : counts = xqc->ucounts;
330 17684485 : break;
331 17680428 : case XFS_DQTYPE_GROUP:
332 17680428 : counts = xqc->gcounts;
333 17680428 : break;
334 17458313 : case XFS_DQTYPE_PROJ:
335 17458313 : counts = xqc->pcounts;
336 17458313 : break;
337 : default:
338 : return NOTIFY_DONE;
339 : }
340 :
341 52823226 : 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 52783551 : mutex_lock(&xqc->lock);
349 52813144 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
350 : xqcheck_dqacct_hash_params);
351 52813144 : if (!dqa)
352 45609203 : goto out_unlock;
353 7203941 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
354 7203941 : if (!dqtrx || dqtrx->q_type == 0)
355 8022 : goto out_unlock;
356 :
357 : /* Update our shadow dquot if we're committing. */
358 7195919 : if (action == XFS_APPLY_DQTRX_COMMIT) {
359 6212281 : error = xqcheck_update_incore_counts(xqc, counts, p->q_id,
360 : dqtrx->icount_delta,
361 6212281 : dqtrx->bcount_delta + dqtrx->delbcnt_delta,
362 6212281 : dqtrx->rtbcount_delta + dqtrx->delrtb_delta);
363 6212281 : if (error)
364 0 : goto out_abort;
365 : }
366 :
367 : /* Free the shadow accounting structure if that was the last user. */
368 7195919 : dqa->refcount--;
369 7195919 : if (dqa->refcount == 0) {
370 2373429 : error = rhashtable_remove_fast(&xqc->shadow_dquot_acct,
371 : &dqa->hash, xqcheck_dqacct_hash_params);
372 2373429 : if (error)
373 0 : goto out_abort;
374 2373429 : xqcheck_dqacct_free(dqa, NULL);
375 : }
376 :
377 7195919 : mutex_unlock(&xqc->lock);
378 7195919 : return NOTIFY_DONE;
379 :
380 0 : out_abort:
381 0 : xchk_iscan_abort(&xqc->iscan);
382 45617225 : out_unlock:
383 45617225 : mutex_unlock(&xqc->lock);
384 45617225 : return NOTIFY_DONE;
385 : }
386 :
387 : /* Record this inode's quota usage in our shadow quota counter data. */
388 : STATIC int
389 229635369 : xqcheck_collect_inode(
390 : struct xqcheck *xqc,
391 : struct xfs_inode *ip)
392 : {
393 229635369 : struct xfs_trans *tp = xqc->sc->tp;
394 229635369 : xfs_filblks_t nblks, rtblks;
395 229635369 : uint ilock_flags = 0;
396 229635369 : xfs_dqid_t id;
397 229635369 : bool isreg = S_ISREG(VFS_I(ip)->i_mode);
398 229635369 : int error = 0;
399 :
400 459252105 : if (xfs_is_quota_inode(&tp->t_mountp->m_sb, ip->i_ino)) {
401 : /*
402 : * Quota files are never counted towards quota, so we do not
403 : * need to take the lock.
404 : */
405 55767 : xchk_iscan_mark_visited(&xqc->iscan, ip);
406 55767 : return 0;
407 : }
408 :
409 : /* Figure out the data / rt device block counts. */
410 229579602 : xfs_ilock(ip, XFS_IOLOCK_SHARED);
411 229579602 : if (isreg)
412 101325633 : xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
413 229579602 : if (XFS_IS_REALTIME_INODE(ip)) {
414 0 : ilock_flags = xfs_ilock_data_map_shared(ip);
415 0 : error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
416 0 : if (error)
417 0 : goto out_abort;
418 : } else {
419 229579602 : ilock_flags = XFS_ILOCK_SHARED;
420 229579602 : xfs_ilock(ip, XFS_ILOCK_SHARED);
421 : }
422 229579602 : xfs_inode_count_blocks(tp, ip, &nblks, &rtblks);
423 :
424 229579602 : if (xchk_iscan_aborted(&xqc->iscan)) {
425 0 : error = -ECANCELED;
426 0 : goto out_incomplete;
427 : }
428 :
429 : /* Update the shadow dquot counters. */
430 229579602 : mutex_lock(&xqc->lock);
431 229579602 : if (xqc->ucounts) {
432 229578862 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_USER);
433 229578862 : error = xqcheck_update_incore_counts(xqc, xqc->ucounts, id, 1,
434 : nblks, rtblks);
435 229578862 : if (error)
436 0 : goto out_mutex;
437 : }
438 :
439 229579602 : if (xqc->gcounts) {
440 229577574 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_GROUP);
441 229577574 : error = xqcheck_update_incore_counts(xqc, xqc->gcounts, id, 1,
442 : nblks, rtblks);
443 229577574 : if (error)
444 0 : goto out_mutex;
445 : }
446 :
447 229579602 : if (xqc->pcounts) {
448 229578474 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_PROJ);
449 229578474 : error = xqcheck_update_incore_counts(xqc, xqc->pcounts, id, 1,
450 : nblks, rtblks);
451 229578474 : if (error)
452 0 : goto out_mutex;
453 : }
454 229579602 : mutex_unlock(&xqc->lock);
455 :
456 229579602 : xchk_iscan_mark_visited(&xqc->iscan, ip);
457 229579602 : goto out_ilock;
458 :
459 0 : out_mutex:
460 0 : mutex_unlock(&xqc->lock);
461 0 : out_abort:
462 0 : xchk_iscan_abort(&xqc->iscan);
463 0 : out_incomplete:
464 0 : xchk_set_incomplete(xqc->sc);
465 229579602 : out_ilock:
466 229579602 : xfs_iunlock(ip, ilock_flags);
467 229579602 : if (isreg)
468 101325633 : xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
469 229579602 : xfs_iunlock(ip, XFS_IOLOCK_SHARED);
470 229579602 : return error;
471 : }
472 :
473 : /* Walk all the allocated inodes and run a quota scan on them. */
474 : STATIC int
475 18662 : xqcheck_collect_counts(
476 : struct xqcheck *xqc)
477 : {
478 18662 : struct xfs_scrub *sc = xqc->sc;
479 18662 : struct xfs_inode *ip;
480 18662 : int error;
481 :
482 : /*
483 : * Set up for a potentially lengthy filesystem scan by reducing our
484 : * transaction resource usage for the duration. Specifically:
485 : *
486 : * Cancel the transaction to release the log grant space while we scan
487 : * the filesystem.
488 : *
489 : * Create a new empty transaction to eliminate the possibility of the
490 : * inode scan deadlocking on cyclical metadata.
491 : *
492 : * We pass the empty transaction to the file scanning function to avoid
493 : * repeatedly cycling empty transactions. This can be done without
494 : * risk of deadlock between sb_internal and the IOLOCK (we take the
495 : * IOLOCK to quiesce the file before scanning) because empty
496 : * transactions do not take sb_internal.
497 : */
498 18662 : xchk_trans_cancel(sc);
499 18662 : error = xchk_trans_alloc_empty(sc);
500 18662 : if (error)
501 : return error;
502 :
503 229654031 : while ((error = xchk_iscan_iter(&xqc->iscan, &ip)) == 1) {
504 229635369 : error = xqcheck_collect_inode(xqc, ip);
505 229635369 : xchk_irele(sc, ip);
506 229635369 : if (error)
507 : break;
508 :
509 229635369 : if (xchk_should_terminate(sc, &error))
510 : break;
511 : }
512 18662 : xchk_iscan_iter_finish(&xqc->iscan);
513 18662 : if (error) {
514 0 : xchk_set_incomplete(sc);
515 : /*
516 : * If we couldn't grab an inode that was busy with a state
517 : * change, change the error code so that we exit to userspace
518 : * as quickly as possible.
519 : */
520 0 : if (error == -EBUSY)
521 : return -ECANCELED;
522 0 : return error;
523 : }
524 :
525 : /*
526 : * Switch out for a real transaction in preparation for building a new
527 : * tree.
528 : */
529 18662 : xchk_trans_cancel(sc);
530 18662 : return xchk_setup_fs(sc);
531 : }
532 :
533 : /*
534 : * Part 2: Comparing dquot resource counters. Walk each xfs_dquot, comparing
535 : * the resource usage counters against our shadow dquots; and then walk each
536 : * shadow dquot (that wasn't covered in the first part), comparing it against
537 : * the xfs_dquot.
538 : */
539 :
540 : /*
541 : * Check the dquot data against what we observed. Caller must hold the dquot
542 : * lock.
543 : */
544 : STATIC int
545 56019437 : xqcheck_compare_dquot(
546 : struct xfs_dquot *dqp,
547 : xfs_dqtype_t dqtype,
548 : void *priv)
549 : {
550 56019437 : struct xqcheck_dquot xcdq;
551 56019437 : struct xqcheck *xqc = priv;
552 56019437 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
553 56019437 : int error;
554 :
555 56019437 : if (xchk_iscan_aborted(&xqc->iscan)) {
556 0 : xchk_set_incomplete(xqc->sc);
557 0 : return -ECANCELED;
558 : }
559 :
560 56019437 : mutex_lock(&xqc->lock);
561 56019437 : error = xfarray_load_sparse(counts, dqp->q_id, &xcdq);
562 56019437 : if (error)
563 0 : goto out_unlock;
564 :
565 56019437 : if (xcdq.icount != dqp->q_ino.count)
566 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
567 :
568 56019437 : if (xcdq.bcount != dqp->q_blk.count)
569 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
570 :
571 56019437 : if (xcdq.rtbcount != dqp->q_rtb.count)
572 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
573 :
574 56019437 : xcdq.flags |= (XQCHECK_DQUOT_COMPARE_SCANNED | XQCHECK_DQUOT_WRITTEN);
575 56019437 : error = xfarray_store(counts, dqp->q_id, &xcdq);
576 56019437 : if (error == -EFBIG) {
577 : /*
578 : * EFBIG means we tried to store data at too high a byte offset
579 : * in the sparse array. IOWs, we cannot complete the check and
580 : * must notify userspace that the check was incomplete. This
581 : * should never happen outside of the collection phase.
582 : */
583 0 : xchk_set_incomplete(xqc->sc);
584 0 : error = -ECANCELED;
585 : }
586 56019437 : mutex_unlock(&xqc->lock);
587 56019437 : if (error)
588 : return error;
589 :
590 56019437 : if (xqc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
591 0 : return -ECANCELED;
592 :
593 : return 0;
594 :
595 : out_unlock:
596 0 : mutex_unlock(&xqc->lock);
597 0 : return error;
598 : }
599 :
600 : /*
601 : * Walk all the observed dquots, and make sure there's a matching incore
602 : * dquot and that its counts match ours.
603 : */
604 : STATIC int
605 55747 : xqcheck_walk_observations(
606 : struct xqcheck *xqc,
607 : xfs_dqtype_t dqtype)
608 : {
609 55747 : struct xqcheck_dquot xcdq;
610 55747 : struct xfs_dquot *dqp;
611 55747 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
612 55747 : xfarray_idx_t cur = XFARRAY_CURSOR_INIT;
613 55747 : int error;
614 :
615 55747 : mutex_lock(&xqc->lock);
616 56075182 : while ((error = xfarray_iter(counts, &cur, &xcdq)) == 1) {
617 56019437 : xfs_dqid_t id = cur - 1;
618 :
619 56019437 : if (xcdq.flags & XQCHECK_DQUOT_COMPARE_SCANNED)
620 55747 : continue;
621 :
622 55963690 : mutex_unlock(&xqc->lock);
623 :
624 55963690 : error = xfs_qm_dqget(xqc->sc->mp, id, dqtype, false, &dqp);
625 55963690 : if (error == -ENOENT) {
626 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, id);
627 0 : return 0;
628 : }
629 55963690 : if (error)
630 0 : return error;
631 :
632 55963690 : error = xqcheck_compare_dquot(dqp, dqtype, xqc);
633 55963690 : xfs_qm_dqput(dqp);
634 55963690 : if (error)
635 0 : return error;
636 :
637 55963690 : if (xchk_should_terminate(xqc->sc, &error))
638 2 : return error;
639 :
640 55963688 : mutex_lock(&xqc->lock);
641 : }
642 55745 : mutex_unlock(&xqc->lock);
643 :
644 55745 : return error;
645 : }
646 :
647 : /* Compare the quota counters we observed against the live dquots. */
648 : STATIC int
649 55747 : xqcheck_compare_dqtype(
650 : struct xqcheck *xqc,
651 : xfs_dqtype_t dqtype)
652 : {
653 55747 : struct xfs_scrub *sc = xqc->sc;
654 55747 : int error;
655 :
656 55747 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
657 : return 0;
658 :
659 : /* If the quota CHKD flag is cleared, we need to repair this quota. */
660 111494 : if (!(xfs_quota_chkd_flag(dqtype) & sc->mp->m_qflags)) {
661 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, 0);
662 0 : return 0;
663 : }
664 :
665 : /* Compare what we observed against the actual dquots. */
666 55747 : error = xfs_qm_dqiterate(sc->mp, dqtype, xqcheck_compare_dquot, xqc);
667 55747 : if (error)
668 : return error;
669 :
670 : /* Walk all the observed dquots and compare to the incore ones. */
671 55747 : return xqcheck_walk_observations(xqc, dqtype);
672 : }
673 :
674 : /* Tear down everything associated with a quotacheck. */
675 : static void
676 18662 : xqcheck_teardown_scan(
677 : void *priv)
678 : {
679 18662 : struct xqcheck *xqc = priv;
680 18662 : struct xfs_quotainfo *qi = xqc->sc->mp->m_quotainfo;
681 :
682 : /* Discourage any hook functions that might be running. */
683 18662 : xchk_iscan_abort(&xqc->iscan);
684 :
685 : /*
686 : * As noted above, the apply hook is responsible for cleaning up the
687 : * shadow dquot accounting data when a transaction completes. The mod
688 : * hook must be removed before the apply hook so that we don't
689 : * mistakenly leave an active shadow account for the mod hook to get
690 : * its hands on. No hooks should be running after these functions
691 : * return.
692 : */
693 18662 : xfs_dqtrx_hook_del(qi, &xqc->hooks);
694 :
695 18662 : if (xqc->shadow_dquot_acct.key_len) {
696 18662 : rhashtable_free_and_destroy(&xqc->shadow_dquot_acct,
697 : xqcheck_dqacct_free, NULL);
698 18662 : xqc->shadow_dquot_acct.key_len = 0;
699 : }
700 :
701 18662 : if (xqc->pcounts) {
702 18545 : xfarray_destroy(xqc->pcounts);
703 18545 : xqc->pcounts = NULL;
704 : }
705 :
706 18662 : if (xqc->gcounts) {
707 18577 : xfarray_destroy(xqc->gcounts);
708 18577 : xqc->gcounts = NULL;
709 : }
710 :
711 18662 : if (xqc->ucounts) {
712 18627 : xfarray_destroy(xqc->ucounts);
713 18627 : xqc->ucounts = NULL;
714 : }
715 :
716 18662 : xchk_iscan_teardown(&xqc->iscan);
717 18662 : mutex_destroy(&xqc->lock);
718 18662 : xqc->sc = NULL;
719 18662 : }
720 :
721 : /*
722 : * Scan all inodes in the entire filesystem to generate quota counter data.
723 : * If the scan is successful, the quota data will be left alive for a repair.
724 : * If any error occurs, we'll tear everything down.
725 : */
726 : STATIC int
727 18662 : xqcheck_setup_scan(
728 : struct xfs_scrub *sc,
729 : struct xqcheck *xqc)
730 : {
731 18662 : char *descr;
732 18662 : struct xfs_quotainfo *qi = sc->mp->m_quotainfo;
733 18662 : unsigned long long max_dquots = ((xfs_dqid_t)-1) + 1;
734 18662 : int error;
735 :
736 18662 : ASSERT(xqc->sc == NULL);
737 18662 : xqc->sc = sc;
738 :
739 18662 : mutex_init(&xqc->lock);
740 :
741 : /* Retry iget every tenth of a second for up to 30 seconds. */
742 18662 : xchk_iscan_start(sc, 30000, 100, &xqc->iscan);
743 :
744 18662 : error = -ENOMEM;
745 18662 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_USER)) {
746 18627 : descr = xchk_xfile_descr(sc, "user dquot records");
747 18627 : error = xfarray_create(descr, max_dquots,
748 : sizeof(struct xqcheck_dquot), &xqc->ucounts);
749 18627 : kfree(descr);
750 18627 : if (error)
751 0 : goto out_teardown;
752 : }
753 :
754 18662 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_GROUP)) {
755 18577 : descr = xchk_xfile_descr(sc, "group dquot records");
756 18577 : error = xfarray_create(descr, max_dquots,
757 : sizeof(struct xqcheck_dquot), &xqc->gcounts);
758 18577 : kfree(descr);
759 18577 : if (error)
760 0 : goto out_teardown;
761 : }
762 :
763 18662 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_PROJ)) {
764 18545 : descr = xchk_xfile_descr(sc, "project dquot records");
765 18545 : error = xfarray_create(descr, max_dquots,
766 : sizeof(struct xqcheck_dquot), &xqc->pcounts);
767 18545 : kfree(descr);
768 18545 : if (error)
769 0 : goto out_teardown;
770 : }
771 :
772 : /*
773 : * Set up hash table to map transactions to our internal shadow dqtrx
774 : * structures.
775 : */
776 18662 : error = rhashtable_init(&xqc->shadow_dquot_acct,
777 : &xqcheck_dqacct_hash_params);
778 18662 : if (error)
779 0 : goto out_teardown;
780 :
781 : /*
782 : * Hook into the quota code. The hook only triggers for inodes that
783 : * were already scanned, and the scanner thread takes each inode's
784 : * ILOCK, which means that any in-progress inode updates will finish
785 : * before we can scan the inode.
786 : *
787 : * The apply hook (which removes the shadow dquot accounting struct)
788 : * must be installed before the mod hook so that we never fail to catch
789 : * the end of a quota update sequence and leave stale shadow data.
790 : */
791 18662 : ASSERT(sc->flags & XCHK_FSGATES_QUOTA);
792 18662 : xfs_hook_setup(&xqc->hooks.mod_hook, xqcheck_mod_live_ino_dqtrx);
793 18662 : xfs_hook_setup(&xqc->hooks.apply_hook, xqcheck_apply_live_dqtrx);
794 :
795 18662 : error = xfs_dqtrx_hook_add(qi, &xqc->hooks);
796 18662 : if (error)
797 0 : goto out_teardown;
798 :
799 : /* Use deferred cleanup to pass the quota count data to repair. */
800 18662 : sc->buf_cleanup = xqcheck_teardown_scan;
801 18662 : return 0;
802 :
803 0 : out_teardown:
804 0 : xqcheck_teardown_scan(xqc);
805 0 : return error;
806 : }
807 :
808 : /* Scrub all counters for a given quota type. */
809 : int
810 18662 : xchk_quotacheck(
811 : struct xfs_scrub *sc)
812 : {
813 18662 : struct xqcheck *xqc = sc->buf;
814 18662 : int error = 0;
815 :
816 : /* Check quota counters on the live filesystem. */
817 18662 : error = xqcheck_setup_scan(sc, xqc);
818 18662 : if (error)
819 : return error;
820 :
821 : /* Walk all inodes, picking up quota information. */
822 18662 : error = xqcheck_collect_counts(xqc);
823 18662 : if (!xchk_xref_process_error(sc, 0, 0, &error))
824 0 : return error;
825 :
826 : /* Fail fast if we're not playing with a full dataset. */
827 18662 : if (xchk_iscan_aborted(&xqc->iscan))
828 0 : xchk_set_incomplete(sc);
829 18662 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
830 : return 0;
831 :
832 : /* Compare quota counters. */
833 18662 : if (xqc->ucounts) {
834 18627 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_USER);
835 18627 : if (!xchk_xref_process_error(sc, 0, 0, &error))
836 0 : return error;
837 : }
838 18662 : if (xqc->gcounts) {
839 18577 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_GROUP);
840 18577 : if (!xchk_xref_process_error(sc, 0, 0, &error))
841 2 : return error;
842 : }
843 18660 : if (xqc->pcounts) {
844 18543 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_PROJ);
845 18543 : if (!xchk_xref_process_error(sc, 0, 0, &error))
846 0 : return error;
847 : }
848 :
849 : /* Check one last time for an incomplete dataset. */
850 18660 : if (xchk_iscan_aborted(&xqc->iscan))
851 0 : xchk_set_incomplete(sc);
852 :
853 : return 0;
854 : }
|