1
2
3
4
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_inode.h"
15#include "xfs_trans.h"
16#include "xfs_btree.h"
17#include "xfs_trace.h"
18#include "xfs_btree_staging.h"
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45STATIC struct xfs_btree_cur *
46xfs_btree_fakeroot_dup_cursor(
47 struct xfs_btree_cur *cur)
48{
49 ASSERT(0);
50 return NULL;
51}
52
53
54
55
56
57
58
59
60STATIC int
61xfs_btree_fakeroot_alloc_block(
62 struct xfs_btree_cur *cur,
63 const union xfs_btree_ptr *start_bno,
64 union xfs_btree_ptr *new_bno,
65 int *stat)
66{
67 ASSERT(0);
68 return -EFSCORRUPTED;
69}
70
71
72
73
74
75STATIC int
76xfs_btree_fakeroot_free_block(
77 struct xfs_btree_cur *cur,
78 struct xfs_buf *bp)
79{
80 ASSERT(0);
81 return -EFSCORRUPTED;
82}
83
84
85STATIC void
86xfs_btree_fakeroot_init_ptr_from_cur(
87 struct xfs_btree_cur *cur,
88 union xfs_btree_ptr *ptr)
89{
90 struct xbtree_afakeroot *afake;
91
92 ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
93
94 afake = cur->bc_ag.afake;
95 ptr->s = cpu_to_be32(afake->af_root);
96}
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113STATIC void
114xfs_btree_afakeroot_set_root(
115 struct xfs_btree_cur *cur,
116 const union xfs_btree_ptr *ptr,
117 int inc)
118{
119 struct xbtree_afakeroot *afake = cur->bc_ag.afake;
120
121 ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
122 afake->af_root = be32_to_cpu(ptr->s);
123 afake->af_levels += inc;
124}
125
126
127
128
129
130
131void
132xfs_btree_stage_afakeroot(
133 struct xfs_btree_cur *cur,
134 struct xbtree_afakeroot *afake)
135{
136 struct xfs_btree_ops *nops;
137
138 ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
139 ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE));
140 ASSERT(cur->bc_tp == NULL);
141
142 nops = kmem_alloc(sizeof(struct xfs_btree_ops), KM_NOFS);
143 memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
144 nops->alloc_block = xfs_btree_fakeroot_alloc_block;
145 nops->free_block = xfs_btree_fakeroot_free_block;
146 nops->init_ptr_from_cur = xfs_btree_fakeroot_init_ptr_from_cur;
147 nops->set_root = xfs_btree_afakeroot_set_root;
148 nops->dup_cursor = xfs_btree_fakeroot_dup_cursor;
149
150 cur->bc_ag.afake = afake;
151 cur->bc_nlevels = afake->af_levels;
152 cur->bc_ops = nops;
153 cur->bc_flags |= XFS_BTREE_STAGING;
154}
155
156
157
158
159
160
161
162void
163xfs_btree_commit_afakeroot(
164 struct xfs_btree_cur *cur,
165 struct xfs_trans *tp,
166 struct xfs_buf *agbp,
167 const struct xfs_btree_ops *ops)
168{
169 ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
170 ASSERT(cur->bc_tp == NULL);
171
172 trace_xfs_btree_commit_afakeroot(cur);
173
174 kmem_free((void *)cur->bc_ops);
175 cur->bc_ag.agbp = agbp;
176 cur->bc_ops = ops;
177 cur->bc_flags &= ~XFS_BTREE_STAGING;
178 cur->bc_tp = tp;
179}
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211void
212xfs_btree_stage_ifakeroot(
213 struct xfs_btree_cur *cur,
214 struct xbtree_ifakeroot *ifake,
215 struct xfs_btree_ops **new_ops)
216{
217 struct xfs_btree_ops *nops;
218
219 ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
220 ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
221 ASSERT(cur->bc_tp == NULL);
222
223 nops = kmem_alloc(sizeof(struct xfs_btree_ops), KM_NOFS);
224 memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
225 nops->alloc_block = xfs_btree_fakeroot_alloc_block;
226 nops->free_block = xfs_btree_fakeroot_free_block;
227 nops->init_ptr_from_cur = xfs_btree_fakeroot_init_ptr_from_cur;
228 nops->dup_cursor = xfs_btree_fakeroot_dup_cursor;
229
230 cur->bc_ino.ifake = ifake;
231 cur->bc_nlevels = ifake->if_levels;
232 cur->bc_ops = nops;
233 cur->bc_flags |= XFS_BTREE_STAGING;
234
235 if (new_ops)
236 *new_ops = nops;
237}
238
239
240
241
242
243
244
245void
246xfs_btree_commit_ifakeroot(
247 struct xfs_btree_cur *cur,
248 struct xfs_trans *tp,
249 int whichfork,
250 const struct xfs_btree_ops *ops)
251{
252 ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
253 ASSERT(cur->bc_tp == NULL);
254
255 trace_xfs_btree_commit_ifakeroot(cur);
256
257 kmem_free((void *)cur->bc_ops);
258 cur->bc_ino.ifake = NULL;
259 cur->bc_ino.whichfork = whichfork;
260 cur->bc_ops = ops;
261 cur->bc_flags &= ~XFS_BTREE_STAGING;
262 cur->bc_tp = tp;
263}
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337static void
338xfs_btree_bload_drop_buf(
339 struct list_head *buffers_list,
340 struct xfs_buf **bpp)
341{
342 if (*bpp == NULL)
343 return;
344
345 if (!xfs_buf_delwri_queue(*bpp, buffers_list))
346 ASSERT(0);
347
348 xfs_buf_relse(*bpp);
349 *bpp = NULL;
350}
351
352
353
354
355
356
357
358
359
360
361
362STATIC int
363xfs_btree_bload_prep_block(
364 struct xfs_btree_cur *cur,
365 struct xfs_btree_bload *bbl,
366 struct list_head *buffers_list,
367 unsigned int level,
368 unsigned int nr_this_block,
369 union xfs_btree_ptr *ptrp,
370 struct xfs_buf **bpp,
371 struct xfs_btree_block **blockp,
372 void *priv)
373{
374 union xfs_btree_ptr new_ptr;
375 struct xfs_buf *new_bp;
376 struct xfs_btree_block *new_block;
377 int ret;
378
379 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
380 level == cur->bc_nlevels - 1) {
381 struct xfs_ifork *ifp = xfs_btree_ifork_ptr(cur);
382 size_t new_size;
383
384 ASSERT(*bpp == NULL);
385
386
387 new_size = bbl->iroot_size(cur, nr_this_block, priv);
388 ifp->if_broot = kmem_zalloc(new_size, 0);
389 ifp->if_broot_bytes = (int)new_size;
390
391
392 xfs_btree_init_block_int(cur->bc_mp, ifp->if_broot,
393 XFS_BUF_DADDR_NULL, cur->bc_btnum, level,
394 nr_this_block, cur->bc_ino.ip->i_ino,
395 cur->bc_flags);
396
397 *bpp = NULL;
398 *blockp = ifp->if_broot;
399 xfs_btree_set_ptr_null(cur, ptrp);
400 return 0;
401 }
402
403
404 xfs_btree_set_ptr_null(cur, &new_ptr);
405 ret = bbl->claim_block(cur, &new_ptr, priv);
406 if (ret)
407 return ret;
408
409 ASSERT(!xfs_btree_ptr_is_null(cur, &new_ptr));
410
411 ret = xfs_btree_get_buf_block(cur, &new_ptr, &new_block, &new_bp);
412 if (ret)
413 return ret;
414
415
416
417
418
419 if (*blockp)
420 xfs_btree_set_sibling(cur, *blockp, &new_ptr, XFS_BB_RIGHTSIB);
421 xfs_btree_bload_drop_buf(buffers_list, bpp);
422
423
424 xfs_btree_init_block_cur(cur, new_bp, level, nr_this_block);
425 xfs_btree_set_sibling(cur, new_block, ptrp, XFS_BB_LEFTSIB);
426
427
428 *bpp = new_bp;
429 *blockp = new_block;
430 xfs_btree_copy_ptrs(cur, ptrp, &new_ptr, 1);
431 return 0;
432}
433
434
435STATIC int
436xfs_btree_bload_leaf(
437 struct xfs_btree_cur *cur,
438 unsigned int recs_this_block,
439 xfs_btree_bload_get_record_fn get_record,
440 struct xfs_btree_block *block,
441 void *priv)
442{
443 unsigned int j;
444 int ret;
445
446
447 for (j = 1; j <= recs_this_block; j++) {
448 union xfs_btree_rec *block_rec;
449
450 ret = get_record(cur, priv);
451 if (ret)
452 return ret;
453 block_rec = xfs_btree_rec_addr(cur, j, block);
454 cur->bc_ops->init_rec_from_cur(cur, block_rec);
455 }
456
457 return 0;
458}
459
460
461
462
463
464
465
466
467
468STATIC int
469xfs_btree_bload_node(
470 struct xfs_btree_cur *cur,
471 unsigned int recs_this_block,
472 union xfs_btree_ptr *child_ptr,
473 struct xfs_btree_block *block)
474{
475 unsigned int j;
476 int ret;
477
478
479 for (j = 1; j <= recs_this_block; j++) {
480 union xfs_btree_key child_key;
481 union xfs_btree_ptr *block_ptr;
482 union xfs_btree_key *block_key;
483 struct xfs_btree_block *child_block;
484 struct xfs_buf *child_bp;
485
486 ASSERT(!xfs_btree_ptr_is_null(cur, child_ptr));
487
488 ret = xfs_btree_get_buf_block(cur, child_ptr, &child_block,
489 &child_bp);
490 if (ret)
491 return ret;
492
493 block_ptr = xfs_btree_ptr_addr(cur, j, block);
494 xfs_btree_copy_ptrs(cur, block_ptr, child_ptr, 1);
495
496 block_key = xfs_btree_key_addr(cur, j, block);
497 xfs_btree_get_keys(cur, child_block, &child_key);
498 xfs_btree_copy_keys(cur, block_key, &child_key, 1);
499
500 xfs_btree_get_sibling(cur, child_block, child_ptr,
501 XFS_BB_RIGHTSIB);
502 xfs_buf_relse(child_bp);
503 }
504
505 return 0;
506}
507
508
509
510
511
512
513STATIC unsigned int
514xfs_btree_bload_max_npb(
515 struct xfs_btree_cur *cur,
516 struct xfs_btree_bload *bbl,
517 unsigned int level)
518{
519 unsigned int ret;
520
521 if (level == cur->bc_nlevels - 1 && cur->bc_ops->get_dmaxrecs)
522 return cur->bc_ops->get_dmaxrecs(cur, level);
523
524 ret = cur->bc_ops->get_maxrecs(cur, level);
525 if (level == 0)
526 ret -= bbl->leaf_slack;
527 else
528 ret -= bbl->node_slack;
529 return ret;
530}
531
532
533
534
535
536
537STATIC unsigned int
538xfs_btree_bload_desired_npb(
539 struct xfs_btree_cur *cur,
540 struct xfs_btree_bload *bbl,
541 unsigned int level)
542{
543 unsigned int npb = xfs_btree_bload_max_npb(cur, bbl, level);
544
545
546 if (level == cur->bc_nlevels - 1)
547 return max(1U, npb);
548
549 return max_t(unsigned int, cur->bc_ops->get_minrecs(cur, level), npb);
550}
551
552
553
554
555
556
557
558STATIC void
559xfs_btree_bload_level_geometry(
560 struct xfs_btree_cur *cur,
561 struct xfs_btree_bload *bbl,
562 unsigned int level,
563 uint64_t nr_this_level,
564 unsigned int *avg_per_block,
565 uint64_t *blocks,
566 uint64_t *blocks_with_extra)
567{
568 uint64_t npb;
569 uint64_t dontcare;
570 unsigned int desired_npb;
571 unsigned int maxnr;
572
573 maxnr = cur->bc_ops->get_maxrecs(cur, level);
574
575
576
577
578
579
580
581
582 desired_npb = xfs_btree_bload_desired_npb(cur, bbl, level);
583 *blocks = div64_u64_rem(nr_this_level, desired_npb, &dontcare);
584 *blocks = max(1ULL, *blocks);
585
586
587
588
589
590
591
592
593
594 npb = div64_u64_rem(nr_this_level, *blocks, blocks_with_extra);
595 if (npb > maxnr || (npb == maxnr && *blocks_with_extra > 0)) {
596 (*blocks)++;
597 npb = div64_u64_rem(nr_this_level, *blocks, blocks_with_extra);
598 }
599
600 *avg_per_block = min_t(uint64_t, npb, nr_this_level);
601
602 trace_xfs_btree_bload_level_geometry(cur, level, nr_this_level,
603 *avg_per_block, desired_npb, *blocks,
604 *blocks_with_extra);
605}
606
607
608
609
610
611
612
613
614static void
615xfs_btree_bload_ensure_slack(
616 struct xfs_btree_cur *cur,
617 int *slack,
618 int level)
619{
620 int maxr;
621 int minr;
622
623 maxr = cur->bc_ops->get_maxrecs(cur, level);
624 minr = cur->bc_ops->get_minrecs(cur, level);
625
626
627
628
629
630
631 if (*slack < 0)
632 *slack = maxr - ((maxr + minr) >> 1);
633
634 *slack = min(*slack, maxr - minr);
635}
636
637
638
639
640
641
642int
643xfs_btree_bload_compute_geometry(
644 struct xfs_btree_cur *cur,
645 struct xfs_btree_bload *bbl,
646 uint64_t nr_records)
647{
648 uint64_t nr_blocks = 0;
649 uint64_t nr_this_level;
650
651 ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
652
653
654
655
656
657
658
659
660 cur->bc_nlevels = cur->bc_maxlevels - 1;
661 xfs_btree_bload_ensure_slack(cur, &bbl->leaf_slack, 0);
662 xfs_btree_bload_ensure_slack(cur, &bbl->node_slack, 1);
663
664 bbl->nr_records = nr_this_level = nr_records;
665 for (cur->bc_nlevels = 1; cur->bc_nlevels <= cur->bc_maxlevels;) {
666 uint64_t level_blocks;
667 uint64_t dontcare64;
668 unsigned int level = cur->bc_nlevels - 1;
669 unsigned int avg_per_block;
670
671 xfs_btree_bload_level_geometry(cur, bbl, level, nr_this_level,
672 &avg_per_block, &level_blocks, &dontcare64);
673
674 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
675
676
677
678
679
680
681
682 if (level != 0 && nr_this_level <= avg_per_block) {
683 nr_blocks++;
684 break;
685 }
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705 cur->bc_nlevels++;
706 ASSERT(cur->bc_nlevels <= cur->bc_maxlevels);
707 xfs_btree_bload_level_geometry(cur, bbl, level,
708 nr_this_level, &avg_per_block,
709 &level_blocks, &dontcare64);
710 } else {
711
712
713
714
715 if (nr_this_level <= avg_per_block) {
716 nr_blocks++;
717 break;
718 }
719
720
721 cur->bc_nlevels++;
722 ASSERT(cur->bc_nlevels <= cur->bc_maxlevels);
723 }
724
725 nr_blocks += level_blocks;
726 nr_this_level = level_blocks;
727 }
728
729 if (cur->bc_nlevels > cur->bc_maxlevels)
730 return -EOVERFLOW;
731
732 bbl->btree_height = cur->bc_nlevels;
733 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
734 bbl->nr_blocks = nr_blocks - 1;
735 else
736 bbl->nr_blocks = nr_blocks;
737 return 0;
738}
739
740
741int
742xfs_btree_bload(
743 struct xfs_btree_cur *cur,
744 struct xfs_btree_bload *bbl,
745 void *priv)
746{
747 struct list_head buffers_list;
748 union xfs_btree_ptr child_ptr;
749 union xfs_btree_ptr ptr;
750 struct xfs_buf *bp = NULL;
751 struct xfs_btree_block *block = NULL;
752 uint64_t nr_this_level = bbl->nr_records;
753 uint64_t blocks;
754 uint64_t i;
755 uint64_t blocks_with_extra;
756 uint64_t total_blocks = 0;
757 unsigned int avg_per_block;
758 unsigned int level = 0;
759 int ret;
760
761 ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
762
763 INIT_LIST_HEAD(&buffers_list);
764 cur->bc_nlevels = bbl->btree_height;
765 xfs_btree_set_ptr_null(cur, &child_ptr);
766 xfs_btree_set_ptr_null(cur, &ptr);
767
768 xfs_btree_bload_level_geometry(cur, bbl, level, nr_this_level,
769 &avg_per_block, &blocks, &blocks_with_extra);
770
771
772 for (i = 0; i < blocks; i++) {
773 unsigned int nr_this_block = avg_per_block;
774
775
776
777
778
779
780
781 if (i < blocks_with_extra)
782 nr_this_block++;
783
784 ret = xfs_btree_bload_prep_block(cur, bbl, &buffers_list, level,
785 nr_this_block, &ptr, &bp, &block, priv);
786 if (ret)
787 goto out;
788
789 trace_xfs_btree_bload_block(cur, level, i, blocks, &ptr,
790 nr_this_block);
791
792 ret = xfs_btree_bload_leaf(cur, nr_this_block, bbl->get_record,
793 block, priv);
794 if (ret)
795 goto out;
796
797
798
799
800
801 if (i == 0)
802 xfs_btree_copy_ptrs(cur, &child_ptr, &ptr, 1);
803 }
804 total_blocks += blocks;
805 xfs_btree_bload_drop_buf(&buffers_list, &bp);
806
807
808 for (level = 1; level < cur->bc_nlevels; level++) {
809 union xfs_btree_ptr first_ptr;
810
811 nr_this_level = blocks;
812 block = NULL;
813 xfs_btree_set_ptr_null(cur, &ptr);
814
815 xfs_btree_bload_level_geometry(cur, bbl, level, nr_this_level,
816 &avg_per_block, &blocks, &blocks_with_extra);
817
818
819 for (i = 0; i < blocks; i++) {
820 unsigned int nr_this_block = avg_per_block;
821
822 if (i < blocks_with_extra)
823 nr_this_block++;
824
825 ret = xfs_btree_bload_prep_block(cur, bbl,
826 &buffers_list, level, nr_this_block,
827 &ptr, &bp, &block, priv);
828 if (ret)
829 goto out;
830
831 trace_xfs_btree_bload_block(cur, level, i, blocks,
832 &ptr, nr_this_block);
833
834 ret = xfs_btree_bload_node(cur, nr_this_block,
835 &child_ptr, block);
836 if (ret)
837 goto out;
838
839
840
841
842
843 if (i == 0)
844 xfs_btree_copy_ptrs(cur, &first_ptr, &ptr, 1);
845 }
846 total_blocks += blocks;
847 xfs_btree_bload_drop_buf(&buffers_list, &bp);
848 xfs_btree_copy_ptrs(cur, &child_ptr, &first_ptr, 1);
849 }
850
851
852 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
853 ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
854 cur->bc_ino.ifake->if_levels = cur->bc_nlevels;
855 cur->bc_ino.ifake->if_blocks = total_blocks - 1;
856 } else {
857 cur->bc_ag.afake->af_root = be32_to_cpu(ptr.s);
858 cur->bc_ag.afake->af_levels = cur->bc_nlevels;
859 cur->bc_ag.afake->af_blocks = total_blocks;
860 }
861
862
863
864
865
866
867 ret = xfs_buf_delwri_submit(&buffers_list);
868 if (ret)
869 goto out;
870 if (!list_empty(&buffers_list)) {
871 ASSERT(list_empty(&buffers_list));
872 ret = -EIO;
873 }
874
875out:
876 xfs_buf_delwri_cancel(&buffers_list);
877 if (bp)
878 xfs_buf_relse(bp);
879 return ret;
880}
881