diff options
| -rw-r--r-- | fs/btrfs/inode.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b83a45dc717e..9b4faac50c18 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -1497,6 +1497,30 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
| 1497 | return 0; | 1497 | return 0; |
| 1498 | } | 1498 | } |
| 1499 | 1499 | ||
| 1500 | /* | ||
| 1501 | * helper function for btrfs_finish_ordered_io, this | ||
| 1502 | * just reads in some of the csum leaves to prime them into ram | ||
| 1503 | * before we start the transaction. It limits the amount of btree | ||
| 1504 | * reads required while inside the transaction. | ||
| 1505 | */ | ||
| 1506 | static noinline void reada_csum(struct btrfs_root *root, | ||
| 1507 | struct btrfs_path *path, | ||
| 1508 | struct btrfs_ordered_extent *ordered_extent) | ||
| 1509 | { | ||
| 1510 | struct btrfs_ordered_sum *sum; | ||
| 1511 | u64 bytenr; | ||
| 1512 | |||
| 1513 | sum = list_entry(ordered_extent->list.next, struct btrfs_ordered_sum, | ||
| 1514 | list); | ||
| 1515 | bytenr = sum->sums[0].bytenr; | ||
| 1516 | |||
| 1517 | /* | ||
| 1518 | * we don't care about the results, the point of this search is | ||
| 1519 | * just to get the btree leaves into ram | ||
| 1520 | */ | ||
| 1521 | btrfs_lookup_csum(NULL, root->fs_info->csum_root, path, bytenr, 0); | ||
| 1522 | } | ||
| 1523 | |||
| 1500 | /* as ordered data IO finishes, this gets called so we can finish | 1524 | /* as ordered data IO finishes, this gets called so we can finish |
| 1501 | * an ordered extent if the range of bytes in the file it covers are | 1525 | * an ordered extent if the range of bytes in the file it covers are |
| 1502 | * fully written. | 1526 | * fully written. |
| @@ -1505,7 +1529,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
| 1505 | { | 1529 | { |
| 1506 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1530 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 1507 | struct btrfs_trans_handle *trans; | 1531 | struct btrfs_trans_handle *trans; |
| 1508 | struct btrfs_ordered_extent *ordered_extent; | 1532 | struct btrfs_ordered_extent *ordered_extent = NULL; |
| 1509 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 1533 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
| 1510 | struct btrfs_path *path; | 1534 | struct btrfs_path *path; |
| 1511 | int compressed = 0; | 1535 | int compressed = 0; |
| @@ -1528,13 +1552,20 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
| 1528 | ret = btrfs_lookup_file_extent(NULL, root, path, | 1552 | ret = btrfs_lookup_file_extent(NULL, root, path, |
| 1529 | inode->i_ino, | 1553 | inode->i_ino, |
| 1530 | start, 0); | 1554 | start, 0); |
| 1555 | ordered_extent = btrfs_lookup_ordered_extent(inode, | ||
| 1556 | start); | ||
| 1557 | if (!list_empty(&ordered_extent->list)) { | ||
| 1558 | btrfs_release_path(root, path); | ||
| 1559 | reada_csum(root, path, ordered_extent); | ||
| 1560 | } | ||
| 1531 | btrfs_free_path(path); | 1561 | btrfs_free_path(path); |
| 1532 | } | 1562 | } |
| 1533 | } | 1563 | } |
| 1534 | 1564 | ||
| 1535 | trans = btrfs_join_transaction(root, 1); | 1565 | trans = btrfs_join_transaction(root, 1); |
| 1536 | 1566 | ||
| 1537 | ordered_extent = btrfs_lookup_ordered_extent(inode, start); | 1567 | if (!ordered_extent) |
| 1568 | ordered_extent = btrfs_lookup_ordered_extent(inode, start); | ||
| 1538 | BUG_ON(!ordered_extent); | 1569 | BUG_ON(!ordered_extent); |
| 1539 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) | 1570 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) |
| 1540 | goto nocow; | 1571 | goto nocow; |
