aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-08 15:46:30 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:59 -0400
commite2008b61401ecb467a8ce1788fcd2116ae1cfbc1 (patch)
tree8f13935108abaca29c894ca1f9309c9813c9e194
parent3063d29f2a4d4a4e9fa1ec77c124514f287c6da7 (diff)
Btrfs: Add some simple throttling to wait for data=ordered and snapshot deletion
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c7
-rw-r--r--fs/btrfs/disk-io.h1
-rw-r--r--fs/btrfs/file.c1
-rw-r--r--fs/btrfs/inode.c12
-rw-r--r--fs/btrfs/transaction.c4
6 files changed, 26 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b55dba58dfaa..f0fb1978553c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -345,6 +345,7 @@ struct btrfs_fs_info {
345 struct completion kobj_unregister; 345 struct completion kobj_unregister;
346 int do_barriers; 346 int do_barriers;
347 int closing; 347 int closing;
348 unsigned long throttles;
348 349
349 u64 total_pinned; 350 u64 total_pinned;
350 spinlock_t delalloc_lock; 351 spinlock_t delalloc_lock;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 34cf1f1f47be..e0940a39ff07 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -631,6 +631,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
631 fs_info->tree_root = tree_root; 631 fs_info->tree_root = tree_root;
632 fs_info->extent_root = extent_root; 632 fs_info->extent_root = extent_root;
633 fs_info->sb = sb; 633 fs_info->sb = sb;
634 fs_info->throttles = 0;
634 fs_info->mount_opt = 0; 635 fs_info->mount_opt = 0;
635 fs_info->max_extent = (u64)-1; 636 fs_info->max_extent = (u64)-1;
636 fs_info->delalloc_bytes = 0; 637 fs_info->delalloc_bytes = 0;
@@ -889,6 +890,12 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
889 set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); 890 set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf);
890} 891}
891 892
893void btrfs_throttle(struct btrfs_root *root)
894{
895 if (root->fs_info->throttles)
896 congestion_wait(WRITE, HZ/10);
897}
898
892void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) 899void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
893{ 900{
894 balance_dirty_pages_ratelimited_nr( 901 balance_dirty_pages_ratelimited_nr(
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index dae9fba8efcd..828f3a2081b6 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -64,4 +64,5 @@ int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf);
64int btrfs_read_buffer(struct extent_buffer *buf); 64int btrfs_read_buffer(struct extent_buffer *buf);
65u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len); 65u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
66void btrfs_csum_final(u32 crc, char *result); 66void btrfs_csum_final(u32 crc, char *result);
67void btrfs_throttle(struct btrfs_root *root);
67#endif 68#endif
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 0a5f4defe59b..897242e87fa7 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -800,6 +800,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
800 balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages); 800 balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages);
801 if (num_pages < (root->leafsize >> PAGE_CACHE_SHIFT) + 1) 801 if (num_pages < (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
802 btrfs_btree_balance_dirty(root, 1); 802 btrfs_btree_balance_dirty(root, 1);
803 btrfs_throttle(root);
803 cond_resched(); 804 cond_resched();
804 } 805 }
805out: 806out:
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 10cece11dbd8..2cb2dd32407e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -610,6 +610,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
610fail: 610fail:
611 mutex_unlock(&root->fs_info->fs_mutex); 611 mutex_unlock(&root->fs_info->fs_mutex);
612 btrfs_btree_balance_dirty(root, nr); 612 btrfs_btree_balance_dirty(root, nr);
613 btrfs_throttle(root);
613 return ret; 614 return ret;
614} 615}
615 616
@@ -644,6 +645,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
644fail: 645fail:
645 mutex_unlock(&root->fs_info->fs_mutex); 646 mutex_unlock(&root->fs_info->fs_mutex);
646 btrfs_btree_balance_dirty(root, nr); 647 btrfs_btree_balance_dirty(root, nr);
648 btrfs_throttle(root);
647 649
648 if (ret && !err) 650 if (ret && !err)
649 err = ret; 651 err = ret;
@@ -1010,6 +1012,7 @@ void btrfs_delete_inode(struct inode *inode)
1010 btrfs_end_transaction(trans, root); 1012 btrfs_end_transaction(trans, root);
1011 mutex_unlock(&root->fs_info->fs_mutex); 1013 mutex_unlock(&root->fs_info->fs_mutex);
1012 btrfs_btree_balance_dirty(root, nr); 1014 btrfs_btree_balance_dirty(root, nr);
1015 btrfs_throttle(root);
1013 return; 1016 return;
1014 1017
1015no_delete_lock: 1018no_delete_lock:
@@ -1017,6 +1020,7 @@ no_delete_lock:
1017 btrfs_end_transaction(trans, root); 1020 btrfs_end_transaction(trans, root);
1018 mutex_unlock(&root->fs_info->fs_mutex); 1021 mutex_unlock(&root->fs_info->fs_mutex);
1019 btrfs_btree_balance_dirty(root, nr); 1022 btrfs_btree_balance_dirty(root, nr);
1023 btrfs_throttle(root);
1020no_delete: 1024no_delete:
1021 clear_inode(inode); 1025 clear_inode(inode);
1022} 1026}
@@ -1574,6 +1578,7 @@ fail:
1574 iput(inode); 1578 iput(inode);
1575 } 1579 }
1576 btrfs_btree_balance_dirty(root, nr); 1580 btrfs_btree_balance_dirty(root, nr);
1581 btrfs_throttle(root);
1577 return err; 1582 return err;
1578} 1583}
1579 1584
@@ -1633,6 +1638,7 @@ fail:
1633 iput(inode); 1638 iput(inode);
1634 } 1639 }
1635 btrfs_btree_balance_dirty(root, nr); 1640 btrfs_btree_balance_dirty(root, nr);
1641 btrfs_throttle(root);
1636 return err; 1642 return err;
1637} 1643}
1638 1644
@@ -1684,6 +1690,7 @@ fail:
1684 iput(inode); 1690 iput(inode);
1685 } 1691 }
1686 btrfs_btree_balance_dirty(root, nr); 1692 btrfs_btree_balance_dirty(root, nr);
1693 btrfs_throttle(root);
1687 return err; 1694 return err;
1688} 1695}
1689 1696
@@ -1752,6 +1759,7 @@ out_unlock:
1752 if (drop_on_err) 1759 if (drop_on_err)
1753 iput(inode); 1760 iput(inode);
1754 btrfs_btree_balance_dirty(root, nr); 1761 btrfs_btree_balance_dirty(root, nr);
1762 btrfs_throttle(root);
1755 return err; 1763 return err;
1756} 1764}
1757 1765
@@ -2117,6 +2125,7 @@ static void btrfs_truncate(struct inode *inode)
2117 BUG_ON(ret); 2125 BUG_ON(ret);
2118 mutex_unlock(&root->fs_info->fs_mutex); 2126 mutex_unlock(&root->fs_info->fs_mutex);
2119 btrfs_btree_balance_dirty(root, nr); 2127 btrfs_btree_balance_dirty(root, nr);
2128 btrfs_throttle(root);
2120} 2129}
2121 2130
2122static int noinline create_subvol(struct btrfs_root *root, char *name, 2131static int noinline create_subvol(struct btrfs_root *root, char *name,
@@ -2245,6 +2254,7 @@ fail:
2245fail_commit: 2254fail_commit:
2246 mutex_unlock(&root->fs_info->fs_mutex); 2255 mutex_unlock(&root->fs_info->fs_mutex);
2247 btrfs_btree_balance_dirty(root, nr); 2256 btrfs_btree_balance_dirty(root, nr);
2257 btrfs_throttle(root);
2248 return ret; 2258 return ret;
2249} 2259}
2250 2260
@@ -2287,6 +2297,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
2287fail_unlock: 2297fail_unlock:
2288 mutex_unlock(&root->fs_info->fs_mutex); 2298 mutex_unlock(&root->fs_info->fs_mutex);
2289 btrfs_btree_balance_dirty(root, nr); 2299 btrfs_btree_balance_dirty(root, nr);
2300 btrfs_throttle(root);
2290 return ret; 2301 return ret;
2291} 2302}
2292 2303
@@ -2827,6 +2838,7 @@ out_fail:
2827 iput(inode); 2838 iput(inode);
2828 } 2839 }
2829 btrfs_btree_balance_dirty(root, nr); 2840 btrfs_btree_balance_dirty(root, nr);
2841 btrfs_throttle(root);
2830 return err; 2842 return err;
2831} 2843}
2832 2844
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index dc9865323e38..614903f5c884 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -424,6 +424,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
424 424
425 num_bytes = btrfs_root_used(&dirty->root->root_item); 425 num_bytes = btrfs_root_used(&dirty->root->root_item);
426 root = dirty->latest_root; 426 root = dirty->latest_root;
427 root->fs_info->throttles++;
427 428
428 while(1) { 429 while(1) {
429 trans = btrfs_start_transaction(tree_root, 1); 430 trans = btrfs_start_transaction(tree_root, 1);
@@ -447,6 +448,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
447 mutex_lock(&tree_root->fs_info->fs_mutex); 448 mutex_lock(&tree_root->fs_info->fs_mutex);
448 } 449 }
449 BUG_ON(ret); 450 BUG_ON(ret);
451 root->fs_info->throttles--;
450 452
451 num_bytes -= btrfs_root_used(&dirty->root->root_item); 453 num_bytes -= btrfs_root_used(&dirty->root->root_item);
452 bytes_used = btrfs_root_used(&root->root_item); 454 bytes_used = btrfs_root_used(&root->root_item);
@@ -484,6 +486,7 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
484 u64 objectid = 0; 486 u64 objectid = 0;
485 int ret; 487 int ret;
486 488
489 root->fs_info->throttles++;
487 while(1) { 490 while(1) {
488 ret = btrfs_find_first_ordered_inode( 491 ret = btrfs_find_first_ordered_inode(
489 &cur_trans->ordered_inode_tree, 492 &cur_trans->ordered_inode_tree,
@@ -523,6 +526,7 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
523 mutex_lock(&root->fs_info->fs_mutex); 526 mutex_lock(&root->fs_info->fs_mutex);
524 mutex_lock(&root->fs_info->trans_mutex); 527 mutex_lock(&root->fs_info->trans_mutex);
525 } 528 }
529 root->fs_info->throttles--;
526 return 0; 530 return 0;
527} 531}
528 532