diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-22 15:59:16 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-22 15:59:16 -0400 |
commit | 79154b1b5bcf87903db7ff16a30b360b78d6fe4f (patch) | |
tree | 7c752c350abd28060c5bd7aa364323051aecac90 /fs/btrfs/disk-io.c | |
parent | e20d96d64f9cf9288ffecc9ad4714e91c3b97ca8 (diff) |
Btrfs: transaction rework
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 115 |
1 files changed, 9 insertions, 106 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index df2061a735cd..9cacca0c525c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -50,89 +50,6 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | ||
54 | struct buffer_head *buf) | ||
55 | { | ||
56 | mark_buffer_dirty(buf); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int __commit_transaction(struct btrfs_trans_handle *trans, struct | ||
61 | btrfs_root *root) | ||
62 | { | ||
63 | filemap_write_and_wait(root->fs_info->sb->s_bdev->bd_inode->i_mapping); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static int commit_tree_roots(struct btrfs_trans_handle *trans, | ||
68 | struct btrfs_fs_info *fs_info) | ||
69 | { | ||
70 | int ret; | ||
71 | u64 old_extent_block; | ||
72 | struct btrfs_root *tree_root = fs_info->tree_root; | ||
73 | struct btrfs_root *extent_root = fs_info->extent_root; | ||
74 | struct btrfs_root *inode_root = fs_info->inode_root; | ||
75 | |||
76 | btrfs_set_root_blocknr(&inode_root->root_item, | ||
77 | inode_root->node->b_blocknr); | ||
78 | ret = btrfs_update_root(trans, tree_root, | ||
79 | &inode_root->root_key, | ||
80 | &inode_root->root_item); | ||
81 | BUG_ON(ret); | ||
82 | while(1) { | ||
83 | old_extent_block = btrfs_root_blocknr(&extent_root->root_item); | ||
84 | if (old_extent_block == extent_root->node->b_blocknr) | ||
85 | break; | ||
86 | btrfs_set_root_blocknr(&extent_root->root_item, | ||
87 | extent_root->node->b_blocknr); | ||
88 | ret = btrfs_update_root(trans, tree_root, | ||
89 | &extent_root->root_key, | ||
90 | &extent_root->root_item); | ||
91 | BUG_ON(ret); | ||
92 | } | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct | ||
97 | btrfs_root *root, struct btrfs_super_block *s) | ||
98 | { | ||
99 | int ret = 0; | ||
100 | struct buffer_head *snap = root->commit_root; | ||
101 | struct btrfs_key snap_key; | ||
102 | |||
103 | if (root->commit_root == root->node) | ||
104 | return 0; | ||
105 | |||
106 | memcpy(&snap_key, &root->root_key, sizeof(snap_key)); | ||
107 | root->root_key.offset++; | ||
108 | |||
109 | btrfs_set_root_blocknr(&root->root_item, root->node->b_blocknr); | ||
110 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, | ||
111 | &root->root_key, &root->root_item); | ||
112 | BUG_ON(ret); | ||
113 | |||
114 | ret = commit_tree_roots(trans, root->fs_info); | ||
115 | BUG_ON(ret); | ||
116 | |||
117 | ret = __commit_transaction(trans, root); | ||
118 | BUG_ON(ret); | ||
119 | |||
120 | write_ctree_super(trans, root, s); | ||
121 | btrfs_finish_extent_commit(trans, root->fs_info->extent_root); | ||
122 | btrfs_finish_extent_commit(trans, root->fs_info->tree_root); | ||
123 | |||
124 | root->commit_root = root->node; | ||
125 | get_bh(root->node); | ||
126 | ret = btrfs_drop_snapshot(trans, root, snap); | ||
127 | BUG_ON(ret); | ||
128 | |||
129 | ret = btrfs_del_root(trans, root->fs_info->tree_root, &snap_key); | ||
130 | BUG_ON(ret); | ||
131 | root->fs_info->generation = root->root_key.offset + 1; | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | static int __setup_root(struct btrfs_super_block *super, | 53 | static int __setup_root(struct btrfs_super_block *super, |
137 | struct btrfs_root *root, | 54 | struct btrfs_root *root, |
138 | struct btrfs_fs_info *fs_info, | 55 | struct btrfs_fs_info *fs_info, |
@@ -197,6 +114,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
197 | fs_info->disk_super = disk_super; | 114 | fs_info->disk_super = disk_super; |
198 | fs_info->sb_buffer = sb_buffer; | 115 | fs_info->sb_buffer = sb_buffer; |
199 | fs_info->sb = sb; | 116 | fs_info->sb = sb; |
117 | mutex_init(&fs_info->trans_mutex); | ||
200 | memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert)); | 118 | memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert)); |
201 | memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); | 119 | memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); |
202 | 120 | ||
@@ -225,7 +143,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
225 | } | 143 | } |
226 | 144 | ||
227 | int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root | 145 | int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root |
228 | *root, struct btrfs_super_block *s) | 146 | *root) |
229 | { | 147 | { |
230 | return 0; | 148 | return 0; |
231 | #if 0 | 149 | #if 0 |
@@ -242,34 +160,19 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root | |||
242 | #endif | 160 | #endif |
243 | } | 161 | } |
244 | 162 | ||
245 | static int drop_cache(struct btrfs_root *root) | ||
246 | { | ||
247 | return 0; | ||
248 | #if 0 | ||
249 | while(!list_empty(&root->fs_info->cache)) { | ||
250 | struct buffer_head *b = list_entry(root->fs_info->cache.next, | ||
251 | struct buffer_head, | ||
252 | cache); | ||
253 | list_del_init(&b->cache); | ||
254 | btrfs_block_release(root, b); | ||
255 | } | ||
256 | return 0; | ||
257 | #endif | ||
258 | } | ||
259 | |||
260 | int close_ctree(struct btrfs_root *root) | 163 | int close_ctree(struct btrfs_root *root) |
261 | { | 164 | { |
262 | int ret; | 165 | int ret; |
263 | struct btrfs_trans_handle *trans; | 166 | struct btrfs_trans_handle *trans; |
264 | 167 | ||
265 | trans = root->fs_info->running_transaction; | 168 | trans = btrfs_start_transaction(root, 1); |
266 | btrfs_commit_transaction(trans, root, root->fs_info->disk_super); | 169 | btrfs_commit_transaction(trans, root); |
267 | ret = commit_tree_roots(trans, root->fs_info); | 170 | /* run commit again to drop the original snapshot */ |
268 | BUG_ON(ret); | 171 | trans = btrfs_start_transaction(root, 1); |
269 | ret = __commit_transaction(trans, root); | 172 | btrfs_commit_transaction(trans, root); |
173 | ret = btrfs_write_and_wait_transaction(NULL, root); | ||
270 | BUG_ON(ret); | 174 | BUG_ON(ret); |
271 | write_ctree_super(trans, root, root->fs_info->disk_super); | 175 | write_ctree_super(NULL, root); |
272 | drop_cache(root); | ||
273 | 176 | ||
274 | if (root->node) | 177 | if (root->node) |
275 | btrfs_block_release(root, root->node); | 178 | btrfs_block_release(root, root->node); |