mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
Btrfs: get forced transaction commits via workqueue
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
08607c1b18
commit
facda1e787
@ -283,6 +283,7 @@ struct btrfs_block_group_cache {
|
||||
struct crypto_hash;
|
||||
|
||||
struct btrfs_fs_info {
|
||||
spinlock_t hash_lock;
|
||||
struct btrfs_root *extent_root;
|
||||
struct btrfs_root *tree_root;
|
||||
struct btrfs_root *dev_root;
|
||||
@ -308,10 +309,11 @@ struct btrfs_fs_info {
|
||||
struct mutex trans_mutex;
|
||||
struct mutex fs_mutex;
|
||||
struct list_head trans_list;
|
||||
struct list_head dead_roots;
|
||||
struct crypto_hash *hash_tfm;
|
||||
struct delayed_work trans_work;
|
||||
spinlock_t hash_lock;
|
||||
int do_barriers;
|
||||
int closing;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -563,6 +563,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
|
||||
INIT_RADIX_TREE(&fs_info->block_group_radix, GFP_KERNEL);
|
||||
INIT_RADIX_TREE(&fs_info->block_group_data_radix, GFP_KERNEL);
|
||||
INIT_LIST_HEAD(&fs_info->trans_list);
|
||||
INIT_LIST_HEAD(&fs_info->dead_roots);
|
||||
sb_set_blocksize(sb, 4096);
|
||||
fs_info->running_transaction = NULL;
|
||||
fs_info->tree_root = tree_root;
|
||||
@ -577,6 +578,8 @@ struct btrfs_root *open_ctree(struct super_block *sb)
|
||||
fs_info->do_barriers = 1;
|
||||
fs_info->extent_tree_insert_nr = 0;
|
||||
fs_info->extent_tree_prealloc_nr = 0;
|
||||
fs_info->closing = 0;
|
||||
|
||||
INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner);
|
||||
BTRFS_I(fs_info->btree_inode)->root = tree_root;
|
||||
memset(&BTRFS_I(fs_info->btree_inode)->location, 0,
|
||||
@ -746,6 +749,7 @@ int close_ctree(struct btrfs_root *root)
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
|
||||
fs_info->closing = 1;
|
||||
btrfs_transaction_flush_work(root);
|
||||
mutex_lock(&fs_info->fs_mutex);
|
||||
trans = btrfs_start_transaction(root, 1);
|
||||
|
@ -12,12 +12,10 @@ static struct workqueue_struct *trans_wq;
|
||||
|
||||
#define BTRFS_ROOT_TRANS_TAG 0
|
||||
|
||||
#define TRANS_MAGIC 0xE1E10E
|
||||
static void put_transaction(struct btrfs_transaction *transaction)
|
||||
{
|
||||
WARN_ON(transaction->use_count == 0);
|
||||
transaction->use_count--;
|
||||
WARN_ON(transaction->magic != TRANS_MAGIC);
|
||||
if (transaction->use_count == 0) {
|
||||
WARN_ON(total_trans == 0);
|
||||
total_trans--;
|
||||
@ -42,7 +40,6 @@ static int join_transaction(struct btrfs_root *root)
|
||||
cur_trans->transid = root->fs_info->generation;
|
||||
init_waitqueue_head(&cur_trans->writer_wait);
|
||||
init_waitqueue_head(&cur_trans->commit_wait);
|
||||
cur_trans->magic = TRANS_MAGIC;
|
||||
cur_trans->in_commit = 0;
|
||||
cur_trans->use_count = 1;
|
||||
cur_trans->commit_done = 0;
|
||||
@ -83,7 +80,6 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
|
||||
h->block_group = NULL;
|
||||
root->fs_info->running_transaction->use_count++;
|
||||
mutex_unlock(&root->fs_info->trans_mutex);
|
||||
h->magic = h->magic2 = TRANS_MAGIC;
|
||||
return h;
|
||||
}
|
||||
|
||||
@ -92,8 +88,6 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
||||
{
|
||||
struct btrfs_transaction *cur_trans;
|
||||
|
||||
WARN_ON(trans->magic != TRANS_MAGIC);
|
||||
WARN_ON(trans->magic2 != TRANS_MAGIC);
|
||||
mutex_lock(&root->fs_info->trans_mutex);
|
||||
cur_trans = root->fs_info->running_transaction;
|
||||
WARN_ON(cur_trans->num_writers < 1);
|
||||
@ -257,8 +251,8 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
|
||||
struct dirty_root *dirty;
|
||||
struct btrfs_trans_handle *trans;
|
||||
int ret;
|
||||
|
||||
while(!list_empty(list)) {
|
||||
mutex_lock(&tree_root->fs_info->fs_mutex);
|
||||
dirty = list_entry(list->next, struct dirty_root, list);
|
||||
list_del_init(&dirty->list);
|
||||
trans = btrfs_start_transaction(tree_root, 1);
|
||||
@ -271,6 +265,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
|
||||
ret = btrfs_end_transaction(trans, tree_root);
|
||||
BUG_ON(ret);
|
||||
kfree(dirty);
|
||||
mutex_unlock(&tree_root->fs_info->fs_mutex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -346,10 +341,18 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
||||
wake_up(&cur_trans->commit_wait);
|
||||
put_transaction(cur_trans);
|
||||
put_transaction(cur_trans);
|
||||
if (root->fs_info->closing)
|
||||
list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots);
|
||||
else
|
||||
list_splice_init(&dirty_fs_roots, &root->fs_info->dead_roots);
|
||||
mutex_unlock(&root->fs_info->trans_mutex);
|
||||
kmem_cache_free(btrfs_trans_handle_cachep, trans);
|
||||
|
||||
drop_dirty_roots(root->fs_info->tree_root, &dirty_fs_roots);
|
||||
if (root->fs_info->closing) {
|
||||
mutex_unlock(&root->fs_info->fs_mutex);
|
||||
drop_dirty_roots(root->fs_info->tree_root, &dirty_fs_roots);
|
||||
mutex_lock(&root->fs_info->fs_mutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -362,11 +365,19 @@ void btrfs_transaction_cleaner(struct work_struct *work)
|
||||
struct btrfs_root *root = fs_info->tree_root;
|
||||
struct btrfs_transaction *cur;
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct list_head dirty_roots;
|
||||
unsigned long now;
|
||||
unsigned long delay = HZ * 30;
|
||||
int ret;
|
||||
|
||||
printk("btrfs transaction cleaner\n");
|
||||
INIT_LIST_HEAD(&dirty_roots);
|
||||
mutex_lock(&root->fs_info->trans_mutex);
|
||||
list_splice_init(&root->fs_info->dead_roots, &dirty_roots);
|
||||
mutex_unlock(&root->fs_info->trans_mutex);
|
||||
|
||||
if (!list_empty(&dirty_roots)) {
|
||||
drop_dirty_roots(root, &dirty_roots);
|
||||
}
|
||||
mutex_lock(&root->fs_info->fs_mutex);
|
||||
mutex_lock(&root->fs_info->trans_mutex);
|
||||
cur = root->fs_info->running_transaction;
|
||||
@ -381,7 +392,6 @@ printk("btrfs transaction cleaner\n");
|
||||
goto out;
|
||||
}
|
||||
mutex_unlock(&root->fs_info->trans_mutex);
|
||||
printk("forcing commit\n");
|
||||
trans = btrfs_start_transaction(root, 1);
|
||||
ret = btrfs_commit_transaction(trans, root);
|
||||
out:
|
||||
|
@ -8,7 +8,6 @@ struct btrfs_transaction {
|
||||
int in_commit;
|
||||
int use_count;
|
||||
int commit_done;
|
||||
int magic;
|
||||
struct list_head list;
|
||||
struct radix_tree_root dirty_pages;
|
||||
unsigned long start_time;
|
||||
@ -17,13 +16,11 @@ struct btrfs_transaction {
|
||||
};
|
||||
|
||||
struct btrfs_trans_handle {
|
||||
int magic;
|
||||
u64 transid;
|
||||
unsigned long blocks_reserved;
|
||||
unsigned long blocks_used;
|
||||
struct btrfs_transaction *transaction;
|
||||
struct btrfs_block_group_cache *block_group;
|
||||
int magic2;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user