aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_alloc.c')
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c227
1 files changed, 109 insertions, 118 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index a9ff3cf82cce..372ad55631fc 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -13,7 +13,6 @@
13#include "xfs_sb.h" 13#include "xfs_sb.h"
14#include "xfs_mount.h" 14#include "xfs_mount.h"
15#include "xfs_defer.h" 15#include "xfs_defer.h"
16#include "xfs_inode.h"
17#include "xfs_btree.h" 16#include "xfs_btree.h"
18#include "xfs_rmap.h" 17#include "xfs_rmap.h"
19#include "xfs_alloc_btree.h" 18#include "xfs_alloc_btree.h"
@@ -21,7 +20,6 @@
21#include "xfs_extent_busy.h" 20#include "xfs_extent_busy.h"
22#include "xfs_errortag.h" 21#include "xfs_errortag.h"
23#include "xfs_error.h" 22#include "xfs_error.h"
24#include "xfs_cksum.h"
25#include "xfs_trace.h" 23#include "xfs_trace.h"
26#include "xfs_trans.h" 24#include "xfs_trans.h"
27#include "xfs_buf_item.h" 25#include "xfs_buf_item.h"
@@ -41,8 +39,6 @@ struct workqueue_struct *xfs_alloc_wq;
41STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *); 39STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *);
42STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *); 40STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *);
43STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); 41STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *);
44STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *,
45 xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *);
46 42
47/* 43/*
48 * Size of the AGFL. For CRC-enabled filesystes we steal a couple of slots in 44 * Size of the AGFL. For CRC-enabled filesystes we steal a couple of slots in
@@ -555,7 +551,7 @@ static xfs_failaddr_t
555xfs_agfl_verify( 551xfs_agfl_verify(
556 struct xfs_buf *bp) 552 struct xfs_buf *bp)
557{ 553{
558 struct xfs_mount *mp = bp->b_target->bt_mount; 554 struct xfs_mount *mp = bp->b_mount;
559 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp); 555 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
560 int i; 556 int i;
561 557
@@ -596,7 +592,7 @@ static void
596xfs_agfl_read_verify( 592xfs_agfl_read_verify(
597 struct xfs_buf *bp) 593 struct xfs_buf *bp)
598{ 594{
599 struct xfs_mount *mp = bp->b_target->bt_mount; 595 struct xfs_mount *mp = bp->b_mount;
600 xfs_failaddr_t fa; 596 xfs_failaddr_t fa;
601 597
602 /* 598 /*
@@ -621,7 +617,7 @@ static void
621xfs_agfl_write_verify( 617xfs_agfl_write_verify(
622 struct xfs_buf *bp) 618 struct xfs_buf *bp)
623{ 619{
624 struct xfs_mount *mp = bp->b_target->bt_mount; 620 struct xfs_mount *mp = bp->b_mount;
625 struct xfs_buf_log_item *bip = bp->b_log_item; 621 struct xfs_buf_log_item *bip = bp->b_log_item;
626 xfs_failaddr_t fa; 622 xfs_failaddr_t fa;
627 623
@@ -700,6 +696,107 @@ xfs_alloc_update_counters(
700 */ 696 */
701 697
702/* 698/*
699 * Deal with the case where only small freespaces remain. Either return the
700 * contents of the last freespace record, or allocate space from the freelist if
701 * there is nothing in the tree.
702 */
703STATIC int /* error */
704xfs_alloc_ag_vextent_small(
705 struct xfs_alloc_arg *args, /* allocation argument structure */
706 struct xfs_btree_cur *ccur, /* optional by-size cursor */
707 xfs_agblock_t *fbnop, /* result block number */
708 xfs_extlen_t *flenp, /* result length */
709 int *stat) /* status: 0-freelist, 1-normal/none */
710{
711 int error = 0;
712 xfs_agblock_t fbno = NULLAGBLOCK;
713 xfs_extlen_t flen = 0;
714 int i = 0;
715
716 /*
717 * If a cntbt cursor is provided, try to allocate the largest record in
718 * the tree. Try the AGFL if the cntbt is empty, otherwise fail the
719 * allocation. Make sure to respect minleft even when pulling from the
720 * freelist.
721 */
722 if (ccur)
723 error = xfs_btree_decrement(ccur, 0, &i);
724 if (error)
725 goto error;
726 if (i) {
727 error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i);
728 if (error)
729 goto error;
730 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error);
731 goto out;
732 }
733
734 if (args->minlen != 1 || args->alignment != 1 ||
735 args->resv == XFS_AG_RESV_AGFL ||
736 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) <=
737 args->minleft))
738 goto out;
739
740 error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
741 if (error)
742 goto error;
743 if (fbno == NULLAGBLOCK)
744 goto out;
745
746 xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1,
747 xfs_alloc_allow_busy_reuse(args->datatype));
748
749 if (xfs_alloc_is_userdata(args->datatype)) {
750 struct xfs_buf *bp;
751
752 bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno);
753 if (!bp) {
754 error = -EFSCORRUPTED;
755 goto error;
756 }
757 xfs_trans_binval(args->tp, bp);
758 }
759 *fbnop = args->agbno = fbno;
760 *flenp = args->len = 1;
761 XFS_WANT_CORRUPTED_GOTO(args->mp,
762 fbno < be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
763 error);
764 args->wasfromfl = 1;
765 trace_xfs_alloc_small_freelist(args);
766
767 /*
768 * If we're feeding an AGFL block to something that doesn't live in the
769 * free space, we need to clear out the OWN_AG rmap.
770 */
771 error = xfs_rmap_free(args->tp, args->agbp, args->agno, fbno, 1,
772 &XFS_RMAP_OINFO_AG);
773 if (error)
774 goto error;
775
776 *stat = 0;
777 return 0;
778
779out:
780 /*
781 * Can't do the allocation, give up.
782 */
783 if (flen < args->minlen) {
784 args->agbno = NULLAGBLOCK;
785 trace_xfs_alloc_small_notenough(args);
786 flen = 0;
787 }
788 *fbnop = fbno;
789 *flenp = flen;
790 *stat = 1;
791 trace_xfs_alloc_small_done(args);
792 return 0;
793
794error:
795 trace_xfs_alloc_small_error(args);
796 return error;
797}
798
799/*
703 * Allocate a variable extent in the allocation group agno. 800 * Allocate a variable extent in the allocation group agno.
704 * Type and bno are used to determine where in the allocation group the 801 * Type and bno are used to determine where in the allocation group the
705 * extent will start. 802 * extent will start.
@@ -1583,112 +1680,6 @@ out_nominleft:
1583} 1680}
1584 1681
1585/* 1682/*
1586 * Deal with the case where only small freespaces remain.
1587 * Either return the contents of the last freespace record,
1588 * or allocate space from the freelist if there is nothing in the tree.
1589 */
1590STATIC int /* error */
1591xfs_alloc_ag_vextent_small(
1592 xfs_alloc_arg_t *args, /* allocation argument structure */
1593 xfs_btree_cur_t *ccur, /* by-size cursor */
1594 xfs_agblock_t *fbnop, /* result block number */
1595 xfs_extlen_t *flenp, /* result length */
1596 int *stat) /* status: 0-freelist, 1-normal/none */
1597{
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 error = xfs_rmap_free(args->tp, args->agbp, args->agno,
1652 fbno, 1, &XFS_RMAP_OINFO_AG);
1653 if (error)
1654 goto error0;
1655
1656 *stat = 0;
1657 return 0;
1658 }
1659 /*
1660 * Nothing in the freelist.
1661 */
1662 else
1663 flen = 0;
1664 }
1665 /*
1666 * Can't allocate from the freelist for some reason.
1667 */
1668 else {
1669 fbno = NULLAGBLOCK;
1670 flen = 0;
1671 }
1672 /*
1673 * Can't do the allocation, give up.
1674 */
1675 if (flen < args->minlen) {
1676 args->agbno = NULLAGBLOCK;
1677 trace_xfs_alloc_small_notenough(args);
1678 flen = 0;
1679 }
1680 *fbnop = fbno;
1681 *flenp = flen;
1682 *stat = 1;
1683 trace_xfs_alloc_small_done(args);
1684 return 0;
1685
1686error0:
1687 trace_xfs_alloc_small_error(args);
1688 return error;
1689}
1690
1691/*
1692 * Free the extent starting at agno/bno for length. 1683 * Free the extent starting at agno/bno for length.
1693 */ 1684 */
1694STATIC int 1685STATIC int
@@ -2095,7 +2086,7 @@ xfs_free_agfl_block(
2095 if (error) 2086 if (error)
2096 return error; 2087 return error;
2097 2088
2098 bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno, 0); 2089 bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno);
2099 if (!bp) 2090 if (!bp)
2100 return -EFSCORRUPTED; 2091 return -EFSCORRUPTED;
2101 xfs_trans_binval(tp, bp); 2092 xfs_trans_binval(tp, bp);
@@ -2586,7 +2577,7 @@ static xfs_failaddr_t
2586xfs_agf_verify( 2577xfs_agf_verify(
2587 struct xfs_buf *bp) 2578 struct xfs_buf *bp)
2588{ 2579{
2589 struct xfs_mount *mp = bp->b_target->bt_mount; 2580 struct xfs_mount *mp = bp->b_mount;
2590 struct xfs_agf *agf = XFS_BUF_TO_AGF(bp); 2581 struct xfs_agf *agf = XFS_BUF_TO_AGF(bp);
2591 2582
2592 if (xfs_sb_version_hascrc(&mp->m_sb)) { 2583 if (xfs_sb_version_hascrc(&mp->m_sb)) {
@@ -2644,7 +2635,7 @@ static void
2644xfs_agf_read_verify( 2635xfs_agf_read_verify(
2645 struct xfs_buf *bp) 2636 struct xfs_buf *bp)
2646{ 2637{
2647 struct xfs_mount *mp = bp->b_target->bt_mount; 2638 struct xfs_mount *mp = bp->b_mount;
2648 xfs_failaddr_t fa; 2639 xfs_failaddr_t fa;
2649 2640
2650 if (xfs_sb_version_hascrc(&mp->m_sb) && 2641 if (xfs_sb_version_hascrc(&mp->m_sb) &&
@@ -2661,7 +2652,7 @@ static void
2661xfs_agf_write_verify( 2652xfs_agf_write_verify(
2662 struct xfs_buf *bp) 2653 struct xfs_buf *bp)
2663{ 2654{
2664 struct xfs_mount *mp = bp->b_target->bt_mount; 2655 struct xfs_mount *mp = bp->b_mount;
2665 struct xfs_buf_log_item *bip = bp->b_log_item; 2656 struct xfs_buf_log_item *bip = bp->b_log_item;
2666 xfs_failaddr_t fa; 2657 xfs_failaddr_t fa;
2667 2658
@@ -3146,7 +3137,7 @@ xfs_alloc_has_record(
3146 3137
3147/* 3138/*
3148 * Walk all the blocks in the AGFL. The @walk_fn can return any negative 3139 * Walk all the blocks in the AGFL. The @walk_fn can return any negative
3149 * error code or XFS_BTREE_QUERY_RANGE_ABORT. 3140 * error code or XFS_ITER_*.
3150 */ 3141 */
3151int 3142int
3152xfs_agfl_walk( 3143xfs_agfl_walk(