transaction.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include <linux/module.h>
  2. #include <linux/fs.h>
  3. #include "ctree.h"
  4. #include "disk-io.h"
  5. #include "transaction.h"
  6. static int total_trans = 0;
  7. static void put_transaction(struct btrfs_transaction *transaction)
  8. {
  9. transaction->use_count--;
  10. if (transaction->use_count == 0) {
  11. WARN_ON(total_trans == 0);
  12. total_trans--;
  13. kfree(transaction);
  14. }
  15. }
  16. static int join_transaction(struct btrfs_root *root)
  17. {
  18. struct btrfs_transaction *cur_trans;
  19. cur_trans = root->fs_info->running_transaction;
  20. if (!cur_trans) {
  21. cur_trans = kmalloc(sizeof(*cur_trans), GFP_NOFS);
  22. total_trans++;
  23. BUG_ON(!cur_trans);
  24. root->fs_info->running_transaction = cur_trans;
  25. cur_trans->num_writers = 0;
  26. cur_trans->transid = root->root_key.offset + 1;
  27. init_waitqueue_head(&cur_trans->writer_wait);
  28. init_waitqueue_head(&cur_trans->commit_wait);
  29. cur_trans->in_commit = 0;
  30. cur_trans->use_count = 1;
  31. cur_trans->commit_done = 0;
  32. }
  33. cur_trans->num_writers++;
  34. return 0;
  35. }
  36. struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
  37. int num_blocks)
  38. {
  39. struct btrfs_trans_handle *h = kmalloc(sizeof(*h), GFP_NOFS);
  40. int ret;
  41. mutex_lock(&root->fs_info->trans_mutex);
  42. ret = join_transaction(root);
  43. BUG_ON(ret);
  44. h->transid = root->fs_info->running_transaction->transid;
  45. h->transaction = root->fs_info->running_transaction;
  46. h->blocks_reserved = num_blocks;
  47. h->blocks_used = 0;
  48. root->fs_info->running_transaction->use_count++;
  49. mutex_unlock(&root->fs_info->trans_mutex);
  50. return h;
  51. }
  52. int btrfs_end_transaction(struct btrfs_trans_handle *trans,
  53. struct btrfs_root *root)
  54. {
  55. struct btrfs_transaction *cur_trans;
  56. mutex_lock(&root->fs_info->trans_mutex);
  57. cur_trans = root->fs_info->running_transaction;
  58. WARN_ON(cur_trans->num_writers < 1);
  59. if (waitqueue_active(&cur_trans->writer_wait))
  60. wake_up(&cur_trans->writer_wait);
  61. cur_trans->num_writers--;
  62. put_transaction(cur_trans);
  63. mutex_unlock(&root->fs_info->trans_mutex);
  64. memset(trans, 0, sizeof(*trans));
  65. kfree(trans);
  66. return 0;
  67. }
  68. int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
  69. struct btrfs_root *root)
  70. {
  71. filemap_write_and_wait(root->fs_info->btree_inode->i_mapping);
  72. return 0;
  73. }
  74. int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
  75. struct btrfs_root *root)
  76. {
  77. int ret;
  78. u64 old_extent_block;
  79. struct btrfs_fs_info *fs_info = root->fs_info;
  80. struct btrfs_root *tree_root = fs_info->tree_root;
  81. struct btrfs_root *extent_root = fs_info->extent_root;
  82. struct btrfs_root *inode_root = fs_info->inode_root;
  83. btrfs_set_root_blocknr(&inode_root->root_item,
  84. inode_root->node->b_blocknr);
  85. ret = btrfs_update_root(trans, tree_root,
  86. &inode_root->root_key,
  87. &inode_root->root_item);
  88. BUG_ON(ret);
  89. while(1) {
  90. old_extent_block = btrfs_root_blocknr(&extent_root->root_item);
  91. if (old_extent_block == extent_root->node->b_blocknr)
  92. break;
  93. btrfs_set_root_blocknr(&extent_root->root_item,
  94. extent_root->node->b_blocknr);
  95. ret = btrfs_update_root(trans, tree_root,
  96. &extent_root->root_key,
  97. &extent_root->root_item);
  98. BUG_ON(ret);
  99. }
  100. return 0;
  101. }
  102. static int wait_for_commit(struct btrfs_root *root,
  103. struct btrfs_transaction *commit)
  104. {
  105. DEFINE_WAIT(wait);
  106. while(!commit->commit_done) {
  107. prepare_to_wait(&commit->commit_wait, &wait,
  108. TASK_UNINTERRUPTIBLE);
  109. if (commit->commit_done)
  110. break;
  111. mutex_unlock(&root->fs_info->trans_mutex);
  112. schedule();
  113. mutex_lock(&root->fs_info->trans_mutex);
  114. }
  115. finish_wait(&commit->commit_wait, &wait);
  116. return 0;
  117. }
  118. int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
  119. struct btrfs_root *root)
  120. {
  121. int ret = 0;
  122. struct buffer_head *snap;
  123. struct btrfs_key snap_key;
  124. struct btrfs_transaction *cur_trans;
  125. DEFINE_WAIT(wait);
  126. mutex_lock(&root->fs_info->trans_mutex);
  127. if (trans->transaction->in_commit) {
  128. cur_trans = trans->transaction;
  129. trans->transaction->use_count++;
  130. btrfs_end_transaction(trans, root);
  131. ret = wait_for_commit(root, cur_trans);
  132. BUG_ON(ret);
  133. put_transaction(cur_trans);
  134. mutex_unlock(&root->fs_info->trans_mutex);
  135. return 0;
  136. }
  137. while (trans->transaction->num_writers > 1) {
  138. prepare_to_wait(&trans->transaction->writer_wait, &wait,
  139. TASK_UNINTERRUPTIBLE);
  140. if (trans->transaction->num_writers <= 1)
  141. break;
  142. mutex_unlock(&root->fs_info->trans_mutex);
  143. schedule();
  144. mutex_lock(&root->fs_info->trans_mutex);
  145. }
  146. finish_wait(&trans->transaction->writer_wait, &wait);
  147. if (root->node != root->commit_root) {
  148. memcpy(&snap_key, &root->root_key, sizeof(snap_key));
  149. root->root_key.offset++;
  150. }
  151. if (btrfs_root_blocknr(&root->root_item) != root->node->b_blocknr) {
  152. btrfs_set_root_blocknr(&root->root_item, root->node->b_blocknr);
  153. ret = btrfs_insert_root(trans, root->fs_info->tree_root,
  154. &root->root_key, &root->root_item);
  155. BUG_ON(ret);
  156. }
  157. ret = btrfs_commit_tree_roots(trans, root);
  158. BUG_ON(ret);
  159. cur_trans = root->fs_info->running_transaction;
  160. root->fs_info->running_transaction = NULL;
  161. mutex_unlock(&root->fs_info->trans_mutex);
  162. ret = btrfs_write_and_wait_transaction(trans, root);
  163. BUG_ON(ret);
  164. write_ctree_super(trans, root);
  165. btrfs_finish_extent_commit(trans, root);
  166. mutex_lock(&root->fs_info->trans_mutex);
  167. put_transaction(cur_trans);
  168. put_transaction(cur_trans);
  169. mutex_unlock(&root->fs_info->trans_mutex);
  170. kfree(trans);
  171. if (root->node != root->commit_root) {
  172. trans = btrfs_start_transaction(root, 1);
  173. snap = root->commit_root;
  174. root->commit_root = root->node;
  175. get_bh(root->node);
  176. ret = btrfs_drop_snapshot(trans, root, snap);
  177. BUG_ON(ret);
  178. ret = btrfs_del_root(trans, root->fs_info->tree_root,
  179. &snap_key);
  180. BUG_ON(ret);
  181. root->fs_info->generation = root->root_key.offset + 1;
  182. ret = btrfs_end_transaction(trans, root);
  183. BUG_ON(ret);
  184. }
  185. return ret;
  186. }