diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 112 |
1 files changed, 84 insertions, 28 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index da828cf5e8f8..d2e732d7af52 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -108,6 +108,13 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start, | |||
| 108 | 108 | ||
| 109 | static int btrfs_dirty_inode(struct inode *inode); | 109 | static int btrfs_dirty_inode(struct inode *inode); |
| 110 | 110 | ||
| 111 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
| 112 | void btrfs_test_inode_set_ops(struct inode *inode) | ||
| 113 | { | ||
| 114 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | ||
| 115 | } | ||
| 116 | #endif | ||
| 117 | |||
| 111 | static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, | 118 | static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, |
| 112 | struct inode *inode, struct inode *dir, | 119 | struct inode *inode, struct inode *dir, |
| 113 | const struct qstr *qstr) | 120 | const struct qstr *qstr) |
| @@ -1542,30 +1549,17 @@ static void btrfs_split_extent_hook(struct inode *inode, | |||
| 1542 | u64 new_size; | 1549 | u64 new_size; |
| 1543 | 1550 | ||
| 1544 | /* | 1551 | /* |
| 1545 | * We need the largest size of the remaining extent to see if we | 1552 | * See the explanation in btrfs_merge_extent_hook, the same |
| 1546 | * need to add a new outstanding extent. Think of the following | 1553 | * applies here, just in reverse. |
| 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 | */ | 1554 | */ |
| 1561 | new_size = orig->end - split + 1; | 1555 | new_size = orig->end - split + 1; |
| 1562 | if ((split - orig->start) > new_size) | 1556 | num_extents = div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, |
| 1563 | new_size = split - orig->start; | ||
| 1564 | |||
| 1565 | num_extents = div64_u64(size + BTRFS_MAX_EXTENT_SIZE - 1, | ||
| 1566 | BTRFS_MAX_EXTENT_SIZE); | 1557 | BTRFS_MAX_EXTENT_SIZE); |
| 1567 | if (div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, | 1558 | new_size = split - orig->start; |
| 1568 | BTRFS_MAX_EXTENT_SIZE) < num_extents) | 1559 | num_extents += div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, |
| 1560 | BTRFS_MAX_EXTENT_SIZE); | ||
| 1561 | if (div64_u64(size + BTRFS_MAX_EXTENT_SIZE - 1, | ||
| 1562 | BTRFS_MAX_EXTENT_SIZE) >= num_extents) | ||
| 1569 | return; | 1563 | return; |
| 1570 | } | 1564 | } |
| 1571 | 1565 | ||
| @@ -1591,8 +1585,10 @@ static void btrfs_merge_extent_hook(struct inode *inode, | |||
| 1591 | if (!(other->state & EXTENT_DELALLOC)) | 1585 | if (!(other->state & EXTENT_DELALLOC)) |
| 1592 | return; | 1586 | return; |
| 1593 | 1587 | ||
| 1594 | old_size = other->end - other->start + 1; | 1588 | if (new->start > other->start) |
| 1595 | new_size = old_size + (new->end - new->start + 1); | 1589 | new_size = new->end - other->start + 1; |
| 1590 | else | ||
| 1591 | new_size = other->end - new->start + 1; | ||
| 1596 | 1592 | ||
| 1597 | /* we're not bigger than the max, unreserve the space and go */ | 1593 | /* we're not bigger than the max, unreserve the space and go */ |
| 1598 | if (new_size <= BTRFS_MAX_EXTENT_SIZE) { | 1594 | if (new_size <= BTRFS_MAX_EXTENT_SIZE) { |
| @@ -1603,13 +1599,32 @@ static void btrfs_merge_extent_hook(struct inode *inode, | |||
| 1603 | } | 1599 | } |
| 1604 | 1600 | ||
| 1605 | /* | 1601 | /* |
| 1606 | * If we grew by another max_extent, just return, we want to keep that | 1602 | * We have to add up either side to figure out how many extents were |
| 1607 | * reserved amount. | 1603 | * accounted for before we merged into one big extent. If the number of |
| 1604 | * extents we accounted for is <= the amount we need for the new range | ||
| 1605 | * then we can return, otherwise drop. Think of it like this | ||
| 1606 | * | ||
| 1607 | * [ 4k][MAX_SIZE] | ||
| 1608 | * | ||
| 1609 | * So we've grown the extent by a MAX_SIZE extent, this would mean we | ||
| 1610 | * need 2 outstanding extents, on one side we have 1 and the other side | ||
| 1611 | * we have 1 so they are == and we can return. But in this case | ||
| 1612 | * | ||
| 1613 | * [MAX_SIZE+4k][MAX_SIZE+4k] | ||
| 1614 | * | ||
| 1615 | * Each range on their own accounts for 2 extents, but merged together | ||
| 1616 | * they are only 3 extents worth of accounting, so we need to drop in | ||
| 1617 | * this case. | ||
| 1608 | */ | 1618 | */ |
| 1619 | old_size = other->end - other->start + 1; | ||
| 1609 | num_extents = div64_u64(old_size + BTRFS_MAX_EXTENT_SIZE - 1, | 1620 | num_extents = div64_u64(old_size + BTRFS_MAX_EXTENT_SIZE - 1, |
| 1610 | BTRFS_MAX_EXTENT_SIZE); | 1621 | BTRFS_MAX_EXTENT_SIZE); |
| 1622 | old_size = new->end - new->start + 1; | ||
| 1623 | num_extents += div64_u64(old_size + BTRFS_MAX_EXTENT_SIZE - 1, | ||
| 1624 | BTRFS_MAX_EXTENT_SIZE); | ||
| 1625 | |||
| 1611 | if (div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, | 1626 | if (div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, |
| 1612 | BTRFS_MAX_EXTENT_SIZE) > num_extents) | 1627 | BTRFS_MAX_EXTENT_SIZE) >= num_extents) |
| 1613 | return; | 1628 | return; |
| 1614 | 1629 | ||
| 1615 | spin_lock(&BTRFS_I(inode)->lock); | 1630 | spin_lock(&BTRFS_I(inode)->lock); |
| @@ -1686,6 +1701,10 @@ static void btrfs_set_bit_hook(struct inode *inode, | |||
| 1686 | spin_unlock(&BTRFS_I(inode)->lock); | 1701 | spin_unlock(&BTRFS_I(inode)->lock); |
| 1687 | } | 1702 | } |
| 1688 | 1703 | ||
| 1704 | /* For sanity tests */ | ||
| 1705 | if (btrfs_test_is_dummy_root(root)) | ||
| 1706 | return; | ||
| 1707 | |||
| 1689 | __percpu_counter_add(&root->fs_info->delalloc_bytes, len, | 1708 | __percpu_counter_add(&root->fs_info->delalloc_bytes, len, |
| 1690 | root->fs_info->delalloc_batch); | 1709 | root->fs_info->delalloc_batch); |
| 1691 | spin_lock(&BTRFS_I(inode)->lock); | 1710 | spin_lock(&BTRFS_I(inode)->lock); |
| @@ -1741,6 +1760,10 @@ static void btrfs_clear_bit_hook(struct inode *inode, | |||
| 1741 | root != root->fs_info->tree_root) | 1760 | root != root->fs_info->tree_root) |
| 1742 | btrfs_delalloc_release_metadata(inode, len); | 1761 | btrfs_delalloc_release_metadata(inode, len); |
| 1743 | 1762 | ||
| 1763 | /* For sanity tests. */ | ||
| 1764 | if (btrfs_test_is_dummy_root(root)) | ||
| 1765 | return; | ||
| 1766 | |||
| 1744 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID | 1767 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID |
| 1745 | && do_list && !(state->state & EXTENT_NORESERVE)) | 1768 | && do_list && !(state->state & EXTENT_NORESERVE)) |
| 1746 | btrfs_free_reserved_data_space(inode, len); | 1769 | btrfs_free_reserved_data_space(inode, len); |
| @@ -7213,7 +7236,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
| 7213 | u64 start = iblock << inode->i_blkbits; | 7236 | u64 start = iblock << inode->i_blkbits; |
| 7214 | u64 lockstart, lockend; | 7237 | u64 lockstart, lockend; |
| 7215 | u64 len = bh_result->b_size; | 7238 | u64 len = bh_result->b_size; |
| 7216 | u64 orig_len = len; | 7239 | u64 *outstanding_extents = NULL; |
| 7217 | int unlock_bits = EXTENT_LOCKED; | 7240 | int unlock_bits = EXTENT_LOCKED; |
| 7218 | int ret = 0; | 7241 | int ret = 0; |
| 7219 | 7242 | ||
| @@ -7225,6 +7248,16 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
| 7225 | lockstart = start; | 7248 | lockstart = start; |
| 7226 | lockend = start + len - 1; | 7249 | lockend = start + len - 1; |
| 7227 | 7250 | ||
| 7251 | if (current->journal_info) { | ||
| 7252 | /* | ||
| 7253 | * Need to pull our outstanding extents and set journal_info to NULL so | ||
| 7254 | * that anything that needs to check if there's a transction doesn't get | ||
| 7255 | * confused. | ||
| 7256 | */ | ||
| 7257 | outstanding_extents = current->journal_info; | ||
| 7258 | current->journal_info = NULL; | ||
| 7259 | } | ||
| 7260 | |||
| 7228 | /* | 7261 | /* |
| 7229 | * If this errors out it's because we couldn't invalidate pagecache for | 7262 | * If this errors out it's because we couldn't invalidate pagecache for |
| 7230 | * this range and we need to fallback to buffered. | 7263 | * this range and we need to fallback to buffered. |
| @@ -7348,11 +7381,20 @@ unlock: | |||
| 7348 | if (start + len > i_size_read(inode)) | 7381 | if (start + len > i_size_read(inode)) |
| 7349 | i_size_write(inode, start + len); | 7382 | i_size_write(inode, start + len); |
| 7350 | 7383 | ||
| 7351 | if (len < orig_len) { | 7384 | /* |
| 7385 | * If we have an outstanding_extents count still set then we're | ||
| 7386 | * within our reservation, otherwise we need to adjust our inode | ||
| 7387 | * counter appropriately. | ||
| 7388 | */ | ||
| 7389 | if (*outstanding_extents) { | ||
| 7390 | (*outstanding_extents)--; | ||
| 7391 | } else { | ||
| 7352 | spin_lock(&BTRFS_I(inode)->lock); | 7392 | spin_lock(&BTRFS_I(inode)->lock); |
| 7353 | BTRFS_I(inode)->outstanding_extents++; | 7393 | BTRFS_I(inode)->outstanding_extents++; |
| 7354 | spin_unlock(&BTRFS_I(inode)->lock); | 7394 | spin_unlock(&BTRFS_I(inode)->lock); |
| 7355 | } | 7395 | } |
| 7396 | |||
| 7397 | current->journal_info = outstanding_extents; | ||
| 7356 | btrfs_free_reserved_data_space(inode, len); | 7398 | btrfs_free_reserved_data_space(inode, len); |
| 7357 | } | 7399 | } |
| 7358 | 7400 | ||
| @@ -7376,6 +7418,8 @@ unlock: | |||
| 7376 | unlock_err: | 7418 | unlock_err: |
| 7377 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, | 7419 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, |
| 7378 | unlock_bits, 1, 0, &cached_state, GFP_NOFS); | 7420 | unlock_bits, 1, 0, &cached_state, GFP_NOFS); |
| 7421 | if (outstanding_extents) | ||
| 7422 | current->journal_info = outstanding_extents; | ||
| 7379 | return ret; | 7423 | return ret; |
| 7380 | } | 7424 | } |
| 7381 | 7425 | ||
| @@ -8075,6 +8119,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 8075 | { | 8119 | { |
| 8076 | struct file *file = iocb->ki_filp; | 8120 | struct file *file = iocb->ki_filp; |
| 8077 | struct inode *inode = file->f_mapping->host; | 8121 | struct inode *inode = file->f_mapping->host; |
| 8122 | u64 outstanding_extents = 0; | ||
| 8078 | size_t count = 0; | 8123 | size_t count = 0; |
| 8079 | int flags = 0; | 8124 | int flags = 0; |
| 8080 | bool wakeup = true; | 8125 | bool wakeup = true; |
| @@ -8112,6 +8157,16 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 8112 | ret = btrfs_delalloc_reserve_space(inode, count); | 8157 | ret = btrfs_delalloc_reserve_space(inode, count); |
| 8113 | if (ret) | 8158 | if (ret) |
| 8114 | goto out; | 8159 | goto out; |
| 8160 | outstanding_extents = div64_u64(count + | ||
| 8161 | BTRFS_MAX_EXTENT_SIZE - 1, | ||
| 8162 | BTRFS_MAX_EXTENT_SIZE); | ||
| 8163 | |||
| 8164 | /* | ||
| 8165 | * We need to know how many extents we reserved so that we can | ||
| 8166 | * do the accounting properly if we go over the number we | ||
| 8167 | * originally calculated. Abuse current->journal_info for this. | ||
| 8168 | */ | ||
| 8169 | current->journal_info = &outstanding_extents; | ||
| 8115 | } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, | 8170 | } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, |
| 8116 | &BTRFS_I(inode)->runtime_flags)) { | 8171 | &BTRFS_I(inode)->runtime_flags)) { |
| 8117 | inode_dio_done(inode); | 8172 | inode_dio_done(inode); |
| @@ -8124,6 +8179,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 8124 | iter, offset, btrfs_get_blocks_direct, NULL, | 8179 | iter, offset, btrfs_get_blocks_direct, NULL, |
| 8125 | btrfs_submit_direct, flags); | 8180 | btrfs_submit_direct, flags); |
| 8126 | if (rw & WRITE) { | 8181 | if (rw & WRITE) { |
| 8182 | current->journal_info = NULL; | ||
| 8127 | if (ret < 0 && ret != -EIOCBQUEUED) | 8183 | if (ret < 0 && ret != -EIOCBQUEUED) |
| 8128 | btrfs_delalloc_release_space(inode, count); | 8184 | btrfs_delalloc_release_space(inode, count); |
| 8129 | else if (ret >= 0 && (size_t)ret < count) | 8185 | else if (ret >= 0 && (size_t)ret < count) |
