aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-02 10:50:19 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-02 10:50:19 -0400
commit2c90e5d658424bc71b111eb5a972240d5d06fe86 (patch)
treef46b830654af0f67ef1691353fe4d79943a05465 /fs/btrfs/transaction.c
parentd6025579531b7ea170ba283b171ff7a6bf7d0e12 (diff)
Btrfs: still corruption hunting
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 84c4e278ce2e..72b52e1e0b1b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -5,13 +5,20 @@
5#include "transaction.h" 5#include "transaction.h"
6 6
7static int total_trans = 0; 7static int total_trans = 0;
8extern struct kmem_cache *btrfs_trans_handle_cachep;
9extern struct kmem_cache *btrfs_transaction_cachep;
10
11#define TRANS_MAGIC 0xE1E10E
8static void put_transaction(struct btrfs_transaction *transaction) 12static void put_transaction(struct btrfs_transaction *transaction)
9{ 13{
14 WARN_ON(transaction->use_count == 0);
10 transaction->use_count--; 15 transaction->use_count--;
16 WARN_ON(transaction->magic != TRANS_MAGIC);
11 if (transaction->use_count == 0) { 17 if (transaction->use_count == 0) {
12 WARN_ON(total_trans == 0); 18 WARN_ON(total_trans == 0);
13 total_trans--; 19 total_trans--;
14 kfree(transaction); 20 memset(transaction, 0, sizeof(*transaction));
21 kmem_cache_free(btrfs_transaction_cachep, transaction);
15 } 22 }
16} 23}
17 24
@@ -20,7 +27,8 @@ static int join_transaction(struct btrfs_root *root)
20 struct btrfs_transaction *cur_trans; 27 struct btrfs_transaction *cur_trans;
21 cur_trans = root->fs_info->running_transaction; 28 cur_trans = root->fs_info->running_transaction;
22 if (!cur_trans) { 29 if (!cur_trans) {
23 cur_trans = kmalloc(sizeof(*cur_trans), GFP_NOFS); 30 cur_trans = kmem_cache_alloc(btrfs_transaction_cachep,
31 GFP_NOFS);
24 total_trans++; 32 total_trans++;
25 BUG_ON(!cur_trans); 33 BUG_ON(!cur_trans);
26 root->fs_info->running_transaction = cur_trans; 34 root->fs_info->running_transaction = cur_trans;
@@ -28,6 +36,7 @@ static int join_transaction(struct btrfs_root *root)
28 cur_trans->transid = root->root_key.offset + 1; 36 cur_trans->transid = root->root_key.offset + 1;
29 init_waitqueue_head(&cur_trans->writer_wait); 37 init_waitqueue_head(&cur_trans->writer_wait);
30 init_waitqueue_head(&cur_trans->commit_wait); 38 init_waitqueue_head(&cur_trans->commit_wait);
39 cur_trans->magic = TRANS_MAGIC;
31 cur_trans->in_commit = 0; 40 cur_trans->in_commit = 0;
32 cur_trans->use_count = 1; 41 cur_trans->use_count = 1;
33 cur_trans->commit_done = 0; 42 cur_trans->commit_done = 0;
@@ -39,7 +48,8 @@ static int join_transaction(struct btrfs_root *root)
39struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, 48struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
40 int num_blocks) 49 int num_blocks)
41{ 50{
42 struct btrfs_trans_handle *h = kmalloc(sizeof(*h), GFP_NOFS); 51 struct btrfs_trans_handle *h =
52 kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
43 int ret; 53 int ret;
44 54
45 mutex_lock(&root->fs_info->trans_mutex); 55 mutex_lock(&root->fs_info->trans_mutex);
@@ -51,6 +61,7 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
51 h->blocks_used = 0; 61 h->blocks_used = 0;
52 root->fs_info->running_transaction->use_count++; 62 root->fs_info->running_transaction->use_count++;
53 mutex_unlock(&root->fs_info->trans_mutex); 63 mutex_unlock(&root->fs_info->trans_mutex);
64 h->magic = h->magic2 = TRANS_MAGIC;
54 return h; 65 return h;
55} 66}
56 67
@@ -58,6 +69,8 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
58 struct btrfs_root *root) 69 struct btrfs_root *root)
59{ 70{
60 struct btrfs_transaction *cur_trans; 71 struct btrfs_transaction *cur_trans;
72 WARN_ON(trans->magic != TRANS_MAGIC);
73 WARN_ON(trans->magic2 != TRANS_MAGIC);
61 mutex_lock(&root->fs_info->trans_mutex); 74 mutex_lock(&root->fs_info->trans_mutex);
62 cur_trans = root->fs_info->running_transaction; 75 cur_trans = root->fs_info->running_transaction;
63 WARN_ON(cur_trans->num_writers < 1); 76 WARN_ON(cur_trans->num_writers < 1);
@@ -67,7 +80,7 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
67 put_transaction(cur_trans); 80 put_transaction(cur_trans);
68 mutex_unlock(&root->fs_info->trans_mutex); 81 mutex_unlock(&root->fs_info->trans_mutex);
69 memset(trans, 0, sizeof(*trans)); 82 memset(trans, 0, sizeof(*trans));
70 kfree(trans); 83 kmem_cache_free(btrfs_trans_handle_cachep, trans);
71 return 0; 84 return 0;
72} 85}
73 86
@@ -75,7 +88,7 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
75int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 88int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
76 struct btrfs_root *root) 89 struct btrfs_root *root)
77{ 90{
78 filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); 91 filemap_write_and_wait(root->fs_info->sb->s_bdev->bd_inode->i_mapping);
79 return 0; 92 return 0;
80} 93}
81 94
@@ -137,6 +150,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
137 150
138 mutex_lock(&root->fs_info->trans_mutex); 151 mutex_lock(&root->fs_info->trans_mutex);
139 if (trans->transaction->in_commit) { 152 if (trans->transaction->in_commit) {
153printk("already in commit!, waiting\n");
140 cur_trans = trans->transaction; 154 cur_trans = trans->transaction;
141 trans->transaction->use_count++; 155 trans->transaction->use_count++;
142 btrfs_end_transaction(trans, root); 156 btrfs_end_transaction(trans, root);
@@ -146,7 +160,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
146 mutex_unlock(&root->fs_info->trans_mutex); 160 mutex_unlock(&root->fs_info->trans_mutex);
147 return 0; 161 return 0;
148 } 162 }
163 cur_trans = trans->transaction;
164 trans->transaction->in_commit = 1;
149 while (trans->transaction->num_writers > 1) { 165 while (trans->transaction->num_writers > 1) {
166 WARN_ON(cur_trans != trans->transaction);
150 prepare_to_wait(&trans->transaction->writer_wait, &wait, 167 prepare_to_wait(&trans->transaction->writer_wait, &wait,
151 TASK_UNINTERRUPTIBLE); 168 TASK_UNINTERRUPTIBLE);
152 if (trans->transaction->num_writers <= 1) 169 if (trans->transaction->num_writers <= 1)
@@ -154,15 +171,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
154 mutex_unlock(&root->fs_info->trans_mutex); 171 mutex_unlock(&root->fs_info->trans_mutex);
155 schedule(); 172 schedule();
156 mutex_lock(&root->fs_info->trans_mutex); 173 mutex_lock(&root->fs_info->trans_mutex);
174 finish_wait(&trans->transaction->writer_wait, &wait);
157 } 175 }
158 finish_wait(&trans->transaction->writer_wait, &wait); 176 finish_wait(&trans->transaction->writer_wait, &wait);
159 177 WARN_ON(cur_trans != trans->transaction);
160 if (root->node != root->commit_root) { 178 if (root->node != root->commit_root) {
161 memcpy(&snap_key, &root->root_key, sizeof(snap_key)); 179 memcpy(&snap_key, &root->root_key, sizeof(snap_key));
162 root->root_key.offset++; 180 root->root_key.offset++;
163 } 181 }
164 182
165
166 if (btrfs_root_blocknr(&root->root_item) != root->node->b_blocknr) { 183 if (btrfs_root_blocknr(&root->root_item) != root->node->b_blocknr) {
167 btrfs_set_root_blocknr(&root->root_item, root->node->b_blocknr); 184 btrfs_set_root_blocknr(&root->root_item, root->node->b_blocknr);
168 ret = btrfs_insert_root(trans, root->fs_info->tree_root, 185 ret = btrfs_insert_root(trans, root->fs_info->tree_root,
@@ -172,22 +189,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
172 189
173 ret = btrfs_commit_tree_roots(trans, root); 190 ret = btrfs_commit_tree_roots(trans, root);
174 BUG_ON(ret); 191 BUG_ON(ret);
175
176 cur_trans = root->fs_info->running_transaction; 192 cur_trans = root->fs_info->running_transaction;
177 root->fs_info->running_transaction = NULL; 193 root->fs_info->running_transaction = NULL;
178 mutex_unlock(&root->fs_info->trans_mutex); 194 mutex_unlock(&root->fs_info->trans_mutex);
179
180 ret = btrfs_write_and_wait_transaction(trans, root); 195 ret = btrfs_write_and_wait_transaction(trans, root);
181 BUG_ON(ret); 196 BUG_ON(ret);
182 197
183 write_ctree_super(trans, root); 198 write_ctree_super(trans, root);
184 btrfs_finish_extent_commit(trans, root); 199 btrfs_finish_extent_commit(trans, root);
185 mutex_lock(&root->fs_info->trans_mutex); 200 mutex_lock(&root->fs_info->trans_mutex);
201 cur_trans->commit_done = 1;
202 wake_up(&cur_trans->commit_wait);
186 put_transaction(cur_trans); 203 put_transaction(cur_trans);
187 put_transaction(cur_trans); 204 put_transaction(cur_trans);
188 mutex_unlock(&root->fs_info->trans_mutex); 205 mutex_unlock(&root->fs_info->trans_mutex);
189 kfree(trans); 206 kmem_cache_free(btrfs_trans_handle_cachep, trans);
190
191 if (root->node != root->commit_root) { 207 if (root->node != root->commit_root) {
192 trans = btrfs_start_transaction(root, 1); 208 trans = btrfs_start_transaction(root, 1);
193 snap = root->commit_root; 209 snap = root->commit_root;
@@ -203,7 +219,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
203 ret = btrfs_end_transaction(trans, root); 219 ret = btrfs_end_transaction(trans, root);
204 BUG_ON(ret); 220 BUG_ON(ret);
205 } 221 }
206
207 return ret; 222 return ret;
208} 223}
209 224