diff options
Diffstat (limited to 'fs/xfs/xfs_alloc.c')
-rw-r--r-- | fs/xfs/xfs_alloc.c | 354 |
1 files changed, 106 insertions, 248 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 2cf944eb796d..94cddbfb2560 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "xfs_ialloc.h" | 38 | #include "xfs_ialloc.h" |
39 | #include "xfs_alloc.h" | 39 | #include "xfs_alloc.h" |
40 | #include "xfs_error.h" | 40 | #include "xfs_error.h" |
41 | #include "xfs_trace.h" | ||
41 | 42 | ||
42 | 43 | ||
43 | #define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b))) | 44 | #define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b))) |
@@ -51,30 +52,6 @@ xfs_alloc_search_busy(xfs_trans_t *tp, | |||
51 | xfs_agblock_t bno, | 52 | xfs_agblock_t bno, |
52 | xfs_extlen_t len); | 53 | xfs_extlen_t len); |
53 | 54 | ||
54 | #if defined(XFS_ALLOC_TRACE) | ||
55 | ktrace_t *xfs_alloc_trace_buf; | ||
56 | |||
57 | #define TRACE_ALLOC(s,a) \ | ||
58 | xfs_alloc_trace_alloc(__func__, s, a, __LINE__) | ||
59 | #define TRACE_FREE(s,a,b,x,f) \ | ||
60 | xfs_alloc_trace_free(__func__, s, mp, a, b, x, f, __LINE__) | ||
61 | #define TRACE_MODAGF(s,a,f) \ | ||
62 | xfs_alloc_trace_modagf(__func__, s, mp, a, f, __LINE__) | ||
63 | #define TRACE_BUSY(__func__,s,ag,agb,l,sl,tp) \ | ||
64 | xfs_alloc_trace_busy(__func__, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSY, __LINE__) | ||
65 | #define TRACE_UNBUSY(__func__,s,ag,sl,tp) \ | ||
66 | xfs_alloc_trace_busy(__func__, s, mp, ag, -1, -1, sl, tp, XFS_ALLOC_KTRACE_UNBUSY, __LINE__) | ||
67 | #define TRACE_BUSYSEARCH(__func__,s,ag,agb,l,tp) \ | ||
68 | xfs_alloc_trace_busy(__func__, s, mp, ag, agb, l, 0, tp, XFS_ALLOC_KTRACE_BUSYSEARCH, __LINE__) | ||
69 | #else | ||
70 | #define TRACE_ALLOC(s,a) | ||
71 | #define TRACE_FREE(s,a,b,x,f) | ||
72 | #define TRACE_MODAGF(s,a,f) | ||
73 | #define TRACE_BUSY(s,a,ag,agb,l,sl,tp) | ||
74 | #define TRACE_UNBUSY(fname,s,ag,sl,tp) | ||
75 | #define TRACE_BUSYSEARCH(fname,s,ag,agb,l,tp) | ||
76 | #endif /* XFS_ALLOC_TRACE */ | ||
77 | |||
78 | /* | 55 | /* |
79 | * Prototypes for per-ag allocation routines | 56 | * Prototypes for per-ag allocation routines |
80 | */ | 57 | */ |
@@ -498,124 +475,6 @@ xfs_alloc_read_agfl( | |||
498 | return 0; | 475 | return 0; |
499 | } | 476 | } |
500 | 477 | ||
501 | #if defined(XFS_ALLOC_TRACE) | ||
502 | /* | ||
503 | * Add an allocation trace entry for an alloc call. | ||
504 | */ | ||
505 | STATIC void | ||
506 | xfs_alloc_trace_alloc( | ||
507 | const char *name, /* function tag string */ | ||
508 | char *str, /* additional string */ | ||
509 | xfs_alloc_arg_t *args, /* allocation argument structure */ | ||
510 | int line) /* source line number */ | ||
511 | { | ||
512 | ktrace_enter(xfs_alloc_trace_buf, | ||
513 | (void *)(__psint_t)(XFS_ALLOC_KTRACE_ALLOC | (line << 16)), | ||
514 | (void *)name, | ||
515 | (void *)str, | ||
516 | (void *)args->mp, | ||
517 | (void *)(__psunsigned_t)args->agno, | ||
518 | (void *)(__psunsigned_t)args->agbno, | ||
519 | (void *)(__psunsigned_t)args->minlen, | ||
520 | (void *)(__psunsigned_t)args->maxlen, | ||
521 | (void *)(__psunsigned_t)args->mod, | ||
522 | (void *)(__psunsigned_t)args->prod, | ||
523 | (void *)(__psunsigned_t)args->minleft, | ||
524 | (void *)(__psunsigned_t)args->total, | ||
525 | (void *)(__psunsigned_t)args->alignment, | ||
526 | (void *)(__psunsigned_t)args->len, | ||
527 | (void *)((((__psint_t)args->type) << 16) | | ||
528 | (__psint_t)args->otype), | ||
529 | (void *)(__psint_t)((args->wasdel << 3) | | ||
530 | (args->wasfromfl << 2) | | ||
531 | (args->isfl << 1) | | ||
532 | (args->userdata << 0))); | ||
533 | } | ||
534 | |||
535 | /* | ||
536 | * Add an allocation trace entry for a free call. | ||
537 | */ | ||
538 | STATIC void | ||
539 | xfs_alloc_trace_free( | ||
540 | const char *name, /* function tag string */ | ||
541 | char *str, /* additional string */ | ||
542 | xfs_mount_t *mp, /* file system mount point */ | ||
543 | xfs_agnumber_t agno, /* allocation group number */ | ||
544 | xfs_agblock_t agbno, /* a.g. relative block number */ | ||
545 | xfs_extlen_t len, /* length of extent */ | ||
546 | int isfl, /* set if is freelist allocation/free */ | ||
547 | int line) /* source line number */ | ||
548 | { | ||
549 | ktrace_enter(xfs_alloc_trace_buf, | ||
550 | (void *)(__psint_t)(XFS_ALLOC_KTRACE_FREE | (line << 16)), | ||
551 | (void *)name, | ||
552 | (void *)str, | ||
553 | (void *)mp, | ||
554 | (void *)(__psunsigned_t)agno, | ||
555 | (void *)(__psunsigned_t)agbno, | ||
556 | (void *)(__psunsigned_t)len, | ||
557 | (void *)(__psint_t)isfl, | ||
558 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * Add an allocation trace entry for modifying an agf. | ||
563 | */ | ||
564 | STATIC void | ||
565 | xfs_alloc_trace_modagf( | ||
566 | const char *name, /* function tag string */ | ||
567 | char *str, /* additional string */ | ||
568 | xfs_mount_t *mp, /* file system mount point */ | ||
569 | xfs_agf_t *agf, /* new agf value */ | ||
570 | int flags, /* logging flags for agf */ | ||
571 | int line) /* source line number */ | ||
572 | { | ||
573 | ktrace_enter(xfs_alloc_trace_buf, | ||
574 | (void *)(__psint_t)(XFS_ALLOC_KTRACE_MODAGF | (line << 16)), | ||
575 | (void *)name, | ||
576 | (void *)str, | ||
577 | (void *)mp, | ||
578 | (void *)(__psint_t)flags, | ||
579 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_seqno), | ||
580 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_length), | ||
581 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), | ||
582 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), | ||
583 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), | ||
584 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), | ||
585 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flfirst), | ||
586 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_fllast), | ||
587 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flcount), | ||
588 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_freeblks), | ||
589 | (void *)(__psunsigned_t)be32_to_cpu(agf->agf_longest)); | ||
590 | } | ||
591 | |||
592 | STATIC void | ||
593 | xfs_alloc_trace_busy( | ||
594 | const char *name, /* function tag string */ | ||
595 | char *str, /* additional string */ | ||
596 | xfs_mount_t *mp, /* file system mount point */ | ||
597 | xfs_agnumber_t agno, /* allocation group number */ | ||
598 | xfs_agblock_t agbno, /* a.g. relative block number */ | ||
599 | xfs_extlen_t len, /* length of extent */ | ||
600 | int slot, /* perag Busy slot */ | ||
601 | xfs_trans_t *tp, | ||
602 | int trtype, /* type: add, delete, search */ | ||
603 | int line) /* source line number */ | ||
604 | { | ||
605 | ktrace_enter(xfs_alloc_trace_buf, | ||
606 | (void *)(__psint_t)(trtype | (line << 16)), | ||
607 | (void *)name, | ||
608 | (void *)str, | ||
609 | (void *)mp, | ||
610 | (void *)(__psunsigned_t)agno, | ||
611 | (void *)(__psunsigned_t)agbno, | ||
612 | (void *)(__psunsigned_t)len, | ||
613 | (void *)(__psint_t)slot, | ||
614 | (void *)tp, | ||
615 | NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
616 | } | ||
617 | #endif /* XFS_ALLOC_TRACE */ | ||
618 | |||
619 | /* | 478 | /* |
620 | * Allocation group level functions. | 479 | * Allocation group level functions. |
621 | */ | 480 | */ |
@@ -665,9 +524,6 @@ xfs_alloc_ag_vextent( | |||
665 | */ | 524 | */ |
666 | if (args->agbno != NULLAGBLOCK) { | 525 | if (args->agbno != NULLAGBLOCK) { |
667 | xfs_agf_t *agf; /* allocation group freelist header */ | 526 | xfs_agf_t *agf; /* allocation group freelist header */ |
668 | #ifdef XFS_ALLOC_TRACE | ||
669 | xfs_mount_t *mp = args->mp; | ||
670 | #endif | ||
671 | long slen = (long)args->len; | 527 | long slen = (long)args->len; |
672 | 528 | ||
673 | ASSERT(args->len >= args->minlen && args->len <= args->maxlen); | 529 | ASSERT(args->len >= args->minlen && args->len <= args->maxlen); |
@@ -682,7 +538,6 @@ xfs_alloc_ag_vextent( | |||
682 | args->pag->pagf_freeblks -= args->len; | 538 | args->pag->pagf_freeblks -= args->len; |
683 | ASSERT(be32_to_cpu(agf->agf_freeblks) <= | 539 | ASSERT(be32_to_cpu(agf->agf_freeblks) <= |
684 | be32_to_cpu(agf->agf_length)); | 540 | be32_to_cpu(agf->agf_length)); |
685 | TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS); | ||
686 | xfs_alloc_log_agf(args->tp, args->agbp, | 541 | xfs_alloc_log_agf(args->tp, args->agbp, |
687 | XFS_AGF_FREEBLKS); | 542 | XFS_AGF_FREEBLKS); |
688 | /* search the busylist for these blocks */ | 543 | /* search the busylist for these blocks */ |
@@ -792,13 +647,14 @@ xfs_alloc_ag_vextent_exact( | |||
792 | } | 647 | } |
793 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); | 648 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); |
794 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 649 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
795 | TRACE_ALLOC("normal", args); | 650 | |
651 | trace_xfs_alloc_exact_done(args); | ||
796 | args->wasfromfl = 0; | 652 | args->wasfromfl = 0; |
797 | return 0; | 653 | return 0; |
798 | 654 | ||
799 | error0: | 655 | error0: |
800 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); | 656 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); |
801 | TRACE_ALLOC("error", args); | 657 | trace_xfs_alloc_exact_error(args); |
802 | return error; | 658 | return error; |
803 | } | 659 | } |
804 | 660 | ||
@@ -958,7 +814,7 @@ xfs_alloc_ag_vextent_near( | |||
958 | args->len = blen; | 814 | args->len = blen; |
959 | if (!xfs_alloc_fix_minleft(args)) { | 815 | if (!xfs_alloc_fix_minleft(args)) { |
960 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 816 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
961 | TRACE_ALLOC("nominleft", args); | 817 | trace_xfs_alloc_near_nominleft(args); |
962 | return 0; | 818 | return 0; |
963 | } | 819 | } |
964 | blen = args->len; | 820 | blen = args->len; |
@@ -981,7 +837,8 @@ xfs_alloc_ag_vextent_near( | |||
981 | goto error0; | 837 | goto error0; |
982 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 838 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
983 | xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); | 839 | xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); |
984 | TRACE_ALLOC("first", args); | 840 | |
841 | trace_xfs_alloc_near_first(args); | ||
985 | return 0; | 842 | return 0; |
986 | } | 843 | } |
987 | /* | 844 | /* |
@@ -1272,7 +1129,7 @@ xfs_alloc_ag_vextent_near( | |||
1272 | * If we couldn't get anything, give up. | 1129 | * If we couldn't get anything, give up. |
1273 | */ | 1130 | */ |
1274 | if (bno_cur_lt == NULL && bno_cur_gt == NULL) { | 1131 | if (bno_cur_lt == NULL && bno_cur_gt == NULL) { |
1275 | TRACE_ALLOC("neither", args); | 1132 | trace_xfs_alloc_size_neither(args); |
1276 | args->agbno = NULLAGBLOCK; | 1133 | args->agbno = NULLAGBLOCK; |
1277 | return 0; | 1134 | return 0; |
1278 | } | 1135 | } |
@@ -1299,7 +1156,7 @@ xfs_alloc_ag_vextent_near( | |||
1299 | args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); | 1156 | args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); |
1300 | xfs_alloc_fix_len(args); | 1157 | xfs_alloc_fix_len(args); |
1301 | if (!xfs_alloc_fix_minleft(args)) { | 1158 | if (!xfs_alloc_fix_minleft(args)) { |
1302 | TRACE_ALLOC("nominleft", args); | 1159 | trace_xfs_alloc_near_nominleft(args); |
1303 | xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); | 1160 | xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); |
1304 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 1161 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
1305 | return 0; | 1162 | return 0; |
@@ -1314,13 +1171,18 @@ xfs_alloc_ag_vextent_near( | |||
1314 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, | 1171 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, |
1315 | ltnew, rlen, XFSA_FIXUP_BNO_OK))) | 1172 | ltnew, rlen, XFSA_FIXUP_BNO_OK))) |
1316 | goto error0; | 1173 | goto error0; |
1317 | TRACE_ALLOC(j ? "gt" : "lt", args); | 1174 | |
1175 | if (j) | ||
1176 | trace_xfs_alloc_near_greater(args); | ||
1177 | else | ||
1178 | trace_xfs_alloc_near_lesser(args); | ||
1179 | |||
1318 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 1180 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
1319 | xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); | 1181 | xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); |
1320 | return 0; | 1182 | return 0; |
1321 | 1183 | ||
1322 | error0: | 1184 | error0: |
1323 | TRACE_ALLOC("error", args); | 1185 | trace_xfs_alloc_near_error(args); |
1324 | if (cnt_cur != NULL) | 1186 | if (cnt_cur != NULL) |
1325 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); | 1187 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); |
1326 | if (bno_cur_lt != NULL) | 1188 | if (bno_cur_lt != NULL) |
@@ -1371,7 +1233,7 @@ xfs_alloc_ag_vextent_size( | |||
1371 | goto error0; | 1233 | goto error0; |
1372 | if (i == 0 || flen == 0) { | 1234 | if (i == 0 || flen == 0) { |
1373 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 1235 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
1374 | TRACE_ALLOC("noentry", args); | 1236 | trace_xfs_alloc_size_noentry(args); |
1375 | return 0; | 1237 | return 0; |
1376 | } | 1238 | } |
1377 | ASSERT(i == 1); | 1239 | ASSERT(i == 1); |
@@ -1448,7 +1310,7 @@ xfs_alloc_ag_vextent_size( | |||
1448 | xfs_alloc_fix_len(args); | 1310 | xfs_alloc_fix_len(args); |
1449 | if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) { | 1311 | if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) { |
1450 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 1312 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
1451 | TRACE_ALLOC("nominleft", args); | 1313 | trace_xfs_alloc_size_nominleft(args); |
1452 | args->agbno = NULLAGBLOCK; | 1314 | args->agbno = NULLAGBLOCK; |
1453 | return 0; | 1315 | return 0; |
1454 | } | 1316 | } |
@@ -1471,11 +1333,11 @@ xfs_alloc_ag_vextent_size( | |||
1471 | args->agbno + args->len <= | 1333 | args->agbno + args->len <= |
1472 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), | 1334 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), |
1473 | error0); | 1335 | error0); |
1474 | TRACE_ALLOC("normal", args); | 1336 | trace_xfs_alloc_size_done(args); |
1475 | return 0; | 1337 | return 0; |
1476 | 1338 | ||
1477 | error0: | 1339 | error0: |
1478 | TRACE_ALLOC("error", args); | 1340 | trace_xfs_alloc_size_error(args); |
1479 | if (cnt_cur) | 1341 | if (cnt_cur) |
1480 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); | 1342 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); |
1481 | if (bno_cur) | 1343 | if (bno_cur) |
@@ -1534,7 +1396,7 @@ xfs_alloc_ag_vextent_small( | |||
1534 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), | 1396 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), |
1535 | error0); | 1397 | error0); |
1536 | args->wasfromfl = 1; | 1398 | args->wasfromfl = 1; |
1537 | TRACE_ALLOC("freelist", args); | 1399 | trace_xfs_alloc_small_freelist(args); |
1538 | *stat = 0; | 1400 | *stat = 0; |
1539 | return 0; | 1401 | return 0; |
1540 | } | 1402 | } |
@@ -1556,17 +1418,17 @@ xfs_alloc_ag_vextent_small( | |||
1556 | */ | 1418 | */ |
1557 | if (flen < args->minlen) { | 1419 | if (flen < args->minlen) { |
1558 | args->agbno = NULLAGBLOCK; | 1420 | args->agbno = NULLAGBLOCK; |
1559 | TRACE_ALLOC("notenough", args); | 1421 | trace_xfs_alloc_small_notenough(args); |
1560 | flen = 0; | 1422 | flen = 0; |
1561 | } | 1423 | } |
1562 | *fbnop = fbno; | 1424 | *fbnop = fbno; |
1563 | *flenp = flen; | 1425 | *flenp = flen; |
1564 | *stat = 1; | 1426 | *stat = 1; |
1565 | TRACE_ALLOC("normal", args); | 1427 | trace_xfs_alloc_small_done(args); |
1566 | return 0; | 1428 | return 0; |
1567 | 1429 | ||
1568 | error0: | 1430 | error0: |
1569 | TRACE_ALLOC("error", args); | 1431 | trace_xfs_alloc_small_error(args); |
1570 | return error; | 1432 | return error; |
1571 | } | 1433 | } |
1572 | 1434 | ||
@@ -1800,26 +1662,25 @@ xfs_free_ag_extent( | |||
1800 | xfs_agf_t *agf; | 1662 | xfs_agf_t *agf; |
1801 | xfs_perag_t *pag; /* per allocation group data */ | 1663 | xfs_perag_t *pag; /* per allocation group data */ |
1802 | 1664 | ||
1665 | pag = xfs_perag_get(mp, agno); | ||
1666 | pag->pagf_freeblks += len; | ||
1667 | xfs_perag_put(pag); | ||
1668 | |||
1803 | agf = XFS_BUF_TO_AGF(agbp); | 1669 | agf = XFS_BUF_TO_AGF(agbp); |
1804 | pag = &mp->m_perag[agno]; | ||
1805 | be32_add_cpu(&agf->agf_freeblks, len); | 1670 | be32_add_cpu(&agf->agf_freeblks, len); |
1806 | xfs_trans_agblocks_delta(tp, len); | 1671 | xfs_trans_agblocks_delta(tp, len); |
1807 | pag->pagf_freeblks += len; | ||
1808 | XFS_WANT_CORRUPTED_GOTO( | 1672 | XFS_WANT_CORRUPTED_GOTO( |
1809 | be32_to_cpu(agf->agf_freeblks) <= | 1673 | be32_to_cpu(agf->agf_freeblks) <= |
1810 | be32_to_cpu(agf->agf_length), | 1674 | be32_to_cpu(agf->agf_length), |
1811 | error0); | 1675 | error0); |
1812 | TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS); | ||
1813 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); | 1676 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); |
1814 | if (!isfl) | 1677 | if (!isfl) |
1815 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); | 1678 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); |
1816 | XFS_STATS_INC(xs_freex); | 1679 | XFS_STATS_INC(xs_freex); |
1817 | XFS_STATS_ADD(xs_freeb, len); | 1680 | XFS_STATS_ADD(xs_freeb, len); |
1818 | } | 1681 | } |
1819 | TRACE_FREE(haveleft ? | 1682 | |
1820 | (haveright ? "both" : "left") : | 1683 | trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); |
1821 | (haveright ? "right" : "none"), | ||
1822 | agno, bno, len, isfl); | ||
1823 | 1684 | ||
1824 | /* | 1685 | /* |
1825 | * Since blocks move to the free list without the coordination | 1686 | * Since blocks move to the free list without the coordination |
@@ -1836,7 +1697,7 @@ xfs_free_ag_extent( | |||
1836 | return 0; | 1697 | return 0; |
1837 | 1698 | ||
1838 | error0: | 1699 | error0: |
1839 | TRACE_FREE("error", agno, bno, len, isfl); | 1700 | trace_xfs_free_extent(mp, agno, bno, len, isfl, -1, -1); |
1840 | if (bno_cur) | 1701 | if (bno_cur) |
1841 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); | 1702 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); |
1842 | if (cnt_cur) | 1703 | if (cnt_cur) |
@@ -2110,10 +1971,12 @@ xfs_alloc_get_freelist( | |||
2110 | xfs_trans_brelse(tp, agflbp); | 1971 | xfs_trans_brelse(tp, agflbp); |
2111 | if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) | 1972 | if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) |
2112 | agf->agf_flfirst = 0; | 1973 | agf->agf_flfirst = 0; |
2113 | pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; | 1974 | |
1975 | pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); | ||
2114 | be32_add_cpu(&agf->agf_flcount, -1); | 1976 | be32_add_cpu(&agf->agf_flcount, -1); |
2115 | xfs_trans_agflist_delta(tp, -1); | 1977 | xfs_trans_agflist_delta(tp, -1); |
2116 | pag->pagf_flcount--; | 1978 | pag->pagf_flcount--; |
1979 | xfs_perag_put(pag); | ||
2117 | 1980 | ||
2118 | logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; | 1981 | logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; |
2119 | if (btreeblk) { | 1982 | if (btreeblk) { |
@@ -2122,7 +1985,6 @@ xfs_alloc_get_freelist( | |||
2122 | logflags |= XFS_AGF_BTREEBLKS; | 1985 | logflags |= XFS_AGF_BTREEBLKS; |
2123 | } | 1986 | } |
2124 | 1987 | ||
2125 | TRACE_MODAGF(NULL, agf, logflags); | ||
2126 | xfs_alloc_log_agf(tp, agbp, logflags); | 1988 | xfs_alloc_log_agf(tp, agbp, logflags); |
2127 | *bnop = bno; | 1989 | *bnop = bno; |
2128 | 1990 | ||
@@ -2165,6 +2027,8 @@ xfs_alloc_log_agf( | |||
2165 | sizeof(xfs_agf_t) | 2027 | sizeof(xfs_agf_t) |
2166 | }; | 2028 | }; |
2167 | 2029 | ||
2030 | trace_xfs_agf(tp->t_mountp, XFS_BUF_TO_AGF(bp), fields, _RET_IP_); | ||
2031 | |||
2168 | xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last); | 2032 | xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last); |
2169 | xfs_trans_log_buf(tp, bp, (uint)first, (uint)last); | 2033 | xfs_trans_log_buf(tp, bp, (uint)first, (uint)last); |
2170 | } | 2034 | } |
@@ -2218,7 +2082,8 @@ xfs_alloc_put_freelist( | |||
2218 | be32_add_cpu(&agf->agf_fllast, 1); | 2082 | be32_add_cpu(&agf->agf_fllast, 1); |
2219 | if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) | 2083 | if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) |
2220 | agf->agf_fllast = 0; | 2084 | agf->agf_fllast = 0; |
2221 | pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; | 2085 | |
2086 | pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); | ||
2222 | be32_add_cpu(&agf->agf_flcount, 1); | 2087 | be32_add_cpu(&agf->agf_flcount, 1); |
2223 | xfs_trans_agflist_delta(tp, 1); | 2088 | xfs_trans_agflist_delta(tp, 1); |
2224 | pag->pagf_flcount++; | 2089 | pag->pagf_flcount++; |
@@ -2229,14 +2094,13 @@ xfs_alloc_put_freelist( | |||
2229 | pag->pagf_btreeblks--; | 2094 | pag->pagf_btreeblks--; |
2230 | logflags |= XFS_AGF_BTREEBLKS; | 2095 | logflags |= XFS_AGF_BTREEBLKS; |
2231 | } | 2096 | } |
2097 | xfs_perag_put(pag); | ||
2232 | 2098 | ||
2233 | TRACE_MODAGF(NULL, agf, logflags); | ||
2234 | xfs_alloc_log_agf(tp, agbp, logflags); | 2099 | xfs_alloc_log_agf(tp, agbp, logflags); |
2235 | 2100 | ||
2236 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); | 2101 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); |
2237 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; | 2102 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; |
2238 | *blockp = cpu_to_be32(bno); | 2103 | *blockp = cpu_to_be32(bno); |
2239 | TRACE_MODAGF(NULL, agf, logflags); | ||
2240 | xfs_alloc_log_agf(tp, agbp, logflags); | 2104 | xfs_alloc_log_agf(tp, agbp, logflags); |
2241 | xfs_trans_log_buf(tp, agflbp, | 2105 | xfs_trans_log_buf(tp, agflbp, |
2242 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), | 2106 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), |
@@ -2294,7 +2158,6 @@ xfs_read_agf( | |||
2294 | xfs_trans_brelse(tp, *bpp); | 2158 | xfs_trans_brelse(tp, *bpp); |
2295 | return XFS_ERROR(EFSCORRUPTED); | 2159 | return XFS_ERROR(EFSCORRUPTED); |
2296 | } | 2160 | } |
2297 | |||
2298 | XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF); | 2161 | XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF); |
2299 | return 0; | 2162 | return 0; |
2300 | } | 2163 | } |
@@ -2317,7 +2180,7 @@ xfs_alloc_read_agf( | |||
2317 | ASSERT(agno != NULLAGNUMBER); | 2180 | ASSERT(agno != NULLAGNUMBER); |
2318 | 2181 | ||
2319 | error = xfs_read_agf(mp, tp, agno, | 2182 | error = xfs_read_agf(mp, tp, agno, |
2320 | (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0, | 2183 | (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0, |
2321 | bpp); | 2184 | bpp); |
2322 | if (error) | 2185 | if (error) |
2323 | return error; | 2186 | return error; |
@@ -2326,7 +2189,7 @@ xfs_alloc_read_agf( | |||
2326 | ASSERT(!XFS_BUF_GETERROR(*bpp)); | 2189 | ASSERT(!XFS_BUF_GETERROR(*bpp)); |
2327 | 2190 | ||
2328 | agf = XFS_BUF_TO_AGF(*bpp); | 2191 | agf = XFS_BUF_TO_AGF(*bpp); |
2329 | pag = &mp->m_perag[agno]; | 2192 | pag = xfs_perag_get(mp, agno); |
2330 | if (!pag->pagf_init) { | 2193 | if (!pag->pagf_init) { |
2331 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); | 2194 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); |
2332 | pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); | 2195 | pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); |
@@ -2337,8 +2200,8 @@ xfs_alloc_read_agf( | |||
2337 | pag->pagf_levels[XFS_BTNUM_CNTi] = | 2200 | pag->pagf_levels[XFS_BTNUM_CNTi] = |
2338 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); | 2201 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); |
2339 | spin_lock_init(&pag->pagb_lock); | 2202 | spin_lock_init(&pag->pagb_lock); |
2340 | pag->pagb_list = kmem_zalloc(XFS_PAGB_NUM_SLOTS * | 2203 | pag->pagb_count = 0; |
2341 | sizeof(xfs_perag_busy_t), KM_SLEEP); | 2204 | memset(pag->pagb_list, 0, sizeof(pag->pagb_list)); |
2342 | pag->pagf_init = 1; | 2205 | pag->pagf_init = 1; |
2343 | } | 2206 | } |
2344 | #ifdef DEBUG | 2207 | #ifdef DEBUG |
@@ -2353,6 +2216,7 @@ xfs_alloc_read_agf( | |||
2353 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); | 2216 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); |
2354 | } | 2217 | } |
2355 | #endif | 2218 | #endif |
2219 | xfs_perag_put(pag); | ||
2356 | return 0; | 2220 | return 0; |
2357 | } | 2221 | } |
2358 | 2222 | ||
@@ -2399,7 +2263,7 @@ xfs_alloc_vextent( | |||
2399 | args->minlen > args->maxlen || args->minlen > agsize || | 2263 | args->minlen > args->maxlen || args->minlen > agsize || |
2400 | args->mod >= args->prod) { | 2264 | args->mod >= args->prod) { |
2401 | args->fsbno = NULLFSBLOCK; | 2265 | args->fsbno = NULLFSBLOCK; |
2402 | TRACE_ALLOC("badargs", args); | 2266 | trace_xfs_alloc_vextent_badargs(args); |
2403 | return 0; | 2267 | return 0; |
2404 | } | 2268 | } |
2405 | minleft = args->minleft; | 2269 | minleft = args->minleft; |
@@ -2412,24 +2276,21 @@ xfs_alloc_vextent( | |||
2412 | * These three force us into a single a.g. | 2276 | * These three force us into a single a.g. |
2413 | */ | 2277 | */ |
2414 | args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); | 2278 | args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); |
2415 | down_read(&mp->m_peraglock); | 2279 | args->pag = xfs_perag_get(mp, args->agno); |
2416 | args->pag = &mp->m_perag[args->agno]; | ||
2417 | args->minleft = 0; | 2280 | args->minleft = 0; |
2418 | error = xfs_alloc_fix_freelist(args, 0); | 2281 | error = xfs_alloc_fix_freelist(args, 0); |
2419 | args->minleft = minleft; | 2282 | args->minleft = minleft; |
2420 | if (error) { | 2283 | if (error) { |
2421 | TRACE_ALLOC("nofix", args); | 2284 | trace_xfs_alloc_vextent_nofix(args); |
2422 | goto error0; | 2285 | goto error0; |
2423 | } | 2286 | } |
2424 | if (!args->agbp) { | 2287 | if (!args->agbp) { |
2425 | up_read(&mp->m_peraglock); | 2288 | trace_xfs_alloc_vextent_noagbp(args); |
2426 | TRACE_ALLOC("noagbp", args); | ||
2427 | break; | 2289 | break; |
2428 | } | 2290 | } |
2429 | args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); | 2291 | args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); |
2430 | if ((error = xfs_alloc_ag_vextent(args))) | 2292 | if ((error = xfs_alloc_ag_vextent(args))) |
2431 | goto error0; | 2293 | goto error0; |
2432 | up_read(&mp->m_peraglock); | ||
2433 | break; | 2294 | break; |
2434 | case XFS_ALLOCTYPE_START_BNO: | 2295 | case XFS_ALLOCTYPE_START_BNO: |
2435 | /* | 2296 | /* |
@@ -2481,14 +2342,13 @@ xfs_alloc_vextent( | |||
2481 | * Loop over allocation groups twice; first time with | 2342 | * Loop over allocation groups twice; first time with |
2482 | * trylock set, second time without. | 2343 | * trylock set, second time without. |
2483 | */ | 2344 | */ |
2484 | down_read(&mp->m_peraglock); | ||
2485 | for (;;) { | 2345 | for (;;) { |
2486 | args->pag = &mp->m_perag[args->agno]; | 2346 | args->pag = xfs_perag_get(mp, args->agno); |
2487 | if (no_min) args->minleft = 0; | 2347 | if (no_min) args->minleft = 0; |
2488 | error = xfs_alloc_fix_freelist(args, flags); | 2348 | error = xfs_alloc_fix_freelist(args, flags); |
2489 | args->minleft = minleft; | 2349 | args->minleft = minleft; |
2490 | if (error) { | 2350 | if (error) { |
2491 | TRACE_ALLOC("nofix", args); | 2351 | trace_xfs_alloc_vextent_nofix(args); |
2492 | goto error0; | 2352 | goto error0; |
2493 | } | 2353 | } |
2494 | /* | 2354 | /* |
@@ -2499,7 +2359,9 @@ xfs_alloc_vextent( | |||
2499 | goto error0; | 2359 | goto error0; |
2500 | break; | 2360 | break; |
2501 | } | 2361 | } |
2502 | TRACE_ALLOC("loopfailed", args); | 2362 | |
2363 | trace_xfs_alloc_vextent_loopfailed(args); | ||
2364 | |||
2503 | /* | 2365 | /* |
2504 | * Didn't work, figure out the next iteration. | 2366 | * Didn't work, figure out the next iteration. |
2505 | */ | 2367 | */ |
@@ -2526,7 +2388,7 @@ xfs_alloc_vextent( | |||
2526 | if (args->agno == sagno) { | 2388 | if (args->agno == sagno) { |
2527 | if (no_min == 1) { | 2389 | if (no_min == 1) { |
2528 | args->agbno = NULLAGBLOCK; | 2390 | args->agbno = NULLAGBLOCK; |
2529 | TRACE_ALLOC("allfailed", args); | 2391 | trace_xfs_alloc_vextent_allfailed(args); |
2530 | break; | 2392 | break; |
2531 | } | 2393 | } |
2532 | if (flags == 0) { | 2394 | if (flags == 0) { |
@@ -2540,8 +2402,8 @@ xfs_alloc_vextent( | |||
2540 | } | 2402 | } |
2541 | } | 2403 | } |
2542 | } | 2404 | } |
2405 | xfs_perag_put(args->pag); | ||
2543 | } | 2406 | } |
2544 | up_read(&mp->m_peraglock); | ||
2545 | if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG)) { | 2407 | if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG)) { |
2546 | if (args->agno == sagno) | 2408 | if (args->agno == sagno) |
2547 | mp->m_agfrotor = (mp->m_agfrotor + 1) % | 2409 | mp->m_agfrotor = (mp->m_agfrotor + 1) % |
@@ -2567,9 +2429,10 @@ xfs_alloc_vextent( | |||
2567 | args->len); | 2429 | args->len); |
2568 | #endif | 2430 | #endif |
2569 | } | 2431 | } |
2432 | xfs_perag_put(args->pag); | ||
2570 | return 0; | 2433 | return 0; |
2571 | error0: | 2434 | error0: |
2572 | up_read(&mp->m_peraglock); | 2435 | xfs_perag_put(args->pag); |
2573 | return error; | 2436 | return error; |
2574 | } | 2437 | } |
2575 | 2438 | ||
@@ -2594,8 +2457,7 @@ xfs_free_extent( | |||
2594 | args.agno = XFS_FSB_TO_AGNO(args.mp, bno); | 2457 | args.agno = XFS_FSB_TO_AGNO(args.mp, bno); |
2595 | ASSERT(args.agno < args.mp->m_sb.sb_agcount); | 2458 | ASSERT(args.agno < args.mp->m_sb.sb_agcount); |
2596 | args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); | 2459 | args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); |
2597 | down_read(&args.mp->m_peraglock); | 2460 | args.pag = xfs_perag_get(args.mp, args.agno); |
2598 | args.pag = &args.mp->m_perag[args.agno]; | ||
2599 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) | 2461 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) |
2600 | goto error0; | 2462 | goto error0; |
2601 | #ifdef DEBUG | 2463 | #ifdef DEBUG |
@@ -2605,7 +2467,7 @@ xfs_free_extent( | |||
2605 | #endif | 2467 | #endif |
2606 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); | 2468 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); |
2607 | error0: | 2469 | error0: |
2608 | up_read(&args.mp->m_peraglock); | 2470 | xfs_perag_put(args.pag); |
2609 | return error; | 2471 | return error; |
2610 | } | 2472 | } |
2611 | 2473 | ||
@@ -2626,15 +2488,15 @@ xfs_alloc_mark_busy(xfs_trans_t *tp, | |||
2626 | xfs_agblock_t bno, | 2488 | xfs_agblock_t bno, |
2627 | xfs_extlen_t len) | 2489 | xfs_extlen_t len) |
2628 | { | 2490 | { |
2629 | xfs_mount_t *mp; | ||
2630 | xfs_perag_busy_t *bsy; | 2491 | xfs_perag_busy_t *bsy; |
2492 | struct xfs_perag *pag; | ||
2631 | int n; | 2493 | int n; |
2632 | 2494 | ||
2633 | mp = tp->t_mountp; | 2495 | pag = xfs_perag_get(tp->t_mountp, agno); |
2634 | spin_lock(&mp->m_perag[agno].pagb_lock); | 2496 | spin_lock(&pag->pagb_lock); |
2635 | 2497 | ||
2636 | /* search pagb_list for an open slot */ | 2498 | /* search pagb_list for an open slot */ |
2637 | for (bsy = mp->m_perag[agno].pagb_list, n = 0; | 2499 | for (bsy = pag->pagb_list, n = 0; |
2638 | n < XFS_PAGB_NUM_SLOTS; | 2500 | n < XFS_PAGB_NUM_SLOTS; |
2639 | bsy++, n++) { | 2501 | bsy++, n++) { |
2640 | if (bsy->busy_tp == NULL) { | 2502 | if (bsy->busy_tp == NULL) { |
@@ -2642,16 +2504,16 @@ xfs_alloc_mark_busy(xfs_trans_t *tp, | |||
2642 | } | 2504 | } |
2643 | } | 2505 | } |
2644 | 2506 | ||
2507 | trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len, n); | ||
2508 | |||
2645 | if (n < XFS_PAGB_NUM_SLOTS) { | 2509 | if (n < XFS_PAGB_NUM_SLOTS) { |
2646 | bsy = &mp->m_perag[agno].pagb_list[n]; | 2510 | bsy = &pag->pagb_list[n]; |
2647 | mp->m_perag[agno].pagb_count++; | 2511 | pag->pagb_count++; |
2648 | TRACE_BUSY("xfs_alloc_mark_busy", "got", agno, bno, len, n, tp); | ||
2649 | bsy->busy_start = bno; | 2512 | bsy->busy_start = bno; |
2650 | bsy->busy_length = len; | 2513 | bsy->busy_length = len; |
2651 | bsy->busy_tp = tp; | 2514 | bsy->busy_tp = tp; |
2652 | xfs_trans_add_busy(tp, agno, n); | 2515 | xfs_trans_add_busy(tp, agno, n); |
2653 | } else { | 2516 | } else { |
2654 | TRACE_BUSY("xfs_alloc_mark_busy", "FULL", agno, bno, len, -1, tp); | ||
2655 | /* | 2517 | /* |
2656 | * The busy list is full! Since it is now not possible to | 2518 | * The busy list is full! Since it is now not possible to |
2657 | * track the free block, make this a synchronous transaction | 2519 | * track the free block, make this a synchronous transaction |
@@ -2661,7 +2523,8 @@ xfs_alloc_mark_busy(xfs_trans_t *tp, | |||
2661 | xfs_trans_set_sync(tp); | 2523 | xfs_trans_set_sync(tp); |
2662 | } | 2524 | } |
2663 | 2525 | ||
2664 | spin_unlock(&mp->m_perag[agno].pagb_lock); | 2526 | spin_unlock(&pag->pagb_lock); |
2527 | xfs_perag_put(pag); | ||
2665 | } | 2528 | } |
2666 | 2529 | ||
2667 | void | 2530 | void |
@@ -2669,24 +2532,23 @@ xfs_alloc_clear_busy(xfs_trans_t *tp, | |||
2669 | xfs_agnumber_t agno, | 2532 | xfs_agnumber_t agno, |
2670 | int idx) | 2533 | int idx) |
2671 | { | 2534 | { |
2672 | xfs_mount_t *mp; | 2535 | struct xfs_perag *pag; |
2673 | xfs_perag_busy_t *list; | 2536 | xfs_perag_busy_t *list; |
2674 | 2537 | ||
2675 | mp = tp->t_mountp; | 2538 | ASSERT(idx < XFS_PAGB_NUM_SLOTS); |
2539 | pag = xfs_perag_get(tp->t_mountp, agno); | ||
2540 | spin_lock(&pag->pagb_lock); | ||
2541 | list = pag->pagb_list; | ||
2676 | 2542 | ||
2677 | spin_lock(&mp->m_perag[agno].pagb_lock); | 2543 | trace_xfs_alloc_unbusy(tp->t_mountp, agno, idx, list[idx].busy_tp == tp); |
2678 | list = mp->m_perag[agno].pagb_list; | ||
2679 | 2544 | ||
2680 | ASSERT(idx < XFS_PAGB_NUM_SLOTS); | ||
2681 | if (list[idx].busy_tp == tp) { | 2545 | if (list[idx].busy_tp == tp) { |
2682 | TRACE_UNBUSY("xfs_alloc_clear_busy", "found", agno, idx, tp); | ||
2683 | list[idx].busy_tp = NULL; | 2546 | list[idx].busy_tp = NULL; |
2684 | mp->m_perag[agno].pagb_count--; | 2547 | pag->pagb_count--; |
2685 | } else { | ||
2686 | TRACE_UNBUSY("xfs_alloc_clear_busy", "missing", agno, idx, tp); | ||
2687 | } | 2548 | } |
2688 | 2549 | ||
2689 | spin_unlock(&mp->m_perag[agno].pagb_lock); | 2550 | spin_unlock(&pag->pagb_lock); |
2551 | xfs_perag_put(pag); | ||
2690 | } | 2552 | } |
2691 | 2553 | ||
2692 | 2554 | ||
@@ -2700,48 +2562,44 @@ xfs_alloc_search_busy(xfs_trans_t *tp, | |||
2700 | xfs_agblock_t bno, | 2562 | xfs_agblock_t bno, |
2701 | xfs_extlen_t len) | 2563 | xfs_extlen_t len) |
2702 | { | 2564 | { |
2703 | xfs_mount_t *mp; | 2565 | struct xfs_perag *pag; |
2704 | xfs_perag_busy_t *bsy; | 2566 | xfs_perag_busy_t *bsy; |
2705 | xfs_agblock_t uend, bend; | 2567 | xfs_agblock_t uend, bend; |
2706 | xfs_lsn_t lsn; | 2568 | xfs_lsn_t lsn = 0; |
2707 | int cnt; | 2569 | int cnt; |
2708 | 2570 | ||
2709 | mp = tp->t_mountp; | 2571 | pag = xfs_perag_get(tp->t_mountp, agno); |
2710 | 2572 | spin_lock(&pag->pagb_lock); | |
2711 | spin_lock(&mp->m_perag[agno].pagb_lock); | 2573 | cnt = pag->pagb_count; |
2712 | cnt = mp->m_perag[agno].pagb_count; | ||
2713 | 2574 | ||
2575 | /* | ||
2576 | * search pagb_list for this slot, skipping open slots. We have to | ||
2577 | * search the entire array as there may be multiple overlaps and | ||
2578 | * we have to get the most recent LSN for the log force to push out | ||
2579 | * all the transactions that span the range. | ||
2580 | */ | ||
2714 | uend = bno + len - 1; | 2581 | uend = bno + len - 1; |
2715 | 2582 | for (cnt = 0; cnt < pag->pagb_count; cnt++) { | |
2716 | /* search pagb_list for this slot, skipping open slots */ | 2583 | bsy = &pag->pagb_list[cnt]; |
2717 | for (bsy = mp->m_perag[agno].pagb_list; cnt; bsy++) { | 2584 | if (!bsy->busy_tp) |
2718 | 2585 | continue; | |
2719 | /* | 2586 | |
2720 | * (start1,length1) within (start2, length2) | 2587 | bend = bsy->busy_start + bsy->busy_length - 1; |
2721 | */ | 2588 | if (bno > bend || uend < bsy->busy_start) |
2722 | if (bsy->busy_tp != NULL) { | 2589 | continue; |
2723 | bend = bsy->busy_start + bsy->busy_length - 1; | 2590 | |
2724 | if ((bno > bend) || (uend < bsy->busy_start)) { | 2591 | /* (start1,length1) within (start2, length2) */ |
2725 | cnt--; | 2592 | if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0) |
2726 | } else { | 2593 | lsn = bsy->busy_tp->t_commit_lsn; |
2727 | TRACE_BUSYSEARCH("xfs_alloc_search_busy", | ||
2728 | "found1", agno, bno, len, tp); | ||
2729 | break; | ||
2730 | } | ||
2731 | } | ||
2732 | } | 2594 | } |
2595 | spin_unlock(&pag->pagb_lock); | ||
2596 | xfs_perag_put(pag); | ||
2597 | trace_xfs_alloc_busysearch(tp->t_mountp, agno, bno, len, lsn); | ||
2733 | 2598 | ||
2734 | /* | 2599 | /* |
2735 | * If a block was found, force the log through the LSN of the | 2600 | * If a block was found, force the log through the LSN of the |
2736 | * transaction that freed the block | 2601 | * transaction that freed the block |
2737 | */ | 2602 | */ |
2738 | if (cnt) { | 2603 | if (lsn) |
2739 | TRACE_BUSYSEARCH("xfs_alloc_search_busy", "found", agno, bno, len, tp); | 2604 | xfs_log_force_lsn(tp->t_mountp, lsn, XFS_LOG_SYNC); |
2740 | lsn = bsy->busy_tp->t_commit_lsn; | ||
2741 | spin_unlock(&mp->m_perag[agno].pagb_lock); | ||
2742 | xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC); | ||
2743 | } else { | ||
2744 | TRACE_BUSYSEARCH("xfs_alloc_search_busy", "not-found", agno, bno, len, tp); | ||
2745 | spin_unlock(&mp->m_perag[agno].pagb_lock); | ||
2746 | } | ||
2747 | } | 2605 | } |