diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-25 08:51:48 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | 81d7ed29ff6bdec903c36c26b386e16c014993b2 (patch) | |
tree | 561f6d5b85c9af14acc97ec45b6ce6622c3ec3f4 /fs | |
parent | bce4eae9864e6b6ebde5d7f05576ff0a6c3724d0 (diff) |
Btrfs: Throttle file_write when data=ordered is flushing the inode
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 1 | ||||
-rw-r--r-- | fs/btrfs/file.c | 1 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 4 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.c | 13 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.h | 1 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 10 |
6 files changed, 28 insertions, 2 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index fe6ef8e34166..5ba83894c8b7 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -31,6 +31,7 @@ struct btrfs_inode { | |||
31 | struct extent_io_tree io_tree; | 31 | struct extent_io_tree io_tree; |
32 | struct extent_io_tree io_failure_tree; | 32 | struct extent_io_tree io_failure_tree; |
33 | struct inode vfs_inode; | 33 | struct inode vfs_inode; |
34 | atomic_t ordered_writeback; | ||
34 | 35 | ||
35 | u64 ordered_trans; | 36 | u64 ordered_trans; |
36 | /* | 37 | /* |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 5d537f26dc83..8effdf4f5d6f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -977,6 +977,7 @@ out_nolock: | |||
977 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); | 977 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); |
978 | } | 978 | } |
979 | current->backing_dev_info = NULL; | 979 | current->backing_dev_info = NULL; |
980 | btrfs_ordered_throttle(root, inode); | ||
980 | return num_written ? num_written : err; | 981 | return num_written ? num_written : err; |
981 | } | 982 | } |
982 | 983 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d58b4d5a1fef..b31f52d4f2ca 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1419,6 +1419,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
1419 | inode->i_mapping, GFP_NOFS); | 1419 | inode->i_mapping, GFP_NOFS); |
1420 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 1420 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
1421 | inode->i_mapping, GFP_NOFS); | 1421 | inode->i_mapping, GFP_NOFS); |
1422 | atomic_set(&BTRFS_I(inode)->ordered_writeback, 0); | ||
1422 | return 0; | 1423 | return 0; |
1423 | } | 1424 | } |
1424 | 1425 | ||
@@ -1728,6 +1729,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
1728 | inode->i_mapping, GFP_NOFS); | 1729 | inode->i_mapping, GFP_NOFS); |
1729 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 1730 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
1730 | inode->i_mapping, GFP_NOFS); | 1731 | inode->i_mapping, GFP_NOFS); |
1732 | atomic_set(&BTRFS_I(inode)->ordered_writeback, 0); | ||
1731 | BTRFS_I(inode)->delalloc_bytes = 0; | 1733 | BTRFS_I(inode)->delalloc_bytes = 0; |
1732 | BTRFS_I(inode)->root = root; | 1734 | BTRFS_I(inode)->root = root; |
1733 | 1735 | ||
@@ -1956,6 +1958,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
1956 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 1958 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
1957 | inode->i_mapping, GFP_NOFS); | 1959 | inode->i_mapping, GFP_NOFS); |
1958 | BTRFS_I(inode)->delalloc_bytes = 0; | 1960 | BTRFS_I(inode)->delalloc_bytes = 0; |
1961 | atomic_set(&BTRFS_I(inode)->ordered_writeback, 0); | ||
1959 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 1962 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
1960 | } | 1963 | } |
1961 | dir->i_sb->s_dirt = 1; | 1964 | dir->i_sb->s_dirt = 1; |
@@ -3292,6 +3295,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
3292 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 3295 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
3293 | inode->i_mapping, GFP_NOFS); | 3296 | inode->i_mapping, GFP_NOFS); |
3294 | BTRFS_I(inode)->delalloc_bytes = 0; | 3297 | BTRFS_I(inode)->delalloc_bytes = 0; |
3298 | atomic_set(&BTRFS_I(inode)->ordered_writeback, 0); | ||
3295 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 3299 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
3296 | } | 3300 | } |
3297 | dir->i_sb->s_dirt = 1; | 3301 | dir->i_sb->s_dirt = 1; |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 3ee51e10c187..b474902c90e2 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -269,3 +269,16 @@ int btrfs_del_ordered_inode(struct inode *inode) | |||
269 | return ret; | 269 | return ret; |
270 | } | 270 | } |
271 | 271 | ||
272 | int btrfs_ordered_throttle(struct btrfs_root *root, struct inode *inode) | ||
273 | { | ||
274 | struct btrfs_transaction *cur = root->fs_info->running_transaction; | ||
275 | while(cur == root->fs_info->running_transaction && | ||
276 | atomic_read(&BTRFS_I(inode)->ordered_writeback)) { | ||
277 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) | ||
278 | congestion_wait(WRITE, HZ/20); | ||
279 | #else | ||
280 | blk_congestion_wait(WRITE, HZ/20); | ||
281 | #endif | ||
282 | } | ||
283 | return 0; | ||
284 | } | ||
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index f25c6771ec64..29047e0abaab 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h | |||
@@ -39,4 +39,5 @@ int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, | |||
39 | u64 *root_objectid, u64 *objectid, | 39 | u64 *root_objectid, u64 *objectid, |
40 | struct inode **inode); | 40 | struct inode **inode); |
41 | int btrfs_del_ordered_inode(struct inode *inode); | 41 | int btrfs_del_ordered_inode(struct inode *inode); |
42 | int btrfs_ordered_throttle(struct btrfs_root *root, struct inode *inode); | ||
42 | #endif | 43 | #endif |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 1ed179c020af..c85cb48d95ee 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -512,8 +512,11 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans, | |||
512 | mutex_unlock(&root->fs_info->trans_mutex); | 512 | mutex_unlock(&root->fs_info->trans_mutex); |
513 | mutex_unlock(&root->fs_info->fs_mutex); | 513 | mutex_unlock(&root->fs_info->fs_mutex); |
514 | 514 | ||
515 | if (S_ISREG(inode->i_mode)) | 515 | if (S_ISREG(inode->i_mode)) { |
516 | atomic_inc(&BTRFS_I(inode)->ordered_writeback); | ||
516 | filemap_fdatawrite(inode->i_mapping); | 517 | filemap_fdatawrite(inode->i_mapping); |
518 | atomic_dec(&BTRFS_I(inode)->ordered_writeback); | ||
519 | } | ||
517 | iput(inode); | 520 | iput(inode); |
518 | 521 | ||
519 | mutex_lock(&root->fs_info->fs_mutex); | 522 | mutex_lock(&root->fs_info->fs_mutex); |
@@ -530,8 +533,11 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans, | |||
530 | mutex_unlock(&root->fs_info->trans_mutex); | 533 | mutex_unlock(&root->fs_info->trans_mutex); |
531 | mutex_unlock(&root->fs_info->fs_mutex); | 534 | mutex_unlock(&root->fs_info->fs_mutex); |
532 | 535 | ||
533 | if (S_ISREG(inode->i_mode)) | 536 | if (S_ISREG(inode->i_mode)) { |
537 | atomic_inc(&BTRFS_I(inode)->ordered_writeback); | ||
534 | filemap_write_and_wait(inode->i_mapping); | 538 | filemap_write_and_wait(inode->i_mapping); |
539 | atomic_dec(&BTRFS_I(inode)->ordered_writeback); | ||
540 | } | ||
535 | atomic_dec(&inode->i_count); | 541 | atomic_dec(&inode->i_count); |
536 | iput(inode); | 542 | iput(inode); |
537 | 543 | ||