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