aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3b957921ba59..8564d8ce03de 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1530,10 +1530,45 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
1530static void btrfs_split_extent_hook(struct inode *inode, 1530static void btrfs_split_extent_hook(struct inode *inode,
1531 struct extent_state *orig, u64 split) 1531 struct extent_state *orig, u64 split)
1532{ 1532{
1533 u64 size;
1534
1533 /* not delalloc, ignore it */ 1535 /* not delalloc, ignore it */
1534 if (!(orig->state & EXTENT_DELALLOC)) 1536 if (!(orig->state & EXTENT_DELALLOC))
1535 return; 1537 return;
1536 1538
1539 size = orig->end - orig->start + 1;
1540 if (size > BTRFS_MAX_EXTENT_SIZE) {
1541 u64 num_extents;
1542 u64 new_size;
1543
1544 /*
1545 * We need the largest size of the remaining extent to see if we
1546 * need to add a new outstanding extent. Think of the following
1547 * case
1548 *
1549 * [MEAX_EXTENT_SIZEx2 - 4k][4k]
1550 *
1551 * The new_size would just be 4k and we'd think we had enough
1552 * outstanding extents for this if we only took one side of the
1553 * split, same goes for the other direction. We need to see if
1554 * the larger size still is the same amount of extents as the
1555 * original size, because if it is we need to add a new
1556 * outstanding extent. But if we split up and the larger size
1557 * is less than the original then we are good to go since we've
1558 * already accounted for the extra extent in our original
1559 * accounting.
1560 */
1561 new_size = orig->end - split + 1;
1562 if ((split - orig->start) > new_size)
1563 new_size = split - orig->start;
1564
1565 num_extents = div64_u64(size + BTRFS_MAX_EXTENT_SIZE - 1,
1566 BTRFS_MAX_EXTENT_SIZE);
1567 if (div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1,
1568 BTRFS_MAX_EXTENT_SIZE) < num_extents)
1569 return;
1570 }
1571
1537 spin_lock(&BTRFS_I(inode)->lock); 1572 spin_lock(&BTRFS_I(inode)->lock);
1538 BTRFS_I(inode)->outstanding_extents++; 1573 BTRFS_I(inode)->outstanding_extents++;
1539 spin_unlock(&BTRFS_I(inode)->lock); 1574 spin_unlock(&BTRFS_I(inode)->lock);
@@ -1549,10 +1584,34 @@ static void btrfs_merge_extent_hook(struct inode *inode,
1549 struct extent_state *new, 1584 struct extent_state *new,
1550 struct extent_state *other) 1585 struct extent_state *other)
1551{ 1586{
1587 u64 new_size, old_size;
1588 u64 num_extents;
1589
1552 /* not delalloc, ignore it */ 1590 /* not delalloc, ignore it */
1553 if (!(other->state & EXTENT_DELALLOC)) 1591 if (!(other->state & EXTENT_DELALLOC))
1554 return; 1592 return;
1555 1593
1594 old_size = other->end - other->start + 1;
1595 new_size = old_size + (new->end - new->start + 1);
1596
1597 /* we're not bigger than the max, unreserve the space and go */
1598 if (new_size <= BTRFS_MAX_EXTENT_SIZE) {
1599 spin_lock(&BTRFS_I(inode)->lock);
1600 BTRFS_I(inode)->outstanding_extents--;
1601 spin_unlock(&BTRFS_I(inode)->lock);
1602 return;
1603 }
1604
1605 /*
1606 * If we grew by another max_extent, just return, we want to keep that
1607 * reserved amount.
1608 */
1609 num_extents = div64_u64(old_size + BTRFS_MAX_EXTENT_SIZE - 1,
1610 BTRFS_MAX_EXTENT_SIZE);
1611 if (div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1,
1612 BTRFS_MAX_EXTENT_SIZE) > num_extents)
1613 return;
1614
1556 spin_lock(&BTRFS_I(inode)->lock); 1615 spin_lock(&BTRFS_I(inode)->lock);
1557 BTRFS_I(inode)->outstanding_extents--; 1616 BTRFS_I(inode)->outstanding_extents--;
1558 spin_unlock(&BTRFS_I(inode)->lock); 1617 spin_unlock(&BTRFS_I(inode)->lock);
@@ -1648,6 +1707,8 @@ static void btrfs_clear_bit_hook(struct inode *inode,
1648 unsigned *bits) 1707 unsigned *bits)
1649{ 1708{
1650 u64 len = state->end + 1 - state->start; 1709 u64 len = state->end + 1 - state->start;
1710 u64 num_extents = div64_u64(len + BTRFS_MAX_EXTENT_SIZE -1,
1711 BTRFS_MAX_EXTENT_SIZE);
1651 1712
1652 spin_lock(&BTRFS_I(inode)->lock); 1713 spin_lock(&BTRFS_I(inode)->lock);
1653 if ((state->state & EXTENT_DEFRAG) && (*bits & EXTENT_DEFRAG)) 1714 if ((state->state & EXTENT_DEFRAG) && (*bits & EXTENT_DEFRAG))
@@ -1667,7 +1728,7 @@ static void btrfs_clear_bit_hook(struct inode *inode,
1667 *bits &= ~EXTENT_FIRST_DELALLOC; 1728 *bits &= ~EXTENT_FIRST_DELALLOC;
1668 } else if (!(*bits & EXTENT_DO_ACCOUNTING)) { 1729 } else if (!(*bits & EXTENT_DO_ACCOUNTING)) {
1669 spin_lock(&BTRFS_I(inode)->lock); 1730 spin_lock(&BTRFS_I(inode)->lock);
1670 BTRFS_I(inode)->outstanding_extents--; 1731 BTRFS_I(inode)->outstanding_extents -= num_extents;
1671 spin_unlock(&BTRFS_I(inode)->lock); 1732 spin_unlock(&BTRFS_I(inode)->lock);
1672 } 1733 }
1673 1734