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 21725 : xfs_btree_mem_head_verify(
30 : struct xfs_buf *bp)
31 : {
32 21725 : struct xfs_btree_mem_head *mhead = bp->b_addr;
33 21725 : struct xfs_mount *mp = bp->b_mount;
34 :
35 21725 : if (!xfs_verify_magic(bp, mhead->mh_magic))
36 0 : return __this_address;
37 21728 : if (be32_to_cpu(mhead->mh_nlevels) == 0)
38 0 : return __this_address;
39 21728 : 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 40 : xfs_btree_mem_head_read_verify(
47 : struct xfs_buf *bp)
48 : {
49 40 : xfs_failaddr_t fa = xfs_btree_mem_head_verify(bp);
50 :
51 40 : if (fa)
52 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
53 40 : }
54 :
55 : static void
56 21153 : xfs_btree_mem_head_write_verify(
57 : struct xfs_buf *bp)
58 : {
59 21153 : xfs_failaddr_t fa = xfs_btree_mem_head_verify(bp);
60 :
61 21160 : if (fa)
62 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
63 21160 : }
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 21161 : xfs_btree_mem_head_init(
77 : struct xfs_buf *head_bp,
78 : unsigned long long owner,
79 : xfileoff_t leaf_xfoff)
80 : {
81 21161 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
82 21161 : struct xfs_mount *mp = head_bp->b_mount;
83 :
84 21161 : mhead->mh_magic = cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC);
85 21161 : mhead->mh_nlevels = cpu_to_be32(1);
86 21161 : mhead->mh_owner = cpu_to_be64(owner);
87 21161 : mhead->mh_root = cpu_to_be64(leaf_xfoff);
88 21161 : uuid_copy(&mhead->mh_uuid, &mp->m_sb.sb_meta_uuid);
89 :
90 21161 : head_bp->b_ops = &xfs_btree_mem_head_buf_ops;
91 21161 : }
92 :
93 : /* Return tree height from the in-memory btree head. */
94 : unsigned int
95 509095647 : xfs_btree_mem_head_nlevels(
96 : struct xfs_buf *head_bp)
97 : {
98 509095647 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
99 :
100 509095647 : return be32_to_cpu(mhead->mh_nlevels);
101 : }
102 :
103 : /* Extract the buftarg target for this xfile btree. */
104 : struct xfs_buftarg *
105 531870396 : xfbtree_target(struct xfbtree *xfbtree)
106 : {
107 1847921276 : 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 20929241 : xfs_daddr_t xfoff_daddr = xfo_to_daddr(xfoff);
117 :
118 1336980121 : return xfs_buftarg_verify_daddr(btp, xfoff_daddr);
119 : }
120 :
121 : /* Is this btree xfile offset contained within the xfile? */
122 : bool
123 208897185 : xfbtree_verify_xfileoff(
124 : struct xfs_btree_cur *cur,
125 : unsigned long long xfoff)
126 : {
127 1316050880 : struct xfs_buftarg *btp = xfbtree_target(cur->bc_mem.xfbtree);
128 :
129 208897185 : return xfbtree_verify_buftarg_xfileoff(btp, xfoff);
130 : }
131 :
132 : /* Check if a btree pointer is reasonable. */
133 : int
134 1107153695 : xfbtree_check_ptr(
135 : struct xfs_btree_cur *cur,
136 : const union xfs_btree_ptr *ptr,
137 : int index,
138 : int level)
139 : {
140 1107153695 : xfileoff_t bt_xfoff;
141 1107153695 : xfs_failaddr_t fa = NULL;
142 :
143 1107153695 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
144 :
145 1107153695 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
146 995981297 : bt_xfoff = be64_to_cpu(ptr->l);
147 : else
148 111172398 : bt_xfoff = be32_to_cpu(ptr->s);
149 :
150 1107153695 : 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 1107152440 : if (bt_xfoff < XFBTREE_INIT_LEAF_BLOCK) {
157 0 : fa = __this_address;
158 0 : goto done;
159 : }
160 :
161 1107152440 : 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 1085571073 : xfbtree_ptr_to_daddr(
175 : struct xfs_btree_cur *cur,
176 : const union xfs_btree_ptr *ptr)
177 : {
178 1085571073 : xfileoff_t bt_xfoff;
179 :
180 1085571073 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
181 995981269 : bt_xfoff = be64_to_cpu(ptr->l);
182 : else
183 89589804 : bt_xfoff = be32_to_cpu(ptr->s);
184 1085571073 : return xfo_to_daddr(bt_xfoff);
185 : }
186 :
187 : /* Set the pointer to point to this buffer. */
188 : void
189 4743 : xfbtree_buf_to_ptr(
190 : struct xfs_btree_cur *cur,
191 : struct xfs_buf *bp,
192 : union xfs_btree_ptr *ptr)
193 : {
194 4743 : xfileoff_t xfoff = xfs_daddr_to_xfo(xfs_buf_daddr(bp));
195 :
196 4743 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
197 0 : ptr->l = cpu_to_be64(xfoff);
198 : else
199 4743 : ptr->s = cpu_to_be32(xfoff);
200 4743 : }
201 :
202 : /* Return the in-memory btree block size, in units of 512 bytes. */
203 531870272 : unsigned int xfbtree_bbsize(void)
204 : {
205 531870272 : return xfo_to_daddr(1);
206 : }
207 :
208 : /* Set the root of an in-memory btree. */
209 : void
210 529 : xfbtree_set_root(
211 : struct xfs_btree_cur *cur,
212 : const union xfs_btree_ptr *ptr,
213 : int inc)
214 : {
215 529 : struct xfs_buf *head_bp = cur->bc_mem.head_bp;
216 529 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
217 :
218 529 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
219 :
220 529 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
221 0 : mhead->mh_root = ptr->l;
222 : } else {
223 529 : uint32_t root = be32_to_cpu(ptr->s);
224 :
225 529 : mhead->mh_root = cpu_to_be64(root);
226 : }
227 529 : be32_add_cpu(&mhead->mh_nlevels, inc);
228 529 : xfs_trans_log_buf(cur->bc_tp, head_bp, 0, sizeof(*mhead) - 1);
229 529 : }
230 :
231 : /* Initialize a pointer from the in-memory btree header. */
232 : void
233 532677853 : xfbtree_init_ptr_from_cur(
234 : struct xfs_btree_cur *cur,
235 : union xfs_btree_ptr *ptr)
236 : {
237 532677853 : struct xfs_buf *head_bp = cur->bc_mem.head_bp;
238 532677853 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
239 :
240 532677853 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
241 :
242 532677853 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
243 497990657 : ptr->l = mhead->mh_root;
244 : } else {
245 34687196 : uint64_t root = be64_to_cpu(mhead->mh_root);
246 :
247 34687196 : ptr->s = cpu_to_be32(root);
248 : }
249 532677853 : }
250 :
251 : /* Duplicate an in-memory btree cursor. */
252 : struct xfs_btree_cur *
253 3345797 : xfbtree_dup_cursor(
254 : struct xfs_btree_cur *cur)
255 : {
256 3345797 : struct xfs_btree_cur *ncur;
257 :
258 3345797 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
259 :
260 3345797 : ncur = xfs_btree_alloc_cursor(cur->bc_mp, cur->bc_tp, cur->bc_btnum,
261 : cur->bc_ops, cur->bc_maxlevels, cur->bc_cache);
262 3345798 : ncur->bc_flags = cur->bc_flags;
263 3345798 : ncur->bc_nlevels = cur->bc_nlevels;
264 3345798 : ncur->bc_statoff = cur->bc_statoff;
265 :
266 6691596 : memcpy(&ncur->bc_mem, &cur->bc_mem, sizeof(cur->bc_mem));
267 :
268 3345798 : if (cur->bc_mem.pag)
269 3345798 : ncur->bc_mem.pag = xfs_perag_hold(cur->bc_mem.pag);
270 :
271 3345796 : return ncur;
272 : }
273 :
274 : /* Check the owner of an in-memory btree block. */
275 : xfs_failaddr_t
276 517932669 : xfbtree_check_block_owner(
277 : struct xfs_btree_cur *cur,
278 : struct xfs_btree_block *block)
279 : {
280 517932669 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
281 :
282 517932669 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
283 497990662 : if (be64_to_cpu(block->bb_u.l.bb_owner) != xfbt->owner)
284 0 : return __this_address;
285 :
286 : return NULL;
287 : }
288 :
289 19942007 : 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 4743 : xfbtree_owner(
298 : struct xfs_btree_cur *cur)
299 : {
300 4743 : return cur->bc_mem.xfbtree->owner;
301 : }
302 :
303 : /* Return the xfile offset (in blocks) of a btree buffer. */
304 : unsigned long long
305 1486292463 : xfbtree_buf_to_xfoff(
306 : struct xfs_btree_cur *cur,
307 : struct xfs_buf *bp)
308 : {
309 1486292463 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
310 :
311 1486292463 : return xfs_daddr_to_xfo(xfs_buf_daddr(bp));
312 : }
313 :
314 : /* Verify a long-format btree block. */
315 : xfs_failaddr_t
316 333073113 : xfbtree_lblock_verify(
317 : struct xfs_buf *bp,
318 : unsigned int max_recs)
319 : {
320 333073113 : struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
321 333073113 : struct xfs_buftarg *btp = bp->b_target;
322 :
323 : /* numrecs verification */
324 333073113 : if (be16_to_cpu(block->bb_numrecs) > max_recs)
325 0 : return __this_address;
326 :
327 : /* sibling pointer verification */
328 333073113 : if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) &&
329 0 : !xfbtree_verify_buftarg_xfileoff(btp,
330 0 : be64_to_cpu(block->bb_u.l.bb_leftsib)))
331 0 : return __this_address;
332 :
333 333073113 : if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) &&
334 0 : !xfbtree_verify_buftarg_xfileoff(btp,
335 0 : 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 17801583 : xfbtree_sblock_verify(
344 : struct xfs_buf *bp,
345 : unsigned int max_recs)
346 : {
347 17801583 : struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
348 17801583 : struct xfs_buftarg *btp = bp->b_target;
349 :
350 : /* numrecs verification */
351 17801583 : if (be16_to_cpu(block->bb_numrecs) > max_recs)
352 0 : return __this_address;
353 :
354 : /* sibling pointer verification */
355 28773411 : if (block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK) &&
356 10971826 : !xfbtree_verify_buftarg_xfileoff(btp,
357 10971826 : be32_to_cpu(block->bb_u.s.bb_leftsib)))
358 0 : return __this_address;
359 :
360 27759001 : if (block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK) &&
361 9957415 : !xfbtree_verify_buftarg_xfileoff(btp,
362 9957415 : 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 21161 : xfbtree_destroy(
371 : struct xfbtree *xfbt)
372 : {
373 21161 : xbitmap_destroy(xfbt->freespace);
374 21158 : kfree(xfbt->freespace);
375 21159 : xfs_buftarg_drain(xfbt->target);
376 21162 : kfree(xfbt);
377 21162 : }
378 :
379 : /* Compute the number of bytes available for records. */
380 : static inline unsigned int
381 21162 : xfbtree_rec_bytes(
382 : struct xfs_mount *mp,
383 : const struct xfbtree_config *cfg)
384 : {
385 21162 : unsigned int blocklen = xfo_to_b(1);
386 :
387 21162 : if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS) {
388 16691 : 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 4471 : if (xfs_has_crc(mp))
395 4471 : 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 21162 : xfbtree_init_leaf_block(
403 : struct xfs_mount *mp,
404 : struct xfbtree *xfbt,
405 : const struct xfbtree_config *cfg)
406 : {
407 21162 : struct xfs_buf *bp;
408 21162 : xfs_daddr_t daddr;
409 21162 : int error;
410 :
411 21162 : daddr = xfo_to_daddr(XFBTREE_INIT_LEAF_BLOCK);
412 21162 : error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
413 21162 : if (error)
414 : return error;
415 :
416 21162 : trace_xfbtree_create_root_buf(xfbt, bp);
417 :
418 21161 : xfs_btree_init_buf(mp, bp, cfg->btree_ops, 0, 0, cfg->owner);
419 21157 : error = xfs_bwrite(bp);
420 21160 : xfs_buf_relse(bp);
421 21147 : if (error)
422 : return error;
423 :
424 21147 : xfbt->xf_used++;
425 21147 : return 0;
426 : }
427 :
428 : /* Initialize the in-memory btree header block. */
429 : STATIC int
430 21158 : xfbtree_init_head(
431 : struct xfbtree *xfbt)
432 : {
433 21158 : struct xfs_buf *bp;
434 21158 : xfs_daddr_t daddr;
435 21158 : int error;
436 :
437 21158 : daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
438 21158 : error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
439 21161 : if (error)
440 : return error;
441 :
442 21160 : xfs_btree_mem_head_init(bp, xfbt->owner, XFBTREE_INIT_LEAF_BLOCK);
443 21159 : error = xfs_bwrite(bp);
444 21159 : xfs_buf_relse(bp);
445 21162 : if (error)
446 : return error;
447 :
448 21162 : xfbt->xf_used++;
449 21162 : return 0;
450 : }
451 :
452 : /* Create an xfile btree backing thing that can be used for in-memory btrees. */
453 : int
454 21162 : xfbtree_create(
455 : struct xfs_mount *mp,
456 : const struct xfbtree_config *cfg,
457 : struct xfbtree **xfbtreep)
458 : {
459 21162 : struct xfbtree *xfbt;
460 21162 : unsigned int blocklen = xfbtree_rec_bytes(mp, cfg);
461 21162 : unsigned int keyptr_len = cfg->btree_ops->key_len;
462 21162 : int error;
463 :
464 : /* Requires an xfile-backed buftarg. */
465 21162 : 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 21162 : xfbt = kzalloc(sizeof(struct xfbtree), XCHK_GFP_FLAGS);
471 21162 : if (!xfbt)
472 : return -ENOMEM;
473 :
474 : /* Assign our memory file and the free space bitmap. */
475 21162 : xfbt->target = cfg->target;
476 21162 : if (cfg->flags & XFBTREE_DIRECT_MAP)
477 21162 : xfbt->target->bt_flags |= XFS_BUFTARG_DIRECT_MAP;
478 :
479 21162 : xfbt->freespace = kmalloc(sizeof(struct xbitmap), XCHK_GFP_FLAGS);
480 21162 : if (!xfbt->freespace) {
481 0 : error = -ENOMEM;
482 0 : goto err_buftarg;
483 : }
484 21162 : xbitmap_init(xfbt->freespace);
485 :
486 : /* Set up min/maxrecs for this btree. */
487 21162 : if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS)
488 16691 : keyptr_len += sizeof(__be64);
489 : else
490 4471 : keyptr_len += sizeof(__be32);
491 21162 : xfbt->maxrecs[0] = blocklen / cfg->btree_ops->rec_len;
492 21162 : xfbt->maxrecs[1] = blocklen / keyptr_len;
493 21162 : xfbt->minrecs[0] = xfbt->maxrecs[0] / 2;
494 21162 : xfbt->minrecs[1] = xfbt->maxrecs[1] / 2;
495 21162 : xfbt->owner = cfg->owner;
496 :
497 : /* Initialize the empty btree. */
498 21162 : error = xfbtree_init_leaf_block(mp, xfbt, cfg);
499 21148 : if (error)
500 0 : goto err_freesp;
501 :
502 21148 : error = xfbtree_init_head(xfbt);
503 21162 : if (error)
504 0 : goto err_freesp;
505 :
506 21162 : trace_xfbtree_create(mp, cfg, xfbt);
507 :
508 21161 : *xfbtreep = xfbt;
509 21161 : 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 509095489 : xfbtree_head_read_buf(
523 : struct xfbtree *xfbt,
524 : struct xfs_trans *tp,
525 : struct xfs_buf **bpp)
526 : {
527 509095489 : struct xfs_buftarg *btp = xfbt->target;
528 509095489 : struct xfs_mount *mp = btp->bt_mount;
529 509095489 : struct xfs_btree_mem_head *mhead;
530 509095489 : struct xfs_buf *bp;
531 509095489 : xfs_daddr_t daddr;
532 509095489 : int error;
533 :
534 509095489 : daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
535 509095489 : error = xfs_trans_read_buf(mp, tp, btp, daddr, xfbtree_bbsize(), 0,
536 : &bp, &xfs_btree_mem_head_buf_ops);
537 509095710 : if (error)
538 : return error;
539 :
540 509095710 : mhead = bp->b_addr;
541 509095710 : 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 509095710 : *bpp = bp;
548 509095710 : return 0;
549 : }
550 :
551 : static inline struct xfile *xfbtree_xfile(struct xfbtree *xfbt)
552 : {
553 4743 : return xfbt->target->bt_xfile;
554 : }
555 :
556 : /* Allocate a block to our in-memory btree. */
557 : int
558 4743 : 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 4743 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
565 4743 : xfileoff_t bt_xfoff;
566 4743 : loff_t pos;
567 4743 : int error;
568 :
569 4743 : 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 4743 : error = xbitmap_take_first_set(xfbt->freespace, 0, -1ULL, &bt_xfoff);
576 4743 : if (error == -ENODATA) {
577 4742 : bt_xfoff = xfbt->xf_used;
578 4742 : xfbt->xf_used++;
579 1 : } else if (error) {
580 : return error;
581 : }
582 :
583 4743 : trace_xfbtree_alloc_block(xfbt, cur, bt_xfoff);
584 :
585 : /* Fail if the block address exceeds the maximum for short pointers. */
586 4743 : 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 4743 : pos = xfo_to_b(bt_xfoff);
593 4743 : error = xfile_prealloc(xfbtree_xfile(xfbt), pos, xfo_to_b(1));
594 4743 : if (error)
595 : return error;
596 :
597 4743 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
598 0 : new->l = cpu_to_be64(bt_xfoff);
599 : else
600 4743 : new->s = cpu_to_be32(bt_xfoff);
601 :
602 4743 : *stat = 1;
603 4743 : return 0;
604 : }
605 :
606 : /* Free a block from our in-memory btree. */
607 : int
608 1 : xfbtree_free_block(
609 : struct xfs_btree_cur *cur,
610 : struct xfs_buf *bp)
611 : {
612 1 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
613 1 : xfileoff_t bt_xfoff, bt_xflen;
614 :
615 1 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
616 :
617 1 : bt_xfoff = xfs_daddr_to_xfot(xfs_buf_daddr(bp));
618 1 : bt_xflen = xfs_daddr_to_xfot(bp->b_length);
619 :
620 1 : trace_xfbtree_free_block(xfbt, cur, bt_xfoff);
621 :
622 1 : 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 22127 : xfbtree_get_minrecs(
628 : struct xfs_btree_cur *cur,
629 : int level)
630 : {
631 22127 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
632 :
633 22127 : return xfbt->minrecs[level != 0];
634 : }
635 :
636 : /* Return the maximum number of records for a btree block. */
637 : int
638 1736960659 : xfbtree_get_maxrecs(
639 : struct xfs_btree_cur *cur,
640 : int level)
641 : {
642 1736960659 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
643 :
644 1736960659 : 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 3194851336 : const struct xfs_buf_log_item *bli;
654 3194851336 : struct xfs_buf *bp;
655 :
656 3194851336 : if (lip->li_type != XFS_LI_BUF)
657 : return NULL;
658 :
659 3194851339 : bli = container_of(lip, struct xfs_buf_log_item, bli_item);
660 3194851339 : bp = bli->bli_buf;
661 3194851339 : 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 362480093 : xfbtree_trans_bdetach(
673 : struct xfs_trans *tp,
674 : struct xfs_buf *bp)
675 : {
676 362480093 : struct xfs_buf_log_item *bli = bp->b_log_item;
677 362480093 : bool dirty;
678 :
679 362480093 : ASSERT(bli != NULL);
680 :
681 362480093 : dirty = bli->bli_flags & (XFS_BLI_DIRTY | XFS_BLI_ORDERED);
682 :
683 362480093 : bli->bli_flags &= ~(XFS_BLI_DIRTY | XFS_BLI_ORDERED |
684 : XFS_BLI_LOGGED | XFS_BLI_STALE);
685 362480093 : clear_bit(XFS_LI_DIRTY, &bli->bli_item.li_flags);
686 :
687 724960348 : while (bp->b_log_item != NULL)
688 362480059 : xfs_trans_bdetach(tp, bp);
689 :
690 362480289 : 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 344692612 : xfbtree_trans_commit(
712 : struct xfbtree *xfbt,
713 : struct xfs_trans *tp)
714 : {
715 344692612 : LIST_HEAD(buffer_list);
716 344692612 : struct xfs_log_item *lip, *n;
717 344692612 : bool corrupt = false;
718 344692612 : 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 3539544041 : list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
725 3194851336 : struct xfs_buf *bp = xfbtree_buf_match(xfbt, lip);
726 362480204 : bool dirty;
727 :
728 362480204 : if (!bp) {
729 5664742264 : if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
730 0 : tp_dirty |= true;
731 2832371132 : continue;
732 : }
733 :
734 362480204 : trace_xfbtree_trans_commit_buf(xfbt, bp);
735 :
736 362480081 : dirty = xfbtree_trans_bdetach(tp, bp);
737 362480314 : if (dirty && !corrupt) {
738 350854062 : 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 350854062 : 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 350854062 : fa = bp->b_ops->verify_struct(bp);
762 350854046 : if (fa) {
763 0 : corrupt = true;
764 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
765 0 : continue;
766 : }
767 :
768 350854046 : if (!(bp->b_flags & _XBF_DIRECT_MAP))
769 0 : xfs_buf_delwri_queue_here(bp, &buffer_list);
770 : }
771 :
772 362480298 : 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 689385410 : tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
780 344692705 : (tp_dirty ? XFS_TRANS_DIRTY : 0);
781 :
782 344692705 : if (corrupt) {
783 0 : xfs_buf_delwri_cancel(&buffer_list);
784 0 : return -EFSCORRUPTED;
785 : }
786 :
787 344692705 : 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 : }
|