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 324 : xqcheck_dqacct_free(
70 : void *ptr,
71 : void *arg)
72 : {
73 1311198 : struct xqcheck_dqacct *dqa = ptr;
74 :
75 324 : kfree(dqa);
76 1310874 : }
77 :
78 : /* Set us up to scrub quota counters. */
79 : int
80 10457 : xchk_setup_quotacheck(
81 : struct xfs_scrub *sc)
82 : {
83 10457 : if (!XFS_IS_QUOTA_ON(sc->mp))
84 : return -ENOENT;
85 :
86 7647 : xchk_fsgates_enable(sc, XCHK_FSGATES_QUOTA);
87 :
88 7647 : sc->buf = kzalloc(sizeof(struct xqcheck), XCHK_GFP_FLAGS);
89 7647 : if (!sc->buf)
90 : return -ENOMEM;
91 :
92 7647 : 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 157481982 : 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 157481982 : struct xqcheck_dquot xcdq;
136 157481982 : int error;
137 :
138 157481982 : error = xfarray_load_sparse(counts, id, &xcdq);
139 157481982 : if (error)
140 : return error;
141 :
142 157481982 : xcdq.flags |= XQCHECK_DQUOT_WRITTEN;
143 157481982 : xcdq.icount += inodes;
144 157481982 : xcdq.bcount += nblks;
145 157481982 : xcdq.rtbcount += rtblks;
146 :
147 157481982 : error = xfarray_store(counts, id, &xcdq);
148 157481982 : 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 7416063 : xqcheck_dqacct_obj_cmpfn(
162 : struct rhashtable_compare_arg *arg,
163 : const void *obj)
164 : {
165 7416063 : const uintptr_t *tx_idp = arg->key;
166 7416063 : const struct xqcheck_dqacct *dqa = obj;
167 :
168 7416063 : if (dqa->tx_id != *tx_idp)
169 77160 : 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 8650101 : xqcheck_get_dqtrx(
185 : struct xqcheck_dqacct *dqa,
186 : xfs_dqtype_t q_type,
187 : xfs_dqid_t q_id)
188 : {
189 8650101 : int i;
190 :
191 17735620 : for (i = 0; i < XQCHECK_MAX_NR_DQTRXS; i++) {
192 17735620 : if (dqa->dqtrx[i].q_type == 0 ||
193 5133482 : (dqa->dqtrx[i].q_type == q_type &&
194 5133482 : dqa->dqtrx[i].q_id == q_id))
195 8650101 : 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 5010661 : xqcheck_mod_live_ino_dqtrx(
207 : struct notifier_block *nb,
208 : unsigned long action,
209 : void *data)
210 : {
211 5010661 : struct xfs_mod_ino_dqtrx_params *p = data;
212 5010661 : struct xqcheck *xqc;
213 5010661 : struct xqcheck_dqacct *dqa;
214 5010661 : struct xqcheck_dqtrx *dqtrx;
215 5010661 : int error;
216 :
217 5010661 : xqc = container_of(nb, struct xqcheck, hooks.mod_hook.nb);
218 :
219 : /* Skip quota reservation fields. */
220 5010661 : 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 5010844 : break;
227 : default:
228 : return NOTIFY_DONE;
229 : }
230 :
231 : /* Ignore dqtrx updates for quota types we don't care about. */
232 5010844 : switch (p->q_type) {
233 1763882 : case XFS_DQTYPE_USER:
234 1763882 : if (!xqc->ucounts)
235 : return NOTIFY_DONE;
236 : break;
237 1763812 : case XFS_DQTYPE_GROUP:
238 1763812 : if (!xqc->gcounts)
239 : return NOTIFY_DONE;
240 : break;
241 1483150 : case XFS_DQTYPE_PROJ:
242 1483150 : 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 5010844 : 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 4646266 : mutex_lock(&xqc->lock);
255 4646274 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
256 : xqcheck_dqacct_hash_params);
257 4646274 : if (!dqa) {
258 1311198 : dqa = kzalloc(sizeof(struct xqcheck_dqacct), XCHK_GFP_FLAGS);
259 1311198 : if (!dqa)
260 0 : goto out_abort;
261 :
262 1311198 : dqa->tx_id = p->tx_id;
263 1311198 : error = rhashtable_insert_fast(&xqc->shadow_dquot_acct,
264 : &dqa->hash, xqcheck_dqacct_hash_params);
265 1311198 : if (error)
266 0 : goto out_abort;
267 : }
268 :
269 : /* Find the shadow dqtrx (or an empty slot) here. */
270 4646274 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
271 4646274 : if (!dqtrx)
272 0 : goto out_abort;
273 4646274 : if (dqtrx->q_type == 0) {
274 3998335 : dqtrx->q_type = p->q_type;
275 3998335 : dqtrx->q_id = p->q_id;
276 3998335 : dqa->refcount++;
277 : }
278 :
279 : /* Update counter */
280 4646274 : switch (action) {
281 2103523 : case XFS_TRANS_DQ_BCOUNT:
282 2103523 : dqtrx->bcount_delta += p->delta;
283 2103523 : break;
284 1331019 : case XFS_TRANS_DQ_DELBCOUNT:
285 1331019 : dqtrx->delbcnt_delta += p->delta;
286 1331019 : break;
287 1211732 : case XFS_TRANS_DQ_ICOUNT:
288 1211732 : dqtrx->icount_delta += p->delta;
289 1211732 : 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 4646274 : mutex_unlock(&xqc->lock);
299 4646274 : 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 30971524 : xqcheck_apply_live_dqtrx(
313 : struct notifier_block *nb,
314 : unsigned long action,
315 : void *data)
316 : {
317 30971524 : struct xfs_apply_dqtrx_params *p = data;
318 30971524 : struct xqcheck *xqc;
319 30971524 : struct xqcheck_dqacct *dqa;
320 30971524 : struct xqcheck_dqtrx *dqtrx;
321 30971524 : struct xfarray *counts;
322 30971524 : int error;
323 :
324 30971524 : xqc = container_of(nb, struct xqcheck, hooks.apply_hook.nb);
325 :
326 : /* Map the dquot type to an incore counter object. */
327 30971524 : switch (p->q_type) {
328 10377243 : case XFS_DQTYPE_USER:
329 10377243 : counts = xqc->ucounts;
330 10377243 : break;
331 10377776 : case XFS_DQTYPE_GROUP:
332 10377776 : counts = xqc->gcounts;
333 10377776 : break;
334 10216505 : case XFS_DQTYPE_PROJ:
335 10216505 : counts = xqc->pcounts;
336 10216505 : break;
337 : default:
338 : return NOTIFY_DONE;
339 : }
340 :
341 30971524 : 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 30942221 : mutex_lock(&xqc->lock);
349 30946897 : dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id,
350 : xqcheck_dqacct_hash_params);
351 30946897 : if (!dqa)
352 26943070 : goto out_unlock;
353 4003827 : dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id);
354 4003827 : if (!dqtrx || dqtrx->q_type == 0)
355 6192 : goto out_unlock;
356 :
357 : /* Update our shadow dquot if we're committing. */
358 3997635 : if (action == XFS_APPLY_DQTRX_COMMIT) {
359 3711351 : error = xqcheck_update_incore_counts(xqc, counts, p->q_id,
360 : dqtrx->icount_delta,
361 3711351 : dqtrx->bcount_delta + dqtrx->delbcnt_delta,
362 3711351 : dqtrx->rtbcount_delta + dqtrx->delrtb_delta);
363 3711351 : if (error)
364 0 : goto out_abort;
365 : }
366 :
367 : /* Free the shadow accounting structure if that was the last user. */
368 3997635 : dqa->refcount--;
369 3997635 : if (dqa->refcount == 0) {
370 1310874 : error = rhashtable_remove_fast(&xqc->shadow_dquot_acct,
371 : &dqa->hash, xqcheck_dqacct_hash_params);
372 1310874 : if (error)
373 0 : goto out_abort;
374 1310874 : xqcheck_dqacct_free(dqa, NULL);
375 : }
376 :
377 3997635 : mutex_unlock(&xqc->lock);
378 3997635 : return NOTIFY_DONE;
379 :
380 0 : out_abort:
381 0 : xchk_iscan_abort(&xqc->iscan);
382 26949262 : out_unlock:
383 26949262 : mutex_unlock(&xqc->lock);
384 26949262 : return NOTIFY_DONE;
385 : }
386 :
387 : /* Record this inode's quota usage in our shadow quota counter data. */
388 : STATIC int
389 51280189 : xqcheck_collect_inode(
390 : struct xqcheck *xqc,
391 : struct xfs_inode *ip)
392 : {
393 51280189 : struct xfs_trans *tp = xqc->sc->tp;
394 51280189 : xfs_filblks_t nblks, rtblks;
395 51280189 : uint ilock_flags = 0;
396 51280189 : xfs_dqid_t id;
397 51280189 : bool isreg = S_ISREG(VFS_I(ip)->i_mode);
398 51280189 : int error = 0;
399 :
400 102552742 : 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 22866 : xchk_iscan_mark_visited(&xqc->iscan, ip);
406 22866 : return 0;
407 : }
408 :
409 : /* Figure out the data / rt device block counts. */
410 51257323 : xfs_ilock(ip, XFS_IOLOCK_SHARED);
411 51257323 : if (isreg)
412 23718706 : xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
413 51257323 : 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 51257323 : ilock_flags = XFS_ILOCK_SHARED;
420 51257323 : xfs_ilock(ip, XFS_ILOCK_SHARED);
421 : }
422 51257323 : xfs_inode_count_blocks(tp, ip, &nblks, &rtblks);
423 :
424 51257323 : if (xchk_iscan_aborted(&xqc->iscan)) {
425 0 : error = -ECANCELED;
426 0 : goto out_incomplete;
427 : }
428 :
429 : /* Update the shadow dquot counters. */
430 51257323 : mutex_lock(&xqc->lock);
431 51257323 : if (xqc->ucounts) {
432 51257075 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_USER);
433 51257075 : error = xqcheck_update_incore_counts(xqc, xqc->ucounts, id, 1,
434 : nblks, rtblks);
435 51257075 : if (error)
436 0 : goto out_mutex;
437 : }
438 :
439 51257323 : if (xqc->gcounts) {
440 51256587 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_GROUP);
441 51256587 : error = xqcheck_update_incore_counts(xqc, xqc->gcounts, id, 1,
442 : nblks, rtblks);
443 51256587 : if (error)
444 0 : goto out_mutex;
445 : }
446 :
447 51257323 : if (xqc->pcounts) {
448 51256969 : id = xfs_qm_id_for_quotatype(ip, XFS_DQTYPE_PROJ);
449 51256969 : error = xqcheck_update_incore_counts(xqc, xqc->pcounts, id, 1,
450 : nblks, rtblks);
451 51256969 : if (error)
452 0 : goto out_mutex;
453 : }
454 51257323 : mutex_unlock(&xqc->lock);
455 :
456 51257323 : xchk_iscan_mark_visited(&xqc->iscan, ip);
457 51257323 : 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 51257323 : out_ilock:
466 51257323 : xfs_iunlock(ip, ilock_flags);
467 51257323 : if (isreg)
468 23718706 : xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
469 51257323 : xfs_iunlock(ip, XFS_IOLOCK_SHARED);
470 51257323 : return error;
471 : }
472 :
473 : /* Walk all the allocated inodes and run a quota scan on them. */
474 : STATIC int
475 7647 : xqcheck_collect_counts(
476 : struct xqcheck *xqc)
477 : {
478 7647 : struct xfs_scrub *sc = xqc->sc;
479 7647 : struct xfs_inode *ip;
480 7647 : 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 7647 : xchk_trans_cancel(sc);
499 7647 : error = xchk_trans_alloc_empty(sc);
500 7647 : if (error)
501 : return error;
502 :
503 51287835 : while ((error = xchk_iscan_iter(&xqc->iscan, &ip)) == 1) {
504 51280189 : error = xqcheck_collect_inode(xqc, ip);
505 51280189 : xchk_irele(sc, ip);
506 51280189 : if (error)
507 : break;
508 :
509 51280189 : if (xchk_should_terminate(sc, &error))
510 : break;
511 : }
512 7647 : xchk_iscan_iter_finish(&xqc->iscan);
513 7647 : if (error) {
514 1 : 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 1 : if (error == -EBUSY)
521 : return -ECANCELED;
522 1 : return error;
523 : }
524 :
525 : /*
526 : * Switch out for a real transaction in preparation for building a new
527 : * tree.
528 : */
529 7646 : xchk_trans_cancel(sc);
530 7646 : 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 10110908 : xqcheck_compare_dquot(
546 : struct xfs_dquot *dqp,
547 : xfs_dqtype_t dqtype,
548 : void *priv)
549 : {
550 10110908 : struct xqcheck_dquot xcdq;
551 10110908 : struct xqcheck *xqc = priv;
552 10110908 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
553 10110908 : int error;
554 :
555 10110908 : if (xchk_iscan_aborted(&xqc->iscan)) {
556 0 : xchk_set_incomplete(xqc->sc);
557 0 : return -ECANCELED;
558 : }
559 :
560 10110908 : mutex_lock(&xqc->lock);
561 10110908 : error = xfarray_load_sparse(counts, dqp->q_id, &xcdq);
562 10110908 : if (error)
563 0 : goto out_unlock;
564 :
565 10110908 : if (xcdq.icount != dqp->q_ino.count)
566 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
567 :
568 10110908 : if (xcdq.bcount != dqp->q_blk.count)
569 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
570 :
571 10110908 : if (xcdq.rtbcount != dqp->q_rtb.count)
572 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, dqp->q_id);
573 :
574 10110908 : xcdq.flags |= (XQCHECK_DQUOT_COMPARE_SCANNED | XQCHECK_DQUOT_WRITTEN);
575 10110908 : error = xfarray_store(counts, dqp->q_id, &xcdq);
576 10110908 : 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 10110908 : mutex_unlock(&xqc->lock);
587 10110908 : if (error)
588 : return error;
589 :
590 10110908 : 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 22857 : xqcheck_walk_observations(
606 : struct xqcheck *xqc,
607 : xfs_dqtype_t dqtype)
608 : {
609 22857 : struct xqcheck_dquot xcdq;
610 22857 : struct xfs_dquot *dqp;
611 22857 : struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
612 22857 : xfarray_idx_t cur = XFARRAY_CURSOR_INIT;
613 22857 : int error;
614 :
615 22857 : mutex_lock(&xqc->lock);
616 10133762 : while ((error = xfarray_iter(counts, &cur, &xcdq)) == 1) {
617 10110908 : xfs_dqid_t id = cur - 1;
618 :
619 10110908 : if (xcdq.flags & XQCHECK_DQUOT_COMPARE_SCANNED)
620 22857 : continue;
621 :
622 10088051 : mutex_unlock(&xqc->lock);
623 :
624 10088051 : error = xfs_qm_dqget(xqc->sc->mp, id, dqtype, false, &dqp);
625 10088051 : if (error == -ENOENT) {
626 0 : xchk_qcheck_set_corrupt(xqc->sc, dqtype, id);
627 0 : return 0;
628 : }
629 10088051 : if (error)
630 0 : return error;
631 :
632 10088051 : error = xqcheck_compare_dquot(dqp, dqtype, xqc);
633 10088051 : xfs_qm_dqput(dqp);
634 10088051 : if (error)
635 0 : return error;
636 :
637 10088051 : if (xchk_should_terminate(xqc->sc, &error))
638 3 : return error;
639 :
640 10088048 : mutex_lock(&xqc->lock);
641 : }
642 22854 : mutex_unlock(&xqc->lock);
643 :
644 22854 : return error;
645 : }
646 :
647 : /* Compare the quota counters we observed against the live dquots. */
648 : STATIC int
649 22857 : xqcheck_compare_dqtype(
650 : struct xqcheck *xqc,
651 : xfs_dqtype_t dqtype)
652 : {
653 22857 : struct xfs_scrub *sc = xqc->sc;
654 22857 : int error;
655 :
656 22857 : 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 45714 : 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 22857 : error = xfs_qm_dqiterate(sc->mp, dqtype, xqcheck_compare_dquot, xqc);
667 22857 : if (error)
668 : return error;
669 :
670 : /* Walk all the observed dquots and compare to the incore ones. */
671 22857 : return xqcheck_walk_observations(xqc, dqtype);
672 : }
673 :
674 : /* Tear down everything associated with a quotacheck. */
675 : static void
676 7647 : xqcheck_teardown_scan(
677 : void *priv)
678 : {
679 7647 : struct xqcheck *xqc = priv;
680 7647 : struct xfs_quotainfo *qi = xqc->sc->mp->m_quotainfo;
681 :
682 : /* Discourage any hook functions that might be running. */
683 7647 : 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 7647 : xfs_dqtrx_hook_del(qi, &xqc->hooks);
694 :
695 7647 : if (xqc->shadow_dquot_acct.key_len) {
696 7647 : rhashtable_free_and_destroy(&xqc->shadow_dquot_acct,
697 : xqcheck_dqacct_free, NULL);
698 7647 : xqc->shadow_dquot_acct.key_len = 0;
699 : }
700 :
701 7647 : if (xqc->pcounts) {
702 7611 : xfarray_destroy(xqc->pcounts);
703 7611 : xqc->pcounts = NULL;
704 : }
705 :
706 7647 : if (xqc->gcounts) {
707 7617 : xfarray_destroy(xqc->gcounts);
708 7617 : xqc->gcounts = NULL;
709 : }
710 :
711 7647 : if (xqc->ucounts) {
712 7635 : xfarray_destroy(xqc->ucounts);
713 7635 : xqc->ucounts = NULL;
714 : }
715 :
716 7647 : xchk_iscan_teardown(&xqc->iscan);
717 7647 : mutex_destroy(&xqc->lock);
718 7647 : xqc->sc = NULL;
719 7647 : }
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 7647 : xqcheck_setup_scan(
728 : struct xfs_scrub *sc,
729 : struct xqcheck *xqc)
730 : {
731 7647 : char *descr;
732 7647 : struct xfs_quotainfo *qi = sc->mp->m_quotainfo;
733 7647 : unsigned long long max_dquots = ((xfs_dqid_t)-1) + 1;
734 7647 : int error;
735 :
736 7647 : ASSERT(xqc->sc == NULL);
737 7647 : xqc->sc = sc;
738 :
739 7647 : mutex_init(&xqc->lock);
740 :
741 : /* Retry iget every tenth of a second for up to 30 seconds. */
742 7647 : xchk_iscan_start(sc, 30000, 100, &xqc->iscan);
743 :
744 7647 : error = -ENOMEM;
745 7647 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_USER)) {
746 7635 : descr = xchk_xfile_descr(sc, "user dquot records");
747 7635 : error = xfarray_create(descr, max_dquots,
748 : sizeof(struct xqcheck_dquot), &xqc->ucounts);
749 7635 : kfree(descr);
750 7635 : if (error)
751 0 : goto out_teardown;
752 : }
753 :
754 7647 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_GROUP)) {
755 7617 : descr = xchk_xfile_descr(sc, "group dquot records");
756 7617 : error = xfarray_create(descr, max_dquots,
757 : sizeof(struct xqcheck_dquot), &xqc->gcounts);
758 7617 : kfree(descr);
759 7617 : if (error)
760 0 : goto out_teardown;
761 : }
762 :
763 7647 : if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_PROJ)) {
764 7611 : descr = xchk_xfile_descr(sc, "project dquot records");
765 7611 : error = xfarray_create(descr, max_dquots,
766 : sizeof(struct xqcheck_dquot), &xqc->pcounts);
767 7611 : kfree(descr);
768 7611 : 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 7647 : error = rhashtable_init(&xqc->shadow_dquot_acct,
777 : &xqcheck_dqacct_hash_params);
778 7647 : 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 7647 : ASSERT(sc->flags & XCHK_FSGATES_QUOTA);
792 7647 : xfs_hook_setup(&xqc->hooks.mod_hook, xqcheck_mod_live_ino_dqtrx);
793 7647 : xfs_hook_setup(&xqc->hooks.apply_hook, xqcheck_apply_live_dqtrx);
794 :
795 7647 : error = xfs_dqtrx_hook_add(qi, &xqc->hooks);
796 7647 : if (error)
797 0 : goto out_teardown;
798 :
799 : /* Use deferred cleanup to pass the quota count data to repair. */
800 7647 : sc->buf_cleanup = xqcheck_teardown_scan;
801 7647 : 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 7647 : xchk_quotacheck(
811 : struct xfs_scrub *sc)
812 : {
813 7647 : struct xqcheck *xqc = sc->buf;
814 7647 : int error = 0;
815 :
816 : /* Check quota counters on the live filesystem. */
817 7647 : error = xqcheck_setup_scan(sc, xqc);
818 7647 : if (error)
819 : return error;
820 :
821 : /* Walk all inodes, picking up quota information. */
822 7647 : error = xqcheck_collect_counts(xqc);
823 7647 : if (!xchk_xref_process_error(sc, 0, 0, &error))
824 1 : return error;
825 :
826 : /* Fail fast if we're not playing with a full dataset. */
827 7646 : if (xchk_iscan_aborted(&xqc->iscan))
828 0 : xchk_set_incomplete(sc);
829 7646 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
830 : return 0;
831 :
832 : /* Compare quota counters. */
833 7646 : if (xqc->ucounts) {
834 7634 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_USER);
835 7634 : if (!xchk_xref_process_error(sc, 0, 0, &error))
836 0 : return error;
837 : }
838 7646 : if (xqc->gcounts) {
839 7616 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_GROUP);
840 7616 : if (!xchk_xref_process_error(sc, 0, 0, &error))
841 3 : return error;
842 : }
843 7643 : if (xqc->pcounts) {
844 7607 : error = xqcheck_compare_dqtype(xqc, XFS_DQTYPE_PROJ);
845 7607 : 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 7643 : if (xchk_iscan_aborted(&xqc->iscan))
851 0 : xchk_set_incomplete(sc);
852 :
853 : return 0;
854 : }
|