diff options
author | Lachlan McIlroy <lachlan@sgi.com> | 2008-06-26 23:32:53 -0400 |
---|---|---|
committer | Niv Sardi <xaiki@debian.org> | 2008-07-28 02:59:10 -0400 |
commit | 4ddd8bb1d25f9cbb345e1f64a56c0f641a787ede (patch) | |
tree | 297e8fa754cbd910450ff76a9058a2ac6cd07b39 | |
parent | e182f57ac019b034b40d16f3c6d8e86826aecd56 (diff) |
[XFS] use minleft when allocating in xfs_bmbt_split()
The bmap btree split code relies on a previous data extent allocation
(from xfs_bmap_btalloc()) to find an AG that has sufficient space to
perform a full btree split, when inserting the extent. When converting
unwritten extents we don't allocate a data extent so a btree split will be
the first allocation. In this case we need to set minleft so the allocator
will pick an AG that has space to complete the split(s).
SGI-PV: 983338
SGI-Modid: xfs-linux-melb:xfs-kern:31357a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 10 |
2 files changed, 24 insertions, 1 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 4aa2f11ba563..3fc09cd8d517 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -1493,12 +1493,25 @@ xfs_bmbt_split( | |||
1493 | left = XFS_BUF_TO_BMBT_BLOCK(lbp); | 1493 | left = XFS_BUF_TO_BMBT_BLOCK(lbp); |
1494 | args.fsbno = cur->bc_private.b.firstblock; | 1494 | args.fsbno = cur->bc_private.b.firstblock; |
1495 | args.firstblock = args.fsbno; | 1495 | args.firstblock = args.fsbno; |
1496 | args.minleft = 0; | ||
1496 | if (args.fsbno == NULLFSBLOCK) { | 1497 | if (args.fsbno == NULLFSBLOCK) { |
1497 | args.fsbno = lbno; | 1498 | args.fsbno = lbno; |
1498 | args.type = XFS_ALLOCTYPE_START_BNO; | 1499 | args.type = XFS_ALLOCTYPE_START_BNO; |
1500 | /* | ||
1501 | * Make sure there is sufficient room left in the AG to | ||
1502 | * complete a full tree split for an extent insert. If | ||
1503 | * we are converting the middle part of an extent then | ||
1504 | * we may need space for two tree splits. | ||
1505 | * | ||
1506 | * We are relying on the caller to make the correct block | ||
1507 | * reservation for this operation to succeed. If the | ||
1508 | * reservation amount is insufficient then we may fail a | ||
1509 | * block allocation here and corrupt the filesystem. | ||
1510 | */ | ||
1511 | args.minleft = xfs_trans_get_block_res(args.tp); | ||
1499 | } else | 1512 | } else |
1500 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 1513 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
1501 | args.mod = args.minleft = args.alignment = args.total = args.isfl = | 1514 | args.mod = args.alignment = args.total = args.isfl = |
1502 | args.userdata = args.minalignslop = 0; | 1515 | args.userdata = args.minalignslop = 0; |
1503 | args.minlen = args.maxlen = args.prod = 1; | 1516 | args.minlen = args.maxlen = args.prod = 1; |
1504 | args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; | 1517 | args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 7edcde691d1a..67f22b2b44b3 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -889,6 +889,16 @@ xfs_iomap_write_unwritten( | |||
889 | count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); | 889 | count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); |
890 | count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb); | 890 | count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb); |
891 | 891 | ||
892 | /* | ||
893 | * Reserve enough blocks in this transaction for two complete extent | ||
894 | * btree splits. We may be converting the middle part of an unwritten | ||
895 | * extent and in this case we will insert two new extents in the btree | ||
896 | * each of which could cause a full split. | ||
897 | * | ||
898 | * This reservation amount will be used in the first call to | ||
899 | * xfs_bmbt_split() to select an AG with enough space to satisfy the | ||
900 | * rest of the operation. | ||
901 | */ | ||
892 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; | 902 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; |
893 | 903 | ||
894 | do { | 904 | do { |