提交 e2008b61 编写于 作者: C Chris Mason

Btrfs: Add some simple throttling to wait for data=ordered and snapshot deletion

Signed-off-by: NChris Mason <chris.mason@oracle.com>
上级 3063d29f
...@@ -345,6 +345,7 @@ struct btrfs_fs_info { ...@@ -345,6 +345,7 @@ struct btrfs_fs_info {
struct completion kobj_unregister; struct completion kobj_unregister;
int do_barriers; int do_barriers;
int closing; int closing;
unsigned long throttles;
u64 total_pinned; u64 total_pinned;
spinlock_t delalloc_lock; spinlock_t delalloc_lock;
......
...@@ -631,6 +631,7 @@ struct btrfs_root *open_ctree(struct super_block *sb) ...@@ -631,6 +631,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info->tree_root = tree_root; fs_info->tree_root = tree_root;
fs_info->extent_root = extent_root; fs_info->extent_root = extent_root;
fs_info->sb = sb; fs_info->sb = sb;
fs_info->throttles = 0;
fs_info->mount_opt = 0; fs_info->mount_opt = 0;
fs_info->max_extent = (u64)-1; fs_info->max_extent = (u64)-1;
fs_info->delalloc_bytes = 0; fs_info->delalloc_bytes = 0;
...@@ -889,6 +890,12 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) ...@@ -889,6 +890,12 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf);
} }
void btrfs_throttle(struct btrfs_root *root)
{
if (root->fs_info->throttles)
congestion_wait(WRITE, HZ/10);
}
void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
{ {
balance_dirty_pages_ratelimited_nr( balance_dirty_pages_ratelimited_nr(
......
...@@ -64,4 +64,5 @@ int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf); ...@@ -64,4 +64,5 @@ int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf);
int btrfs_read_buffer(struct extent_buffer *buf); int btrfs_read_buffer(struct extent_buffer *buf);
u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len); u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
void btrfs_csum_final(u32 crc, char *result); void btrfs_csum_final(u32 crc, char *result);
void btrfs_throttle(struct btrfs_root *root);
#endif #endif
...@@ -800,6 +800,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, ...@@ -800,6 +800,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages); balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages);
if (num_pages < (root->leafsize >> PAGE_CACHE_SHIFT) + 1) if (num_pages < (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
btrfs_btree_balance_dirty(root, 1); btrfs_btree_balance_dirty(root, 1);
btrfs_throttle(root);
cond_resched(); cond_resched();
} }
out: out:
......
...@@ -610,6 +610,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -610,6 +610,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
fail: fail:
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return ret; return ret;
} }
...@@ -644,6 +645,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -644,6 +645,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
fail: fail:
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
if (ret && !err) if (ret && !err)
err = ret; err = ret;
...@@ -1010,6 +1012,7 @@ void btrfs_delete_inode(struct inode *inode) ...@@ -1010,6 +1012,7 @@ void btrfs_delete_inode(struct inode *inode)
btrfs_end_transaction(trans, root); btrfs_end_transaction(trans, root);
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return; return;
no_delete_lock: no_delete_lock:
...@@ -1017,6 +1020,7 @@ void btrfs_delete_inode(struct inode *inode) ...@@ -1017,6 +1020,7 @@ void btrfs_delete_inode(struct inode *inode)
btrfs_end_transaction(trans, root); btrfs_end_transaction(trans, root);
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
no_delete: no_delete:
clear_inode(inode); clear_inode(inode);
} }
...@@ -1574,6 +1578,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -1574,6 +1578,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
iput(inode); iput(inode);
} }
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return err; return err;
} }
...@@ -1633,6 +1638,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, ...@@ -1633,6 +1638,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
iput(inode); iput(inode);
} }
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return err; return err;
} }
...@@ -1684,6 +1690,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -1684,6 +1690,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
iput(inode); iput(inode);
} }
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return err; return err;
} }
...@@ -1752,6 +1759,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1752,6 +1759,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (drop_on_err) if (drop_on_err)
iput(inode); iput(inode);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return err; return err;
} }
...@@ -2117,6 +2125,7 @@ static void btrfs_truncate(struct inode *inode) ...@@ -2117,6 +2125,7 @@ static void btrfs_truncate(struct inode *inode)
BUG_ON(ret); BUG_ON(ret);
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
} }
static int noinline create_subvol(struct btrfs_root *root, char *name, static int noinline create_subvol(struct btrfs_root *root, char *name,
...@@ -2245,6 +2254,7 @@ static int noinline create_subvol(struct btrfs_root *root, char *name, ...@@ -2245,6 +2254,7 @@ static int noinline create_subvol(struct btrfs_root *root, char *name,
fail_commit: fail_commit:
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return ret; return ret;
} }
...@@ -2287,6 +2297,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) ...@@ -2287,6 +2297,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
fail_unlock: fail_unlock:
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return ret; return ret;
} }
...@@ -2827,6 +2838,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -2827,6 +2838,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
iput(inode); iput(inode);
} }
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
btrfs_throttle(root);
return err; return err;
} }
......
...@@ -424,6 +424,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, ...@@ -424,6 +424,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
num_bytes = btrfs_root_used(&dirty->root->root_item); num_bytes = btrfs_root_used(&dirty->root->root_item);
root = dirty->latest_root; root = dirty->latest_root;
root->fs_info->throttles++;
while(1) { while(1) {
trans = btrfs_start_transaction(tree_root, 1); trans = btrfs_start_transaction(tree_root, 1);
...@@ -447,6 +448,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, ...@@ -447,6 +448,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
mutex_lock(&tree_root->fs_info->fs_mutex); mutex_lock(&tree_root->fs_info->fs_mutex);
} }
BUG_ON(ret); BUG_ON(ret);
root->fs_info->throttles--;
num_bytes -= btrfs_root_used(&dirty->root->root_item); num_bytes -= btrfs_root_used(&dirty->root->root_item);
bytes_used = btrfs_root_used(&root->root_item); bytes_used = btrfs_root_used(&root->root_item);
...@@ -484,6 +486,7 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans, ...@@ -484,6 +486,7 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
u64 objectid = 0; u64 objectid = 0;
int ret; int ret;
root->fs_info->throttles++;
while(1) { while(1) {
ret = btrfs_find_first_ordered_inode( ret = btrfs_find_first_ordered_inode(
&cur_trans->ordered_inode_tree, &cur_trans->ordered_inode_tree,
...@@ -523,6 +526,7 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans, ...@@ -523,6 +526,7 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans,
mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->fs_mutex);
mutex_lock(&root->fs_info->trans_mutex); mutex_lock(&root->fs_info->trans_mutex);
} }
root->fs_info->throttles--;
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册