aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_alloc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-12 20:17:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-12 20:17:51 -0400
commit4ce9d181ebe53abbca5f450b8a2984b8c3a38f26 (patch)
treeb563ac755c99ddf430402b2850199fdb625f1f7c /fs/xfs/libxfs/xfs_alloc.c
parent5010fe9f095414b959fd6fda63986dc90fd0c419 (diff)
parent488ca3d8d088ec4658c87aaec6a91e98acccdd54 (diff)
Merge tag 'xfs-5.3-merge-12' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs updates from Darrick Wong: "In this release there are a significant amounts of consolidations and cleanups in the log code; restructuring of the log to issue struct bios directly; new bulkstat ioctls to return v5 fs inode information (and fix all the padding problems of the old ioctl); the beginnings of multithreaded inode walks (e.g. quotacheck); and a reduction in memory usage in the online scrub code leading to reduced runtimes. - Refactor inode geometry calculation into a single structure instead of open-coding pieces everywhere. - Add online repair to build options. - Remove unnecessary function call flags and functions. - Claim maintainership of various loose xfs documentation and header files. - Use struct bio directly for log buffer IOs instead of struct xfs_buf. - Reduce log item boilerplate code requirements. - Merge log item code spread across too many files. - Further distinguish between log item commits and cancellations. - Various small cleanups to the ag small allocator. - Support cgroup-aware writeback - libxfs refactoring for mkfs cleanup - Remove unneeded #includes - Fix a memory allocation miscalculation in the new log bio code - Fix bisection problems - Fix a crash in ioend processing caused by tripping over freeing of preallocated transactions - Split out a generic inode walk mechanism from the bulkstat code, hook up all the internal users to use the walking code, then clean up bulkstat to serve only the bulkstat ioctls. - Add a multithreaded iwalk implementation to speed up quotacheck on fast storage with many CPUs. - Remove unnecessary return values in logging teardown functions. - Supplement the bstat and inogrp structures with new bulkstat and inumbers structures that have all the fields we need for v5 filesystem features and none of the padding problems of their predecessors. - Wire up new ioctls that use the new structures with a much simpler bulk_ireq structure at the head instead of the pointerhappy mess we had before. - Enable userspace to constrain bulkstat returns to a single AG or a single special inode so that we can phase out a lot of geometry guesswork in userspace. - Reduce memory consumption and zeroing overhead in extended attribute scrub code. - Fix some behavioral regressions in the new bulkstat backend code. - Fix some behavioral regressions in the new log bio code" * tag 'xfs-5.3-merge-12' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (100 commits) xfs: chain bios the right way around in xfs_rw_bdev xfs: bump INUMBERS cursor correctly in xfs_inumbers_walk xfs: don't update lastino for FSBULKSTAT_SINGLE xfs: online scrub needn't bother zeroing its temporary buffer xfs: only allocate memory for scrubbing attributes when we need it xfs: refactor attr scrub memory allocation function xfs: refactor extended attribute buffer pointer functions xfs: attribute scrub should use seen_enough to pass error values xfs: allow single bulkstat of special inodes xfs: specify AG in bulk req xfs: wire up the v5 inumbers ioctl xfs: wire up new v5 bulkstat ioctls xfs: introduce v5 inode group structure xfs: introduce new v5 bulkstat structure xfs: rename bulkstat functions xfs: remove various bulk request typedef usage fs: xfs: xfs_log: Change return type from int to void xfs: poll waiting for quotacheck xfs: multithreaded iwalk implementation xfs: refactor INUMBERS to use iwalk functions ...
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(