diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-06-25 16:01:31 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:03 -0400 |
commit | 89ce8a63d0c761fbb02089850605360f389477d8 (patch) | |
tree | a509b1daf6e41f7768eaf49235c573690f12ef9b /fs/btrfs/inode.c | |
parent | 333db94cdde9e6dfdedab9290d04d812f83e0922 (diff) |
Add btrfs_end_transaction_throttle to force writers to wait for pending commits
The existing throttle mechanism was often not sufficient to prevent
new writers from coming in and making a given transaction run forever.
This adds an explicit wait at the end of most operations so they will
allow the current transaction to close.
There is no wait inside file_write, inode updates, or cow filling, all which
have different deadlock possibilities.
This is a temporary measure until better asynchronous commit support is
added. This code leads to stalls as it waits for data=ordered
writeback, and it really needs to be fixed.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index cf27b5984627..bbba3350d023 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -855,10 +855,9 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
855 | btrfs_del_ordered_inode(inode, 1); | 855 | btrfs_del_ordered_inode(inode, 1); |
856 | } | 856 | } |
857 | 857 | ||
858 | btrfs_end_transaction(trans, root); | 858 | btrfs_end_transaction_throttle(trans, root); |
859 | fail: | 859 | fail: |
860 | btrfs_btree_balance_dirty(root, nr); | 860 | btrfs_btree_balance_dirty(root, nr); |
861 | btrfs_throttle(root); | ||
862 | return ret; | 861 | return ret; |
863 | } | 862 | } |
864 | 863 | ||
@@ -889,10 +888,9 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
889 | } | 888 | } |
890 | 889 | ||
891 | nr = trans->blocks_used; | 890 | nr = trans->blocks_used; |
892 | ret = btrfs_end_transaction(trans, root); | 891 | ret = btrfs_end_transaction_throttle(trans, root); |
893 | fail: | 892 | fail: |
894 | btrfs_btree_balance_dirty(root, nr); | 893 | btrfs_btree_balance_dirty(root, nr); |
895 | btrfs_throttle(root); | ||
896 | 894 | ||
897 | if (ret && !err) | 895 | if (ret && !err) |
898 | err = ret; | 896 | err = ret; |
@@ -1871,14 +1869,13 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1871 | btrfs_update_inode_block_group(trans, dir); | 1869 | btrfs_update_inode_block_group(trans, dir); |
1872 | out_unlock: | 1870 | out_unlock: |
1873 | nr = trans->blocks_used; | 1871 | nr = trans->blocks_used; |
1874 | btrfs_end_transaction(trans, root); | 1872 | btrfs_end_transaction_throttle(trans, root); |
1875 | fail: | 1873 | fail: |
1876 | if (drop_inode) { | 1874 | if (drop_inode) { |
1877 | inode_dec_link_count(inode); | 1875 | inode_dec_link_count(inode); |
1878 | iput(inode); | 1876 | iput(inode); |
1879 | } | 1877 | } |
1880 | btrfs_btree_balance_dirty(root, nr); | 1878 | btrfs_btree_balance_dirty(root, nr); |
1881 | btrfs_throttle(root); | ||
1882 | return err; | 1879 | return err; |
1883 | } | 1880 | } |
1884 | 1881 | ||
@@ -1936,14 +1933,13 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
1936 | btrfs_update_inode_block_group(trans, dir); | 1933 | btrfs_update_inode_block_group(trans, dir); |
1937 | out_unlock: | 1934 | out_unlock: |
1938 | nr = trans->blocks_used; | 1935 | nr = trans->blocks_used; |
1939 | btrfs_end_transaction(trans, root); | 1936 | btrfs_end_transaction_throttle(trans, root); |
1940 | fail: | 1937 | fail: |
1941 | if (drop_inode) { | 1938 | if (drop_inode) { |
1942 | inode_dec_link_count(inode); | 1939 | inode_dec_link_count(inode); |
1943 | iput(inode); | 1940 | iput(inode); |
1944 | } | 1941 | } |
1945 | btrfs_btree_balance_dirty(root, nr); | 1942 | btrfs_btree_balance_dirty(root, nr); |
1946 | btrfs_throttle(root); | ||
1947 | return err; | 1943 | return err; |
1948 | } | 1944 | } |
1949 | 1945 | ||
@@ -1985,14 +1981,13 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1985 | drop_inode = 1; | 1981 | drop_inode = 1; |
1986 | 1982 | ||
1987 | nr = trans->blocks_used; | 1983 | nr = trans->blocks_used; |
1988 | btrfs_end_transaction(trans, root); | 1984 | btrfs_end_transaction_throttle(trans, root); |
1989 | fail: | 1985 | fail: |
1990 | if (drop_inode) { | 1986 | if (drop_inode) { |
1991 | inode_dec_link_count(inode); | 1987 | inode_dec_link_count(inode); |
1992 | iput(inode); | 1988 | iput(inode); |
1993 | } | 1989 | } |
1994 | btrfs_btree_balance_dirty(root, nr); | 1990 | btrfs_btree_balance_dirty(root, nr); |
1995 | btrfs_throttle(root); | ||
1996 | return err; | 1991 | return err; |
1997 | } | 1992 | } |
1998 | 1993 | ||
@@ -2055,13 +2050,12 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
2055 | 2050 | ||
2056 | out_fail: | 2051 | out_fail: |
2057 | nr = trans->blocks_used; | 2052 | nr = trans->blocks_used; |
2058 | btrfs_end_transaction(trans, root); | 2053 | btrfs_end_transaction_throttle(trans, root); |
2059 | 2054 | ||
2060 | out_unlock: | 2055 | out_unlock: |
2061 | if (drop_on_err) | 2056 | if (drop_on_err) |
2062 | iput(inode); | 2057 | iput(inode); |
2063 | btrfs_btree_balance_dirty(root, nr); | 2058 | btrfs_btree_balance_dirty(root, nr); |
2064 | btrfs_throttle(root); | ||
2065 | return err; | 2059 | return err; |
2066 | } | 2060 | } |
2067 | 2061 | ||
@@ -2587,10 +2581,9 @@ static void btrfs_truncate(struct inode *inode) | |||
2587 | btrfs_update_inode(trans, root, inode); | 2581 | btrfs_update_inode(trans, root, inode); |
2588 | nr = trans->blocks_used; | 2582 | nr = trans->blocks_used; |
2589 | 2583 | ||
2590 | ret = btrfs_end_transaction(trans, root); | 2584 | ret = btrfs_end_transaction_throttle(trans, root); |
2591 | BUG_ON(ret); | 2585 | BUG_ON(ret); |
2592 | btrfs_btree_balance_dirty(root, nr); | 2586 | btrfs_btree_balance_dirty(root, nr); |
2593 | btrfs_throttle(root); | ||
2594 | } | 2587 | } |
2595 | 2588 | ||
2596 | /* | 2589 | /* |
@@ -2912,14 +2905,13 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2912 | 2905 | ||
2913 | out_unlock: | 2906 | out_unlock: |
2914 | nr = trans->blocks_used; | 2907 | nr = trans->blocks_used; |
2915 | btrfs_end_transaction(trans, root); | 2908 | btrfs_end_transaction_throttle(trans, root); |
2916 | out_fail: | 2909 | out_fail: |
2917 | if (drop_inode) { | 2910 | if (drop_inode) { |
2918 | inode_dec_link_count(inode); | 2911 | inode_dec_link_count(inode); |
2919 | iput(inode); | 2912 | iput(inode); |
2920 | } | 2913 | } |
2921 | btrfs_btree_balance_dirty(root, nr); | 2914 | btrfs_btree_balance_dirty(root, nr); |
2922 | btrfs_throttle(root); | ||
2923 | return err; | 2915 | return err; |
2924 | } | 2916 | } |
2925 | 2917 | ||