Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Copyright (C) 2018-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_defer.h"
13 : #include "xfs_btree.h"
14 : #include "xfs_btree_staging.h"
15 : #include "xfs_bit.h"
16 : #include "xfs_log_format.h"
17 : #include "xfs_trans.h"
18 : #include "xfs_sb.h"
19 : #include "xfs_inode.h"
20 : #include "xfs_inode_fork.h"
21 : #include "xfs_alloc.h"
22 : #include "xfs_rtalloc.h"
23 : #include "xfs_bmap.h"
24 : #include "xfs_bmap_util.h"
25 : #include "xfs_bmap_btree.h"
26 : #include "xfs_rmap.h"
27 : #include "xfs_rmap_btree.h"
28 : #include "xfs_refcount.h"
29 : #include "xfs_quota.h"
30 : #include "xfs_ialloc.h"
31 : #include "xfs_ag.h"
32 : #include "xfs_reflink.h"
33 : #include "scrub/xfs_scrub.h"
34 : #include "scrub/scrub.h"
35 : #include "scrub/common.h"
36 : #include "scrub/btree.h"
37 : #include "scrub/trace.h"
38 : #include "scrub/repair.h"
39 : #include "scrub/bitmap.h"
40 : #include "scrub/xfile.h"
41 : #include "scrub/xfarray.h"
42 : #include "scrub/newbt.h"
43 : #include "scrub/reap.h"
44 :
45 : /*
46 : * Inode Fork Block Mapping (BMBT) Repair
47 : * ======================================
48 : *
49 : * Gather all the rmap records for the inode and fork we're fixing, reset the
50 : * incore fork, then recreate the btree.
51 : */
52 : struct xrep_bmap {
53 : /* Old bmbt blocks */
54 : struct xfsb_bitmap old_bmbt_blocks;
55 :
56 : /* New fork. */
57 : struct xrep_newbt new_bmapbt;
58 :
59 : /* List of new bmap records. */
60 : struct xfarray *bmap_records;
61 :
62 : struct xfs_scrub *sc;
63 :
64 : /* How many blocks did we find allocated to this file? */
65 : xfs_rfsblock_t nblocks;
66 :
67 : /* How many bmbt blocks did we find for this fork? */
68 : xfs_rfsblock_t old_bmbt_block_count;
69 :
70 : /* get_records()'s position in the free space record array. */
71 : xfarray_idx_t array_cur;
72 :
73 : /* How many real (non-hole, non-delalloc) mappings do we have? */
74 : uint64_t real_mappings;
75 :
76 : /* Which fork are we fixing? */
77 : int whichfork;
78 :
79 : /* Are there shared extents? */
80 : bool shared_extents;
81 :
82 : /* Do we allow unwritten extents? */
83 : bool allow_unwritten;
84 : };
85 :
86 : /* Is this space extent shared? Flag the inode if it is. */
87 : STATIC int
88 254145 : xrep_bmap_discover_shared(
89 : struct xrep_bmap *rb,
90 : xfs_fsblock_t startblock,
91 : xfs_filblks_t blockcount,
92 : bool unwritten)
93 : {
94 254145 : struct xfs_scrub *sc = rb->sc;
95 254145 : xfs_agblock_t agbno;
96 254145 : xfs_agblock_t fbno;
97 254145 : xfs_extlen_t flen;
98 254145 : int error;
99 :
100 : /*
101 : * Only investigate if we need to set the shared extents flag if we are
102 : * adding a written extent mapping to the data fork of a regular file
103 : * on reflink filesystem.
104 : */
105 254145 : if (rb->shared_extents)
106 : return 0;
107 159094 : if (unwritten)
108 : return 0;
109 136209 : if (rb->whichfork != XFS_DATA_FORK)
110 : return 0;
111 104930 : if (!S_ISREG(VFS_I(sc->ip)->i_mode))
112 : return 0;
113 100178 : if (!xfs_has_reflink(sc->mp))
114 : return 0;
115 100178 : if (XFS_IS_REALTIME_INODE(sc->ip))
116 : return 0;
117 :
118 100178 : agbno = XFS_FSB_TO_AGBNO(sc->mp, startblock);
119 100178 : error = xfs_refcount_find_shared(sc->sa.refc_cur, agbno, blockcount,
120 : &fbno, &flen, false);
121 100178 : if (error)
122 : return error;
123 :
124 100178 : if (fbno != NULLAGBLOCK)
125 0 : rb->shared_extents = true;
126 :
127 : return 0;
128 : }
129 :
130 : /* Remember this reverse-mapping as a series of bmap records. */
131 : STATIC int
132 254145 : xrep_bmap_from_rmap(
133 : struct xrep_bmap *rb,
134 : xfs_fileoff_t startoff,
135 : xfs_fsblock_t startblock,
136 : xfs_filblks_t blockcount,
137 : bool unwritten)
138 : {
139 254145 : struct xfs_bmbt_irec irec = {
140 : .br_startoff = startoff,
141 : .br_startblock = startblock,
142 254145 : .br_state = unwritten ? XFS_EXT_UNWRITTEN : XFS_EXT_NORM,
143 : };
144 254145 : struct xfs_bmbt_rec rbe;
145 254145 : struct xfs_scrub *sc = rb->sc;
146 254145 : int error = 0;
147 :
148 : /*
149 : * If we're repairing the data fork of a non-reflinked regular file on
150 : * a reflink filesystem, we need to figure out if this space extent is
151 : * shared.
152 : */
153 254145 : error = xrep_bmap_discover_shared(rb, startblock, blockcount,
154 : unwritten);
155 254145 : if (error)
156 : return error;
157 :
158 254145 : do {
159 254145 : xfs_failaddr_t fa;
160 :
161 254145 : irec.br_blockcount = min_t(xfs_filblks_t, blockcount,
162 : XFS_MAX_BMBT_EXTLEN);
163 :
164 254145 : fa = xfs_bmap_validate_extent(sc->ip, rb->whichfork, &irec);
165 254144 : if (fa)
166 : return -EFSCORRUPTED;
167 :
168 254144 : xfs_bmbt_disk_set_all(&rbe, &irec);
169 :
170 254144 : trace_xrep_bmap_found(sc->ip, rb->whichfork, &irec);
171 :
172 254144 : if (xchk_should_terminate(sc, &error))
173 0 : return error;
174 :
175 254145 : error = xfarray_append(rb->bmap_records, &rbe);
176 254145 : if (error)
177 0 : return error;
178 :
179 254145 : rb->real_mappings++;
180 :
181 254145 : irec.br_startblock += irec.br_blockcount;
182 254145 : irec.br_startoff += irec.br_blockcount;
183 254145 : blockcount -= irec.br_blockcount;
184 254145 : } while (blockcount > 0);
185 :
186 : return 0;
187 : }
188 :
189 : /* Check for any obvious errors or conflicts in the file mapping. */
190 : STATIC int
191 270386 : xrep_bmap_check_fork_rmap(
192 : struct xrep_bmap *rb,
193 : struct xfs_btree_cur *cur,
194 : const struct xfs_rmap_irec *rec)
195 : {
196 270386 : struct xfs_scrub *sc = rb->sc;
197 270386 : enum xbtree_recpacking outcome;
198 270386 : int error;
199 :
200 : /*
201 : * Data extents for rt files are never stored on the data device, but
202 : * everything else (xattrs, bmbt blocks) can be.
203 : */
204 270386 : if (XFS_IS_REALTIME_INODE(sc->ip) &&
205 0 : !(rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)))
206 : return -EFSCORRUPTED;
207 :
208 : /* Check that this is within the AG. */
209 270386 : if (!xfs_verify_agbext(cur->bc_ag.pag, rec->rm_startblock,
210 270386 : rec->rm_blockcount))
211 : return -EFSCORRUPTED;
212 :
213 : /* Check the file offset range. */
214 535110 : if (!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
215 264724 : !xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount))
216 : return -EFSCORRUPTED;
217 :
218 : /* No contradictory flags. */
219 270386 : if ((rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)) &&
220 37668 : (rec->rm_flags & XFS_RMAP_UNWRITTEN))
221 : return -EFSCORRUPTED;
222 :
223 : /* Make sure this isn't free space. */
224 270386 : error = xfs_alloc_has_records(sc->sa.bno_cur, rec->rm_startblock,
225 270386 : rec->rm_blockcount, &outcome);
226 270386 : if (error)
227 : return error;
228 270386 : if (outcome != XBTREE_RECPACKING_EMPTY)
229 : return -EFSCORRUPTED;
230 :
231 : /* Must not be an inode chunk. */
232 270386 : error = xfs_ialloc_has_inodes_at_extent(sc->sa.ino_cur,
233 270386 : rec->rm_startblock, rec->rm_blockcount, &outcome);
234 270386 : if (error)
235 : return error;
236 270386 : if (outcome != XBTREE_RECPACKING_EMPTY)
237 0 : return -EFSCORRUPTED;
238 :
239 : return 0;
240 : }
241 :
242 : /* Record extents that belong to this inode's fork. */
243 : STATIC int
244 3315556385 : xrep_bmap_walk_rmap(
245 : struct xfs_btree_cur *cur,
246 : const struct xfs_rmap_irec *rec,
247 : void *priv)
248 : {
249 3315556385 : struct xrep_bmap *rb = priv;
250 3315556385 : struct xfs_mount *mp = cur->bc_mp;
251 3315556385 : xfs_fsblock_t fsbno;
252 3315556385 : int error = 0;
253 :
254 3315556385 : if (xchk_should_terminate(rb->sc, &error))
255 0 : return error;
256 :
257 3315622005 : if (rec->rm_owner != rb->sc->ip->i_ino)
258 : return 0;
259 :
260 270386 : error = xrep_bmap_check_fork_rmap(rb, cur, rec);
261 270386 : if (error)
262 : return error;
263 :
264 : /*
265 : * Record all blocks allocated to this file even if the extent isn't
266 : * for the fork we're rebuilding so that we can reset di_nblocks later.
267 : */
268 270386 : rb->nblocks += rec->rm_blockcount;
269 :
270 : /* If this rmap isn't for the fork we want, we're done. */
271 270386 : if (rb->whichfork == XFS_DATA_FORK &&
272 228898 : (rec->rm_flags & XFS_RMAP_ATTR_FORK))
273 : return 0;
274 269659 : if (rb->whichfork == XFS_ATTR_FORK &&
275 41488 : !(rec->rm_flags & XFS_RMAP_ATTR_FORK))
276 : return 0;
277 :
278 : /* Reject unwritten extents if we don't allow those. */
279 259450 : if ((rec->rm_flags & XFS_RMAP_UNWRITTEN) && !rb->allow_unwritten)
280 : return -EFSCORRUPTED;
281 :
282 259450 : fsbno = XFS_AGB_TO_FSB(mp, cur->bc_ag.pag->pag_agno,
283 : rec->rm_startblock);
284 :
285 259450 : if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK) {
286 5305 : rb->old_bmbt_block_count += rec->rm_blockcount;
287 5305 : return xfsb_bitmap_set(&rb->old_bmbt_blocks, fsbno,
288 5305 : rec->rm_blockcount);
289 : }
290 :
291 254145 : return xrep_bmap_from_rmap(rb, rec->rm_offset, fsbno,
292 254145 : rec->rm_blockcount,
293 : rec->rm_flags & XFS_RMAP_UNWRITTEN);
294 : }
295 :
296 : /*
297 : * Compare two block mapping records. We want to sort in order of increasing
298 : * file offset.
299 : */
300 : static int
301 1177519 : xrep_bmap_extent_cmp(
302 : const void *a,
303 : const void *b)
304 : {
305 1177519 : xfs_fileoff_t ao;
306 1177519 : xfs_fileoff_t bo;
307 :
308 1177519 : ao = xfs_bmbt_disk_get_startoff((struct xfs_bmbt_rec *)a);
309 1177519 : bo = xfs_bmbt_disk_get_startoff((struct xfs_bmbt_rec *)b);
310 :
311 1177519 : if (ao > bo)
312 : return 1;
313 662661 : else if (ao < bo)
314 662661 : return -1;
315 : return 0;
316 : }
317 :
318 : /*
319 : * Sort the bmap extents by fork offset or else the records will be in the
320 : * wrong order. Ensure there are no overlaps in the file offset ranges.
321 : */
322 : STATIC int
323 60814 : xrep_bmap_sort_records(
324 : struct xrep_bmap *rb)
325 : {
326 60814 : struct xfs_bmbt_irec irec;
327 60814 : xfs_fileoff_t next_off = 0;
328 60814 : xfarray_idx_t array_cur;
329 60814 : int error;
330 :
331 60814 : error = xfarray_sort(rb->bmap_records, xrep_bmap_extent_cmp,
332 : XFARRAY_SORT_KILLABLE);
333 60814 : if (error)
334 : return error;
335 :
336 314959 : foreach_xfarray_idx(rb->bmap_records, array_cur) {
337 254145 : struct xfs_bmbt_rec rec;
338 :
339 254145 : if (xchk_should_terminate(rb->sc, &error))
340 0 : return error;
341 :
342 254145 : error = xfarray_load(rb->bmap_records, array_cur, &rec);
343 254145 : if (error)
344 0 : return error;
345 :
346 254145 : xfs_bmbt_disk_get_all(&rec, &irec);
347 :
348 254145 : if (irec.br_startoff < next_off)
349 : return -EFSCORRUPTED;
350 :
351 254145 : next_off = irec.br_startoff + irec.br_blockcount;
352 : }
353 :
354 : return 0;
355 : }
356 :
357 : /* Scan one AG for reverse mappings that we can turn into extent maps. */
358 : STATIC int
359 243256 : xrep_bmap_scan_ag(
360 : struct xrep_bmap *rb,
361 : struct xfs_perag *pag)
362 : {
363 243256 : struct xfs_scrub *sc = rb->sc;
364 243256 : int error;
365 :
366 243256 : error = xrep_ag_init(sc, pag, &sc->sa);
367 243256 : if (error)
368 : return error;
369 :
370 243256 : error = xfs_rmap_query_all(sc->sa.rmap_cur, xrep_bmap_walk_rmap, rb);
371 243256 : xchk_ag_free(sc, &sc->sa);
372 243256 : return error;
373 : }
374 :
375 : /* Find the delalloc extents from the old incore extent tree. */
376 : STATIC int
377 60814 : xrep_bmap_find_delalloc(
378 : struct xrep_bmap *rb)
379 : {
380 60814 : struct xfs_bmbt_irec irec;
381 60814 : struct xfs_iext_cursor icur;
382 60814 : struct xfs_bmbt_rec rbe;
383 60814 : struct xfs_inode *ip = rb->sc->ip;
384 60814 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, rb->whichfork);
385 60814 : int error = 0;
386 :
387 : /*
388 : * Skip this scan if we don't expect to find delayed allocation
389 : * reservations in this fork.
390 : */
391 60814 : if (rb->whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0)
392 : return 0;
393 :
394 1335 : for_each_xfs_iext(ifp, &icur, &irec) {
395 1252 : if (!isnullstartblock(irec.br_startblock))
396 1252 : continue;
397 :
398 0 : xfs_bmbt_disk_set_all(&rbe, &irec);
399 :
400 0 : trace_xrep_bmap_found(ip, rb->whichfork, &irec);
401 :
402 0 : if (xchk_should_terminate(rb->sc, &error))
403 0 : return error;
404 :
405 0 : error = xfarray_append(rb->bmap_records, &rbe);
406 0 : if (error)
407 0 : return error;
408 : }
409 :
410 : return 0;
411 : }
412 :
413 : /*
414 : * Collect block mappings for this fork of this inode and decide if we have
415 : * enough space to rebuild. Caller is responsible for cleaning up the list if
416 : * anything goes wrong.
417 : */
418 : STATIC int
419 60814 : xrep_bmap_find_mappings(
420 : struct xrep_bmap *rb)
421 : {
422 60814 : struct xfs_scrub *sc = rb->sc;
423 60814 : struct xfs_perag *pag;
424 60814 : xfs_agnumber_t agno;
425 60814 : int error = 0;
426 :
427 : /* Iterate the rmaps for extents. */
428 304070 : for_each_perag(sc->mp, agno, pag) {
429 243256 : error = xrep_bmap_scan_ag(rb, pag);
430 243256 : if (error) {
431 0 : xfs_perag_rele(pag);
432 0 : return error;
433 : }
434 : }
435 :
436 60814 : return xrep_bmap_find_delalloc(rb);
437 : }
438 :
439 : /* Retrieve real extent mappings for bulk loading the bmap btree. */
440 : STATIC int
441 5338 : xrep_bmap_get_records(
442 : struct xfs_btree_cur *cur,
443 : unsigned int idx,
444 : struct xfs_btree_block *block,
445 : unsigned int nr_wanted,
446 : void *priv)
447 : {
448 5338 : struct xfs_bmbt_rec rec;
449 5338 : struct xfs_bmbt_irec *irec = &cur->bc_rec.b;
450 5338 : struct xrep_bmap *rb = priv;
451 5338 : union xfs_btree_rec *block_rec;
452 5338 : unsigned int loaded;
453 5338 : int error;
454 :
455 153291 : for (loaded = 0; loaded < nr_wanted; loaded++, idx++) {
456 147953 : do {
457 147953 : error = xfarray_load(rb->bmap_records, rb->array_cur++,
458 : &rec);
459 147953 : if (error)
460 0 : return error;
461 :
462 147953 : xfs_bmbt_disk_get_all(&rec, irec);
463 147953 : } while (isnullstartblock(irec->br_startblock));
464 :
465 147953 : block_rec = xfs_btree_rec_addr(cur, idx, block);
466 147953 : cur->bc_ops->init_rec_from_cur(cur, block_rec);
467 : }
468 :
469 5338 : return loaded;
470 : }
471 :
472 : /* Feed one of the new btree blocks to the bulk loader. */
473 : STATIC int
474 5340 : xrep_bmap_claim_block(
475 : struct xfs_btree_cur *cur,
476 : union xfs_btree_ptr *ptr,
477 : void *priv)
478 : {
479 5340 : struct xrep_bmap *rb = priv;
480 5340 : int error;
481 :
482 5340 : error = xrep_newbt_relog_autoreap(&rb->new_bmapbt);
483 5340 : if (error)
484 : return error;
485 :
486 5340 : return xrep_newbt_claim_block(cur, &rb->new_bmapbt, ptr);
487 : }
488 :
489 : /* Figure out how much space we need to create the incore btree root block. */
490 : STATIC size_t
491 5163 : xrep_bmap_iroot_size(
492 : struct xfs_btree_cur *cur,
493 : unsigned int level,
494 : unsigned int nr_this_level,
495 : void *priv)
496 : {
497 5163 : ASSERT(level > 0);
498 :
499 5163 : return XFS_BMAP_BROOT_SPACE_CALC(cur->bc_mp, nr_this_level);
500 : }
501 :
502 : /* Update the inode counters. */
503 : STATIC int
504 60814 : xrep_bmap_reset_counters(
505 : struct xrep_bmap *rb)
506 : {
507 60814 : struct xfs_scrub *sc = rb->sc;
508 60814 : struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake;
509 60814 : int64_t delta;
510 :
511 60814 : if (rb->shared_extents)
512 7836 : sc->ip->i_diflags2 |= XFS_DIFLAG2_REFLINK;
513 :
514 : /*
515 : * Update the inode block counts to reflect the extents we found in the
516 : * rmapbt.
517 : */
518 60814 : delta = ifake->if_blocks - rb->old_bmbt_block_count;
519 60814 : sc->ip->i_nblocks = rb->nblocks + delta;
520 60814 : xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE);
521 :
522 : /*
523 : * Adjust the quota counts by the difference in size between the old
524 : * and new bmbt.
525 : */
526 60814 : xfs_trans_mod_dquot_byino(sc->tp, sc->ip, XFS_TRANS_DQ_BCOUNT, delta);
527 60814 : return 0;
528 : }
529 :
530 : /*
531 : * Create a new iext tree and load it with block mappings. If the inode is
532 : * in extents format, that's all we need to do to commit the new mappings.
533 : * If it is in btree format, this takes care of preloading the incore tree.
534 : */
535 : STATIC int
536 60814 : xrep_bmap_extents_load(
537 : struct xrep_bmap *rb)
538 : {
539 60814 : struct xfs_iext_cursor icur;
540 60814 : struct xfs_bmbt_irec irec;
541 60814 : struct xfs_ifork *ifp = rb->new_bmapbt.ifake.if_fork;
542 60814 : xfarray_idx_t array_cur;
543 60814 : int error;
544 :
545 60814 : ASSERT(ifp->if_bytes == 0);
546 :
547 : /* Add all the mappings (incl. delalloc) to the incore extent tree. */
548 60814 : xfs_iext_first(ifp, &icur);
549 375763 : foreach_xfarray_idx(rb->bmap_records, array_cur) {
550 254133 : struct xfs_bmbt_rec rec;
551 :
552 254133 : error = xfarray_load(rb->bmap_records, array_cur, &rec);
553 254138 : if (error)
554 0 : return error;
555 :
556 254138 : xfs_bmbt_disk_get_all(&rec, &irec);
557 :
558 254135 : xfs_iext_insert_raw(ifp, &icur, &irec);
559 254130 : if (!isnullstartblock(irec.br_startblock))
560 254130 : ifp->if_nextents++;
561 :
562 254130 : xfs_iext_next(ifp, &icur);
563 : }
564 :
565 60814 : return xrep_ino_ensure_extent_count(rb->sc, rb->whichfork,
566 : ifp->if_nextents);
567 : }
568 :
569 : /*
570 : * Reserve new btree blocks, bulk load the bmap records into the ondisk btree,
571 : * and load the incore extent tree.
572 : */
573 : STATIC int
574 5163 : xrep_bmap_btree_load(
575 : struct xrep_bmap *rb,
576 : struct xfs_btree_cur *bmap_cur)
577 : {
578 5163 : struct xfs_scrub *sc = rb->sc;
579 5163 : int error;
580 :
581 : /* Compute how many blocks we'll need. */
582 5163 : error = xfs_btree_bload_compute_geometry(bmap_cur,
583 : &rb->new_bmapbt.bload, rb->real_mappings);
584 5163 : if (error)
585 : return error;
586 :
587 : /* Last chance to abort before we start committing fixes. */
588 5163 : if (xchk_should_terminate(sc, &error))
589 0 : return error;
590 :
591 : /*
592 : * Guess how many blocks we're going to need to rebuild an entire bmap
593 : * from the number of extents we found, and pump up our transaction to
594 : * have sufficient block reservation. We're allowed to exceed file
595 : * quota to repair inconsistent metadata.
596 : */
597 10326 : error = xfs_trans_reserve_more_inode(sc->tp, sc->ip,
598 5163 : rb->new_bmapbt.bload.nr_blocks, 0, true);
599 5163 : if (error)
600 : return error;
601 :
602 : /* Reserve the space we'll need for the new btree. */
603 5163 : error = xrep_newbt_alloc_blocks(&rb->new_bmapbt,
604 : rb->new_bmapbt.bload.nr_blocks);
605 5163 : if (error)
606 : return error;
607 :
608 : /* Add all observed bmap records. */
609 5163 : rb->array_cur = XFARRAY_CURSOR_INIT;
610 5163 : error = xfs_btree_bload(bmap_cur, &rb->new_bmapbt.bload, rb);
611 5163 : if (error)
612 : return error;
613 :
614 : /*
615 : * Load the new bmap records into the new incore extent tree to
616 : * preserve delalloc reservations for regular files. The directory
617 : * code loads the extent tree during xfs_dir_open and assumes
618 : * thereafter that it remains loaded, so we must not violate that
619 : * assumption.
620 : */
621 5163 : return xrep_bmap_extents_load(rb);
622 : }
623 :
624 : /*
625 : * Use the collected bmap information to stage a new bmap fork. If this is
626 : * successful we'll return with the new fork information logged to the repair
627 : * transaction but not yet committed. The caller must ensure that the inode
628 : * is joined to the transaction; the inode will be joined to a clean
629 : * transaction when the function returns.
630 : */
631 : STATIC int
632 60814 : xrep_bmap_build_new_fork(
633 : struct xrep_bmap *rb)
634 : {
635 60814 : struct xfs_owner_info oinfo;
636 60814 : struct xfs_scrub *sc = rb->sc;
637 60814 : struct xfs_btree_cur *bmap_cur;
638 60814 : struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake;
639 60814 : int error;
640 :
641 60814 : error = xrep_bmap_sort_records(rb);
642 60814 : if (error)
643 : return error;
644 :
645 : /*
646 : * Prepare to construct the new fork by initializing the new btree
647 : * structure and creating a fake ifork in the ifakeroot structure.
648 : */
649 60814 : xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork);
650 60814 : error = xrep_newbt_init_inode(&rb->new_bmapbt, sc, rb->whichfork,
651 : &oinfo);
652 60814 : if (error)
653 : return error;
654 :
655 60814 : rb->new_bmapbt.bload.get_records = xrep_bmap_get_records;
656 60814 : rb->new_bmapbt.bload.claim_block = xrep_bmap_claim_block;
657 60814 : rb->new_bmapbt.bload.iroot_size = xrep_bmap_iroot_size;
658 60814 : bmap_cur = xfs_bmbt_stage_cursor(sc->mp, sc->ip, ifake);
659 :
660 : /*
661 : * Figure out the size and format of the new fork, then fill it with
662 : * all the bmap records we've found. Join the inode to the transaction
663 : * so that we can roll the transaction while holding the inode locked.
664 : */
665 60814 : if (rb->real_mappings <= XFS_IFORK_MAXEXT(sc->ip, rb->whichfork)) {
666 55651 : ifake->if_fork->if_format = XFS_DINODE_FMT_EXTENTS;
667 55651 : error = xrep_bmap_extents_load(rb);
668 : } else {
669 5163 : ifake->if_fork->if_format = XFS_DINODE_FMT_BTREE;
670 5163 : error = xrep_bmap_btree_load(rb, bmap_cur);
671 : }
672 60814 : if (error)
673 0 : goto err_cur;
674 :
675 : /*
676 : * Install the new fork in the inode. After this point the old mapping
677 : * data are no longer accessible and the new tree is live. We delete
678 : * the cursor immediately after committing the staged root because the
679 : * staged fork might be in extents format.
680 : */
681 60814 : xfs_bmbt_commit_staged_btree(bmap_cur, sc->tp, rb->whichfork);
682 60814 : xfs_btree_del_cursor(bmap_cur, 0);
683 :
684 : /* Reset the inode counters now that we've changed the fork. */
685 60814 : error = xrep_bmap_reset_counters(rb);
686 60814 : if (error)
687 0 : goto err_newbt;
688 :
689 : /* Dispose of any unused blocks and the accounting information. */
690 60814 : error = xrep_newbt_commit(&rb->new_bmapbt);
691 60813 : if (error)
692 : return error;
693 :
694 60813 : return xrep_roll_trans(sc);
695 :
696 : err_cur:
697 0 : if (bmap_cur)
698 0 : xfs_btree_del_cursor(bmap_cur, error);
699 0 : err_newbt:
700 0 : xrep_newbt_cancel(&rb->new_bmapbt);
701 0 : return error;
702 : }
703 :
704 : /*
705 : * Now that we've logged the new inode btree, invalidate all of the old blocks
706 : * and free them, if there were any.
707 : */
708 : STATIC int
709 60814 : xrep_bmap_remove_old_tree(
710 : struct xrep_bmap *rb)
711 : {
712 60814 : struct xfs_scrub *sc = rb->sc;
713 60814 : struct xfs_owner_info oinfo;
714 :
715 : /* Free the old bmbt blocks if they're not in use. */
716 60814 : xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork);
717 60814 : return xrep_reap_fsblocks(sc, &rb->old_bmbt_blocks, &oinfo);
718 : }
719 :
720 : /* Check for garbage inputs. Returns -ECANCELED if there's nothing to do. */
721 : STATIC int
722 6689681 : xrep_bmap_check_inputs(
723 : struct xfs_scrub *sc,
724 : int whichfork)
725 : {
726 6689681 : struct xfs_ifork *ifp = xfs_ifork_ptr(sc->ip, whichfork);
727 :
728 6689676 : ASSERT(whichfork == XFS_DATA_FORK || whichfork == XFS_ATTR_FORK);
729 :
730 6689676 : if (!xfs_has_rmapbt(sc->mp))
731 : return -EOPNOTSUPP;
732 :
733 : /* No fork means nothing to rebuild. */
734 187818 : if (!ifp)
735 : return -ECANCELED;
736 :
737 : /*
738 : * We only know how to repair extent mappings, which is to say that we
739 : * only support extents and btree fork format. Repairs to a local
740 : * format fork require a higher level repair function, so we do not
741 : * have any work to do here.
742 : */
743 187818 : switch (ifp->if_format) {
744 : case XFS_DINODE_FMT_DEV:
745 : case XFS_DINODE_FMT_LOCAL:
746 : case XFS_DINODE_FMT_UUID:
747 : return -ECANCELED;
748 : case XFS_DINODE_FMT_EXTENTS:
749 : case XFS_DINODE_FMT_BTREE:
750 60814 : break;
751 0 : default:
752 0 : return -EFSCORRUPTED;
753 : }
754 :
755 60814 : if (whichfork == XFS_ATTR_FORK)
756 : return 0;
757 :
758 : /* Only files, symlinks, and directories get to have data forks. */
759 30331 : switch (VFS_I(sc->ip)->i_mode & S_IFMT) {
760 : case S_IFREG:
761 : case S_IFDIR:
762 : case S_IFLNK:
763 : /* ok */
764 30331 : break;
765 : default:
766 : return -EINVAL;
767 : }
768 :
769 : /* Don't know how to rebuild realtime data forks. */
770 30331 : if (XFS_IS_REALTIME_INODE(sc->ip))
771 0 : return -EOPNOTSUPP;
772 :
773 : return 0;
774 : }
775 :
776 : /* Repair an inode fork. */
777 : int
778 6689689 : xrep_bmap(
779 : struct xfs_scrub *sc,
780 : int whichfork,
781 : bool allow_unwritten)
782 : {
783 6689689 : struct xrep_bmap *rb;
784 6689689 : char *descr;
785 6689689 : unsigned int max_bmbt_recs;
786 6689689 : bool large_extcount;
787 6689689 : int error = 0;
788 :
789 6689689 : error = xrep_bmap_check_inputs(sc, whichfork);
790 6689706 : if (error == -ECANCELED)
791 : return 0;
792 6562702 : if (error)
793 : return error;
794 :
795 60814 : rb = kzalloc(sizeof(struct xrep_bmap), XCHK_GFP_FLAGS);
796 60814 : if (!rb)
797 : return -ENOMEM;
798 60814 : rb->sc = sc;
799 60814 : rb->whichfork = whichfork;
800 60814 : rb->allow_unwritten = allow_unwritten;
801 :
802 : /*
803 : * No need to waste time scanning for shared extents if the inode is
804 : * already marked.
805 : */
806 60814 : if (whichfork == XFS_DATA_FORK && xfs_is_reflink_inode(sc->ip))
807 7836 : rb->shared_extents = true;
808 :
809 : /* Set up enough storage to handle the max records for this fork. */
810 60814 : large_extcount = xfs_has_large_extent_counts(sc->mp);
811 60814 : max_bmbt_recs = xfs_iext_max_nextents(large_extcount, whichfork);
812 91297 : descr = xchk_xfile_ino_descr(sc, "%s fork mapping records",
813 : whichfork == XFS_DATA_FORK ? "data" : "attr");
814 60814 : error = xfarray_create(descr, max_bmbt_recs,
815 : sizeof(struct xfs_bmbt_rec), &rb->bmap_records);
816 60814 : kfree(descr);
817 60814 : if (error)
818 0 : goto out_rb;
819 :
820 : /* Collect all reverse mappings for this fork's extents. */
821 60814 : xfsb_bitmap_init(&rb->old_bmbt_blocks);
822 60814 : error = xrep_bmap_find_mappings(rb);
823 60814 : if (error)
824 0 : goto out_bitmap;
825 :
826 60814 : xfs_trans_ijoin(sc->tp, sc->ip, 0);
827 :
828 : /* Rebuild the bmap information. */
829 60814 : error = xrep_bmap_build_new_fork(rb);
830 60814 : if (error)
831 0 : goto out_bitmap;
832 :
833 : /* Kill the old tree. */
834 60814 : error = xrep_bmap_remove_old_tree(rb);
835 :
836 60814 : out_bitmap:
837 60814 : xfsb_bitmap_destroy(&rb->old_bmbt_blocks);
838 60814 : xfarray_destroy(rb->bmap_records);
839 60814 : out_rb:
840 60814 : kfree(rb);
841 60814 : return error;
842 : }
843 :
844 : /* Repair an inode's data fork. */
845 : int
846 3328558 : xrep_bmap_data(
847 : struct xfs_scrub *sc)
848 : {
849 3328558 : return xrep_bmap(sc, XFS_DATA_FORK, true);
850 : }
851 :
852 : /* Repair an inode's attr fork. */
853 : int
854 3357850 : xrep_bmap_attr(
855 : struct xfs_scrub *sc)
856 : {
857 3357850 : return xrep_bmap(sc, XFS_ATTR_FORK, false);
858 : }
|