diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-04-19 21:01:03 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-04-19 21:01:03 -0400 |
commit | 8fd17795b2261ecb1bad2a6df09ef14c4957a3fb (patch) | |
tree | baab31275c20f5848f11688678158cf50875834e /fs/btrfs/transaction.c | |
parent | 7e38180e207c8707691c12395e990a5d583c5e71 (diff) |
Btrfs: early fsync support
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8740752f3845..078cb9cbf9dd 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -19,6 +19,7 @@ static void put_transaction(struct btrfs_transaction *transaction) | |||
19 | if (transaction->use_count == 0) { | 19 | if (transaction->use_count == 0) { |
20 | WARN_ON(total_trans == 0); | 20 | WARN_ON(total_trans == 0); |
21 | total_trans--; | 21 | total_trans--; |
22 | list_del_init(&transaction->list); | ||
22 | memset(transaction, 0, sizeof(*transaction)); | 23 | memset(transaction, 0, sizeof(*transaction)); |
23 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 24 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
24 | } | 25 | } |
@@ -43,6 +44,7 @@ static int join_transaction(struct btrfs_root *root) | |||
43 | cur_trans->in_commit = 0; | 44 | cur_trans->in_commit = 0; |
44 | cur_trans->use_count = 1; | 45 | cur_trans->use_count = 1; |
45 | cur_trans->commit_done = 0; | 46 | cur_trans->commit_done = 0; |
47 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | ||
46 | } | 48 | } |
47 | cur_trans->num_writers++; | 49 | cur_trans->num_writers++; |
48 | return 0; | 50 | return 0; |
@@ -236,6 +238,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
236 | { | 238 | { |
237 | int ret = 0; | 239 | int ret = 0; |
238 | struct btrfs_transaction *cur_trans; | 240 | struct btrfs_transaction *cur_trans; |
241 | struct btrfs_transaction *prev_trans = NULL; | ||
239 | struct list_head dirty_fs_roots; | 242 | struct list_head dirty_fs_roots; |
240 | DEFINE_WAIT(wait); | 243 | DEFINE_WAIT(wait); |
241 | 244 | ||
@@ -272,13 +275,29 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
272 | BUG_ON(ret); | 275 | BUG_ON(ret); |
273 | cur_trans = root->fs_info->running_transaction; | 276 | cur_trans = root->fs_info->running_transaction; |
274 | root->fs_info->running_transaction = NULL; | 277 | root->fs_info->running_transaction = NULL; |
275 | btrfs_set_super_generation(root->fs_info->disk_super, | 278 | if (cur_trans->list.prev != &root->fs_info->trans_list) { |
276 | root->fs_info->generation + 1); | 279 | prev_trans = list_entry(cur_trans->list.prev, |
280 | struct btrfs_transaction, list); | ||
281 | if (prev_trans->commit_done) | ||
282 | prev_trans = NULL; | ||
283 | else | ||
284 | prev_trans->use_count++; | ||
285 | } | ||
277 | mutex_unlock(&root->fs_info->trans_mutex); | 286 | mutex_unlock(&root->fs_info->trans_mutex); |
287 | mutex_unlock(&root->fs_info->fs_mutex); | ||
278 | ret = btrfs_write_and_wait_transaction(trans, root); | 288 | ret = btrfs_write_and_wait_transaction(trans, root); |
289 | if (prev_trans) { | ||
290 | mutex_lock(&root->fs_info->trans_mutex); | ||
291 | wait_for_commit(root, prev_trans); | ||
292 | put_transaction(prev_trans); | ||
293 | mutex_unlock(&root->fs_info->trans_mutex); | ||
294 | } | ||
295 | btrfs_set_super_generation(root->fs_info->disk_super, | ||
296 | cur_trans->transid); | ||
279 | BUG_ON(ret); | 297 | BUG_ON(ret); |
280 | |||
281 | write_ctree_super(trans, root); | 298 | write_ctree_super(trans, root); |
299 | |||
300 | mutex_lock(&root->fs_info->fs_mutex); | ||
282 | btrfs_finish_extent_commit(trans, root); | 301 | btrfs_finish_extent_commit(trans, root); |
283 | mutex_lock(&root->fs_info->trans_mutex); | 302 | mutex_lock(&root->fs_info->trans_mutex); |
284 | cur_trans->commit_done = 1; | 303 | cur_trans->commit_done = 1; |