Commit b812ce28796f746f14ba6cc451250c422db447b2

Authored by Josef Bacik
Committed by Chris Mason
1 parent a95249b392

Btrfs: inline csums if we're fsyncing

The tree logging stuff needs the csums to be on the ordered extents in order
to log them properly, so mark that we're sync and inline the csum creation
so we don't have to wait on the csumming to be done when logging extents
that are still in flight.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>

Showing 3 changed files with 21 additions and 1 deletions Side-by-side Diff

fs/btrfs/btrfs_inode.h
... ... @@ -91,6 +91,9 @@
91 91  
92 92 unsigned long runtime_flags;
93 93  
  94 + /* Keep track of who's O_SYNC/fsycing currently */
  95 + atomic_t sync_writers;
  96 +
94 97 /* full 64 bit generation number, struct vfs_inode doesn't have a big
95 98 * enough field for this.
96 99 */
... ... @@ -1472,6 +1472,7 @@
1472 1472 ssize_t num_written = 0;
1473 1473 ssize_t err = 0;
1474 1474 size_t count, ocount;
  1475 + bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
1475 1476  
1476 1477 sb_start_write(inode->i_sb);
1477 1478  
... ... @@ -1529,6 +1530,9 @@
1529 1530 }
1530 1531 }
1531 1532  
  1533 + if (sync)
  1534 + atomic_inc(&BTRFS_I(inode)->sync_writers);
  1535 +
1532 1536 if (unlikely(file->f_flags & O_DIRECT)) {
1533 1537 num_written = __btrfs_direct_write(iocb, iov, nr_segs,
1534 1538 pos, ppos, count, ocount);
... ... @@ -1563,6 +1567,8 @@
1563 1567 num_written = err;
1564 1568 }
1565 1569 out:
  1570 + if (sync)
  1571 + atomic_dec(&BTRFS_I(inode)->sync_writers);
1566 1572 sb_end_write(inode->i_sb);
1567 1573 current->backing_dev_info = NULL;
1568 1574 return num_written ? num_written : err;
1569 1575  
... ... @@ -1613,7 +1619,9 @@
1613 1619 * out of the ->i_mutex. If so, we can flush the dirty pages by
1614 1620 * multi-task, and make the performance up.
1615 1621 */
  1622 + atomic_inc(&BTRFS_I(inode)->sync_writers);
1616 1623 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
  1624 + atomic_dec(&BTRFS_I(inode)->sync_writers);
1617 1625 if (ret)
1618 1626 return ret;
1619 1627  
... ... @@ -1622,6 +1622,7 @@
1622 1622 int ret = 0;
1623 1623 int skip_sum;
1624 1624 int metadata = 0;
  1625 + int async = !atomic_read(&BTRFS_I(inode)->sync_writers);
1625 1626  
1626 1627 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
1627 1628  
... ... @@ -1644,7 +1645,7 @@
1644 1645 goto out;
1645 1646 }
1646 1647 goto mapit;
1647   - } else if (!skip_sum) {
  1648 + } else if (async && !skip_sum) {
1648 1649 /* csum items have already been cloned */
1649 1650 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID)
1650 1651 goto mapit;
... ... @@ -1655,6 +1656,10 @@
1655 1656 __btrfs_submit_bio_start,
1656 1657 __btrfs_submit_bio_done);
1657 1658 goto out;
  1659 + } else if (!skip_sum) {
  1660 + ret = btrfs_csum_one_bio(root, inode, bio, 0, 0);
  1661 + if (ret)
  1662 + goto out;
1658 1663 }
1659 1664  
1660 1665 mapit:
... ... @@ -6333,6 +6338,9 @@
6333 6338 struct btrfs_root *root = BTRFS_I(inode)->root;
6334 6339 int ret;
6335 6340  
  6341 + if (async_submit)
  6342 + async_submit = !atomic_read(&BTRFS_I(inode)->sync_writers);
  6343 +
6336 6344 bio_get(bio);
6337 6345  
6338 6346 if (!write) {
... ... @@ -7113,6 +7121,7 @@
7113 7121 extent_io_tree_init(&ei->io_failure_tree, &inode->i_data);
7114 7122 ei->io_tree.track_uptodate = 1;
7115 7123 ei->io_failure_tree.track_uptodate = 1;
  7124 + atomic_set(&ei->sync_writers, 0);
7116 7125 mutex_init(&ei->log_mutex);
7117 7126 mutex_init(&ei->delalloc_mutex);
7118 7127 btrfs_ordered_inode_tree_init(&ei->ordered_tree);