Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */
2 : /*
3 : * Copyright (C) 2021-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_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_bit.h"
13 : #include "xfs_mount.h"
14 : #include "xfs_trans.h"
15 : #include "xfs_buf_item.h"
16 : #include "xfs_btree.h"
17 : #include "xfs_error.h"
18 : #include "xfs_btree_mem.h"
19 : #include "xfs_ag.h"
20 : #include "scrub/scrub.h"
21 : #include "scrub/xfile.h"
22 : #include "scrub/xfbtree.h"
23 : #include "scrub/bitmap.h"
24 : #include "scrub/trace.h"
25 :
26 : /* btree ops functions for in-memory btrees. */
27 :
28 : static xfs_failaddr_t
29 50272 : xfs_btree_mem_head_verify(
30 : struct xfs_buf *bp)
31 : {
32 50272 : struct xfs_btree_mem_head *mhead = bp->b_addr;
33 50272 : struct xfs_mount *mp = bp->b_mount;
34 :
35 50272 : if (!xfs_verify_magic(bp, mhead->mh_magic))
36 0 : return __this_address;
37 50199 : if (be32_to_cpu(mhead->mh_nlevels) == 0)
38 0 : return __this_address;
39 50199 : if (!uuid_equal(&mhead->mh_uuid, &mp->m_sb.sb_meta_uuid))
40 0 : return __this_address;
41 :
42 : return NULL;
43 : }
44 :
45 : static void
46 1 : xfs_btree_mem_head_read_verify(
47 : struct xfs_buf *bp)
48 : {
49 1 : xfs_failaddr_t fa = xfs_btree_mem_head_verify(bp);
50 :
51 1 : if (fa)
52 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
53 1 : }
54 :
55 : static void
56 45841 : xfs_btree_mem_head_write_verify(
57 : struct xfs_buf *bp)
58 : {
59 45841 : xfs_failaddr_t fa = xfs_btree_mem_head_verify(bp);
60 :
61 45746 : if (fa)
62 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
63 45746 : }
64 :
65 : static const struct xfs_buf_ops xfs_btree_mem_head_buf_ops = {
66 : .name = "xfs_btree_mem_head",
67 : .magic = { cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC),
68 : cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC) },
69 : .verify_read = xfs_btree_mem_head_read_verify,
70 : .verify_write = xfs_btree_mem_head_write_verify,
71 : .verify_struct = xfs_btree_mem_head_verify,
72 : };
73 :
74 : /* Initialize the header block for an in-memory btree. */
75 : static inline void
76 45882 : xfs_btree_mem_head_init(
77 : struct xfs_buf *head_bp,
78 : unsigned long long owner,
79 : xfileoff_t leaf_xfoff)
80 : {
81 45882 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
82 45882 : struct xfs_mount *mp = head_bp->b_mount;
83 :
84 45882 : mhead->mh_magic = cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC);
85 45882 : mhead->mh_nlevels = cpu_to_be32(1);
86 45882 : mhead->mh_owner = cpu_to_be64(owner);
87 45882 : mhead->mh_root = cpu_to_be64(leaf_xfoff);
88 45882 : uuid_copy(&mhead->mh_uuid, &mp->m_sb.sb_meta_uuid);
89 :
90 45853 : head_bp->b_ops = &xfs_btree_mem_head_buf_ops;
91 45853 : }
92 :
93 : /* Return tree height from the in-memory btree head. */
94 : unsigned int
95 476018191 : xfs_btree_mem_head_nlevels(
96 : struct xfs_buf *head_bp)
97 : {
98 476018191 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
99 :
100 476018191 : return be32_to_cpu(mhead->mh_nlevels);
101 : }
102 :
103 : /* Extract the buftarg target for this xfile btree. */
104 : struct xfs_buftarg *
105 693458634 : xfbtree_target(struct xfbtree *xfbtree)
106 : {
107 3860282863 : return xfbtree->target;
108 : }
109 :
110 : /* Is this daddr (sector offset) contained within the buffer target? */
111 : static inline bool
112 : xfbtree_verify_buftarg_xfileoff(
113 : struct xfs_buftarg *btp,
114 : xfileoff_t xfoff)
115 : {
116 3342559242 : xfs_daddr_t xfoff_daddr = xfo_to_daddr(xfoff);
117 :
118 3342559242 : return xfs_buftarg_verify_daddr(btp, xfoff_daddr);
119 : }
120 :
121 : /* Is this btree xfile offset contained within the xfile? */
122 : bool
123 1435579593 : xfbtree_verify_xfileoff(
124 : struct xfs_btree_cur *cur,
125 : unsigned long long xfoff)
126 : {
127 3166824229 : struct xfs_buftarg *btp = xfbtree_target(cur->bc_mem.xfbtree);
128 :
129 1435579593 : return xfbtree_verify_buftarg_xfileoff(btp, xfoff);
130 : }
131 :
132 : /* Check if a btree pointer is reasonable. */
133 : int
134 1731244636 : xfbtree_check_ptr(
135 : struct xfs_btree_cur *cur,
136 : const union xfs_btree_ptr *ptr,
137 : int index,
138 : int level)
139 : {
140 1731244636 : xfileoff_t bt_xfoff;
141 1731244636 : xfs_failaddr_t fa = NULL;
142 :
143 1731244636 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
144 :
145 1731244636 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
146 846301908 : bt_xfoff = be64_to_cpu(ptr->l);
147 : else
148 884942728 : bt_xfoff = be32_to_cpu(ptr->s);
149 :
150 1731244636 : if (!xfbtree_verify_xfileoff(cur, bt_xfoff)) {
151 0 : fa = __this_address;
152 0 : goto done;
153 : }
154 :
155 : /* Can't point to the head or anything before it */
156 1731232825 : if (bt_xfoff < XFBTREE_INIT_LEAF_BLOCK) {
157 0 : fa = __this_address;
158 0 : goto done;
159 : }
160 :
161 1731232825 : done:
162 0 : if (fa) {
163 0 : xfs_err(cur->bc_mp,
164 : "In-memory: Corrupt btree %d flags 0x%x pointer at level %d index %d fa %pS.",
165 : cur->bc_btnum, cur->bc_flags, level, index,
166 : fa);
167 0 : return -EFSCORRUPTED;
168 : }
169 : return 0;
170 : }
171 :
172 : /* Convert a btree pointer to a daddr */
173 : xfs_daddr_t
174 1491616462 : xfbtree_ptr_to_daddr(
175 : struct xfs_btree_cur *cur,
176 : const union xfs_btree_ptr *ptr)
177 : {
178 1491616462 : xfileoff_t bt_xfoff;
179 :
180 1491616462 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
181 846296315 : bt_xfoff = be64_to_cpu(ptr->l);
182 : else
183 645320147 : bt_xfoff = be32_to_cpu(ptr->s);
184 1491616462 : return xfo_to_daddr(bt_xfoff);
185 : }
186 :
187 : /* Set the pointer to point to this buffer. */
188 : void
189 378888 : xfbtree_buf_to_ptr(
190 : struct xfs_btree_cur *cur,
191 : struct xfs_buf *bp,
192 : union xfs_btree_ptr *ptr)
193 : {
194 378888 : xfileoff_t xfoff = xfs_daddr_to_xfo(xfs_buf_daddr(bp));
195 :
196 378888 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
197 13 : ptr->l = cpu_to_be64(xfoff);
198 : else
199 378875 : ptr->s = cpu_to_be32(xfoff);
200 378888 : }
201 :
202 : /* Return the in-memory btree block size, in units of 512 bytes. */
203 693458272 : unsigned int xfbtree_bbsize(void)
204 : {
205 693458272 : return xfo_to_daddr(1);
206 : }
207 :
208 : /* Set the root of an in-memory btree. */
209 : void
210 4440 : xfbtree_set_root(
211 : struct xfs_btree_cur *cur,
212 : const union xfs_btree_ptr *ptr,
213 : int inc)
214 : {
215 4440 : struct xfs_buf *head_bp = cur->bc_mem.head_bp;
216 4440 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
217 :
218 4440 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
219 :
220 4440 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
221 10 : mhead->mh_root = ptr->l;
222 : } else {
223 4430 : uint32_t root = be32_to_cpu(ptr->s);
224 :
225 4430 : mhead->mh_root = cpu_to_be64(root);
226 : }
227 4440 : be32_add_cpu(&mhead->mh_nlevels, inc);
228 4440 : xfs_trans_log_buf(cur->bc_tp, head_bp, 0, sizeof(*mhead) - 1);
229 4440 : }
230 :
231 : /* Initialize a pointer from the in-memory btree header. */
232 : void
233 586049325 : xfbtree_init_ptr_from_cur(
234 : struct xfs_btree_cur *cur,
235 : union xfs_btree_ptr *ptr)
236 : {
237 586049325 : struct xfs_buf *head_bp = cur->bc_mem.head_bp;
238 586049325 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
239 :
240 586049325 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
241 :
242 586049325 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
243 423145646 : ptr->l = mhead->mh_root;
244 : } else {
245 162903679 : uint64_t root = be64_to_cpu(mhead->mh_root);
246 :
247 162903679 : ptr->s = cpu_to_be32(root);
248 : }
249 586049325 : }
250 :
251 : /* Duplicate an in-memory btree cursor. */
252 : struct xfs_btree_cur *
253 24408478 : xfbtree_dup_cursor(
254 : struct xfs_btree_cur *cur)
255 : {
256 24408478 : struct xfs_btree_cur *ncur;
257 :
258 24408478 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
259 :
260 24408478 : ncur = xfs_btree_alloc_cursor(cur->bc_mp, cur->bc_tp, cur->bc_btnum,
261 24408478 : cur->bc_ops, cur->bc_maxlevels, cur->bc_cache);
262 24408251 : ncur->bc_flags = cur->bc_flags;
263 24408251 : ncur->bc_nlevels = cur->bc_nlevels;
264 24408251 : ncur->bc_statoff = cur->bc_statoff;
265 :
266 48816502 : memcpy(&ncur->bc_mem, &cur->bc_mem, sizeof(cur->bc_mem));
267 :
268 24408251 : if (cur->bc_mem.pag)
269 24407049 : ncur->bc_mem.pag = xfs_perag_hold(cur->bc_mem.pag);
270 :
271 24408640 : return ncur;
272 : }
273 :
274 : /* Check the owner of an in-memory btree block. */
275 : xfs_failaddr_t
276 570700950 : xfbtree_check_block_owner(
277 : struct xfs_btree_cur *cur,
278 : struct xfs_btree_block *block)
279 : {
280 570700950 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
281 :
282 570700950 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
283 423151420 : if (be64_to_cpu(block->bb_u.l.bb_owner) != xfbt->owner)
284 0 : return __this_address;
285 :
286 : return NULL;
287 : }
288 :
289 147549530 : if (be32_to_cpu(block->bb_u.s.bb_owner) != xfbt->owner)
290 0 : return __this_address;
291 :
292 : return NULL;
293 : }
294 :
295 : /* Return the owner of this in-memory btree. */
296 : unsigned long long
297 378885 : xfbtree_owner(
298 : struct xfs_btree_cur *cur)
299 : {
300 378885 : return cur->bc_mem.xfbtree->owner;
301 : }
302 :
303 : /* Return the xfile offset (in blocks) of a btree buffer. */
304 : unsigned long long
305 2023385155 : xfbtree_buf_to_xfoff(
306 : struct xfs_btree_cur *cur,
307 : struct xfs_buf *bp)
308 : {
309 2023385155 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
310 :
311 2023385155 : return xfs_daddr_to_xfo(xfs_buf_daddr(bp));
312 : }
313 :
314 : /* Verify a long-format btree block. */
315 : xfs_failaddr_t
316 289202417 : xfbtree_lblock_verify(
317 : struct xfs_buf *bp,
318 : unsigned int max_recs)
319 : {
320 289202417 : struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
321 289202417 : struct xfs_buftarg *btp = bp->b_target;
322 :
323 : /* numrecs verification */
324 289202417 : if (be16_to_cpu(block->bb_numrecs) > max_recs)
325 0 : return __this_address;
326 :
327 : /* sibling pointer verification */
328 289204116 : if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) &&
329 : !xfbtree_verify_buftarg_xfileoff(btp,
330 1699 : be64_to_cpu(block->bb_u.l.bb_leftsib)))
331 0 : return __this_address;
332 :
333 289205352 : if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) &&
334 : !xfbtree_verify_buftarg_xfileoff(btp,
335 2935 : be64_to_cpu(block->bb_u.l.bb_rightsib)))
336 0 : return __this_address;
337 :
338 : return NULL;
339 : }
340 :
341 : /* Verify a short-format btree block. */
342 : xfs_failaddr_t
343 103732288 : xfbtree_sblock_verify(
344 : struct xfs_buf *bp,
345 : unsigned int max_recs)
346 : {
347 103732288 : struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
348 103732288 : struct xfs_buftarg *btp = bp->b_target;
349 :
350 : /* numrecs verification */
351 103732288 : if (be16_to_cpu(block->bb_numrecs) > max_recs)
352 0 : return __this_address;
353 :
354 : /* sibling pointer verification */
355 194700735 : if (block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK) &&
356 90969647 : !xfbtree_verify_buftarg_xfileoff(btp,
357 90969647 : be32_to_cpu(block->bb_u.s.bb_leftsib)))
358 0 : return __this_address;
359 :
360 188491615 : if (block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK) &&
361 84760732 : !xfbtree_verify_buftarg_xfileoff(btp,
362 84760732 : be32_to_cpu(block->bb_u.s.bb_rightsib)))
363 0 : return __this_address;
364 :
365 : return NULL;
366 : }
367 :
368 : /* Close the btree xfile and release all resources. */
369 : void
370 45679 : xfbtree_destroy(
371 : struct xfbtree *xfbt)
372 : {
373 45679 : xbitmap_destroy(xfbt->freespace);
374 45751 : kfree(xfbt->freespace);
375 45792 : xfs_buftarg_drain(xfbt->target);
376 45806 : kfree(xfbt);
377 45813 : }
378 :
379 : /* Compute the number of bytes available for records. */
380 : static inline unsigned int
381 45796 : xfbtree_rec_bytes(
382 : struct xfs_mount *mp,
383 : const struct xfbtree_config *cfg)
384 : {
385 45796 : unsigned int blocklen = xfo_to_b(1);
386 :
387 45796 : if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS) {
388 30275 : if (xfs_has_crc(mp))
389 : return blocklen - XFS_BTREE_LBLOCK_CRC_LEN;
390 :
391 0 : return blocklen - XFS_BTREE_LBLOCK_LEN;
392 : }
393 :
394 15521 : if (xfs_has_crc(mp))
395 15510 : return blocklen - XFS_BTREE_SBLOCK_CRC_LEN;
396 :
397 : return blocklen - XFS_BTREE_SBLOCK_LEN;
398 : }
399 :
400 : /* Initialize an empty leaf block as the btree root. */
401 : STATIC int
402 45844 : xfbtree_init_leaf_block(
403 : struct xfs_mount *mp,
404 : struct xfbtree *xfbt,
405 : const struct xfbtree_config *cfg)
406 : {
407 45844 : struct xfs_buf *bp;
408 45844 : xfs_daddr_t daddr;
409 45844 : int error;
410 :
411 45844 : daddr = xfo_to_daddr(XFBTREE_INIT_LEAF_BLOCK);
412 45844 : error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
413 45793 : if (error)
414 : return error;
415 :
416 45792 : trace_xfbtree_create_root_buf(xfbt, bp);
417 :
418 45760 : xfs_btree_init_buf(mp, bp, cfg->btree_ops, 0, 0, cfg->owner);
419 45720 : error = xfs_bwrite(bp);
420 45801 : xfs_buf_relse(bp);
421 45816 : if (error)
422 : return error;
423 :
424 45816 : xfbt->xf_used++;
425 45816 : return 0;
426 : }
427 :
428 : /* Initialize the in-memory btree header block. */
429 : STATIC int
430 45659 : xfbtree_init_head(
431 : struct xfbtree *xfbt)
432 : {
433 45659 : struct xfs_buf *bp;
434 45659 : xfs_daddr_t daddr;
435 45659 : int error;
436 :
437 45659 : daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
438 45659 : error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
439 45889 : if (error)
440 : return error;
441 :
442 45890 : xfs_btree_mem_head_init(bp, xfbt->owner, XFBTREE_INIT_LEAF_BLOCK);
443 45855 : error = xfs_bwrite(bp);
444 45851 : xfs_buf_relse(bp);
445 45870 : if (error)
446 : return error;
447 :
448 45870 : xfbt->xf_used++;
449 45870 : return 0;
450 : }
451 :
452 : /* Create an xfile btree backing thing that can be used for in-memory btrees. */
453 : int
454 45789 : xfbtree_create(
455 : struct xfs_mount *mp,
456 : const struct xfbtree_config *cfg,
457 : struct xfbtree **xfbtreep)
458 : {
459 45789 : struct xfbtree *xfbt;
460 45789 : unsigned int blocklen = xfbtree_rec_bytes(mp, cfg);
461 45789 : unsigned int keyptr_len = cfg->btree_ops->key_len;
462 45789 : int error;
463 :
464 : /* Requires an xfile-backed buftarg. */
465 45789 : if (!(cfg->target->bt_flags & XFS_BUFTARG_XFILE)) {
466 0 : ASSERT(cfg->target->bt_flags & XFS_BUFTARG_XFILE);
467 0 : return -EINVAL;
468 : }
469 :
470 45789 : xfbt = kzalloc(sizeof(struct xfbtree), XCHK_GFP_FLAGS);
471 45803 : if (!xfbt)
472 : return -ENOMEM;
473 :
474 : /* Assign our memory file and the free space bitmap. */
475 45803 : xfbt->target = cfg->target;
476 45803 : if (cfg->flags & XFBTREE_DIRECT_MAP)
477 45821 : xfbt->target->bt_flags |= XFS_BUFTARG_DIRECT_MAP;
478 :
479 45803 : xfbt->freespace = kmalloc(sizeof(struct xbitmap), XCHK_GFP_FLAGS);
480 45877 : if (!xfbt->freespace) {
481 0 : error = -ENOMEM;
482 0 : goto err_buftarg;
483 : }
484 45877 : xbitmap_init(xfbt->freespace);
485 :
486 : /* Set up min/maxrecs for this btree. */
487 45869 : if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS)
488 30318 : keyptr_len += sizeof(__be64);
489 : else
490 15551 : keyptr_len += sizeof(__be32);
491 45869 : xfbt->maxrecs[0] = blocklen / cfg->btree_ops->rec_len;
492 45869 : xfbt->maxrecs[1] = blocklen / keyptr_len;
493 45869 : xfbt->minrecs[0] = xfbt->maxrecs[0] / 2;
494 45869 : xfbt->minrecs[1] = xfbt->maxrecs[1] / 2;
495 45869 : xfbt->owner = cfg->owner;
496 :
497 : /* Initialize the empty btree. */
498 45869 : error = xfbtree_init_leaf_block(mp, xfbt, cfg);
499 45696 : if (error)
500 0 : goto err_freesp;
501 :
502 45696 : error = xfbtree_init_head(xfbt);
503 45870 : if (error)
504 0 : goto err_freesp;
505 :
506 45870 : trace_xfbtree_create(mp, cfg, xfbt);
507 :
508 45855 : *xfbtreep = xfbt;
509 45855 : return 0;
510 :
511 0 : err_freesp:
512 0 : xbitmap_destroy(xfbt->freespace);
513 0 : kfree(xfbt->freespace);
514 0 : err_buftarg:
515 0 : xfs_buftarg_drain(xfbt->target);
516 0 : kfree(xfbt);
517 0 : return error;
518 : }
519 :
520 : /* Read the in-memory btree head. */
521 : int
522 476013054 : xfbtree_head_read_buf(
523 : struct xfbtree *xfbt,
524 : struct xfs_trans *tp,
525 : struct xfs_buf **bpp)
526 : {
527 476013054 : struct xfs_buftarg *btp = xfbt->target;
528 476013054 : struct xfs_mount *mp = btp->bt_mount;
529 476013054 : struct xfs_btree_mem_head *mhead;
530 476013054 : struct xfs_buf *bp;
531 476013054 : xfs_daddr_t daddr;
532 476013054 : int error;
533 :
534 476013054 : daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
535 476013054 : error = xfs_trans_read_buf(mp, tp, btp, daddr, xfbtree_bbsize(), 0,
536 : &bp, &xfs_btree_mem_head_buf_ops);
537 476011874 : if (error)
538 : return error;
539 :
540 476011874 : mhead = bp->b_addr;
541 476011874 : if (be64_to_cpu(mhead->mh_owner) != xfbt->owner) {
542 0 : xfs_verifier_error(bp, -EFSCORRUPTED, __this_address);
543 0 : xfs_trans_brelse(tp, bp);
544 0 : return -EFSCORRUPTED;
545 : }
546 :
547 476011874 : *bpp = bp;
548 476011874 : return 0;
549 : }
550 :
551 : static inline struct xfile *xfbtree_xfile(struct xfbtree *xfbt)
552 : {
553 378888 : return xfbt->target->bt_xfile;
554 : }
555 :
556 : /* Allocate a block to our in-memory btree. */
557 : int
558 378888 : xfbtree_alloc_block(
559 : struct xfs_btree_cur *cur,
560 : const union xfs_btree_ptr *start,
561 : union xfs_btree_ptr *new,
562 : int *stat)
563 : {
564 378888 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
565 378888 : xfileoff_t bt_xfoff;
566 378888 : loff_t pos;
567 378888 : int error;
568 :
569 378888 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
570 :
571 : /*
572 : * Find the first free block in the free space bitmap and take it. If
573 : * none are found, seek to end of the file.
574 : */
575 378888 : error = xbitmap_take_first_set(xfbt->freespace, 0, -1ULL, &bt_xfoff);
576 378888 : if (error == -ENODATA) {
577 378876 : bt_xfoff = xfbt->xf_used;
578 378876 : xfbt->xf_used++;
579 12 : } else if (error) {
580 : return error;
581 : }
582 :
583 378888 : trace_xfbtree_alloc_block(xfbt, cur, bt_xfoff);
584 :
585 : /* Fail if the block address exceeds the maximum for short pointers. */
586 378888 : if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS) && bt_xfoff >= INT_MAX) {
587 0 : *stat = 0;
588 0 : return 0;
589 : }
590 :
591 : /* Make sure we actually can write to the block before we return it. */
592 378888 : pos = xfo_to_b(bt_xfoff);
593 378888 : error = xfile_prealloc(xfbtree_xfile(xfbt), pos, xfo_to_b(1));
594 378889 : if (error)
595 : return error;
596 :
597 378889 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
598 13 : new->l = cpu_to_be64(bt_xfoff);
599 : else
600 378876 : new->s = cpu_to_be32(bt_xfoff);
601 :
602 378889 : *stat = 1;
603 378889 : return 0;
604 : }
605 :
606 : /* Free a block from our in-memory btree. */
607 : int
608 25 : xfbtree_free_block(
609 : struct xfs_btree_cur *cur,
610 : struct xfs_buf *bp)
611 : {
612 25 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
613 25 : xfileoff_t bt_xfoff, bt_xflen;
614 :
615 25 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
616 :
617 25 : bt_xfoff = xfs_daddr_to_xfot(xfs_buf_daddr(bp));
618 25 : bt_xflen = xfs_daddr_to_xfot(bp->b_length);
619 :
620 25 : trace_xfbtree_free_block(xfbt, cur, bt_xfoff);
621 :
622 25 : return xbitmap_set(xfbt->freespace, bt_xfoff, bt_xflen);
623 : }
624 :
625 : /* Return the minimum number of records for a btree block. */
626 : int
627 64450 : xfbtree_get_minrecs(
628 : struct xfs_btree_cur *cur,
629 : int level)
630 : {
631 64450 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
632 :
633 64450 : return xfbt->minrecs[level != 0];
634 : }
635 :
636 : /* Return the maximum number of records for a btree block. */
637 : int
638 3817646169 : xfbtree_get_maxrecs(
639 : struct xfs_btree_cur *cur,
640 : int level)
641 : {
642 3817646169 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
643 :
644 3817646169 : return xfbt->maxrecs[level != 0];
645 : }
646 :
647 : /* If this log item is a buffer item that came from the xfbtree, return it. */
648 : static inline struct xfs_buf *
649 : xfbtree_buf_match(
650 : struct xfbtree *xfbt,
651 : const struct xfs_log_item *lip)
652 : {
653 2849466411 : const struct xfs_buf_log_item *bli;
654 2849466411 : struct xfs_buf *bp;
655 :
656 2849466411 : if (lip->li_type != XFS_LI_BUF)
657 : return NULL;
658 :
659 2849466799 : bli = container_of(lip, struct xfs_buf_log_item, bli_item);
660 2849466799 : bp = bli->bli_buf;
661 2849466799 : if (bp->b_target != xfbt->target)
662 : return NULL;
663 :
664 : return bp;
665 : }
666 :
667 : /*
668 : * Detach this (probably dirty) xfbtree buffer from the transaction by any
669 : * means necessary. Returns true if the buffer needs to be written.
670 : */
671 : STATIC bool
672 451232467 : xfbtree_trans_bdetach(
673 : struct xfs_trans *tp,
674 : struct xfs_buf *bp)
675 : {
676 451232467 : struct xfs_buf_log_item *bli = bp->b_log_item;
677 451232467 : bool dirty;
678 :
679 451232467 : ASSERT(bli != NULL);
680 :
681 451232467 : dirty = bli->bli_flags & (XFS_BLI_DIRTY | XFS_BLI_ORDERED);
682 :
683 451232467 : bli->bli_flags &= ~(XFS_BLI_DIRTY | XFS_BLI_ORDERED |
684 : XFS_BLI_LOGGED | XFS_BLI_STALE);
685 451232467 : clear_bit(XFS_LI_DIRTY, &bli->bli_item.li_flags);
686 :
687 902487044 : while (bp->b_log_item != NULL)
688 451242659 : xfs_trans_bdetach(tp, bp);
689 :
690 451244385 : return dirty;
691 : }
692 :
693 : /*
694 : * Commit changes to the incore btree immediately by writing all dirty xfbtree
695 : * buffers to the backing xfile. This detaches all xfbtree buffers from the
696 : * transaction, even on failure. The buffer locks are dropped between the
697 : * delwri queue and submit, so the caller must synchronize btree access.
698 : *
699 : * Normally we'd let the buffers commit with the transaction and get written to
700 : * the xfile via the log, but online repair stages ephemeral btrees in memory
701 : * and uses the btree_staging functions to write new btrees to disk atomically.
702 : * The in-memory btree (and its backing store) are discarded at the end of the
703 : * repair phase, which means that xfbtree buffers cannot commit with the rest
704 : * of a transaction.
705 : *
706 : * In other words, online repair only needs the transaction to collect buffer
707 : * pointers and to avoid buffer deadlocks, not to guarantee consistency of
708 : * updates.
709 : */
710 : int
711 343812900 : xfbtree_trans_commit(
712 : struct xfbtree *xfbt,
713 : struct xfs_trans *tp)
714 : {
715 343812900 : LIST_HEAD(buffer_list);
716 343812900 : struct xfs_log_item *lip, *n;
717 343812900 : bool corrupt = false;
718 343812900 : bool tp_dirty = false;
719 :
720 : /*
721 : * For each xfbtree buffer attached to the transaction, write the dirty
722 : * buffers to the xfile and release them.
723 : */
724 3193283484 : list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
725 2849466411 : struct xfs_buf *bp = xfbtree_buf_match(xfbt, lip);
726 451239677 : bool dirty;
727 :
728 451239677 : if (!bp) {
729 4796453468 : if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
730 0 : tp_dirty |= true;
731 2398226734 : continue;
732 : }
733 :
734 451239677 : trace_xfbtree_trans_commit_buf(xfbt, bp);
735 :
736 451234996 : dirty = xfbtree_trans_bdetach(tp, bp);
737 451246977 : if (dirty && !corrupt) {
738 392900839 : xfs_failaddr_t fa;
739 :
740 : /*
741 : * Because this btree is ephemeral, validate the buffer
742 : * structure before delwri_submit so that we can return
743 : * corruption errors to the caller without shutting
744 : * down the filesystem.
745 : *
746 : * Buffers that are directly mapped to the xfile do not
747 : * need to be queued for IO at all. Check if the DRAM
748 : * has been poisoned, however.
749 : *
750 : * If the buffer fails verification, log the failure
751 : * but continue walking the transaction items so that
752 : * we remove all ephemeral btree buffers.
753 : */
754 392900839 : if (xfs_buf_check_poisoned(bp)) {
755 0 : corrupt = true;
756 0 : xfs_verifier_error(bp, -EFSCORRUPTED,
757 0 : __this_address);
758 0 : continue;
759 : }
760 :
761 392899218 : fa = bp->b_ops->verify_struct(bp);
762 392886062 : if (fa) {
763 0 : corrupt = true;
764 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
765 0 : continue;
766 : }
767 :
768 392886062 : if (!(bp->b_flags & _XBF_DIRECT_MAP))
769 0 : xfs_buf_delwri_queue_here(bp, &buffer_list);
770 : }
771 :
772 451232200 : xfs_buf_relse(bp);
773 : }
774 :
775 : /*
776 : * Reset the transaction's dirty flag to reflect the dirty state of the
777 : * log items that are still attached.
778 : */
779 687634146 : tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
780 343817073 : (tp_dirty ? XFS_TRANS_DIRTY : 0);
781 :
782 343817073 : if (corrupt) {
783 0 : xfs_buf_delwri_cancel(&buffer_list);
784 0 : return -EFSCORRUPTED;
785 : }
786 :
787 343817073 : if (list_empty(&buffer_list))
788 : return 0;
789 :
790 0 : return xfs_buf_delwri_submit(&buffer_list);
791 : }
792 :
793 : /*
794 : * Cancel changes to the incore btree by detaching all the xfbtree buffers.
795 : * Changes are not written to the backing store. This is needed for online
796 : * repair btrees, which are by nature ephemeral.
797 : */
798 : void
799 0 : xfbtree_trans_cancel(
800 : struct xfbtree *xfbt,
801 : struct xfs_trans *tp)
802 : {
803 0 : struct xfs_log_item *lip, *n;
804 0 : bool tp_dirty = false;
805 :
806 0 : list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
807 0 : struct xfs_buf *bp = xfbtree_buf_match(xfbt, lip);
808 :
809 0 : if (!bp) {
810 0 : if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
811 0 : tp_dirty |= true;
812 0 : continue;
813 : }
814 :
815 0 : trace_xfbtree_trans_cancel_buf(xfbt, bp);
816 :
817 0 : xfbtree_trans_bdetach(tp, bp);
818 0 : xfs_buf_relse(bp);
819 : }
820 :
821 : /*
822 : * Reset the transaction's dirty flag to reflect the dirty state of the
823 : * log items that are still attached.
824 : */
825 0 : tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
826 0 : (tp_dirty ? XFS_TRANS_DIRTY : 0);
827 0 : }
|