aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-11-16 13:56:32 -0500
committerChris Mason <chris.mason@fusionio.com>2012-12-16 20:46:22 -0500
commitb812ce28796f746f14ba6cc451250c422db447b2 (patch)
tree81f116613d7642b80a5a23668b7642d7931ad672 /fs
parenta95249b392c3ab843d7b25ab6817ecc9ea0b82ee (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/btrfs_inode.h3
-rw-r--r--fs/btrfs/file.c8
-rw-r--r--fs/btrfs/inode.c11
3 files changed, 21 insertions, 1 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 2411baf35220..2a8c242bc4f5 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -91,6 +91,9 @@ struct btrfs_inode {
91 91
92 unsigned long runtime_flags; 92 unsigned long runtime_flags;
93 93
94 /* Keep track of who's O_SYNC/fsycing currently */
95 atomic_t sync_writers;
96
94 /* full 64 bit generation number, struct vfs_inode doesn't have a big 97 /* full 64 bit generation number, struct vfs_inode doesn't have a big
95 * enough field for this. 98 * enough field for this.
96 */ 99 */
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 71c2dc1ea15a..7f4654a15207 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1472,6 +1472,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1472 ssize_t num_written = 0; 1472 ssize_t num_written = 0;
1473 ssize_t err = 0; 1473 ssize_t err = 0;
1474 size_t count, ocount; 1474 size_t count, ocount;
1475 bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
1475 1476
1476 sb_start_write(inode->i_sb); 1477 sb_start_write(inode->i_sb);
1477 1478
@@ -1529,6 +1530,9 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1529 } 1530 }
1530 } 1531 }
1531 1532
1533 if (sync)
1534 atomic_inc(&BTRFS_I(inode)->sync_writers);
1535
1532 if (unlikely(file->f_flags & O_DIRECT)) { 1536 if (unlikely(file->f_flags & O_DIRECT)) {
1533 num_written = __btrfs_direct_write(iocb, iov, nr_segs, 1537 num_written = __btrfs_direct_write(iocb, iov, nr_segs,
1534 pos, ppos, count, ocount); 1538 pos, ppos, count, ocount);
@@ -1563,6 +1567,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1563 num_written = err; 1567 num_written = err;
1564 } 1568 }
1565out: 1569out:
1570 if (sync)
1571 atomic_dec(&BTRFS_I(inode)->sync_writers);
1566 sb_end_write(inode->i_sb); 1572 sb_end_write(inode->i_sb);
1567 current->backing_dev_info = NULL; 1573 current->backing_dev_info = NULL;
1568 return num_written ? num_written : err; 1574 return num_written ? num_written : err;
@@ -1613,7 +1619,9 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
1613 * out of the ->i_mutex. If so, we can flush the dirty pages by 1619 * out of the ->i_mutex. If so, we can flush the dirty pages by
1614 * multi-task, and make the performance up. 1620 * multi-task, and make the performance up.
1615 */ 1621 */
1622 atomic_inc(&BTRFS_I(inode)->sync_writers);
1616 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 1623 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
1624 atomic_dec(&BTRFS_I(inode)->sync_writers);
1617 if (ret) 1625 if (ret)
1618 return ret; 1626 return ret;
1619 1627
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 123815f3b454..7855aac36706 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1622,6 +1622,7 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
1622 int ret = 0; 1622 int ret = 0;
1623 int skip_sum; 1623 int skip_sum;
1624 int metadata = 0; 1624 int metadata = 0;
1625 int async = !atomic_read(&BTRFS_I(inode)->sync_writers);
1625 1626
1626 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 1627 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
1627 1628
@@ -1644,7 +1645,7 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
1644 goto out; 1645 goto out;
1645 } 1646 }
1646 goto mapit; 1647 goto mapit;
1647 } else if (!skip_sum) { 1648 } else if (async && !skip_sum) {
1648 /* csum items have already been cloned */ 1649 /* csum items have already been cloned */
1649 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) 1650 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID)
1650 goto mapit; 1651 goto mapit;
@@ -1655,6 +1656,10 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
1655 __btrfs_submit_bio_start, 1656 __btrfs_submit_bio_start,
1656 __btrfs_submit_bio_done); 1657 __btrfs_submit_bio_done);
1657 goto out; 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
1660mapit: 1665mapit:
@@ -6333,6 +6338,9 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
6333 struct btrfs_root *root = BTRFS_I(inode)->root; 6338 struct btrfs_root *root = BTRFS_I(inode)->root;
6334 int ret; 6339 int ret;
6335 6340
6341 if (async_submit)
6342 async_submit = !atomic_read(&BTRFS_I(inode)->sync_writers);
6343
6336 bio_get(bio); 6344 bio_get(bio);
6337 6345
6338 if (!write) { 6346 if (!write) {
@@ -7113,6 +7121,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
7113 extent_io_tree_init(&ei->io_failure_tree, &inode->i_data); 7121 extent_io_tree_init(&ei->io_failure_tree, &inode->i_data);
7114 ei->io_tree.track_uptodate = 1; 7122 ei->io_tree.track_uptodate = 1;
7115 ei->io_failure_tree.track_uptodate = 1; 7123 ei->io_failure_tree.track_uptodate = 1;
7124 atomic_set(&ei->sync_writers, 0);
7116 mutex_init(&ei->log_mutex); 7125 mutex_init(&ei->log_mutex);
7117 mutex_init(&ei->delalloc_mutex); 7126 mutex_init(&ei->delalloc_mutex);
7118 btrfs_ordered_inode_tree_init(&ei->ordered_tree); 7127 btrfs_ordered_inode_tree_init(&ei->ordered_tree);