1
2
3
4
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_defer.h"
13#include "xfs_btree.h"
14#include "xfs_bit.h"
15#include "xfs_log_format.h"
16#include "xfs_trans.h"
17#include "xfs_sb.h"
18#include "xfs_inode.h"
19#include "xfs_icache.h"
20#include "xfs_alloc.h"
21#include "xfs_alloc_btree.h"
22#include "xfs_ialloc.h"
23#include "xfs_ialloc_btree.h"
24#include "xfs_rmap.h"
25#include "xfs_rmap_btree.h"
26#include "xfs_refcount.h"
27#include "xfs_refcount_btree.h"
28#include "xfs_extent_busy.h"
29#include "xfs_ag_resv.h"
30#include "xfs_trans_space.h"
31#include "xfs_quota.h"
32#include "xfs_attr.h"
33#include "xfs_reflink.h"
34#include "scrub/xfs_scrub.h"
35#include "scrub/scrub.h"
36#include "scrub/common.h"
37#include "scrub/trace.h"
38#include "scrub/repair.h"
39#include "scrub/bitmap.h"
40
41
42
43
44
45
46int
47xrep_attempt(
48 struct xfs_inode *ip,
49 struct xfs_scrub *sc)
50{
51 int error = 0;
52
53 trace_xrep_attempt(ip, sc->sm, error);
54
55 xchk_ag_btcur_free(&sc->sa);
56
57
58 ASSERT(sc->ops->repair);
59 error = sc->ops->repair(sc);
60 trace_xrep_done(ip, sc->sm, error);
61 switch (error) {
62 case 0:
63
64
65
66
67 sc->sm->sm_flags &= ~XFS_SCRUB_FLAGS_OUT;
68 sc->flags |= XREP_ALREADY_FIXED;
69 return -EAGAIN;
70 case -EDEADLOCK:
71 case -EAGAIN:
72
73 if (!(sc->flags & XCHK_TRY_HARDER)) {
74 sc->flags |= XCHK_TRY_HARDER;
75 return -EAGAIN;
76 }
77
78
79
80
81
82 return -EFSCORRUPTED;
83 default:
84 return error;
85 }
86}
87
88
89
90
91
92
93
94
95
96
97void
98xrep_failure(
99 struct xfs_mount *mp)
100{
101 xfs_alert_ratelimited(mp,
102"Corruption not fixed during online repair. Unmount and run xfs_repair.");
103}
104
105
106
107
108
109int
110xrep_probe(
111 struct xfs_scrub *sc)
112{
113 int error = 0;
114
115 if (xchk_should_terminate(sc, &error))
116 return error;
117
118 return 0;
119}
120
121
122
123
124
125int
126xrep_roll_ag_trans(
127 struct xfs_scrub *sc)
128{
129 int error;
130
131
132 if (sc->sa.agi_bp)
133 xfs_trans_bhold(sc->tp, sc->sa.agi_bp);
134 if (sc->sa.agf_bp)
135 xfs_trans_bhold(sc->tp, sc->sa.agf_bp);
136 if (sc->sa.agfl_bp)
137 xfs_trans_bhold(sc->tp, sc->sa.agfl_bp);
138
139
140
141
142
143
144
145
146 error = xfs_trans_roll(&sc->tp);
147 if (error)
148 return error;
149
150
151 if (sc->sa.agi_bp)
152 xfs_trans_bjoin(sc->tp, sc->sa.agi_bp);
153 if (sc->sa.agf_bp)
154 xfs_trans_bjoin(sc->tp, sc->sa.agf_bp);
155 if (sc->sa.agfl_bp)
156 xfs_trans_bjoin(sc->tp, sc->sa.agfl_bp);
157
158 return 0;
159}
160
161
162
163
164
165
166bool
167xrep_ag_has_space(
168 struct xfs_perag *pag,
169 xfs_extlen_t nr_blocks,
170 enum xfs_ag_resv_type type)
171{
172 return !xfs_ag_resv_critical(pag, XFS_AG_RESV_RMAPBT) &&
173 !xfs_ag_resv_critical(pag, XFS_AG_RESV_METADATA) &&
174 pag->pagf_freeblks > xfs_ag_resv_needed(pag, type) + nr_blocks;
175}
176
177
178
179
180
181
182xfs_extlen_t
183xrep_calc_ag_resblks(
184 struct xfs_scrub *sc)
185{
186 struct xfs_mount *mp = sc->mp;
187 struct xfs_scrub_metadata *sm = sc->sm;
188 struct xfs_perag *pag;
189 struct xfs_buf *bp;
190 xfs_agino_t icount = NULLAGINO;
191 xfs_extlen_t aglen = NULLAGBLOCK;
192 xfs_extlen_t usedlen;
193 xfs_extlen_t freelen;
194 xfs_extlen_t bnobt_sz;
195 xfs_extlen_t inobt_sz;
196 xfs_extlen_t rmapbt_sz;
197 xfs_extlen_t refcbt_sz;
198 int error;
199
200 if (!(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR))
201 return 0;
202
203 pag = xfs_perag_get(mp, sm->sm_agno);
204 if (pag->pagi_init) {
205
206 icount = pag->pagi_count;
207 } else {
208
209 error = xfs_ialloc_read_agi(mp, NULL, sm->sm_agno, &bp);
210 if (!error) {
211 icount = pag->pagi_count;
212 xfs_buf_relse(bp);
213 }
214 }
215
216
217 error = xfs_alloc_read_agf(mp, NULL, sm->sm_agno, 0, &bp);
218 if (!error) {
219 aglen = be32_to_cpu(XFS_BUF_TO_AGF(bp)->agf_length);
220 freelen = be32_to_cpu(XFS_BUF_TO_AGF(bp)->agf_freeblks);
221 usedlen = aglen - freelen;
222 xfs_buf_relse(bp);
223 }
224 xfs_perag_put(pag);
225
226
227 if (icount == NULLAGINO ||
228 !xfs_verify_agino(mp, sm->sm_agno, icount)) {
229 xfs_agino_t first, last;
230
231 xfs_agino_range(mp, sm->sm_agno, &first, &last);
232 icount = last - first + 1;
233 }
234
235
236 if (aglen == NULLAGBLOCK ||
237 aglen != xfs_ag_block_count(mp, sm->sm_agno) ||
238 freelen >= aglen) {
239 aglen = xfs_ag_block_count(mp, sm->sm_agno);
240 freelen = aglen;
241 usedlen = aglen;
242 }
243
244 trace_xrep_calc_ag_resblks(mp, sm->sm_agno, icount, aglen,
245 freelen, usedlen);
246
247
248
249
250
251
252 bnobt_sz = 2 * xfs_allocbt_calc_size(mp, freelen);
253 if (xfs_sb_version_hassparseinodes(&mp->m_sb))
254 inobt_sz = xfs_iallocbt_calc_size(mp, icount /
255 XFS_INODES_PER_HOLEMASK_BIT);
256 else
257 inobt_sz = xfs_iallocbt_calc_size(mp, icount /
258 XFS_INODES_PER_CHUNK);
259 if (xfs_sb_version_hasfinobt(&mp->m_sb))
260 inobt_sz *= 2;
261 if (xfs_sb_version_hasreflink(&mp->m_sb))
262 refcbt_sz = xfs_refcountbt_calc_size(mp, usedlen);
263 else
264 refcbt_sz = 0;
265 if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
266
267
268
269
270
271
272
273
274 if (xfs_sb_version_hasreflink(&mp->m_sb))
275 rmapbt_sz = xfs_rmapbt_calc_size(mp,
276 (unsigned long long)aglen * 2);
277 else
278 rmapbt_sz = xfs_rmapbt_calc_size(mp, usedlen);
279 } else {
280 rmapbt_sz = 0;
281 }
282
283 trace_xrep_calc_ag_resblks_btsize(mp, sm->sm_agno, bnobt_sz,
284 inobt_sz, rmapbt_sz, refcbt_sz);
285
286 return max(max(bnobt_sz, inobt_sz), max(rmapbt_sz, refcbt_sz));
287}
288
289
290int
291xrep_alloc_ag_block(
292 struct xfs_scrub *sc,
293 const struct xfs_owner_info *oinfo,
294 xfs_fsblock_t *fsbno,
295 enum xfs_ag_resv_type resv)
296{
297 struct xfs_alloc_arg args = {0};
298 xfs_agblock_t bno;
299 int error;
300
301 switch (resv) {
302 case XFS_AG_RESV_AGFL:
303 case XFS_AG_RESV_RMAPBT:
304 error = xfs_alloc_get_freelist(sc->tp, sc->sa.agf_bp, &bno, 1);
305 if (error)
306 return error;
307 if (bno == NULLAGBLOCK)
308 return -ENOSPC;
309 xfs_extent_busy_reuse(sc->mp, sc->sa.agno, bno,
310 1, false);
311 *fsbno = XFS_AGB_TO_FSB(sc->mp, sc->sa.agno, bno);
312 if (resv == XFS_AG_RESV_RMAPBT)
313 xfs_ag_resv_rmapbt_alloc(sc->mp, sc->sa.agno);
314 return 0;
315 default:
316 break;
317 }
318
319 args.tp = sc->tp;
320 args.mp = sc->mp;
321 args.oinfo = *oinfo;
322 args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.agno, 0);
323 args.minlen = 1;
324 args.maxlen = 1;
325 args.prod = 1;
326 args.type = XFS_ALLOCTYPE_THIS_AG;
327 args.resv = resv;
328
329 error = xfs_alloc_vextent(&args);
330 if (error)
331 return error;
332 if (args.fsbno == NULLFSBLOCK)
333 return -ENOSPC;
334 ASSERT(args.len == 1);
335 *fsbno = args.fsbno;
336
337 return 0;
338}
339
340
341int
342xrep_init_btblock(
343 struct xfs_scrub *sc,
344 xfs_fsblock_t fsb,
345 struct xfs_buf **bpp,
346 xfs_btnum_t btnum,
347 const struct xfs_buf_ops *ops)
348{
349 struct xfs_trans *tp = sc->tp;
350 struct xfs_mount *mp = sc->mp;
351 struct xfs_buf *bp;
352
353 trace_xrep_init_btblock(mp, XFS_FSB_TO_AGNO(mp, fsb),
354 XFS_FSB_TO_AGBNO(mp, fsb), btnum);
355
356 ASSERT(XFS_FSB_TO_AGNO(mp, fsb) == sc->sa.agno);
357 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, fsb),
358 XFS_FSB_TO_BB(mp, 1), 0);
359 xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
360 xfs_btree_init_block(mp, bp, btnum, 0, 0, sc->sa.agno, 0);
361 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_BTREE_BUF);
362 xfs_trans_log_buf(tp, bp, 0, bp->b_length);
363 bp->b_ops = ops;
364 *bpp = bp;
365
366 return 0;
367}
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438int
439xrep_invalidate_blocks(
440 struct xfs_scrub *sc,
441 struct xfs_bitmap *bitmap)
442{
443 struct xfs_bitmap_range *bmr;
444 struct xfs_bitmap_range *n;
445 struct xfs_buf *bp;
446 xfs_fsblock_t fsbno;
447
448
449
450
451
452
453
454
455
456 for_each_xfs_bitmap_block(fsbno, bmr, n, bitmap) {
457
458 if (!xfs_verify_fsbno(sc->mp, fsbno))
459 continue;
460 bp = xfs_buf_incore(sc->mp->m_ddev_targp,
461 XFS_FSB_TO_DADDR(sc->mp, fsbno),
462 XFS_FSB_TO_BB(sc->mp, 1), XBF_TRYLOCK);
463 if (bp) {
464 xfs_trans_bjoin(sc->tp, bp);
465 xfs_trans_binval(sc->tp, bp);
466 }
467 }
468
469 return 0;
470}
471
472
473int
474xrep_fix_freelist(
475 struct xfs_scrub *sc,
476 bool can_shrink)
477{
478 struct xfs_alloc_arg args = {0};
479
480 args.mp = sc->mp;
481 args.tp = sc->tp;
482 args.agno = sc->sa.agno;
483 args.alignment = 1;
484 args.pag = sc->sa.pag;
485
486 return xfs_alloc_fix_freelist(&args,
487 can_shrink ? 0 : XFS_ALLOC_FLAG_NOSHRINK);
488}
489
490
491
492
493STATIC int
494xrep_put_freelist(
495 struct xfs_scrub *sc,
496 xfs_agblock_t agbno)
497{
498 int error;
499
500
501 error = xrep_fix_freelist(sc, true);
502 if (error)
503 return error;
504
505
506
507
508
509
510 error = xfs_rmap_alloc(sc->tp, sc->sa.agf_bp, sc->sa.agno, agbno, 1,
511 &XFS_RMAP_OINFO_AG);
512 if (error)
513 return error;
514
515
516 error = xfs_alloc_put_freelist(sc->tp, sc->sa.agf_bp, sc->sa.agfl_bp,
517 agbno, 0);
518 if (error)
519 return error;
520 xfs_extent_busy_insert(sc->tp, sc->sa.agno, agbno, 1,
521 XFS_EXTENT_BUSY_SKIP_DISCARD);
522
523 return 0;
524}
525
526
527STATIC int
528xrep_reap_block(
529 struct xfs_scrub *sc,
530 xfs_fsblock_t fsbno,
531 const struct xfs_owner_info *oinfo,
532 enum xfs_ag_resv_type resv)
533{
534 struct xfs_btree_cur *cur;
535 struct xfs_buf *agf_bp = NULL;
536 xfs_agnumber_t agno;
537 xfs_agblock_t agbno;
538 bool has_other_rmap;
539 int error;
540
541 agno = XFS_FSB_TO_AGNO(sc->mp, fsbno);
542 agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno);
543
544
545
546
547
548
549 if (sc->ip) {
550 error = xfs_alloc_read_agf(sc->mp, sc->tp, agno, 0, &agf_bp);
551 if (error)
552 return error;
553 if (!agf_bp)
554 return -ENOMEM;
555 } else {
556 agf_bp = sc->sa.agf_bp;
557 }
558 cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, agf_bp, agno);
559
560
561 error = xfs_rmap_has_other_keys(cur, agbno, 1, oinfo, &has_other_rmap);
562 xfs_btree_del_cursor(cur, error);
563 if (error)
564 goto out_free;
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579 if (has_other_rmap)
580 error = xfs_rmap_free(sc->tp, agf_bp, agno, agbno, 1, oinfo);
581 else if (resv == XFS_AG_RESV_AGFL)
582 error = xrep_put_freelist(sc, agbno);
583 else
584 error = xfs_free_extent(sc->tp, fsbno, 1, oinfo, resv);
585 if (agf_bp != sc->sa.agf_bp)
586 xfs_trans_brelse(sc->tp, agf_bp);
587 if (error)
588 return error;
589
590 if (sc->ip)
591 return xfs_trans_roll_inode(&sc->tp, sc->ip);
592 return xrep_roll_ag_trans(sc);
593
594out_free:
595 if (agf_bp != sc->sa.agf_bp)
596 xfs_trans_brelse(sc->tp, agf_bp);
597 return error;
598}
599
600
601int
602xrep_reap_extents(
603 struct xfs_scrub *sc,
604 struct xfs_bitmap *bitmap,
605 const struct xfs_owner_info *oinfo,
606 enum xfs_ag_resv_type type)
607{
608 struct xfs_bitmap_range *bmr;
609 struct xfs_bitmap_range *n;
610 xfs_fsblock_t fsbno;
611 int error = 0;
612
613 ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb));
614
615 for_each_xfs_bitmap_block(fsbno, bmr, n, bitmap) {
616 ASSERT(sc->ip != NULL ||
617 XFS_FSB_TO_AGNO(sc->mp, fsbno) == sc->sa.agno);
618 trace_xrep_dispose_btree_extent(sc->mp,
619 XFS_FSB_TO_AGNO(sc->mp, fsbno),
620 XFS_FSB_TO_AGBNO(sc->mp, fsbno), 1);
621
622 error = xrep_reap_block(sc, fsbno, oinfo, type);
623 if (error)
624 goto out;
625 }
626
627out:
628 xfs_bitmap_destroy(bitmap);
629 return error;
630}
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659struct xrep_findroot {
660 struct xfs_scrub *sc;
661 struct xfs_buf *agfl_bp;
662 struct xfs_agf *agf;
663 struct xrep_find_ag_btree *btree_info;
664};
665
666
667STATIC int
668xrep_findroot_agfl_walk(
669 struct xfs_mount *mp,
670 xfs_agblock_t bno,
671 void *priv)
672{
673 xfs_agblock_t *agbno = priv;
674
675 return (*agbno == bno) ? XFS_BTREE_QUERY_RANGE_ABORT : 0;
676}
677
678
679STATIC int
680xrep_findroot_block(
681 struct xrep_findroot *ri,
682 struct xrep_find_ag_btree *fab,
683 uint64_t owner,
684 xfs_agblock_t agbno,
685 bool *done_with_block)
686{
687 struct xfs_mount *mp = ri->sc->mp;
688 struct xfs_buf *bp;
689 struct xfs_btree_block *btblock;
690 xfs_daddr_t daddr;
691 int block_level;
692 int error = 0;
693
694 daddr = XFS_AGB_TO_DADDR(mp, ri->sc->sa.agno, agbno);
695
696
697
698
699
700
701
702 if (owner == XFS_RMAP_OWN_AG) {
703 error = xfs_agfl_walk(mp, ri->agf, ri->agfl_bp,
704 xrep_findroot_agfl_walk, &agbno);
705 if (error == XFS_BTREE_QUERY_RANGE_ABORT)
706 return 0;
707 if (error)
708 return error;
709 }
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729 error = xfs_trans_read_buf(mp, ri->sc->tp, mp->m_ddev_targp, daddr,
730 mp->m_bsize, 0, &bp, NULL);
731 if (error)
732 return error;
733
734
735 btblock = XFS_BUF_TO_BLOCK(bp);
736 ASSERT(fab->buf_ops->magic[1] != 0);
737 if (btblock->bb_magic != fab->buf_ops->magic[1])
738 goto out;
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754 if (bp->b_ops) {
755 if (bp->b_ops != fab->buf_ops)
756 goto out;
757 } else {
758 ASSERT(!xfs_trans_buf_is_dirty(bp));
759 if (!uuid_equal(&btblock->bb_u.s.bb_uuid,
760 &mp->m_sb.sb_meta_uuid))
761 goto out;
762
763
764
765
766
767 bp->b_ops = fab->buf_ops;
768 fab->buf_ops->verify_read(bp);
769 if (bp->b_error) {
770 bp->b_ops = NULL;
771 bp->b_error = 0;
772 goto out;
773 }
774
775
776
777
778
779 }
780
781
782
783
784
785 *done_with_block = true;
786
787
788
789
790
791
792
793
794
795
796
797 block_level = xfs_btree_get_level(btblock);
798 if (block_level + 1 == fab->height) {
799 fab->root = NULLAGBLOCK;
800 goto out;
801 } else if (block_level < fab->height) {
802 goto out;
803 }
804
805
806
807
808
809
810 fab->height = block_level + 1;
811
812
813
814
815
816
817 if (btblock->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK) &&
818 btblock->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK))
819 fab->root = agbno;
820 else
821 fab->root = NULLAGBLOCK;
822
823 trace_xrep_findroot_block(mp, ri->sc->sa.agno, agbno,
824 be32_to_cpu(btblock->bb_magic), fab->height - 1);
825out:
826 xfs_trans_brelse(ri->sc->tp, bp);
827 return error;
828}
829
830
831
832
833
834STATIC int
835xrep_findroot_rmap(
836 struct xfs_btree_cur *cur,
837 struct xfs_rmap_irec *rec,
838 void *priv)
839{
840 struct xrep_findroot *ri = priv;
841 struct xrep_find_ag_btree *fab;
842 xfs_agblock_t b;
843 bool done;
844 int error = 0;
845
846
847 if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner))
848 return 0;
849
850
851 for (b = 0; b < rec->rm_blockcount; b++) {
852 done = false;
853 for (fab = ri->btree_info; fab->buf_ops; fab++) {
854 if (rec->rm_owner != fab->rmap_owner)
855 continue;
856 error = xrep_findroot_block(ri, fab,
857 rec->rm_owner, rec->rm_startblock + b,
858 &done);
859 if (error)
860 return error;
861 if (done)
862 break;
863 }
864 }
865
866 return 0;
867}
868
869
870int
871xrep_find_ag_btree_roots(
872 struct xfs_scrub *sc,
873 struct xfs_buf *agf_bp,
874 struct xrep_find_ag_btree *btree_info,
875 struct xfs_buf *agfl_bp)
876{
877 struct xfs_mount *mp = sc->mp;
878 struct xrep_findroot ri;
879 struct xrep_find_ag_btree *fab;
880 struct xfs_btree_cur *cur;
881 int error;
882
883 ASSERT(xfs_buf_islocked(agf_bp));
884 ASSERT(agfl_bp == NULL || xfs_buf_islocked(agfl_bp));
885
886 ri.sc = sc;
887 ri.btree_info = btree_info;
888 ri.agf = XFS_BUF_TO_AGF(agf_bp);
889 ri.agfl_bp = agfl_bp;
890 for (fab = btree_info; fab->buf_ops; fab++) {
891 ASSERT(agfl_bp || fab->rmap_owner != XFS_RMAP_OWN_AG);
892 ASSERT(XFS_RMAP_NON_INODE_OWNER(fab->rmap_owner));
893 fab->root = NULLAGBLOCK;
894 fab->height = 0;
895 }
896
897 cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno);
898 error = xfs_rmap_query_all(cur, xrep_findroot_rmap, &ri);
899 xfs_btree_del_cursor(cur, error);
900
901 return error;
902}
903
904
905void
906xrep_force_quotacheck(
907 struct xfs_scrub *sc,
908 uint dqtype)
909{
910 uint flag;
911
912 flag = xfs_quota_chkd_flag(dqtype);
913 if (!(flag & sc->mp->m_qflags))
914 return;
915
916 sc->mp->m_qflags &= ~flag;
917 spin_lock(&sc->mp->m_sb_lock);
918 sc->mp->m_sb.sb_qflags &= ~flag;
919 spin_unlock(&sc->mp->m_sb_lock);
920 xfs_log_sb(sc->tp);
921}
922
923
924
925
926
927
928
929
930
931
932
933int
934xrep_ino_dqattach(
935 struct xfs_scrub *sc)
936{
937 int error;
938
939 error = xfs_qm_dqattach_locked(sc->ip, false);
940 switch (error) {
941 case -EFSBADCRC:
942 case -EFSCORRUPTED:
943 case -ENOENT:
944 xfs_err_ratelimited(sc->mp,
945"inode %llu repair encountered quota error %d, quotacheck forced.",
946 (unsigned long long)sc->ip->i_ino, error);
947 if (XFS_IS_UQUOTA_ON(sc->mp) && !sc->ip->i_udquot)
948 xrep_force_quotacheck(sc, XFS_DQ_USER);
949 if (XFS_IS_GQUOTA_ON(sc->mp) && !sc->ip->i_gdquot)
950 xrep_force_quotacheck(sc, XFS_DQ_GROUP);
951 if (XFS_IS_PQUOTA_ON(sc->mp) && !sc->ip->i_pdquot)
952 xrep_force_quotacheck(sc, XFS_DQ_PROJ);
953
954 case -ESRCH:
955 error = 0;
956 break;
957 default:
958 break;
959 }
960
961 return error;
962}
963