diff options
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 14 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_format.h | 11 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rmap_btree.c | 6 |
3 files changed, 28 insertions, 3 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 776ae2f325d1..3dd8f1d54498 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
@@ -1582,6 +1582,7 @@ xfs_alloc_ag_vextent_small( | |||
1582 | xfs_extlen_t *flenp, /* result length */ | 1582 | xfs_extlen_t *flenp, /* result length */ |
1583 | int *stat) /* status: 0-freelist, 1-normal/none */ | 1583 | int *stat) /* status: 0-freelist, 1-normal/none */ |
1584 | { | 1584 | { |
1585 | struct xfs_owner_info oinfo; | ||
1585 | int error; | 1586 | int error; |
1586 | xfs_agblock_t fbno; | 1587 | xfs_agblock_t fbno; |
1587 | xfs_extlen_t flen; | 1588 | xfs_extlen_t flen; |
@@ -1624,6 +1625,18 @@ xfs_alloc_ag_vextent_small( | |||
1624 | error0); | 1625 | error0); |
1625 | args->wasfromfl = 1; | 1626 | args->wasfromfl = 1; |
1626 | trace_xfs_alloc_small_freelist(args); | 1627 | trace_xfs_alloc_small_freelist(args); |
1628 | |||
1629 | /* | ||
1630 | * If we're feeding an AGFL block to something that | ||
1631 | * doesn't live in the free space, we need to clear | ||
1632 | * out the OWN_AG rmap. | ||
1633 | */ | ||
1634 | xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); | ||
1635 | error = xfs_rmap_free(args->tp, args->agbp, args->agno, | ||
1636 | fbno, 1, &oinfo); | ||
1637 | if (error) | ||
1638 | goto error0; | ||
1639 | |||
1627 | *stat = 0; | 1640 | *stat = 0; |
1628 | return 0; | 1641 | return 0; |
1629 | } | 1642 | } |
@@ -2264,6 +2277,7 @@ xfs_alloc_log_agf( | |||
2264 | offsetof(xfs_agf_t, agf_longest), | 2277 | offsetof(xfs_agf_t, agf_longest), |
2265 | offsetof(xfs_agf_t, agf_btreeblks), | 2278 | offsetof(xfs_agf_t, agf_btreeblks), |
2266 | offsetof(xfs_agf_t, agf_uuid), | 2279 | offsetof(xfs_agf_t, agf_uuid), |
2280 | offsetof(xfs_agf_t, agf_rmap_blocks), | ||
2267 | sizeof(xfs_agf_t) | 2281 | sizeof(xfs_agf_t) |
2268 | }; | 2282 | }; |
2269 | 2283 | ||
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index f814d42c73b2..e6a8bea0f7ba 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h | |||
@@ -640,12 +640,15 @@ typedef struct xfs_agf { | |||
640 | __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ | 640 | __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ |
641 | uuid_t agf_uuid; /* uuid of filesystem */ | 641 | uuid_t agf_uuid; /* uuid of filesystem */ |
642 | 642 | ||
643 | __be32 agf_rmap_blocks; /* rmapbt blocks used */ | ||
644 | __be32 agf_padding; /* padding */ | ||
645 | |||
643 | /* | 646 | /* |
644 | * reserve some contiguous space for future logged fields before we add | 647 | * reserve some contiguous space for future logged fields before we add |
645 | * the unlogged fields. This makes the range logging via flags and | 648 | * the unlogged fields. This makes the range logging via flags and |
646 | * structure offsets much simpler. | 649 | * structure offsets much simpler. |
647 | */ | 650 | */ |
648 | __be64 agf_spare64[16]; | 651 | __be64 agf_spare64[15]; |
649 | 652 | ||
650 | /* unlogged fields, written during buffer writeback. */ | 653 | /* unlogged fields, written during buffer writeback. */ |
651 | __be64 agf_lsn; /* last write sequence */ | 654 | __be64 agf_lsn; /* last write sequence */ |
@@ -670,7 +673,8 @@ typedef struct xfs_agf { | |||
670 | #define XFS_AGF_LONGEST 0x00000400 | 673 | #define XFS_AGF_LONGEST 0x00000400 |
671 | #define XFS_AGF_BTREEBLKS 0x00000800 | 674 | #define XFS_AGF_BTREEBLKS 0x00000800 |
672 | #define XFS_AGF_UUID 0x00001000 | 675 | #define XFS_AGF_UUID 0x00001000 |
673 | #define XFS_AGF_NUM_BITS 13 | 676 | #define XFS_AGF_RMAP_BLOCKS 0x00002000 |
677 | #define XFS_AGF_NUM_BITS 14 | ||
674 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) | 678 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) |
675 | 679 | ||
676 | #define XFS_AGF_FLAGS \ | 680 | #define XFS_AGF_FLAGS \ |
@@ -686,7 +690,8 @@ typedef struct xfs_agf { | |||
686 | { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ | 690 | { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ |
687 | { XFS_AGF_LONGEST, "LONGEST" }, \ | 691 | { XFS_AGF_LONGEST, "LONGEST" }, \ |
688 | { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ | 692 | { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ |
689 | { XFS_AGF_UUID, "UUID" } | 693 | { XFS_AGF_UUID, "UUID" }, \ |
694 | { XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" } | ||
690 | 695 | ||
691 | /* disk block (xfs_daddr_t) in the AG */ | 696 | /* disk block (xfs_daddr_t) in the AG */ |
692 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) | 697 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) |
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index bc1faebc84ec..17b8eeb34ac8 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c | |||
@@ -98,6 +98,8 @@ xfs_rmapbt_alloc_block( | |||
98 | union xfs_btree_ptr *new, | 98 | union xfs_btree_ptr *new, |
99 | int *stat) | 99 | int *stat) |
100 | { | 100 | { |
101 | struct xfs_buf *agbp = cur->bc_private.a.agbp; | ||
102 | struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); | ||
101 | int error; | 103 | int error; |
102 | xfs_agblock_t bno; | 104 | xfs_agblock_t bno; |
103 | 105 | ||
@@ -124,6 +126,8 @@ xfs_rmapbt_alloc_block( | |||
124 | 126 | ||
125 | xfs_trans_agbtree_delta(cur->bc_tp, 1); | 127 | xfs_trans_agbtree_delta(cur->bc_tp, 1); |
126 | new->s = cpu_to_be32(bno); | 128 | new->s = cpu_to_be32(bno); |
129 | be32_add_cpu(&agf->agf_rmap_blocks, 1); | ||
130 | xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); | ||
127 | 131 | ||
128 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); | 132 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); |
129 | *stat = 1; | 133 | *stat = 1; |
@@ -143,6 +147,8 @@ xfs_rmapbt_free_block( | |||
143 | bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); | 147 | bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); |
144 | trace_xfs_rmapbt_free_block(cur->bc_mp, cur->bc_private.a.agno, | 148 | trace_xfs_rmapbt_free_block(cur->bc_mp, cur->bc_private.a.agno, |
145 | bno, 1); | 149 | bno, 1); |
150 | be32_add_cpu(&agf->agf_rmap_blocks, -1); | ||
151 | xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); | ||
146 | error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); | 152 | error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); |
147 | if (error) | 153 | if (error) |
148 | return error; | 154 | return error; |