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 80276 : xfs_btree_mem_head_verify(
31 : struct xfs_buf *bp)
32 : {
33 80276 : struct xfs_btree_mem_head *mhead = bp->b_addr;
34 80276 : struct xfs_mount *mp = bp->b_mount;
35 :
36 80276 : if (!xfs_verify_magic(bp, mhead->mh_magic))
37 0 : return __this_address;
38 80266 : if (be32_to_cpu(mhead->mh_nlevels) == 0)
39 0 : return __this_address;
40 80267 : 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 93 : xfs_btree_mem_head_read_verify(
48 : struct xfs_buf *bp)
49 : {
50 93 : xfs_failaddr_t fa = xfs_btree_mem_head_verify(bp);
51 :
52 93 : if (fa)
53 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
54 93 : }
55 :
56 : static void
57 78468 : xfs_btree_mem_head_write_verify(
58 : struct xfs_buf *bp)
59 : {
60 78468 : xfs_failaddr_t fa = xfs_btree_mem_head_verify(bp);
61 :
62 78465 : if (fa)
63 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
64 78465 : }
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 78478 : xfs_btree_mem_head_init(
78 : struct xfs_buf *head_bp,
79 : unsigned long long owner,
80 : xfileoff_t leaf_xfoff)
81 : {
82 78478 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
83 78478 : struct xfs_mount *mp = head_bp->b_mount;
84 :
85 78478 : mhead->mh_magic = cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC);
86 78478 : mhead->mh_nlevels = cpu_to_be32(1);
87 78478 : mhead->mh_owner = cpu_to_be64(owner);
88 78478 : mhead->mh_root = cpu_to_be64(leaf_xfoff);
89 78478 : uuid_copy(&mhead->mh_uuid, &mp->m_sb.sb_meta_uuid);
90 :
91 78477 : head_bp->b_ops = &xfs_btree_mem_head_buf_ops;
92 78477 : }
93 :
94 : /* Return tree height from the in-memory btree head. */
95 : unsigned int
96 1051761266 : xfs_btree_mem_head_nlevels(
97 : struct xfs_buf *head_bp)
98 : {
99 1051761266 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
100 :
101 1051761266 : return be32_to_cpu(mhead->mh_nlevels);
102 : }
103 :
104 : /* Extract the buftarg target for this xfile btree. */
105 : struct xfs_buftarg *
106 1099145543 : xfbtree_target(struct xfbtree *xfbtree)
107 : {
108 3816884439 : 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 43887232 : xfs_daddr_t xfoff_daddr = xfo_to_daddr(xfoff);
118 :
119 2761626128 : return xfs_buftarg_verify_daddr(btp, xfoff_daddr);
120 : }
121 :
122 : /* Is this btree xfile offset contained within the xfile? */
123 : bool
124 414321085 : xfbtree_verify_xfileoff(
125 : struct xfs_btree_cur *cur,
126 : unsigned long long xfoff)
127 : {
128 2717738896 : struct xfs_buftarg *btp = xfbtree_target(cur->bc_mem.xfbtree);
129 :
130 414321085 : return xfbtree_verify_buftarg_xfileoff(btp, xfoff);
131 : }
132 :
133 : /* Check if a btree pointer is reasonable. */
134 : int
135 2303417811 : xfbtree_check_ptr(
136 : struct xfs_btree_cur *cur,
137 : const union xfs_btree_ptr *ptr,
138 : int index,
139 : int level)
140 : {
141 2303417811 : xfileoff_t bt_xfoff;
142 2303417811 : xfs_failaddr_t fa = NULL;
143 :
144 2303417811 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
145 :
146 2303417811 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
147 2125839197 : bt_xfoff = be64_to_cpu(ptr->l);
148 : else
149 177578614 : bt_xfoff = be32_to_cpu(ptr->s);
150 :
151 2303417811 : 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 2303417612 : if (bt_xfoff < XFBTREE_INIT_LEAF_BLOCK) {
158 0 : fa = __this_address;
159 0 : goto done;
160 : }
161 :
162 2303417612 : 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 2254738134 : xfbtree_ptr_to_daddr(
176 : struct xfs_btree_cur *cur,
177 : const union xfs_btree_ptr *ptr)
178 : {
179 2254738134 : xfileoff_t bt_xfoff;
180 :
181 2254738134 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
182 2110538161 : bt_xfoff = be64_to_cpu(ptr->l);
183 : else
184 144199973 : bt_xfoff = be32_to_cpu(ptr->s);
185 2254738134 : return xfo_to_daddr(bt_xfoff);
186 : }
187 :
188 : /* Set the pointer to point to this buffer. */
189 : void
190 11191 : xfbtree_buf_to_ptr(
191 : struct xfs_btree_cur *cur,
192 : struct xfs_buf *bp,
193 : union xfs_btree_ptr *ptr)
194 : {
195 11191 : xfileoff_t xfoff = xfs_daddr_to_xfo(xfs_buf_daddr(bp));
196 :
197 11191 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
198 2914 : ptr->l = cpu_to_be64(xfoff);
199 : else
200 8277 : ptr->s = cpu_to_be32(xfoff);
201 11191 : }
202 :
203 : /* Return the in-memory btree block size, in units of 512 bytes. */
204 1099145547 : unsigned int xfbtree_bbsize(void)
205 : {
206 1099145547 : return xfo_to_daddr(1);
207 : }
208 :
209 : /* Set the root of an in-memory btree. */
210 : void
211 1707 : xfbtree_set_root(
212 : struct xfs_btree_cur *cur,
213 : const union xfs_btree_ptr *ptr,
214 : int inc)
215 : {
216 1707 : struct xfs_buf *head_bp = cur->bc_mem.head_bp;
217 1707 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
218 :
219 1707 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
220 :
221 1707 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
222 192 : mhead->mh_root = ptr->l;
223 : } else {
224 1515 : uint32_t root = be32_to_cpu(ptr->s);
225 :
226 1515 : mhead->mh_root = cpu_to_be64(root);
227 : }
228 1707 : be32_add_cpu(&mhead->mh_nlevels, inc);
229 1707 : xfs_trans_log_buf(cur->bc_tp, head_bp, 0, sizeof(*mhead) - 1);
230 1707 : }
231 :
232 : /* Initialize a pointer from the in-memory btree header. */
233 : void
234 1106417099 : xfbtree_init_ptr_from_cur(
235 : struct xfs_btree_cur *cur,
236 : union xfs_btree_ptr *ptr)
237 : {
238 1106417099 : struct xfs_buf *head_bp = cur->bc_mem.head_bp;
239 1106417099 : struct xfs_btree_mem_head *mhead = head_bp->b_addr;
240 :
241 1106417099 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
242 :
243 1106417099 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
244 1047395269 : ptr->l = mhead->mh_root;
245 : } else {
246 59021830 : uint64_t root = be64_to_cpu(mhead->mh_root);
247 :
248 59021830 : ptr->s = cpu_to_be32(root);
249 : }
250 1106417099 : }
251 :
252 : /* Duplicate an in-memory btree cursor. */
253 : struct xfs_btree_cur *
254 6660483 : xfbtree_dup_cursor(
255 : struct xfs_btree_cur *cur)
256 : {
257 6660483 : struct xfs_btree_cur *ncur;
258 :
259 6660483 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
260 :
261 6660483 : ncur = xfs_btree_alloc_cursor(cur->bc_mp, cur->bc_tp, cur->bc_btnum,
262 : cur->bc_ops, cur->bc_maxlevels, cur->bc_cache);
263 6660483 : ncur->bc_flags = cur->bc_flags;
264 6660483 : ncur->bc_nlevels = cur->bc_nlevels;
265 6660483 : ncur->bc_statoff = cur->bc_statoff;
266 :
267 13320966 : memcpy(&ncur->bc_mem, &cur->bc_mem, sizeof(cur->bc_mem));
268 :
269 6660483 : if (cur->bc_mem.pag)
270 4309634 : ncur->bc_mem.pag = xfs_perag_hold(cur->bc_mem.pag);
271 6660483 : if (cur->bc_mem.rtg)
272 2350849 : ncur->bc_mem.rtg = xfs_rtgroup_hold(cur->bc_mem.rtg);
273 :
274 6660483 : return ncur;
275 : }
276 :
277 : /* Check the owner of an in-memory btree block. */
278 : xfs_failaddr_t
279 1071397119 : xfbtree_check_block_owner(
280 : struct xfs_btree_cur *cur,
281 : struct xfs_btree_block *block)
282 : {
283 1071397119 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
284 :
285 1071397119 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
286 1038284485 : if (be64_to_cpu(block->bb_u.l.bb_owner) != xfbt->owner)
287 0 : return __this_address;
288 :
289 : return NULL;
290 : }
291 :
292 33112634 : 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 11191 : xfbtree_owner(
301 : struct xfs_btree_cur *cur)
302 : {
303 11191 : return cur->bc_mem.xfbtree->owner;
304 : }
305 :
306 : /* Return the xfile offset (in blocks) of a btree buffer. */
307 : unsigned long long
308 3093635335 : xfbtree_buf_to_xfoff(
309 : struct xfs_btree_cur *cur,
310 : struct xfs_buf *bp)
311 : {
312 3093635335 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
313 :
314 3093635335 : return xfs_daddr_to_xfo(xfs_buf_daddr(bp));
315 : }
316 :
317 : /* Verify a long-format btree block. */
318 : xfs_failaddr_t
319 703240240 : xfbtree_lblock_verify(
320 : struct xfs_buf *bp,
321 : unsigned int max_recs)
322 : {
323 703240240 : struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
324 703240240 : struct xfs_buftarg *btp = bp->b_target;
325 :
326 : /* numrecs verification */
327 703240240 : if (be16_to_cpu(block->bb_numrecs) > max_recs)
328 0 : return __this_address;
329 :
330 : /* sibling pointer verification */
331 710920581 : if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) &&
332 7680343 : !xfbtree_verify_buftarg_xfileoff(btp,
333 7680343 : be64_to_cpu(block->bb_u.l.bb_leftsib)))
334 0 : return __this_address;
335 :
336 710786679 : if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) &&
337 7546441 : !xfbtree_verify_buftarg_xfileoff(btp,
338 7546441 : 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 28234856 : xfbtree_sblock_verify(
347 : struct xfs_buf *bp,
348 : unsigned int max_recs)
349 : {
350 28234856 : struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
351 28234856 : struct xfs_buftarg *btp = bp->b_target;
352 :
353 : /* numrecs verification */
354 28234856 : if (be16_to_cpu(block->bb_numrecs) > max_recs)
355 0 : return __this_address;
356 :
357 : /* sibling pointer verification */
358 43298818 : if (block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK) &&
359 15063962 : !xfbtree_verify_buftarg_xfileoff(btp,
360 15063962 : be32_to_cpu(block->bb_u.s.bb_leftsib)))
361 0 : return __this_address;
362 :
363 41831342 : if (block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK) &&
364 13596486 : !xfbtree_verify_buftarg_xfileoff(btp,
365 13596486 : 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 78472 : xfbtree_destroy(
374 : struct xfbtree *xfbt)
375 : {
376 78472 : xbitmap_destroy(xfbt->freespace);
377 78471 : kfree(xfbt->freespace);
378 78474 : xfs_buftarg_drain(xfbt->target);
379 78479 : kfree(xfbt);
380 78478 : }
381 :
382 : /* Compute the number of bytes available for records. */
383 : static inline unsigned int
384 78479 : xfbtree_rec_bytes(
385 : struct xfs_mount *mp,
386 : const struct xfbtree_config *cfg)
387 : {
388 78479 : unsigned int blocklen = xfo_to_b(1);
389 :
390 78479 : if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS) {
391 69218 : 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 9261 : if (xfs_has_crc(mp))
398 9261 : 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 78479 : xfbtree_init_leaf_block(
406 : struct xfs_mount *mp,
407 : struct xfbtree *xfbt,
408 : const struct xfbtree_config *cfg)
409 : {
410 78479 : struct xfs_buf *bp;
411 78479 : xfs_daddr_t daddr;
412 78479 : int error;
413 :
414 78479 : daddr = xfo_to_daddr(XFBTREE_INIT_LEAF_BLOCK);
415 78479 : error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
416 78470 : if (error)
417 : return error;
418 :
419 78472 : trace_xfbtree_create_root_buf(xfbt, bp);
420 :
421 78470 : xfs_btree_init_buf(mp, bp, cfg->btree_ops, 0, 0, cfg->owner);
422 78466 : error = xfs_bwrite(bp);
423 78473 : xfs_buf_relse(bp);
424 78463 : if (error)
425 : return error;
426 :
427 78463 : xfbt->xf_used++;
428 78463 : return 0;
429 : }
430 :
431 : /* Initialize the in-memory btree header block. */
432 : STATIC int
433 78478 : xfbtree_init_head(
434 : struct xfbtree *xfbt)
435 : {
436 78478 : struct xfs_buf *bp;
437 78478 : xfs_daddr_t daddr;
438 78478 : int error;
439 :
440 78478 : daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
441 78478 : error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
442 78478 : if (error)
443 : return error;
444 :
445 78478 : xfs_btree_mem_head_init(bp, xfbt->owner, XFBTREE_INIT_LEAF_BLOCK);
446 78478 : error = xfs_bwrite(bp);
447 78478 : xfs_buf_relse(bp);
448 78478 : if (error)
449 : return error;
450 :
451 78478 : xfbt->xf_used++;
452 78478 : return 0;
453 : }
454 :
455 : /* Create an xfile btree backing thing that can be used for in-memory btrees. */
456 : int
457 78479 : xfbtree_create(
458 : struct xfs_mount *mp,
459 : const struct xfbtree_config *cfg,
460 : struct xfbtree **xfbtreep)
461 : {
462 78479 : struct xfbtree *xfbt;
463 78479 : unsigned int blocklen = xfbtree_rec_bytes(mp, cfg);
464 78479 : unsigned int keyptr_len = cfg->btree_ops->key_len;
465 78479 : int error;
466 :
467 : /* Requires an xfile-backed buftarg. */
468 78479 : 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 78479 : xfbt = kzalloc(sizeof(struct xfbtree), XCHK_GFP_FLAGS);
474 78479 : if (!xfbt)
475 : return -ENOMEM;
476 :
477 : /* Assign our memory file and the free space bitmap. */
478 78479 : xfbt->target = cfg->target;
479 78479 : if (cfg->flags & XFBTREE_DIRECT_MAP)
480 78479 : xfbt->target->bt_flags |= XFS_BUFTARG_DIRECT_MAP;
481 :
482 78479 : xfbt->freespace = kmalloc(sizeof(struct xbitmap), XCHK_GFP_FLAGS);
483 78479 : if (!xfbt->freespace) {
484 0 : error = -ENOMEM;
485 0 : goto err_buftarg;
486 : }
487 78479 : xbitmap_init(xfbt->freespace);
488 :
489 : /* Set up min/maxrecs for this btree. */
490 78479 : if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS)
491 69218 : keyptr_len += sizeof(__be64);
492 : else
493 9261 : keyptr_len += sizeof(__be32);
494 78479 : xfbt->maxrecs[0] = blocklen / cfg->btree_ops->rec_len;
495 78479 : xfbt->maxrecs[1] = blocklen / keyptr_len;
496 78479 : xfbt->minrecs[0] = xfbt->maxrecs[0] / 2;
497 78479 : xfbt->minrecs[1] = xfbt->maxrecs[1] / 2;
498 78479 : xfbt->owner = cfg->owner;
499 :
500 : /* Initialize the empty btree. */
501 78479 : error = xfbtree_init_leaf_block(mp, xfbt, cfg);
502 78465 : if (error)
503 0 : goto err_freesp;
504 :
505 78465 : error = xfbtree_init_head(xfbt);
506 78479 : if (error)
507 0 : goto err_freesp;
508 :
509 78479 : trace_xfbtree_create(mp, cfg, xfbt);
510 :
511 78478 : *xfbtreep = xfbt;
512 78478 : 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 1051760716 : xfbtree_head_read_buf(
526 : struct xfbtree *xfbt,
527 : struct xfs_trans *tp,
528 : struct xfs_buf **bpp)
529 : {
530 1051760716 : struct xfs_buftarg *btp = xfbt->target;
531 1051760716 : struct xfs_mount *mp = btp->bt_mount;
532 1051760716 : struct xfs_btree_mem_head *mhead;
533 1051760716 : struct xfs_buf *bp;
534 1051760716 : xfs_daddr_t daddr;
535 1051760716 : int error;
536 :
537 1051760716 : daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
538 1051760716 : error = xfs_trans_read_buf(mp, tp, btp, daddr, xfbtree_bbsize(), 0,
539 : &bp, &xfs_btree_mem_head_buf_ops);
540 1051761276 : if (error)
541 : return error;
542 :
543 1051761276 : mhead = bp->b_addr;
544 1051761276 : 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 1051761276 : *bpp = bp;
551 1051761276 : return 0;
552 : }
553 :
554 : static inline struct xfile *xfbtree_xfile(struct xfbtree *xfbt)
555 : {
556 11191 : return xfbt->target->bt_xfile;
557 : }
558 :
559 : /* Allocate a block to our in-memory btree. */
560 : int
561 11191 : 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 11191 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
568 11191 : xfileoff_t bt_xfoff;
569 11191 : loff_t pos;
570 11191 : int error;
571 :
572 11191 : 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 11191 : error = xbitmap_take_first_set(xfbt->freespace, 0, -1ULL, &bt_xfoff);
579 11191 : if (error == -ENODATA) {
580 11189 : bt_xfoff = xfbt->xf_used;
581 11189 : xfbt->xf_used++;
582 2 : } else if (error) {
583 : return error;
584 : }
585 :
586 11191 : trace_xfbtree_alloc_block(xfbt, cur, bt_xfoff);
587 :
588 : /* Fail if the block address exceeds the maximum for short pointers. */
589 11191 : 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 11191 : pos = xfo_to_b(bt_xfoff);
596 11191 : error = xfile_prealloc(xfbtree_xfile(xfbt), pos, xfo_to_b(1));
597 11191 : if (error)
598 : return error;
599 :
600 11191 : if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
601 2914 : new->l = cpu_to_be64(bt_xfoff);
602 : else
603 8277 : new->s = cpu_to_be32(bt_xfoff);
604 :
605 11191 : *stat = 1;
606 11191 : return 0;
607 : }
608 :
609 : /* Free a block from our in-memory btree. */
610 : int
611 2 : xfbtree_free_block(
612 : struct xfs_btree_cur *cur,
613 : struct xfs_buf *bp)
614 : {
615 2 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
616 2 : xfileoff_t bt_xfoff, bt_xflen;
617 :
618 2 : ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
619 :
620 2 : bt_xfoff = xfs_daddr_to_xfot(xfs_buf_daddr(bp));
621 2 : bt_xflen = xfs_daddr_to_xfot(bp->b_length);
622 :
623 2 : trace_xfbtree_free_block(xfbt, cur, bt_xfoff);
624 :
625 2 : 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 109295 : xfbtree_get_minrecs(
631 : struct xfs_btree_cur *cur,
632 : int level)
633 : {
634 109295 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
635 :
636 109295 : return xfbt->minrecs[level != 0];
637 : }
638 :
639 : /* Return the maximum number of records for a btree block. */
640 : int
641 3626998184 : xfbtree_get_maxrecs(
642 : struct xfs_btree_cur *cur,
643 : int level)
644 : {
645 3626998184 : struct xfbtree *xfbt = cur->bc_mem.xfbtree;
646 :
647 3626998184 : 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 4729525197 : const struct xfs_buf_log_item *bli;
657 4729525197 : struct xfs_buf *bp;
658 :
659 4729525197 : if (lip->li_type != XFS_LI_BUF)
660 : return NULL;
661 :
662 4729525195 : bli = container_of(lip, struct xfs_buf_log_item, bli_item);
663 4729525195 : bp = bli->bli_buf;
664 4729525195 : 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 758903551 : xfbtree_trans_bdetach(
676 : struct xfs_trans *tp,
677 : struct xfs_buf *bp)
678 : {
679 758903551 : struct xfs_buf_log_item *bli = bp->b_log_item;
680 758903551 : bool dirty;
681 :
682 758903551 : ASSERT(bli != NULL);
683 :
684 758903551 : dirty = bli->bli_flags & (XFS_BLI_DIRTY | XFS_BLI_ORDERED);
685 :
686 758903551 : bli->bli_flags &= ~(XFS_BLI_DIRTY | XFS_BLI_ORDERED |
687 : XFS_BLI_LOGGED | XFS_BLI_STALE);
688 758903551 : clear_bit(XFS_LI_DIRTY, &bli->bli_item.li_flags);
689 :
690 1517807899 : while (bp->b_log_item != NULL)
691 758903858 : xfs_trans_bdetach(tp, bp);
692 :
693 758904041 : 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 719890222 : xfbtree_trans_commit(
715 : struct xfbtree *xfbt,
716 : struct xfs_trans *tp)
717 : {
718 719890222 : LIST_HEAD(buffer_list);
719 719890222 : struct xfs_log_item *lip, *n;
720 719890222 : bool corrupt = false;
721 719890222 : 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 5449415529 : list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
728 4729525197 : struct xfs_buf *bp = xfbtree_buf_match(xfbt, lip);
729 758903942 : bool dirty;
730 :
731 758903942 : if (!bp) {
732 7941242510 : if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
733 0 : tp_dirty |= true;
734 3970621255 : continue;
735 : }
736 :
737 758903942 : trace_xfbtree_trans_commit_buf(xfbt, bp);
738 :
739 758903900 : dirty = xfbtree_trans_bdetach(tp, bp);
740 758904052 : if (dirty && !corrupt) {
741 731398323 : 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 731398323 : 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 731398342 : fa = bp->b_ops->verify_struct(bp);
765 731398321 : if (fa) {
766 0 : corrupt = true;
767 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
768 0 : continue;
769 : }
770 :
771 731398321 : if (!(bp->b_flags & _XBF_DIRECT_MAP))
772 0 : xfs_buf_delwri_queue_here(bp, &buffer_list);
773 : }
774 :
775 758904050 : 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 1439780664 : tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
783 719890332 : (tp_dirty ? XFS_TRANS_DIRTY : 0);
784 :
785 719890332 : if (corrupt) {
786 0 : xfs_buf_delwri_cancel(&buffer_list);
787 0 : return -EFSCORRUPTED;
788 : }
789 :
790 719890332 : 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 : }
|