aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@fusionio.com>2013-02-20 14:05:45 -0500
committerChris Mason <chris.mason@fusionio.com>2013-02-20 14:05:45 -0500
commitb2c6b3e0611c58fbeb6b9c0892b6249f7bdfaf6b (patch)
treede7cf0825605aa6acf33a8d107003efd7aedbe72 /fs/btrfs/file.c
parent19f949f52599ba7c3f67a5897ac6be14bfcb1200 (diff)
parent272d26d0ad8c0e326689f2fa3cdc6a5fcc8e74e0 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-next into for-linus-3.9
Signed-off-by: Chris Mason <chris.mason@fusionio.com> Conflicts: fs/btrfs/disk-io.c
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index aeb84469d2c4..9f67e623206d 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -30,11 +30,11 @@
30#include <linux/statfs.h> 30#include <linux/statfs.h>
31#include <linux/compat.h> 31#include <linux/compat.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/btrfs.h>
33#include "ctree.h" 34#include "ctree.h"
34#include "disk-io.h" 35#include "disk-io.h"
35#include "transaction.h" 36#include "transaction.h"
36#include "btrfs_inode.h" 37#include "btrfs_inode.h"
37#include "ioctl.h"
38#include "print-tree.h" 38#include "print-tree.h"
39#include "tree-log.h" 39#include "tree-log.h"
40#include "locking.h" 40#include "locking.h"
@@ -1544,7 +1544,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1544 * although we have opened a file as writable, we have 1544 * although we have opened a file as writable, we have
1545 * to stop this write operation to ensure FS consistency. 1545 * to stop this write operation to ensure FS consistency.
1546 */ 1546 */
1547 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { 1547 if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) {
1548 mutex_unlock(&inode->i_mutex); 1548 mutex_unlock(&inode->i_mutex);
1549 err = -EROFS; 1549 err = -EROFS;
1550 goto out; 1550 goto out;
@@ -1627,7 +1627,20 @@ int btrfs_release_file(struct inode *inode, struct file *filp)
1627 */ 1627 */
1628 if (test_and_clear_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, 1628 if (test_and_clear_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
1629 &BTRFS_I(inode)->runtime_flags)) { 1629 &BTRFS_I(inode)->runtime_flags)) {
1630 btrfs_add_ordered_operation(NULL, BTRFS_I(inode)->root, inode); 1630 struct btrfs_trans_handle *trans;
1631 struct btrfs_root *root = BTRFS_I(inode)->root;
1632
1633 /*
1634 * We need to block on a committing transaction to keep us from
1635 * throwing a ordered operation on to the list and causing
1636 * something like sync to deadlock trying to flush out this
1637 * inode.
1638 */
1639 trans = btrfs_start_transaction(root, 0);
1640 if (IS_ERR(trans))
1641 return PTR_ERR(trans);
1642 btrfs_add_ordered_operation(trans, BTRFS_I(inode)->root, inode);
1643 btrfs_end_transaction(trans, root);
1631 if (inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) 1644 if (inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT)
1632 filemap_flush(inode->i_mapping); 1645 filemap_flush(inode->i_mapping);
1633 } 1646 }
@@ -1654,16 +1667,21 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
1654 struct btrfs_root *root = BTRFS_I(inode)->root; 1667 struct btrfs_root *root = BTRFS_I(inode)->root;
1655 int ret = 0; 1668 int ret = 0;
1656 struct btrfs_trans_handle *trans; 1669 struct btrfs_trans_handle *trans;
1670 bool full_sync = 0;
1657 1671
1658 trace_btrfs_sync_file(file, datasync); 1672 trace_btrfs_sync_file(file, datasync);
1659 1673
1660 /* 1674 /*
1661 * We write the dirty pages in the range and wait until they complete 1675 * We write the dirty pages in the range and wait until they complete
1662 * out of the ->i_mutex. If so, we can flush the dirty pages by 1676 * out of the ->i_mutex. If so, we can flush the dirty pages by
1663 * multi-task, and make the performance up. 1677 * multi-task, and make the performance up. See
1678 * btrfs_wait_ordered_range for an explanation of the ASYNC check.
1664 */ 1679 */
1665 atomic_inc(&BTRFS_I(inode)->sync_writers); 1680 atomic_inc(&BTRFS_I(inode)->sync_writers);
1666 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 1681 ret = filemap_fdatawrite_range(inode->i_mapping, start, end);
1682 if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
1683 &BTRFS_I(inode)->runtime_flags))
1684 ret = filemap_fdatawrite_range(inode->i_mapping, start, end);
1667 atomic_dec(&BTRFS_I(inode)->sync_writers); 1685 atomic_dec(&BTRFS_I(inode)->sync_writers);
1668 if (ret) 1686 if (ret)
1669 return ret; 1687 return ret;
@@ -1675,7 +1693,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
1675 * range being left. 1693 * range being left.
1676 */ 1694 */
1677 atomic_inc(&root->log_batch); 1695 atomic_inc(&root->log_batch);
1678 btrfs_wait_ordered_range(inode, start, end - start + 1); 1696 full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
1697 &BTRFS_I(inode)->runtime_flags);
1698 if (full_sync)
1699 btrfs_wait_ordered_range(inode, start, end - start + 1);
1679 atomic_inc(&root->log_batch); 1700 atomic_inc(&root->log_batch);
1680 1701
1681 /* 1702 /*
@@ -1742,13 +1763,25 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
1742 1763
1743 if (ret != BTRFS_NO_LOG_SYNC) { 1764 if (ret != BTRFS_NO_LOG_SYNC) {
1744 if (ret > 0) { 1765 if (ret > 0) {
1766 /*
1767 * If we didn't already wait for ordered extents we need
1768 * to do that now.
1769 */
1770 if (!full_sync)
1771 btrfs_wait_ordered_range(inode, start,
1772 end - start + 1);
1745 ret = btrfs_commit_transaction(trans, root); 1773 ret = btrfs_commit_transaction(trans, root);
1746 } else { 1774 } else {
1747 ret = btrfs_sync_log(trans, root); 1775 ret = btrfs_sync_log(trans, root);
1748 if (ret == 0) 1776 if (ret == 0) {
1749 ret = btrfs_end_transaction(trans, root); 1777 ret = btrfs_end_transaction(trans, root);
1750 else 1778 } else {
1779 if (!full_sync)
1780 btrfs_wait_ordered_range(inode, start,
1781 end -
1782 start + 1);
1751 ret = btrfs_commit_transaction(trans, root); 1783 ret = btrfs_commit_transaction(trans, root);
1784 }
1752 } 1785 }
1753 } else { 1786 } else {
1754 ret = btrfs_end_transaction(trans, root); 1787 ret = btrfs_end_transaction(trans, root);