hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/fs/xfs/libxfs/xfs_alloc.c
....@@ -13,7 +13,6 @@
1313 #include "xfs_sb.h"
1414 #include "xfs_mount.h"
1515 #include "xfs_defer.h"
16
-#include "xfs_inode.h"
1716 #include "xfs_btree.h"
1817 #include "xfs_rmap.h"
1918 #include "xfs_alloc_btree.h"
....@@ -21,7 +20,6 @@
2120 #include "xfs_extent_busy.h"
2221 #include "xfs_errortag.h"
2322 #include "xfs_error.h"
24
-#include "xfs_cksum.h"
2523 #include "xfs_trace.h"
2624 #include "xfs_trans.h"
2725 #include "xfs_buf_item.h"
....@@ -41,8 +39,6 @@
4139 STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *);
4240 STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *);
4341 STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *);
44
-STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *,
45
- xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *);
4642
4743 /*
4844 * Size of the AGFL. For CRC-enabled filesystes we steal a couple of slots in
....@@ -150,9 +146,13 @@
150146 xfs_extlen_t len, /* length of extent */
151147 int *stat) /* success/failure */
152148 {
149
+ int error;
150
+
153151 cur->bc_rec.a.ar_startblock = bno;
154152 cur->bc_rec.a.ar_blockcount = len;
155
- return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
153
+ error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
154
+ cur->bc_ag.abt.active = (*stat == 1);
155
+ return error;
156156 }
157157
158158 /*
....@@ -166,9 +166,13 @@
166166 xfs_extlen_t len, /* length of extent */
167167 int *stat) /* success/failure */
168168 {
169
+ int error;
170
+
169171 cur->bc_rec.a.ar_startblock = bno;
170172 cur->bc_rec.a.ar_blockcount = len;
171
- return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
173
+ error = xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
174
+ cur->bc_ag.abt.active = (*stat == 1);
175
+ return error;
172176 }
173177
174178 /*
....@@ -182,9 +186,19 @@
182186 xfs_extlen_t len, /* length of extent */
183187 int *stat) /* success/failure */
184188 {
189
+ int error;
185190 cur->bc_rec.a.ar_startblock = bno;
186191 cur->bc_rec.a.ar_blockcount = len;
187
- return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
192
+ error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
193
+ cur->bc_ag.abt.active = (*stat == 1);
194
+ return error;
195
+}
196
+
197
+static inline bool
198
+xfs_alloc_cur_active(
199
+ struct xfs_btree_cur *cur)
200
+{
201
+ return cur && cur->bc_ag.abt.active;
188202 }
189203
190204 /*
....@@ -216,7 +230,7 @@
216230 int *stat) /* output: success/failure */
217231 {
218232 struct xfs_mount *mp = cur->bc_mp;
219
- xfs_agnumber_t agno = cur->bc_private.a.agno;
233
+ xfs_agnumber_t agno = cur->bc_ag.agno;
220234 union xfs_btree_rec *rec;
221235 int error;
222236
....@@ -317,7 +331,7 @@
317331 xfs_extlen_t newlen1=0; /* length with newbno1 */
318332 xfs_extlen_t newlen2=0; /* length with newbno2 */
319333 xfs_agblock_t wantend; /* end of target extent */
320
- bool userdata = xfs_alloc_is_userdata(datatype);
334
+ bool userdata = datatype & XFS_ALLOC_USERDATA;
321335
322336 ASSERT(freelen >= wantlen);
323337 freeend = freebno + freelen;
....@@ -437,13 +451,17 @@
437451 #ifdef DEBUG
438452 if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i)))
439453 return error;
440
- XFS_WANT_CORRUPTED_RETURN(mp,
441
- i == 1 && nfbno1 == fbno && nflen1 == flen);
454
+ if (XFS_IS_CORRUPT(mp,
455
+ i != 1 ||
456
+ nfbno1 != fbno ||
457
+ nflen1 != flen))
458
+ return -EFSCORRUPTED;
442459 #endif
443460 } else {
444461 if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
445462 return error;
446
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
463
+ if (XFS_IS_CORRUPT(mp, i != 1))
464
+ return -EFSCORRUPTED;
447465 }
448466 /*
449467 * Look up the record in the by-block tree if necessary.
....@@ -452,13 +470,17 @@
452470 #ifdef DEBUG
453471 if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i)))
454472 return error;
455
- XFS_WANT_CORRUPTED_RETURN(mp,
456
- i == 1 && nfbno1 == fbno && nflen1 == flen);
473
+ if (XFS_IS_CORRUPT(mp,
474
+ i != 1 ||
475
+ nfbno1 != fbno ||
476
+ nflen1 != flen))
477
+ return -EFSCORRUPTED;
457478 #endif
458479 } else {
459480 if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
460481 return error;
461
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
482
+ if (XFS_IS_CORRUPT(mp, i != 1))
483
+ return -EFSCORRUPTED;
462484 }
463485
464486 #ifdef DEBUG
....@@ -469,8 +491,10 @@
469491 bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]);
470492 cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]);
471493
472
- XFS_WANT_CORRUPTED_RETURN(mp,
473
- bnoblock->bb_numrecs == cntblock->bb_numrecs);
494
+ if (XFS_IS_CORRUPT(mp,
495
+ bnoblock->bb_numrecs !=
496
+ cntblock->bb_numrecs))
497
+ return -EFSCORRUPTED;
474498 }
475499 #endif
476500
....@@ -500,25 +524,30 @@
500524 */
501525 if ((error = xfs_btree_delete(cnt_cur, &i)))
502526 return error;
503
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
527
+ if (XFS_IS_CORRUPT(mp, i != 1))
528
+ return -EFSCORRUPTED;
504529 /*
505530 * Add new by-size btree entry(s).
506531 */
507532 if (nfbno1 != NULLAGBLOCK) {
508533 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
509534 return error;
510
- XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
535
+ if (XFS_IS_CORRUPT(mp, i != 0))
536
+ return -EFSCORRUPTED;
511537 if ((error = xfs_btree_insert(cnt_cur, &i)))
512538 return error;
513
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
539
+ if (XFS_IS_CORRUPT(mp, i != 1))
540
+ return -EFSCORRUPTED;
514541 }
515542 if (nfbno2 != NULLAGBLOCK) {
516543 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
517544 return error;
518
- XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
545
+ if (XFS_IS_CORRUPT(mp, i != 0))
546
+ return -EFSCORRUPTED;
519547 if ((error = xfs_btree_insert(cnt_cur, &i)))
520548 return error;
521
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
549
+ if (XFS_IS_CORRUPT(mp, i != 1))
550
+ return -EFSCORRUPTED;
522551 }
523552 /*
524553 * Fix up the by-block btree entry(s).
....@@ -529,7 +558,8 @@
529558 */
530559 if ((error = xfs_btree_delete(bno_cur, &i)))
531560 return error;
532
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
561
+ if (XFS_IS_CORRUPT(mp, i != 1))
562
+ return -EFSCORRUPTED;
533563 } else {
534564 /*
535565 * Update the by-block entry to start later|be shorter.
....@@ -543,10 +573,12 @@
543573 */
544574 if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
545575 return error;
546
- XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
576
+ if (XFS_IS_CORRUPT(mp, i != 0))
577
+ return -EFSCORRUPTED;
547578 if ((error = xfs_btree_insert(bno_cur, &i)))
548579 return error;
549
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
580
+ if (XFS_IS_CORRUPT(mp, i != 1))
581
+ return -EFSCORRUPTED;
550582 }
551583 return 0;
552584 }
....@@ -555,8 +587,9 @@
555587 xfs_agfl_verify(
556588 struct xfs_buf *bp)
557589 {
558
- struct xfs_mount *mp = bp->b_target->bt_mount;
590
+ struct xfs_mount *mp = bp->b_mount;
559591 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
592
+ __be32 *agfl_bno = xfs_buf_to_agfl_bno(bp);
560593 int i;
561594
562595 /*
....@@ -568,9 +601,9 @@
568601 if (!xfs_sb_version_hascrc(&mp->m_sb))
569602 return NULL;
570603
571
- if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
604
+ if (!xfs_verify_magic(bp, agfl->agfl_magicnum))
572605 return __this_address;
573
- if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC)
606
+ if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
574607 return __this_address;
575608 /*
576609 * during growfs operations, the perag is not fully initialised,
....@@ -582,8 +615,8 @@
582615 return __this_address;
583616
584617 for (i = 0; i < xfs_agfl_size(mp); i++) {
585
- if (be32_to_cpu(agfl->agfl_bno[i]) != NULLAGBLOCK &&
586
- be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks)
618
+ if (be32_to_cpu(agfl_bno[i]) != NULLAGBLOCK &&
619
+ be32_to_cpu(agfl_bno[i]) >= mp->m_sb.sb_agblocks)
587620 return __this_address;
588621 }
589622
....@@ -596,7 +629,7 @@
596629 xfs_agfl_read_verify(
597630 struct xfs_buf *bp)
598631 {
599
- struct xfs_mount *mp = bp->b_target->bt_mount;
632
+ struct xfs_mount *mp = bp->b_mount;
600633 xfs_failaddr_t fa;
601634
602635 /*
....@@ -621,7 +654,7 @@
621654 xfs_agfl_write_verify(
622655 struct xfs_buf *bp)
623656 {
624
- struct xfs_mount *mp = bp->b_target->bt_mount;
657
+ struct xfs_mount *mp = bp->b_mount;
625658 struct xfs_buf_log_item *bip = bp->b_log_item;
626659 xfs_failaddr_t fa;
627660
....@@ -643,6 +676,7 @@
643676
644677 const struct xfs_buf_ops xfs_agfl_buf_ops = {
645678 .name = "xfs_agfl",
679
+ .magic = { cpu_to_be32(XFS_AGFL_MAGIC), cpu_to_be32(XFS_AGFL_MAGIC) },
646680 .verify_read = xfs_agfl_read_verify,
647681 .verify_write = xfs_agfl_write_verify,
648682 .verify_struct = xfs_agfl_verify,
....@@ -676,27 +710,413 @@
676710 STATIC int
677711 xfs_alloc_update_counters(
678712 struct xfs_trans *tp,
679
- struct xfs_perag *pag,
680713 struct xfs_buf *agbp,
681714 long len)
682715 {
683
- struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
716
+ struct xfs_agf *agf = agbp->b_addr;
684717
685
- pag->pagf_freeblks += len;
718
+ agbp->b_pag->pagf_freeblks += len;
686719 be32_add_cpu(&agf->agf_freeblks, len);
687720
688721 xfs_trans_agblocks_delta(tp, len);
689722 if (unlikely(be32_to_cpu(agf->agf_freeblks) >
690
- be32_to_cpu(agf->agf_length)))
723
+ be32_to_cpu(agf->agf_length))) {
724
+ xfs_buf_mark_corrupt(agbp);
691725 return -EFSCORRUPTED;
726
+ }
692727
693728 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
694729 return 0;
695730 }
696731
697732 /*
698
- * Allocation group level functions.
733
+ * Block allocation algorithm and data structures.
699734 */
735
+struct xfs_alloc_cur {
736
+ struct xfs_btree_cur *cnt; /* btree cursors */
737
+ struct xfs_btree_cur *bnolt;
738
+ struct xfs_btree_cur *bnogt;
739
+ xfs_extlen_t cur_len;/* current search length */
740
+ xfs_agblock_t rec_bno;/* extent startblock */
741
+ xfs_extlen_t rec_len;/* extent length */
742
+ xfs_agblock_t bno; /* alloc bno */
743
+ xfs_extlen_t len; /* alloc len */
744
+ xfs_extlen_t diff; /* diff from search bno */
745
+ unsigned int busy_gen;/* busy state */
746
+ bool busy;
747
+};
748
+
749
+/*
750
+ * Set up cursors, etc. in the extent allocation cursor. This function can be
751
+ * called multiple times to reset an initialized structure without having to
752
+ * reallocate cursors.
753
+ */
754
+static int
755
+xfs_alloc_cur_setup(
756
+ struct xfs_alloc_arg *args,
757
+ struct xfs_alloc_cur *acur)
758
+{
759
+ int error;
760
+ int i;
761
+
762
+ ASSERT(args->alignment == 1 || args->type != XFS_ALLOCTYPE_THIS_BNO);
763
+
764
+ acur->cur_len = args->maxlen;
765
+ acur->rec_bno = 0;
766
+ acur->rec_len = 0;
767
+ acur->bno = 0;
768
+ acur->len = 0;
769
+ acur->diff = -1;
770
+ acur->busy = false;
771
+ acur->busy_gen = 0;
772
+
773
+ /*
774
+ * Perform an initial cntbt lookup to check for availability of maxlen
775
+ * extents. If this fails, we'll return -ENOSPC to signal the caller to
776
+ * attempt a small allocation.
777
+ */
778
+ if (!acur->cnt)
779
+ acur->cnt = xfs_allocbt_init_cursor(args->mp, args->tp,
780
+ args->agbp, args->agno, XFS_BTNUM_CNT);
781
+ error = xfs_alloc_lookup_ge(acur->cnt, 0, args->maxlen, &i);
782
+ if (error)
783
+ return error;
784
+
785
+ /*
786
+ * Allocate the bnobt left and right search cursors.
787
+ */
788
+ if (!acur->bnolt)
789
+ acur->bnolt = xfs_allocbt_init_cursor(args->mp, args->tp,
790
+ args->agbp, args->agno, XFS_BTNUM_BNO);
791
+ if (!acur->bnogt)
792
+ acur->bnogt = xfs_allocbt_init_cursor(args->mp, args->tp,
793
+ args->agbp, args->agno, XFS_BTNUM_BNO);
794
+ return i == 1 ? 0 : -ENOSPC;
795
+}
796
+
797
+static void
798
+xfs_alloc_cur_close(
799
+ struct xfs_alloc_cur *acur,
800
+ bool error)
801
+{
802
+ int cur_error = XFS_BTREE_NOERROR;
803
+
804
+ if (error)
805
+ cur_error = XFS_BTREE_ERROR;
806
+
807
+ if (acur->cnt)
808
+ xfs_btree_del_cursor(acur->cnt, cur_error);
809
+ if (acur->bnolt)
810
+ xfs_btree_del_cursor(acur->bnolt, cur_error);
811
+ if (acur->bnogt)
812
+ xfs_btree_del_cursor(acur->bnogt, cur_error);
813
+ acur->cnt = acur->bnolt = acur->bnogt = NULL;
814
+}
815
+
816
+/*
817
+ * Check an extent for allocation and track the best available candidate in the
818
+ * allocation structure. The cursor is deactivated if it has entered an out of
819
+ * range state based on allocation arguments. Optionally return the extent
820
+ * extent geometry and allocation status if requested by the caller.
821
+ */
822
+static int
823
+xfs_alloc_cur_check(
824
+ struct xfs_alloc_arg *args,
825
+ struct xfs_alloc_cur *acur,
826
+ struct xfs_btree_cur *cur,
827
+ int *new)
828
+{
829
+ int error, i;
830
+ xfs_agblock_t bno, bnoa, bnew;
831
+ xfs_extlen_t len, lena, diff = -1;
832
+ bool busy;
833
+ unsigned busy_gen = 0;
834
+ bool deactivate = false;
835
+ bool isbnobt = cur->bc_btnum == XFS_BTNUM_BNO;
836
+
837
+ *new = 0;
838
+
839
+ error = xfs_alloc_get_rec(cur, &bno, &len, &i);
840
+ if (error)
841
+ return error;
842
+ if (XFS_IS_CORRUPT(args->mp, i != 1))
843
+ return -EFSCORRUPTED;
844
+
845
+ /*
846
+ * Check minlen and deactivate a cntbt cursor if out of acceptable size
847
+ * range (i.e., walking backwards looking for a minlen extent).
848
+ */
849
+ if (len < args->minlen) {
850
+ deactivate = !isbnobt;
851
+ goto out;
852
+ }
853
+
854
+ busy = xfs_alloc_compute_aligned(args, bno, len, &bnoa, &lena,
855
+ &busy_gen);
856
+ acur->busy |= busy;
857
+ if (busy)
858
+ acur->busy_gen = busy_gen;
859
+ /* deactivate a bnobt cursor outside of locality range */
860
+ if (bnoa < args->min_agbno || bnoa > args->max_agbno) {
861
+ deactivate = isbnobt;
862
+ goto out;
863
+ }
864
+ if (lena < args->minlen)
865
+ goto out;
866
+
867
+ args->len = XFS_EXTLEN_MIN(lena, args->maxlen);
868
+ xfs_alloc_fix_len(args);
869
+ ASSERT(args->len >= args->minlen);
870
+ if (args->len < acur->len)
871
+ goto out;
872
+
873
+ /*
874
+ * We have an aligned record that satisfies minlen and beats or matches
875
+ * the candidate extent size. Compare locality for near allocation mode.
876
+ */
877
+ ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO);
878
+ diff = xfs_alloc_compute_diff(args->agbno, args->len,
879
+ args->alignment, args->datatype,
880
+ bnoa, lena, &bnew);
881
+ if (bnew == NULLAGBLOCK)
882
+ goto out;
883
+
884
+ /*
885
+ * Deactivate a bnobt cursor with worse locality than the current best.
886
+ */
887
+ if (diff > acur->diff) {
888
+ deactivate = isbnobt;
889
+ goto out;
890
+ }
891
+
892
+ ASSERT(args->len > acur->len ||
893
+ (args->len == acur->len && diff <= acur->diff));
894
+ acur->rec_bno = bno;
895
+ acur->rec_len = len;
896
+ acur->bno = bnew;
897
+ acur->len = args->len;
898
+ acur->diff = diff;
899
+ *new = 1;
900
+
901
+ /*
902
+ * We're done if we found a perfect allocation. This only deactivates
903
+ * the current cursor, but this is just an optimization to terminate a
904
+ * cntbt search that otherwise runs to the edge of the tree.
905
+ */
906
+ if (acur->diff == 0 && acur->len == args->maxlen)
907
+ deactivate = true;
908
+out:
909
+ if (deactivate)
910
+ cur->bc_ag.abt.active = false;
911
+ trace_xfs_alloc_cur_check(args->mp, cur->bc_btnum, bno, len, diff,
912
+ *new);
913
+ return 0;
914
+}
915
+
916
+/*
917
+ * Complete an allocation of a candidate extent. Remove the extent from both
918
+ * trees and update the args structure.
919
+ */
920
+STATIC int
921
+xfs_alloc_cur_finish(
922
+ struct xfs_alloc_arg *args,
923
+ struct xfs_alloc_cur *acur)
924
+{
925
+ struct xfs_agf __maybe_unused *agf = args->agbp->b_addr;
926
+ int error;
927
+
928
+ ASSERT(acur->cnt && acur->bnolt);
929
+ ASSERT(acur->bno >= acur->rec_bno);
930
+ ASSERT(acur->bno + acur->len <= acur->rec_bno + acur->rec_len);
931
+ ASSERT(acur->rec_bno + acur->rec_len <= be32_to_cpu(agf->agf_length));
932
+
933
+ error = xfs_alloc_fixup_trees(acur->cnt, acur->bnolt, acur->rec_bno,
934
+ acur->rec_len, acur->bno, acur->len, 0);
935
+ if (error)
936
+ return error;
937
+
938
+ args->agbno = acur->bno;
939
+ args->len = acur->len;
940
+ args->wasfromfl = 0;
941
+
942
+ trace_xfs_alloc_cur(args);
943
+ return 0;
944
+}
945
+
946
+/*
947
+ * Locality allocation lookup algorithm. This expects a cntbt cursor and uses
948
+ * bno optimized lookup to search for extents with ideal size and locality.
949
+ */
950
+STATIC int
951
+xfs_alloc_cntbt_iter(
952
+ struct xfs_alloc_arg *args,
953
+ struct xfs_alloc_cur *acur)
954
+{
955
+ struct xfs_btree_cur *cur = acur->cnt;
956
+ xfs_agblock_t bno;
957
+ xfs_extlen_t len, cur_len;
958
+ int error;
959
+ int i;
960
+
961
+ if (!xfs_alloc_cur_active(cur))
962
+ return 0;
963
+
964
+ /* locality optimized lookup */
965
+ cur_len = acur->cur_len;
966
+ error = xfs_alloc_lookup_ge(cur, args->agbno, cur_len, &i);
967
+ if (error)
968
+ return error;
969
+ if (i == 0)
970
+ return 0;
971
+ error = xfs_alloc_get_rec(cur, &bno, &len, &i);
972
+ if (error)
973
+ return error;
974
+
975
+ /* check the current record and update search length from it */
976
+ error = xfs_alloc_cur_check(args, acur, cur, &i);
977
+ if (error)
978
+ return error;
979
+ ASSERT(len >= acur->cur_len);
980
+ acur->cur_len = len;
981
+
982
+ /*
983
+ * We looked up the first record >= [agbno, len] above. The agbno is a
984
+ * secondary key and so the current record may lie just before or after
985
+ * agbno. If it is past agbno, check the previous record too so long as
986
+ * the length matches as it may be closer. Don't check a smaller record
987
+ * because that could deactivate our cursor.
988
+ */
989
+ if (bno > args->agbno) {
990
+ error = xfs_btree_decrement(cur, 0, &i);
991
+ if (!error && i) {
992
+ error = xfs_alloc_get_rec(cur, &bno, &len, &i);
993
+ if (!error && i && len == acur->cur_len)
994
+ error = xfs_alloc_cur_check(args, acur, cur,
995
+ &i);
996
+ }
997
+ if (error)
998
+ return error;
999
+ }
1000
+
1001
+ /*
1002
+ * Increment the search key until we find at least one allocation
1003
+ * candidate or if the extent we found was larger. Otherwise, double the
1004
+ * search key to optimize the search. Efficiency is more important here
1005
+ * than absolute best locality.
1006
+ */
1007
+ cur_len <<= 1;
1008
+ if (!acur->len || acur->cur_len >= cur_len)
1009
+ acur->cur_len++;
1010
+ else
1011
+ acur->cur_len = cur_len;
1012
+
1013
+ return error;
1014
+}
1015
+
1016
+/*
1017
+ * Deal with the case where only small freespaces remain. Either return the
1018
+ * contents of the last freespace record, or allocate space from the freelist if
1019
+ * there is nothing in the tree.
1020
+ */
1021
+STATIC int /* error */
1022
+xfs_alloc_ag_vextent_small(
1023
+ struct xfs_alloc_arg *args, /* allocation argument structure */
1024
+ struct xfs_btree_cur *ccur, /* optional by-size cursor */
1025
+ xfs_agblock_t *fbnop, /* result block number */
1026
+ xfs_extlen_t *flenp, /* result length */
1027
+ int *stat) /* status: 0-freelist, 1-normal/none */
1028
+{
1029
+ struct xfs_agf *agf = args->agbp->b_addr;
1030
+ int error = 0;
1031
+ xfs_agblock_t fbno = NULLAGBLOCK;
1032
+ xfs_extlen_t flen = 0;
1033
+ int i = 0;
1034
+
1035
+ /*
1036
+ * If a cntbt cursor is provided, try to allocate the largest record in
1037
+ * the tree. Try the AGFL if the cntbt is empty, otherwise fail the
1038
+ * allocation. Make sure to respect minleft even when pulling from the
1039
+ * freelist.
1040
+ */
1041
+ if (ccur)
1042
+ error = xfs_btree_decrement(ccur, 0, &i);
1043
+ if (error)
1044
+ goto error;
1045
+ if (i) {
1046
+ error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i);
1047
+ if (error)
1048
+ goto error;
1049
+ if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1050
+ error = -EFSCORRUPTED;
1051
+ goto error;
1052
+ }
1053
+ goto out;
1054
+ }
1055
+
1056
+ if (args->minlen != 1 || args->alignment != 1 ||
1057
+ args->resv == XFS_AG_RESV_AGFL ||
1058
+ be32_to_cpu(agf->agf_flcount) <= args->minleft)
1059
+ goto out;
1060
+
1061
+ error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
1062
+ if (error)
1063
+ goto error;
1064
+ if (fbno == NULLAGBLOCK)
1065
+ goto out;
1066
+
1067
+ xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1,
1068
+ (args->datatype & XFS_ALLOC_NOBUSY));
1069
+
1070
+ if (args->datatype & XFS_ALLOC_USERDATA) {
1071
+ struct xfs_buf *bp;
1072
+
1073
+ error = xfs_trans_get_buf(args->tp, args->mp->m_ddev_targp,
1074
+ XFS_AGB_TO_DADDR(args->mp, args->agno, fbno),
1075
+ args->mp->m_bsize, 0, &bp);
1076
+ if (error)
1077
+ goto error;
1078
+ xfs_trans_binval(args->tp, bp);
1079
+ }
1080
+ *fbnop = args->agbno = fbno;
1081
+ *flenp = args->len = 1;
1082
+ if (XFS_IS_CORRUPT(args->mp, fbno >= be32_to_cpu(agf->agf_length))) {
1083
+ error = -EFSCORRUPTED;
1084
+ goto error;
1085
+ }
1086
+ args->wasfromfl = 1;
1087
+ trace_xfs_alloc_small_freelist(args);
1088
+
1089
+ /*
1090
+ * If we're feeding an AGFL block to something that doesn't live in the
1091
+ * free space, we need to clear out the OWN_AG rmap.
1092
+ */
1093
+ error = xfs_rmap_free(args->tp, args->agbp, args->agno, fbno, 1,
1094
+ &XFS_RMAP_OINFO_AG);
1095
+ if (error)
1096
+ goto error;
1097
+
1098
+ *stat = 0;
1099
+ return 0;
1100
+
1101
+out:
1102
+ /*
1103
+ * Can't do the allocation, give up.
1104
+ */
1105
+ if (flen < args->minlen) {
1106
+ args->agbno = NULLAGBLOCK;
1107
+ trace_xfs_alloc_small_notenough(args);
1108
+ flen = 0;
1109
+ }
1110
+ *fbnop = fbno;
1111
+ *flenp = flen;
1112
+ *stat = 1;
1113
+ trace_xfs_alloc_small_done(args);
1114
+ return 0;
1115
+
1116
+error:
1117
+ trace_xfs_alloc_small_error(args);
1118
+ return error;
1119
+}
7001120
7011121 /*
7021122 * Allocate a variable extent in the allocation group agno.
....@@ -754,8 +1174,7 @@
7541174 }
7551175
7561176 if (!args->wasfromfl) {
757
- error = xfs_alloc_update_counters(args->tp, args->pag,
758
- args->agbp,
1177
+ error = xfs_alloc_update_counters(args->tp, args->agbp,
7591178 -((long)(args->len)));
7601179 if (error)
7611180 return error;
....@@ -781,6 +1200,7 @@
7811200 xfs_alloc_ag_vextent_exact(
7821201 xfs_alloc_arg_t *args) /* allocation argument structure */
7831202 {
1203
+ struct xfs_agf __maybe_unused *agf = args->agbp->b_addr;
7841204 xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */
7851205 xfs_btree_cur_t *cnt_cur;/* by count btree cursor */
7861206 int error;
....@@ -817,7 +1237,10 @@
8171237 error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i);
8181238 if (error)
8191239 goto error0;
820
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1240
+ if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1241
+ error = -EFSCORRUPTED;
1242
+ goto error0;
1243
+ }
8211244 ASSERT(fbno <= args->agbno);
8221245
8231246 /*
....@@ -856,8 +1279,7 @@
8561279 */
8571280 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
8581281 args->agno, XFS_BTNUM_CNT);
859
- ASSERT(args->agbno + args->len <=
860
- be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
1282
+ ASSERT(args->agbno + args->len <= be32_to_cpu(agf->agf_length));
8611283 error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
8621284 args->len, XFSA_FIXUP_BNO_OK);
8631285 if (error) {
....@@ -886,98 +1308,243 @@
8861308 }
8871309
8881310 /*
889
- * Search the btree in a given direction via the search cursor and compare
890
- * the records found against the good extent we've already found.
1311
+ * Search a given number of btree records in a given direction. Check each
1312
+ * record against the good extent we've already found.
8911313 */
8921314 STATIC int
893
-xfs_alloc_find_best_extent(
894
- struct xfs_alloc_arg *args, /* allocation argument structure */
895
- struct xfs_btree_cur **gcur, /* good cursor */
896
- struct xfs_btree_cur **scur, /* searching cursor */
897
- xfs_agblock_t gdiff, /* difference for search comparison */
898
- xfs_agblock_t *sbno, /* extent found by search */
899
- xfs_extlen_t *slen, /* extent length */
900
- xfs_agblock_t *sbnoa, /* aligned extent found by search */
901
- xfs_extlen_t *slena, /* aligned extent length */
902
- int dir) /* 0 = search right, 1 = search left */
1315
+xfs_alloc_walk_iter(
1316
+ struct xfs_alloc_arg *args,
1317
+ struct xfs_alloc_cur *acur,
1318
+ struct xfs_btree_cur *cur,
1319
+ bool increment,
1320
+ bool find_one, /* quit on first candidate */
1321
+ int count, /* rec count (-1 for infinite) */
1322
+ int *stat)
9031323 {
904
- xfs_agblock_t new;
905
- xfs_agblock_t sdiff;
9061324 int error;
9071325 int i;
908
- unsigned busy_gen;
9091326
910
- /* The good extent is perfect, no need to search. */
911
- if (!gdiff)
912
- goto out_use_good;
1327
+ *stat = 0;
9131328
9141329 /*
915
- * Look until we find a better one, run out of space or run off the end.
1330
+ * Search so long as the cursor is active or we find a better extent.
1331
+ * The cursor is deactivated if it extends beyond the range of the
1332
+ * current allocation candidate.
9161333 */
917
- do {
918
- error = xfs_alloc_get_rec(*scur, sbno, slen, &i);
1334
+ while (xfs_alloc_cur_active(cur) && count) {
1335
+ error = xfs_alloc_cur_check(args, acur, cur, &i);
9191336 if (error)
920
- goto error0;
921
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
922
- xfs_alloc_compute_aligned(args, *sbno, *slen,
923
- sbnoa, slena, &busy_gen);
924
-
925
- /*
926
- * The good extent is closer than this one.
927
- */
928
- if (!dir) {
929
- if (*sbnoa > args->max_agbno)
930
- goto out_use_good;
931
- if (*sbnoa >= args->agbno + gdiff)
932
- goto out_use_good;
933
- } else {
934
- if (*sbnoa < args->min_agbno)
935
- goto out_use_good;
936
- if (*sbnoa <= args->agbno - gdiff)
937
- goto out_use_good;
1337
+ return error;
1338
+ if (i == 1) {
1339
+ *stat = 1;
1340
+ if (find_one)
1341
+ break;
9381342 }
1343
+ if (!xfs_alloc_cur_active(cur))
1344
+ break;
9391345
940
- /*
941
- * Same distance, compare length and pick the best.
942
- */
943
- if (*slena >= args->minlen) {
944
- args->len = XFS_EXTLEN_MIN(*slena, args->maxlen);
945
- xfs_alloc_fix_len(args);
946
-
947
- sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
948
- args->alignment,
949
- args->datatype, *sbnoa,
950
- *slena, &new);
951
-
952
- /*
953
- * Choose closer size and invalidate other cursor.
954
- */
955
- if (sdiff < gdiff)
956
- goto out_use_search;
957
- goto out_use_good;
958
- }
959
-
960
- if (!dir)
961
- error = xfs_btree_increment(*scur, 0, &i);
1346
+ if (increment)
1347
+ error = xfs_btree_increment(cur, 0, &i);
9621348 else
963
- error = xfs_btree_decrement(*scur, 0, &i);
1349
+ error = xfs_btree_decrement(cur, 0, &i);
9641350 if (error)
965
- goto error0;
966
- } while (i);
1351
+ return error;
1352
+ if (i == 0)
1353
+ cur->bc_ag.abt.active = false;
9671354
968
-out_use_good:
969
- xfs_btree_del_cursor(*scur, XFS_BTREE_NOERROR);
970
- *scur = NULL;
1355
+ if (count > 0)
1356
+ count--;
1357
+ }
1358
+
9711359 return 0;
1360
+}
9721361
973
-out_use_search:
974
- xfs_btree_del_cursor(*gcur, XFS_BTREE_NOERROR);
975
- *gcur = NULL;
1362
+/*
1363
+ * Search the by-bno and by-size btrees in parallel in search of an extent with
1364
+ * ideal locality based on the NEAR mode ->agbno locality hint.
1365
+ */
1366
+STATIC int
1367
+xfs_alloc_ag_vextent_locality(
1368
+ struct xfs_alloc_arg *args,
1369
+ struct xfs_alloc_cur *acur,
1370
+ int *stat)
1371
+{
1372
+ struct xfs_btree_cur *fbcur = NULL;
1373
+ int error;
1374
+ int i;
1375
+ bool fbinc;
1376
+
1377
+ ASSERT(acur->len == 0);
1378
+ ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO);
1379
+
1380
+ *stat = 0;
1381
+
1382
+ error = xfs_alloc_lookup_ge(acur->cnt, args->agbno, acur->cur_len, &i);
1383
+ if (error)
1384
+ return error;
1385
+ error = xfs_alloc_lookup_le(acur->bnolt, args->agbno, 0, &i);
1386
+ if (error)
1387
+ return error;
1388
+ error = xfs_alloc_lookup_ge(acur->bnogt, args->agbno, 0, &i);
1389
+ if (error)
1390
+ return error;
1391
+
1392
+ /*
1393
+ * Search the bnobt and cntbt in parallel. Search the bnobt left and
1394
+ * right and lookup the closest extent to the locality hint for each
1395
+ * extent size key in the cntbt. The entire search terminates
1396
+ * immediately on a bnobt hit because that means we've found best case
1397
+ * locality. Otherwise the search continues until the cntbt cursor runs
1398
+ * off the end of the tree. If no allocation candidate is found at this
1399
+ * point, give up on locality, walk backwards from the end of the cntbt
1400
+ * and take the first available extent.
1401
+ *
1402
+ * The parallel tree searches balance each other out to provide fairly
1403
+ * consistent performance for various situations. The bnobt search can
1404
+ * have pathological behavior in the worst case scenario of larger
1405
+ * allocation requests and fragmented free space. On the other hand, the
1406
+ * bnobt is able to satisfy most smaller allocation requests much more
1407
+ * quickly than the cntbt. The cntbt search can sift through fragmented
1408
+ * free space and sets of free extents for larger allocation requests
1409
+ * more quickly than the bnobt. Since the locality hint is just a hint
1410
+ * and we don't want to scan the entire bnobt for perfect locality, the
1411
+ * cntbt search essentially bounds the bnobt search such that we can
1412
+ * find good enough locality at reasonable performance in most cases.
1413
+ */
1414
+ while (xfs_alloc_cur_active(acur->bnolt) ||
1415
+ xfs_alloc_cur_active(acur->bnogt) ||
1416
+ xfs_alloc_cur_active(acur->cnt)) {
1417
+
1418
+ trace_xfs_alloc_cur_lookup(args);
1419
+
1420
+ /*
1421
+ * Search the bnobt left and right. In the case of a hit, finish
1422
+ * the search in the opposite direction and we're done.
1423
+ */
1424
+ error = xfs_alloc_walk_iter(args, acur, acur->bnolt, false,
1425
+ true, 1, &i);
1426
+ if (error)
1427
+ return error;
1428
+ if (i == 1) {
1429
+ trace_xfs_alloc_cur_left(args);
1430
+ fbcur = acur->bnogt;
1431
+ fbinc = true;
1432
+ break;
1433
+ }
1434
+ error = xfs_alloc_walk_iter(args, acur, acur->bnogt, true, true,
1435
+ 1, &i);
1436
+ if (error)
1437
+ return error;
1438
+ if (i == 1) {
1439
+ trace_xfs_alloc_cur_right(args);
1440
+ fbcur = acur->bnolt;
1441
+ fbinc = false;
1442
+ break;
1443
+ }
1444
+
1445
+ /*
1446
+ * Check the extent with best locality based on the current
1447
+ * extent size search key and keep track of the best candidate.
1448
+ */
1449
+ error = xfs_alloc_cntbt_iter(args, acur);
1450
+ if (error)
1451
+ return error;
1452
+ if (!xfs_alloc_cur_active(acur->cnt)) {
1453
+ trace_xfs_alloc_cur_lookup_done(args);
1454
+ break;
1455
+ }
1456
+ }
1457
+
1458
+ /*
1459
+ * If we failed to find anything due to busy extents, return empty
1460
+ * handed so the caller can flush and retry. If no busy extents were
1461
+ * found, walk backwards from the end of the cntbt as a last resort.
1462
+ */
1463
+ if (!xfs_alloc_cur_active(acur->cnt) && !acur->len && !acur->busy) {
1464
+ error = xfs_btree_decrement(acur->cnt, 0, &i);
1465
+ if (error)
1466
+ return error;
1467
+ if (i) {
1468
+ acur->cnt->bc_ag.abt.active = true;
1469
+ fbcur = acur->cnt;
1470
+ fbinc = false;
1471
+ }
1472
+ }
1473
+
1474
+ /*
1475
+ * Search in the opposite direction for a better entry in the case of
1476
+ * a bnobt hit or walk backwards from the end of the cntbt.
1477
+ */
1478
+ if (fbcur) {
1479
+ error = xfs_alloc_walk_iter(args, acur, fbcur, fbinc, true, -1,
1480
+ &i);
1481
+ if (error)
1482
+ return error;
1483
+ }
1484
+
1485
+ if (acur->len)
1486
+ *stat = 1;
1487
+
9761488 return 0;
1489
+}
9771490
978
-error0:
979
- /* caller invalidates cursors */
980
- return error;
1491
+/* Check the last block of the cnt btree for allocations. */
1492
+static int
1493
+xfs_alloc_ag_vextent_lastblock(
1494
+ struct xfs_alloc_arg *args,
1495
+ struct xfs_alloc_cur *acur,
1496
+ xfs_agblock_t *bno,
1497
+ xfs_extlen_t *len,
1498
+ bool *allocated)
1499
+{
1500
+ int error;
1501
+ int i;
1502
+
1503
+#ifdef DEBUG
1504
+ /* Randomly don't execute the first algorithm. */
1505
+ if (prandom_u32() & 1)
1506
+ return 0;
1507
+#endif
1508
+
1509
+ /*
1510
+ * Start from the entry that lookup found, sequence through all larger
1511
+ * free blocks. If we're actually pointing at a record smaller than
1512
+ * maxlen, go to the start of this block, and skip all those smaller
1513
+ * than minlen.
1514
+ */
1515
+ if (*len || args->alignment > 1) {
1516
+ acur->cnt->bc_ptrs[0] = 1;
1517
+ do {
1518
+ error = xfs_alloc_get_rec(acur->cnt, bno, len, &i);
1519
+ if (error)
1520
+ return error;
1521
+ if (XFS_IS_CORRUPT(args->mp, i != 1))
1522
+ return -EFSCORRUPTED;
1523
+ if (*len >= args->minlen)
1524
+ break;
1525
+ error = xfs_btree_increment(acur->cnt, 0, &i);
1526
+ if (error)
1527
+ return error;
1528
+ } while (i);
1529
+ ASSERT(*len >= args->minlen);
1530
+ if (!i)
1531
+ return 0;
1532
+ }
1533
+
1534
+ error = xfs_alloc_walk_iter(args, acur, acur->cnt, true, false, -1, &i);
1535
+ if (error)
1536
+ return error;
1537
+
1538
+ /*
1539
+ * It didn't work. We COULD be in a case where there's a good record
1540
+ * somewhere, so try again.
1541
+ */
1542
+ if (acur->len == 0)
1543
+ return 0;
1544
+
1545
+ trace_xfs_alloc_near_first(args);
1546
+ *allocated = true;
1547
+ return 0;
9811548 }
9821549
9831550 /*
....@@ -986,41 +1553,17 @@
9861553 * and of the form k * prod + mod unless there's nothing that large.
9871554 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
9881555 */
989
-STATIC int /* error */
1556
+STATIC int
9901557 xfs_alloc_ag_vextent_near(
991
- xfs_alloc_arg_t *args) /* allocation argument structure */
1558
+ struct xfs_alloc_arg *args)
9921559 {
993
- xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */
994
- xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */
995
- xfs_btree_cur_t *cnt_cur; /* cursor for count btree */
996
- xfs_agblock_t gtbno; /* start bno of right side entry */
997
- xfs_agblock_t gtbnoa; /* aligned ... */
998
- xfs_extlen_t gtdiff; /* difference to right side entry */
999
- xfs_extlen_t gtlen; /* length of right side entry */
1000
- xfs_extlen_t gtlena; /* aligned ... */
1001
- xfs_agblock_t gtnew; /* useful start bno of right side */
1002
- int error; /* error code */
1003
- int i; /* result code, temporary */
1004
- int j; /* result code, temporary */
1005
- xfs_agblock_t ltbno; /* start bno of left side entry */
1006
- xfs_agblock_t ltbnoa; /* aligned ... */
1007
- xfs_extlen_t ltdiff; /* difference to left side entry */
1008
- xfs_extlen_t ltlen; /* length of left side entry */
1009
- xfs_extlen_t ltlena; /* aligned ... */
1010
- xfs_agblock_t ltnew; /* useful start bno of left side */
1011
- xfs_extlen_t rlen; /* length of returned extent */
1012
- bool busy;
1013
- unsigned busy_gen;
1014
-#ifdef DEBUG
1015
- /*
1016
- * Randomly don't execute the first algorithm.
1017
- */
1018
- int dofirst; /* set to do first algorithm */
1560
+ struct xfs_alloc_cur acur = {};
1561
+ int error; /* error code */
1562
+ int i; /* result code, temporary */
1563
+ xfs_agblock_t bno;
1564
+ xfs_extlen_t len;
10191565
1020
- dofirst = prandom_u32() & 1;
1021
-#endif
1022
-
1023
- /* handle unitialized agbno range so caller doesn't have to */
1566
+ /* handle uninitialized agbno range so caller doesn't have to */
10241567 if (!args->min_agbno && !args->max_agbno)
10251568 args->max_agbno = args->mp->m_sb.sb_agblocks - 1;
10261569 ASSERT(args->min_agbno <= args->max_agbno);
....@@ -1032,40 +1575,27 @@
10321575 args->agbno = args->max_agbno;
10331576
10341577 restart:
1035
- bno_cur_lt = NULL;
1036
- bno_cur_gt = NULL;
1037
- ltlen = 0;
1038
- gtlena = 0;
1039
- ltlena = 0;
1040
- busy = false;
1578
+ len = 0;
10411579
10421580 /*
1043
- * Get a cursor for the by-size btree.
1581
+ * Set up cursors and see if there are any free extents as big as
1582
+ * maxlen. If not, pick the last entry in the tree unless the tree is
1583
+ * empty.
10441584 */
1045
- cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1046
- args->agno, XFS_BTNUM_CNT);
1047
-
1048
- /*
1049
- * See if there are any free extents as big as maxlen.
1050
- */
1051
- if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i)))
1052
- goto error0;
1053
- /*
1054
- * If none, then pick up the last entry in the tree unless the
1055
- * tree is empty.
1056
- */
1057
- if (!i) {
1058
- if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &ltbno,
1059
- &ltlen, &i)))
1060
- goto error0;
1061
- if (i == 0 || ltlen == 0) {
1062
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1585
+ error = xfs_alloc_cur_setup(args, &acur);
1586
+ if (error == -ENOSPC) {
1587
+ error = xfs_alloc_ag_vextent_small(args, acur.cnt, &bno,
1588
+ &len, &i);
1589
+ if (error)
1590
+ goto out;
1591
+ if (i == 0 || len == 0) {
10631592 trace_xfs_alloc_near_noentry(args);
1064
- return 0;
1593
+ goto out;
10651594 }
10661595 ASSERT(i == 1);
1596
+ } else if (error) {
1597
+ goto out;
10671598 }
1068
- args->wasfromfl = 0;
10691599
10701600 /*
10711601 * First algorithm.
....@@ -1074,311 +1604,47 @@
10741604 * near the right edge of the tree. If it's in the last btree leaf
10751605 * block, then we just examine all the entries in that block
10761606 * that are big enough, and pick the best one.
1077
- * This is written as a while loop so we can break out of it,
1078
- * but we never loop back to the top.
10791607 */
1080
- while (xfs_btree_islastblock(cnt_cur, 0)) {
1081
- xfs_extlen_t bdiff;
1082
- int besti=0;
1083
- xfs_extlen_t blen=0;
1084
- xfs_agblock_t bnew=0;
1608
+ if (xfs_btree_islastblock(acur.cnt, 0)) {
1609
+ bool allocated = false;
10851610
1086
-#ifdef DEBUG
1087
- if (dofirst)
1088
- break;
1089
-#endif
1090
- /*
1091
- * Start from the entry that lookup found, sequence through
1092
- * all larger free blocks. If we're actually pointing at a
1093
- * record smaller than maxlen, go to the start of this block,
1094
- * and skip all those smaller than minlen.
1095
- */
1096
- if (ltlen || args->alignment > 1) {
1097
- cnt_cur->bc_ptrs[0] = 1;
1098
- do {
1099
- if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno,
1100
- &ltlen, &i)))
1101
- goto error0;
1102
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1103
- if (ltlen >= args->minlen)
1104
- break;
1105
- if ((error = xfs_btree_increment(cnt_cur, 0, &i)))
1106
- goto error0;
1107
- } while (i);
1108
- ASSERT(ltlen >= args->minlen);
1109
- if (!i)
1110
- break;
1111
- }
1112
- i = cnt_cur->bc_ptrs[0];
1113
- for (j = 1, blen = 0, bdiff = 0;
1114
- !error && j && (blen < args->maxlen || bdiff > 0);
1115
- error = xfs_btree_increment(cnt_cur, 0, &j)) {
1116
- /*
1117
- * For each entry, decide if it's better than
1118
- * the previous best entry.
1119
- */
1120
- if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
1121
- goto error0;
1122
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1123
- busy = xfs_alloc_compute_aligned(args, ltbno, ltlen,
1124
- &ltbnoa, &ltlena, &busy_gen);
1125
- if (ltlena < args->minlen)
1126
- continue;
1127
- if (ltbnoa < args->min_agbno || ltbnoa > args->max_agbno)
1128
- continue;
1129
- args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1130
- xfs_alloc_fix_len(args);
1131
- ASSERT(args->len >= args->minlen);
1132
- if (args->len < blen)
1133
- continue;
1134
- ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
1135
- args->alignment, args->datatype, ltbnoa,
1136
- ltlena, &ltnew);
1137
- if (ltnew != NULLAGBLOCK &&
1138
- (args->len > blen || ltdiff < bdiff)) {
1139
- bdiff = ltdiff;
1140
- bnew = ltnew;
1141
- blen = args->len;
1142
- besti = cnt_cur->bc_ptrs[0];
1143
- }
1144
- }
1145
- /*
1146
- * It didn't work. We COULD be in a case where
1147
- * there's a good record somewhere, so try again.
1148
- */
1149
- if (blen == 0)
1150
- break;
1151
- /*
1152
- * Point at the best entry, and retrieve it again.
1153
- */
1154
- cnt_cur->bc_ptrs[0] = besti;
1155
- if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
1156
- goto error0;
1157
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1158
- ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
1159
- args->len = blen;
1160
-
1161
- /*
1162
- * We are allocating starting at bnew for blen blocks.
1163
- */
1164
- args->agbno = bnew;
1165
- ASSERT(bnew >= ltbno);
1166
- ASSERT(bnew + blen <= ltbno + ltlen);
1167
- /*
1168
- * Set up a cursor for the by-bno tree.
1169
- */
1170
- bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp,
1171
- args->agbp, args->agno, XFS_BTNUM_BNO);
1172
- /*
1173
- * Fix up the btree entries.
1174
- */
1175
- if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno,
1176
- ltlen, bnew, blen, XFSA_FIXUP_CNT_OK)))
1177
- goto error0;
1178
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1179
- xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1180
-
1181
- trace_xfs_alloc_near_first(args);
1182
- return 0;
1183
- }
1184
- /*
1185
- * Second algorithm.
1186
- * Search in the by-bno tree to the left and to the right
1187
- * simultaneously, until in each case we find a space big enough,
1188
- * or run into the edge of the tree. When we run into the edge,
1189
- * we deallocate that cursor.
1190
- * If both searches succeed, we compare the two spaces and pick
1191
- * the better one.
1192
- * With alignment, it's possible for both to fail; the upper
1193
- * level algorithm that picks allocation groups for allocations
1194
- * is not supposed to do this.
1195
- */
1196
- /*
1197
- * Allocate and initialize the cursor for the leftward search.
1198
- */
1199
- bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1200
- args->agno, XFS_BTNUM_BNO);
1201
- /*
1202
- * Lookup <= bno to find the leftward search's starting point.
1203
- */
1204
- if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i)))
1205
- goto error0;
1206
- if (!i) {
1207
- /*
1208
- * Didn't find anything; use this cursor for the rightward
1209
- * search.
1210
- */
1211
- bno_cur_gt = bno_cur_lt;
1212
- bno_cur_lt = NULL;
1213
- }
1214
- /*
1215
- * Found something. Duplicate the cursor for the rightward search.
1216
- */
1217
- else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt)))
1218
- goto error0;
1219
- /*
1220
- * Increment the cursor, so we will point at the entry just right
1221
- * of the leftward entry if any, or to the leftmost entry.
1222
- */
1223
- if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
1224
- goto error0;
1225
- if (!i) {
1226
- /*
1227
- * It failed, there are no rightward entries.
1228
- */
1229
- xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR);
1230
- bno_cur_gt = NULL;
1231
- }
1232
- /*
1233
- * Loop going left with the leftward cursor, right with the
1234
- * rightward cursor, until either both directions give up or
1235
- * we find an entry at least as big as minlen.
1236
- */
1237
- do {
1238
- if (bno_cur_lt) {
1239
- if ((error = xfs_alloc_get_rec(bno_cur_lt, &ltbno, &ltlen, &i)))
1240
- goto error0;
1241
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1242
- busy |= xfs_alloc_compute_aligned(args, ltbno, ltlen,
1243
- &ltbnoa, &ltlena, &busy_gen);
1244
- if (ltlena >= args->minlen && ltbnoa >= args->min_agbno)
1245
- break;
1246
- if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i)))
1247
- goto error0;
1248
- if (!i || ltbnoa < args->min_agbno) {
1249
- xfs_btree_del_cursor(bno_cur_lt,
1250
- XFS_BTREE_NOERROR);
1251
- bno_cur_lt = NULL;
1252
- }
1253
- }
1254
- if (bno_cur_gt) {
1255
- if ((error = xfs_alloc_get_rec(bno_cur_gt, &gtbno, &gtlen, &i)))
1256
- goto error0;
1257
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1258
- busy |= xfs_alloc_compute_aligned(args, gtbno, gtlen,
1259
- &gtbnoa, &gtlena, &busy_gen);
1260
- if (gtlena >= args->minlen && gtbnoa <= args->max_agbno)
1261
- break;
1262
- if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
1263
- goto error0;
1264
- if (!i || gtbnoa > args->max_agbno) {
1265
- xfs_btree_del_cursor(bno_cur_gt,
1266
- XFS_BTREE_NOERROR);
1267
- bno_cur_gt = NULL;
1268
- }
1269
- }
1270
- } while (bno_cur_lt || bno_cur_gt);
1271
-
1272
- /*
1273
- * Got both cursors still active, need to find better entry.
1274
- */
1275
- if (bno_cur_lt && bno_cur_gt) {
1276
- if (ltlena >= args->minlen) {
1277
- /*
1278
- * Left side is good, look for a right side entry.
1279
- */
1280
- args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1281
- xfs_alloc_fix_len(args);
1282
- ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
1283
- args->alignment, args->datatype, ltbnoa,
1284
- ltlena, &ltnew);
1285
-
1286
- error = xfs_alloc_find_best_extent(args,
1287
- &bno_cur_lt, &bno_cur_gt,
1288
- ltdiff, &gtbno, &gtlen,
1289
- &gtbnoa, &gtlena,
1290
- 0 /* search right */);
1291
- } else {
1292
- ASSERT(gtlena >= args->minlen);
1293
-
1294
- /*
1295
- * Right side is good, look for a left side entry.
1296
- */
1297
- args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
1298
- xfs_alloc_fix_len(args);
1299
- gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
1300
- args->alignment, args->datatype, gtbnoa,
1301
- gtlena, &gtnew);
1302
-
1303
- error = xfs_alloc_find_best_extent(args,
1304
- &bno_cur_gt, &bno_cur_lt,
1305
- gtdiff, &ltbno, &ltlen,
1306
- &ltbnoa, &ltlena,
1307
- 1 /* search left */);
1308
- }
1309
-
1611
+ error = xfs_alloc_ag_vextent_lastblock(args, &acur, &bno, &len,
1612
+ &allocated);
13101613 if (error)
1311
- goto error0;
1614
+ goto out;
1615
+ if (allocated)
1616
+ goto alloc_finish;
13121617 }
1618
+
1619
+ /*
1620
+ * Second algorithm. Combined cntbt and bnobt search to find ideal
1621
+ * locality.
1622
+ */
1623
+ error = xfs_alloc_ag_vextent_locality(args, &acur, &i);
1624
+ if (error)
1625
+ goto out;
13131626
13141627 /*
13151628 * If we couldn't get anything, give up.
13161629 */
1317
- if (bno_cur_lt == NULL && bno_cur_gt == NULL) {
1318
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1319
-
1320
- if (busy) {
1630
+ if (!acur.len) {
1631
+ if (acur.busy) {
13211632 trace_xfs_alloc_near_busy(args);
1322
- xfs_extent_busy_flush(args->mp, args->pag, busy_gen);
1633
+ xfs_extent_busy_flush(args->mp, args->pag,
1634
+ acur.busy_gen);
13231635 goto restart;
13241636 }
13251637 trace_xfs_alloc_size_neither(args);
13261638 args->agbno = NULLAGBLOCK;
1327
- return 0;
1639
+ goto out;
13281640 }
13291641
1330
- /*
1331
- * At this point we have selected a freespace entry, either to the
1332
- * left or to the right. If it's on the right, copy all the
1333
- * useful variables to the "left" set so we only have one
1334
- * copy of this code.
1335
- */
1336
- if (bno_cur_gt) {
1337
- bno_cur_lt = bno_cur_gt;
1338
- bno_cur_gt = NULL;
1339
- ltbno = gtbno;
1340
- ltbnoa = gtbnoa;
1341
- ltlen = gtlen;
1342
- ltlena = gtlena;
1343
- j = 1;
1344
- } else
1345
- j = 0;
1642
+alloc_finish:
1643
+ /* fix up btrees on a successful allocation */
1644
+ error = xfs_alloc_cur_finish(args, &acur);
13461645
1347
- /*
1348
- * Fix up the length and compute the useful address.
1349
- */
1350
- args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1351
- xfs_alloc_fix_len(args);
1352
- rlen = args->len;
1353
- (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
1354
- args->datatype, ltbnoa, ltlena, &ltnew);
1355
- ASSERT(ltnew >= ltbno);
1356
- ASSERT(ltnew + rlen <= ltbnoa + ltlena);
1357
- ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
1358
- ASSERT(ltnew >= args->min_agbno && ltnew <= args->max_agbno);
1359
- args->agbno = ltnew;
1360
-
1361
- if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen,
1362
- ltnew, rlen, XFSA_FIXUP_BNO_OK)))
1363
- goto error0;
1364
-
1365
- if (j)
1366
- trace_xfs_alloc_near_greater(args);
1367
- else
1368
- trace_xfs_alloc_near_lesser(args);
1369
-
1370
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1371
- xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1372
- return 0;
1373
-
1374
- error0:
1375
- trace_xfs_alloc_near_error(args);
1376
- if (cnt_cur != NULL)
1377
- xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1378
- if (bno_cur_lt != NULL)
1379
- xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR);
1380
- if (bno_cur_gt != NULL)
1381
- xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR);
1646
+out:
1647
+ xfs_alloc_cur_close(&acur, error);
13821648 return error;
13831649 }
13841650
....@@ -1392,6 +1658,7 @@
13921658 xfs_alloc_ag_vextent_size(
13931659 xfs_alloc_arg_t *args) /* allocation argument structure */
13941660 {
1661
+ struct xfs_agf *agf = args->agbp->b_addr;
13951662 xfs_btree_cur_t *bno_cur; /* cursor for bno btree */
13961663 xfs_btree_cur_t *cnt_cur; /* cursor for cnt btree */
13971664 int error; /* error result */
....@@ -1447,7 +1714,10 @@
14471714 error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i);
14481715 if (error)
14491716 goto error0;
1450
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1717
+ if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1718
+ error = -EFSCORRUPTED;
1719
+ goto error0;
1720
+ }
14511721
14521722 busy = xfs_alloc_compute_aligned(args, fbno, flen,
14531723 &rbno, &rlen, &busy_gen);
....@@ -1481,8 +1751,13 @@
14811751 * This can't happen in the second case above.
14821752 */
14831753 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
1484
- XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 ||
1485
- (rlen <= flen && rbno + rlen <= fbno + flen), error0);
1754
+ if (XFS_IS_CORRUPT(args->mp,
1755
+ rlen != 0 &&
1756
+ (rlen > flen ||
1757
+ rbno + rlen > fbno + flen))) {
1758
+ error = -EFSCORRUPTED;
1759
+ goto error0;
1760
+ }
14861761 if (rlen < args->maxlen) {
14871762 xfs_agblock_t bestfbno;
14881763 xfs_extlen_t bestflen;
....@@ -1501,15 +1776,22 @@
15011776 if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen,
15021777 &i)))
15031778 goto error0;
1504
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1779
+ if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1780
+ error = -EFSCORRUPTED;
1781
+ goto error0;
1782
+ }
15051783 if (flen < bestrlen)
15061784 break;
15071785 busy = xfs_alloc_compute_aligned(args, fbno, flen,
15081786 &rbno, &rlen, &busy_gen);
15091787 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
1510
- XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 ||
1511
- (rlen <= flen && rbno + rlen <= fbno + flen),
1512
- error0);
1788
+ if (XFS_IS_CORRUPT(args->mp,
1789
+ rlen != 0 &&
1790
+ (rlen > flen ||
1791
+ rbno + rlen > fbno + flen))) {
1792
+ error = -EFSCORRUPTED;
1793
+ goto error0;
1794
+ }
15131795 if (rlen > bestrlen) {
15141796 bestrlen = rlen;
15151797 bestrbno = rbno;
....@@ -1522,7 +1804,10 @@
15221804 if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen,
15231805 &i)))
15241806 goto error0;
1525
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1807
+ if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1808
+ error = -EFSCORRUPTED;
1809
+ goto error0;
1810
+ }
15261811 rlen = bestrlen;
15271812 rbno = bestrbno;
15281813 flen = bestflen;
....@@ -1545,7 +1830,10 @@
15451830 xfs_alloc_fix_len(args);
15461831
15471832 rlen = args->len;
1548
- XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0);
1833
+ if (XFS_IS_CORRUPT(args->mp, rlen > flen)) {
1834
+ error = -EFSCORRUPTED;
1835
+ goto error0;
1836
+ }
15491837 /*
15501838 * Allocate and initialize a cursor for the by-block tree.
15511839 */
....@@ -1559,10 +1847,12 @@
15591847 cnt_cur = bno_cur = NULL;
15601848 args->len = rlen;
15611849 args->agbno = rbno;
1562
- XFS_WANT_CORRUPTED_GOTO(args->mp,
1563
- args->agbno + args->len <=
1564
- be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
1565
- error0);
1850
+ if (XFS_IS_CORRUPT(args->mp,
1851
+ args->agbno + args->len >
1852
+ be32_to_cpu(agf->agf_length))) {
1853
+ error = -EFSCORRUPTED;
1854
+ goto error0;
1855
+ }
15661856 trace_xfs_alloc_size_done(args);
15671857 return 0;
15681858
....@@ -1582,140 +1872,31 @@
15821872 }
15831873
15841874 /*
1585
- * Deal with the case where only small freespaces remain.
1586
- * Either return the contents of the last freespace record,
1587
- * or allocate space from the freelist if there is nothing in the tree.
1588
- */
1589
-STATIC int /* error */
1590
-xfs_alloc_ag_vextent_small(
1591
- xfs_alloc_arg_t *args, /* allocation argument structure */
1592
- xfs_btree_cur_t *ccur, /* by-size cursor */
1593
- xfs_agblock_t *fbnop, /* result block number */
1594
- xfs_extlen_t *flenp, /* result length */
1595
- int *stat) /* status: 0-freelist, 1-normal/none */
1596
-{
1597
- struct xfs_owner_info oinfo;
1598
- int error;
1599
- xfs_agblock_t fbno;
1600
- xfs_extlen_t flen;
1601
- int i;
1602
-
1603
- if ((error = xfs_btree_decrement(ccur, 0, &i)))
1604
- goto error0;
1605
- if (i) {
1606
- if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i)))
1607
- goto error0;
1608
- XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1609
- }
1610
- /*
1611
- * Nothing in the btree, try the freelist. Make sure
1612
- * to respect minleft even when pulling from the
1613
- * freelist.
1614
- */
1615
- else if (args->minlen == 1 && args->alignment == 1 &&
1616
- args->resv != XFS_AG_RESV_AGFL &&
1617
- (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
1618
- > args->minleft)) {
1619
- error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
1620
- if (error)
1621
- goto error0;
1622
- if (fbno != NULLAGBLOCK) {
1623
- xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1,
1624
- xfs_alloc_allow_busy_reuse(args->datatype));
1625
-
1626
- if (xfs_alloc_is_userdata(args->datatype)) {
1627
- xfs_buf_t *bp;
1628
-
1629
- bp = xfs_btree_get_bufs(args->mp, args->tp,
1630
- args->agno, fbno, 0);
1631
- if (!bp) {
1632
- error = -EFSCORRUPTED;
1633
- goto error0;
1634
- }
1635
- xfs_trans_binval(args->tp, bp);
1636
- }
1637
- args->len = 1;
1638
- args->agbno = fbno;
1639
- XFS_WANT_CORRUPTED_GOTO(args->mp,
1640
- args->agbno + args->len <=
1641
- be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
1642
- error0);
1643
- args->wasfromfl = 1;
1644
- trace_xfs_alloc_small_freelist(args);
1645
-
1646
- /*
1647
- * If we're feeding an AGFL block to something that
1648
- * doesn't live in the free space, we need to clear
1649
- * out the OWN_AG rmap.
1650
- */
1651
- xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
1652
- error = xfs_rmap_free(args->tp, args->agbp, args->agno,
1653
- fbno, 1, &oinfo);
1654
- if (error)
1655
- goto error0;
1656
-
1657
- *stat = 0;
1658
- return 0;
1659
- }
1660
- /*
1661
- * Nothing in the freelist.
1662
- */
1663
- else
1664
- flen = 0;
1665
- }
1666
- /*
1667
- * Can't allocate from the freelist for some reason.
1668
- */
1669
- else {
1670
- fbno = NULLAGBLOCK;
1671
- flen = 0;
1672
- }
1673
- /*
1674
- * Can't do the allocation, give up.
1675
- */
1676
- if (flen < args->minlen) {
1677
- args->agbno = NULLAGBLOCK;
1678
- trace_xfs_alloc_small_notenough(args);
1679
- flen = 0;
1680
- }
1681
- *fbnop = fbno;
1682
- *flenp = flen;
1683
- *stat = 1;
1684
- trace_xfs_alloc_small_done(args);
1685
- return 0;
1686
-
1687
-error0:
1688
- trace_xfs_alloc_small_error(args);
1689
- return error;
1690
-}
1691
-
1692
-/*
16931875 * Free the extent starting at agno/bno for length.
16941876 */
16951877 STATIC int
16961878 xfs_free_ag_extent(
1697
- xfs_trans_t *tp,
1698
- xfs_buf_t *agbp,
1699
- xfs_agnumber_t agno,
1700
- xfs_agblock_t bno,
1701
- xfs_extlen_t len,
1702
- struct xfs_owner_info *oinfo,
1703
- enum xfs_ag_resv_type type)
1879
+ struct xfs_trans *tp,
1880
+ struct xfs_buf *agbp,
1881
+ xfs_agnumber_t agno,
1882
+ xfs_agblock_t bno,
1883
+ xfs_extlen_t len,
1884
+ const struct xfs_owner_info *oinfo,
1885
+ enum xfs_ag_resv_type type)
17041886 {
1705
- xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */
1706
- xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */
1707
- int error; /* error return value */
1708
- xfs_agblock_t gtbno; /* start of right neighbor block */
1709
- xfs_extlen_t gtlen; /* length of right neighbor block */
1710
- int haveleft; /* have a left neighbor block */
1711
- int haveright; /* have a right neighbor block */
1712
- int i; /* temp, result code */
1713
- xfs_agblock_t ltbno; /* start of left neighbor block */
1714
- xfs_extlen_t ltlen; /* length of left neighbor block */
1715
- xfs_mount_t *mp; /* mount point struct for filesystem */
1716
- xfs_agblock_t nbno; /* new starting block of freespace */
1717
- xfs_extlen_t nlen; /* new length of freespace */
1718
- xfs_perag_t *pag; /* per allocation group data */
1887
+ struct xfs_mount *mp;
1888
+ struct xfs_btree_cur *bno_cur;
1889
+ struct xfs_btree_cur *cnt_cur;
1890
+ xfs_agblock_t gtbno; /* start of right neighbor */
1891
+ xfs_extlen_t gtlen; /* length of right neighbor */
1892
+ xfs_agblock_t ltbno; /* start of left neighbor */
1893
+ xfs_extlen_t ltlen; /* length of left neighbor */
1894
+ xfs_agblock_t nbno; /* new starting block of freesp */
1895
+ xfs_extlen_t nlen; /* new length of freespace */
1896
+ int haveleft; /* have a left neighbor */
1897
+ int haveright; /* have a right neighbor */
1898
+ int i;
1899
+ int error;
17191900
17201901 bno_cur = cnt_cur = NULL;
17211902 mp = tp->t_mountp;
....@@ -1742,7 +1923,10 @@
17421923 */
17431924 if ((error = xfs_alloc_get_rec(bno_cur, &ltbno, &ltlen, &i)))
17441925 goto error0;
1745
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1926
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1927
+ error = -EFSCORRUPTED;
1928
+ goto error0;
1929
+ }
17461930 /*
17471931 * It's not contiguous, though.
17481932 */
....@@ -1754,8 +1938,10 @@
17541938 * space was invalid, it's (partly) already free.
17551939 * Very bad.
17561940 */
1757
- XFS_WANT_CORRUPTED_GOTO(mp,
1758
- ltbno + ltlen <= bno, error0);
1941
+ if (XFS_IS_CORRUPT(mp, ltbno + ltlen > bno)) {
1942
+ error = -EFSCORRUPTED;
1943
+ goto error0;
1944
+ }
17591945 }
17601946 }
17611947 /*
....@@ -1770,7 +1956,10 @@
17701956 */
17711957 if ((error = xfs_alloc_get_rec(bno_cur, &gtbno, &gtlen, &i)))
17721958 goto error0;
1773
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1959
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1960
+ error = -EFSCORRUPTED;
1961
+ goto error0;
1962
+ }
17741963 /*
17751964 * It's not contiguous, though.
17761965 */
....@@ -1782,7 +1971,10 @@
17821971 * space was invalid, it's (partly) already free.
17831972 * Very bad.
17841973 */
1785
- XFS_WANT_CORRUPTED_GOTO(mp, gtbno >= bno + len, error0);
1974
+ if (XFS_IS_CORRUPT(mp, bno + len > gtbno)) {
1975
+ error = -EFSCORRUPTED;
1976
+ goto error0;
1977
+ }
17861978 }
17871979 }
17881980 /*
....@@ -1799,31 +1991,49 @@
17991991 */
18001992 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
18011993 goto error0;
1802
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1994
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1995
+ error = -EFSCORRUPTED;
1996
+ goto error0;
1997
+ }
18031998 if ((error = xfs_btree_delete(cnt_cur, &i)))
18041999 goto error0;
1805
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2000
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2001
+ error = -EFSCORRUPTED;
2002
+ goto error0;
2003
+ }
18062004 /*
18072005 * Delete the old by-size entry on the right.
18082006 */
18092007 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
18102008 goto error0;
1811
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2009
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2010
+ error = -EFSCORRUPTED;
2011
+ goto error0;
2012
+ }
18122013 if ((error = xfs_btree_delete(cnt_cur, &i)))
18132014 goto error0;
1814
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2015
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2016
+ error = -EFSCORRUPTED;
2017
+ goto error0;
2018
+ }
18152019 /*
18162020 * Delete the old by-block entry for the right block.
18172021 */
18182022 if ((error = xfs_btree_delete(bno_cur, &i)))
18192023 goto error0;
1820
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2024
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2025
+ error = -EFSCORRUPTED;
2026
+ goto error0;
2027
+ }
18212028 /*
18222029 * Move the by-block cursor back to the left neighbor.
18232030 */
18242031 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
18252032 goto error0;
1826
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2033
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2034
+ error = -EFSCORRUPTED;
2035
+ goto error0;
2036
+ }
18272037 #ifdef DEBUG
18282038 /*
18292039 * Check that this is the right record: delete didn't
....@@ -1836,9 +2046,13 @@
18362046 if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen,
18372047 &i)))
18382048 goto error0;
1839
- XFS_WANT_CORRUPTED_GOTO(mp,
1840
- i == 1 && xxbno == ltbno && xxlen == ltlen,
1841
- error0);
2049
+ if (XFS_IS_CORRUPT(mp,
2050
+ i != 1 ||
2051
+ xxbno != ltbno ||
2052
+ xxlen != ltlen)) {
2053
+ error = -EFSCORRUPTED;
2054
+ goto error0;
2055
+ }
18422056 }
18432057 #endif
18442058 /*
....@@ -1859,17 +2073,26 @@
18592073 */
18602074 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
18612075 goto error0;
1862
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2076
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2077
+ error = -EFSCORRUPTED;
2078
+ goto error0;
2079
+ }
18632080 if ((error = xfs_btree_delete(cnt_cur, &i)))
18642081 goto error0;
1865
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2082
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2083
+ error = -EFSCORRUPTED;
2084
+ goto error0;
2085
+ }
18662086 /*
18672087 * Back up the by-block cursor to the left neighbor, and
18682088 * update its length.
18692089 */
18702090 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
18712091 goto error0;
1872
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2092
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2093
+ error = -EFSCORRUPTED;
2094
+ goto error0;
2095
+ }
18732096 nbno = ltbno;
18742097 nlen = len + ltlen;
18752098 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
....@@ -1885,10 +2108,16 @@
18852108 */
18862109 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
18872110 goto error0;
1888
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2111
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2112
+ error = -EFSCORRUPTED;
2113
+ goto error0;
2114
+ }
18892115 if ((error = xfs_btree_delete(cnt_cur, &i)))
18902116 goto error0;
1891
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2117
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2118
+ error = -EFSCORRUPTED;
2119
+ goto error0;
2120
+ }
18922121 /*
18932122 * Update the starting block and length of the right
18942123 * neighbor in the by-block tree.
....@@ -1907,7 +2136,10 @@
19072136 nlen = len;
19082137 if ((error = xfs_btree_insert(bno_cur, &i)))
19092138 goto error0;
1910
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2139
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2140
+ error = -EFSCORRUPTED;
2141
+ goto error0;
2142
+ }
19112143 }
19122144 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
19132145 bno_cur = NULL;
....@@ -1916,20 +2148,24 @@
19162148 */
19172149 if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
19182150 goto error0;
1919
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, error0);
2151
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
2152
+ error = -EFSCORRUPTED;
2153
+ goto error0;
2154
+ }
19202155 if ((error = xfs_btree_insert(cnt_cur, &i)))
19212156 goto error0;
1922
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
2157
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2158
+ error = -EFSCORRUPTED;
2159
+ goto error0;
2160
+ }
19232161 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
19242162 cnt_cur = NULL;
19252163
19262164 /*
19272165 * Update the freespace totals in the ag and superblock.
19282166 */
1929
- pag = xfs_perag_get(mp, agno);
1930
- error = xfs_alloc_update_counters(tp, pag, agbp, len);
1931
- xfs_ag_resv_free_extent(pag, type, tp, len);
1932
- xfs_perag_put(pag);
2167
+ error = xfs_alloc_update_counters(tp, agbp, len);
2168
+ xfs_ag_resv_free_extent(agbp->b_pag, type, tp, len);
19332169 if (error)
19342170 goto error0;
19352171
....@@ -1999,30 +2235,39 @@
19992235 * reservations and AGFL rules in place, we can return this extent.
20002236 */
20012237 if (pag->pagf_longest > delta)
2002
- return pag->pagf_longest - delta;
2238
+ return min_t(xfs_extlen_t, pag->pag_mount->m_ag_max_usable,
2239
+ pag->pagf_longest - delta);
20032240
20042241 /* Otherwise, let the caller try for 1 block if there's space. */
20052242 return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
20062243 }
20072244
2245
+/*
2246
+ * Compute the minimum length of the AGFL in the given AG. If @pag is NULL,
2247
+ * return the largest possible minimum length.
2248
+ */
20082249 unsigned int
20092250 xfs_alloc_min_freelist(
20102251 struct xfs_mount *mp,
20112252 struct xfs_perag *pag)
20122253 {
2254
+ /* AG btrees have at least 1 level. */
2255
+ static const uint8_t fake_levels[XFS_BTNUM_AGF] = {1, 1, 1};
2256
+ const uint8_t *levels = pag ? pag->pagf_levels : fake_levels;
20132257 unsigned int min_free;
20142258
2259
+ ASSERT(mp->m_ag_maxlevels > 0);
2260
+
20152261 /* space needed by-bno freespace btree */
2016
- min_free = min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_BNOi] + 1,
2262
+ min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1,
20172263 mp->m_ag_maxlevels);
20182264 /* space needed by-size freespace btree */
2019
- min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1,
2265
+ min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1,
20202266 mp->m_ag_maxlevels);
20212267 /* space needed reverse mapping used space btree */
20222268 if (xfs_sb_version_hasrmapbt(&mp->m_sb))
2023
- min_free += min_t(unsigned int,
2024
- pag->pagf_levels[XFS_BTNUM_RMAPi] + 1,
2025
- mp->m_rmap_maxlevels);
2269
+ min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1,
2270
+ mp->m_rmap_maxlevels);
20262271
20272272 return min_free;
20282273 }
....@@ -2043,6 +2288,7 @@
20432288 xfs_extlen_t alloc_len, longest;
20442289 xfs_extlen_t reservation; /* blocks that are still reserved */
20452290 int available;
2291
+ xfs_extlen_t agflcount;
20462292
20472293 if (flags & XFS_ALLOC_FLAG_FREEING)
20482294 return true;
....@@ -2055,8 +2301,13 @@
20552301 if (longest < alloc_len)
20562302 return false;
20572303
2058
- /* do we have enough free space remaining for the allocation? */
2059
- available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
2304
+ /*
2305
+ * Do we have enough free space remaining for the allocation? Don't
2306
+ * account extra agfl blocks because we are about to defer free them,
2307
+ * making them unavailable until the current transaction commits.
2308
+ */
2309
+ agflcount = min_t(xfs_extlen_t, pag->pagf_flcount, min_free);
2310
+ available = (int)(pag->pagf_freeblks + agflcount -
20602311 reservation - min_free - args->minleft);
20612312 if (available < (int)max(args->total, alloc_len))
20622313 return false;
....@@ -2090,9 +2341,11 @@
20902341 if (error)
20912342 return error;
20922343
2093
- bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno, 0);
2094
- if (!bp)
2095
- return -EFSCORRUPTED;
2344
+ error = xfs_trans_get_buf(tp, tp->t_mountp->m_ddev_targp,
2345
+ XFS_AGB_TO_DADDR(tp->t_mountp, agno, agbno),
2346
+ tp->t_mountp->m_bsize, 0, &bp);
2347
+ if (error)
2348
+ return error;
20962349 xfs_trans_binval(tp, bp);
20972350
20982351 return 0;
....@@ -2165,7 +2418,7 @@
21652418 struct xfs_perag *pag)
21662419 {
21672420 struct xfs_mount *mp = tp->t_mountp;
2168
- struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
2421
+ struct xfs_agf *agf = agbp->b_addr;
21692422
21702423 ASSERT(pag->pagf_agflreset);
21712424 trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_);
....@@ -2209,7 +2462,8 @@
22092462 ASSERT(xfs_bmap_free_item_zone != NULL);
22102463 ASSERT(oinfo != NULL);
22112464
2212
- new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP);
2465
+ new = kmem_cache_alloc(xfs_bmap_free_item_zone,
2466
+ GFP_KERNEL | __GFP_NOFAIL);
22132467 new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
22142468 new->xefi_blockcount = 1;
22152469 new->xefi_oinfo = *oinfo;
....@@ -2239,14 +2493,16 @@
22392493 xfs_extlen_t need; /* total blocks needed in freelist */
22402494 int error = 0;
22412495
2496
+ /* deferred ops (AGFL block frees) require permanent transactions */
2497
+ ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
2498
+
22422499 if (!pag->pagf_init) {
22432500 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2244
- if (error)
2501
+ if (error) {
2502
+ /* Couldn't lock the AGF so skip this AG. */
2503
+ if (error == -EAGAIN)
2504
+ error = 0;
22452505 goto out_no_agbp;
2246
- if (!pag->pagf_init) {
2247
- ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2248
- ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
2249
- goto out_agbp_relse;
22502506 }
22512507 }
22522508
....@@ -2255,7 +2511,7 @@
22552511 * somewhere else if we are not being asked to try harder at this
22562512 * point
22572513 */
2258
- if (pag->pagf_metadata && xfs_alloc_is_userdata(args->datatype) &&
2514
+ if (pag->pagf_metadata && (args->datatype & XFS_ALLOC_USERDATA) &&
22592515 (flags & XFS_ALLOC_FLAG_TRYLOCK)) {
22602516 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
22612517 goto out_agbp_relse;
....@@ -2272,11 +2528,10 @@
22722528 */
22732529 if (!agbp) {
22742530 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2275
- if (error)
2276
- goto out_no_agbp;
2277
- if (!agbp) {
2278
- ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2279
- ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
2531
+ if (error) {
2532
+ /* Couldn't lock the AGF so skip this AG. */
2533
+ if (error == -EAGAIN)
2534
+ error = 0;
22802535 goto out_no_agbp;
22812536 }
22822537 }
....@@ -2315,10 +2570,11 @@
23152570 * repair/rmap.c in xfsprogs for details.
23162571 */
23172572 memset(&targs, 0, sizeof(targs));
2573
+ /* struct copy below */
23182574 if (flags & XFS_ALLOC_FLAG_NORMAP)
2319
- xfs_rmap_skip_owner_update(&targs.oinfo);
2575
+ targs.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
23202576 else
2321
- xfs_rmap_ag_owner(&targs.oinfo, XFS_RMAP_OWN_AG);
2577
+ targs.oinfo = XFS_RMAP_OINFO_AG;
23222578 while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) {
23232579 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
23242580 if (error)
....@@ -2395,7 +2651,7 @@
23952651 xfs_agblock_t *bnop, /* block address retrieved from freelist */
23962652 int btreeblk) /* destination is a AGF btree */
23972653 {
2398
- xfs_agf_t *agf; /* a.g. freespace structure */
2654
+ struct xfs_agf *agf = agbp->b_addr;
23992655 xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
24002656 xfs_agblock_t bno; /* block number returned */
24012657 __be32 *agfl_bno;
....@@ -2407,7 +2663,6 @@
24072663 /*
24082664 * Freelist is empty, give up.
24092665 */
2410
- agf = XFS_BUF_TO_AGF(agbp);
24112666 if (!agf->agf_flcount) {
24122667 *bnop = NULLAGBLOCK;
24132668 return 0;
....@@ -2424,19 +2679,18 @@
24242679 /*
24252680 * Get the block number and update the data structures.
24262681 */
2427
- agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
2682
+ agfl_bno = xfs_buf_to_agfl_bno(agflbp);
24282683 bno = be32_to_cpu(agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
24292684 be32_add_cpu(&agf->agf_flfirst, 1);
24302685 xfs_trans_brelse(tp, agflbp);
24312686 if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp))
24322687 agf->agf_flfirst = 0;
24332688
2434
- pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
2689
+ pag = agbp->b_pag;
24352690 ASSERT(!pag->pagf_agflreset);
24362691 be32_add_cpu(&agf->agf_flcount, -1);
24372692 xfs_trans_agflist_delta(tp, -1);
24382693 pag->pagf_flcount--;
2439
- xfs_perag_put(pag);
24402694
24412695 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
24422696 if (btreeblk) {
....@@ -2485,7 +2739,7 @@
24852739 sizeof(xfs_agf_t)
24862740 };
24872741
2488
- trace_xfs_agf(tp->t_mountp, XFS_BUF_TO_AGF(bp), fields, _RET_IP_);
2742
+ trace_xfs_agf(tp->t_mountp, bp->b_addr, fields, _RET_IP_);
24892743
24902744 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGF_BUF);
24912745
....@@ -2506,11 +2760,10 @@
25062760 xfs_buf_t *bp;
25072761 int error;
25082762
2509
- if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp)))
2510
- return error;
2511
- if (bp)
2763
+ error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp);
2764
+ if (!error)
25122765 xfs_trans_brelse(tp, bp);
2513
- return 0;
2766
+ return error;
25142767 }
25152768
25162769 /*
....@@ -2524,17 +2777,14 @@
25242777 xfs_agblock_t bno, /* block being freed */
25252778 int btreeblk) /* block came from a AGF btree */
25262779 {
2527
- xfs_agf_t *agf; /* a.g. freespace structure */
2780
+ struct xfs_mount *mp = tp->t_mountp;
2781
+ struct xfs_agf *agf = agbp->b_addr;
25282782 __be32 *blockp;/* pointer to array entry */
25292783 int error;
25302784 int logflags;
2531
- xfs_mount_t *mp; /* mount structure */
25322785 xfs_perag_t *pag; /* per allocation group data */
25332786 __be32 *agfl_bno;
25342787 int startoff;
2535
-
2536
- agf = XFS_BUF_TO_AGF(agbp);
2537
- mp = tp->t_mountp;
25382788
25392789 if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp,
25402790 be32_to_cpu(agf->agf_seqno), &agflbp)))
....@@ -2543,7 +2793,7 @@
25432793 if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp))
25442794 agf->agf_fllast = 0;
25452795
2546
- pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
2796
+ pag = agbp->b_pag;
25472797 ASSERT(!pag->pagf_agflreset);
25482798 be32_add_cpu(&agf->agf_flcount, 1);
25492799 xfs_trans_agflist_delta(tp, 1);
....@@ -2555,13 +2805,12 @@
25552805 pag->pagf_btreeblks--;
25562806 logflags |= XFS_AGF_BTREEBLKS;
25572807 }
2558
- xfs_perag_put(pag);
25592808
25602809 xfs_alloc_log_agf(tp, agbp, logflags);
25612810
25622811 ASSERT(be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp));
25632812
2564
- agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
2813
+ agfl_bno = xfs_buf_to_agfl_bno(agflbp);
25652814 blockp = &agfl_bno[be32_to_cpu(agf->agf_fllast)];
25662815 *blockp = cpu_to_be32(bno);
25672816 startoff = (char *)blockp - (char *)agflbp->b_addr;
....@@ -2578,19 +2827,20 @@
25782827 xfs_agf_verify(
25792828 struct xfs_buf *bp)
25802829 {
2581
- struct xfs_mount *mp = bp->b_target->bt_mount;
2582
- struct xfs_agf *agf = XFS_BUF_TO_AGF(bp);
2830
+ struct xfs_mount *mp = bp->b_mount;
2831
+ struct xfs_agf *agf = bp->b_addr;
25832832
25842833 if (xfs_sb_version_hascrc(&mp->m_sb)) {
25852834 if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
25862835 return __this_address;
2587
- if (!xfs_log_check_lsn(mp,
2588
- be64_to_cpu(XFS_BUF_TO_AGF(bp)->agf_lsn)))
2836
+ if (!xfs_log_check_lsn(mp, be64_to_cpu(agf->agf_lsn)))
25892837 return __this_address;
25902838 }
25912839
2592
- if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
2593
- XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
2840
+ if (!xfs_verify_magic(bp, agf->agf_magicnum))
2841
+ return __this_address;
2842
+
2843
+ if (!(XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
25942844 be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
25952845 be32_to_cpu(agf->agf_flfirst) < xfs_agfl_size(mp) &&
25962846 be32_to_cpu(agf->agf_fllast) < xfs_agfl_size(mp) &&
....@@ -2650,7 +2900,7 @@
26502900 xfs_agf_read_verify(
26512901 struct xfs_buf *bp)
26522902 {
2653
- struct xfs_mount *mp = bp->b_target->bt_mount;
2903
+ struct xfs_mount *mp = bp->b_mount;
26542904 xfs_failaddr_t fa;
26552905
26562906 if (xfs_sb_version_hascrc(&mp->m_sb) &&
....@@ -2667,8 +2917,9 @@
26672917 xfs_agf_write_verify(
26682918 struct xfs_buf *bp)
26692919 {
2670
- struct xfs_mount *mp = bp->b_target->bt_mount;
2920
+ struct xfs_mount *mp = bp->b_mount;
26712921 struct xfs_buf_log_item *bip = bp->b_log_item;
2922
+ struct xfs_agf *agf = bp->b_addr;
26722923 xfs_failaddr_t fa;
26732924
26742925 fa = xfs_agf_verify(bp);
....@@ -2681,13 +2932,14 @@
26812932 return;
26822933
26832934 if (bip)
2684
- XFS_BUF_TO_AGF(bp)->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
2935
+ agf->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
26852936
26862937 xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF);
26872938 }
26882939
26892940 const struct xfs_buf_ops xfs_agf_buf_ops = {
26902941 .name = "xfs_agf",
2942
+ .magic = { cpu_to_be32(XFS_AGF_MAGIC), cpu_to_be32(XFS_AGF_MAGIC) },
26912943 .verify_read = xfs_agf_read_verify,
26922944 .verify_write = xfs_agf_write_verify,
26932945 .verify_struct = xfs_agf_verify,
....@@ -2709,14 +2961,11 @@
27092961 trace_xfs_read_agf(mp, agno);
27102962
27112963 ASSERT(agno != NULLAGNUMBER);
2712
- error = xfs_trans_read_buf(
2713
- mp, tp, mp->m_ddev_targp,
2964
+ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
27142965 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
27152966 XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
27162967 if (error)
27172968 return error;
2718
- if (!*bpp)
2719
- return 0;
27202969
27212970 ASSERT(!(*bpp)->b_error);
27222971 xfs_buf_set_ref(*bpp, XFS_AGF_REF);
....@@ -2740,18 +2989,19 @@
27402989
27412990 trace_xfs_alloc_read_agf(mp, agno);
27422991
2992
+ /* We don't support trylock when freeing. */
2993
+ ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) !=
2994
+ (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK));
27432995 ASSERT(agno != NULLAGNUMBER);
27442996 error = xfs_read_agf(mp, tp, agno,
27452997 (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
27462998 bpp);
27472999 if (error)
27483000 return error;
2749
- if (!*bpp)
2750
- return 0;
27513001 ASSERT(!(*bpp)->b_error);
27523002
2753
- agf = XFS_BUF_TO_AGF(*bpp);
2754
- pag = xfs_perag_get(mp, agno);
3003
+ agf = (*bpp)->b_addr;
3004
+ pag = (*bpp)->b_pag;
27553005 if (!pag->pagf_init) {
27563006 pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
27573007 pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
....@@ -2779,7 +3029,6 @@
27793029 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
27803030 }
27813031 #endif
2782
- xfs_perag_put(pag);
27833032 return 0;
27843033 }
27853034
....@@ -2970,13 +3219,6 @@
29703219 args->len);
29713220 #endif
29723221
2973
- /* Zero the extent if we were asked to do so */
2974
- if (args->datatype & XFS_ALLOC_USERDATA_ZERO) {
2975
- error = xfs_zero_extent(args->ip, args->fsbno, args->len);
2976
- if (error)
2977
- goto error0;
2978
- }
2979
-
29803222 }
29813223 xfs_perag_put(args->pag);
29823224 return 0;
....@@ -3025,21 +3267,22 @@
30253267 * Just break up the extent address and hand off to xfs_free_ag_extent
30263268 * after fixing up the freelist.
30273269 */
3028
-int /* error */
3270
+int
30293271 __xfs_free_extent(
3030
- struct xfs_trans *tp, /* transaction pointer */
3031
- xfs_fsblock_t bno, /* starting block number of extent */
3032
- xfs_extlen_t len, /* length of extent */
3033
- struct xfs_owner_info *oinfo, /* extent owner */
3034
- enum xfs_ag_resv_type type, /* block reservation type */
3035
- bool skip_discard)
3272
+ struct xfs_trans *tp,
3273
+ xfs_fsblock_t bno,
3274
+ xfs_extlen_t len,
3275
+ const struct xfs_owner_info *oinfo,
3276
+ enum xfs_ag_resv_type type,
3277
+ bool skip_discard)
30363278 {
3037
- struct xfs_mount *mp = tp->t_mountp;
3038
- struct xfs_buf *agbp;
3039
- xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
3040
- xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
3041
- int error;
3042
- unsigned int busy_flags = 0;
3279
+ struct xfs_mount *mp = tp->t_mountp;
3280
+ struct xfs_buf *agbp;
3281
+ xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
3282
+ xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
3283
+ struct xfs_agf *agf;
3284
+ int error;
3285
+ unsigned int busy_flags = 0;
30433286
30443287 ASSERT(len != 0);
30453288 ASSERT(type != XFS_AG_RESV_AGFL);
....@@ -3051,13 +3294,18 @@
30513294 error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
30523295 if (error)
30533296 return error;
3297
+ agf = agbp->b_addr;
30543298
3055
- XFS_WANT_CORRUPTED_GOTO(mp, agbno < mp->m_sb.sb_agblocks, err);
3299
+ if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) {
3300
+ error = -EFSCORRUPTED;
3301
+ goto err;
3302
+ }
30563303
30573304 /* validate the extent size is legal now we have the agf locked */
3058
- XFS_WANT_CORRUPTED_GOTO(mp,
3059
- agbno + len <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_length),
3060
- err);
3305
+ if (XFS_IS_CORRUPT(mp, agbno + len > be32_to_cpu(agf->agf_length))) {
3306
+ error = -EFSCORRUPTED;
3307
+ goto err;
3308
+ }
30613309
30623310 error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type);
30633311 if (error)
....@@ -3151,7 +3399,7 @@
31513399
31523400 /*
31533401 * Walk all the blocks in the AGFL. The @walk_fn can return any negative
3154
- * error code or XFS_BTREE_QUERY_RANGE_ABORT.
3402
+ * error code or XFS_ITER_*.
31553403 */
31563404 int
31573405 xfs_agfl_walk(
....@@ -3165,7 +3413,7 @@
31653413 unsigned int i;
31663414 int error;
31673415
3168
- agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
3416
+ agfl_bno = xfs_buf_to_agfl_bno(agflbp);
31693417 i = be32_to_cpu(agf->agf_flfirst);
31703418
31713419 /* Nothing to walk in an empty AGFL. */