1 #include <linux/module.h>
5 #include "transaction.h"
8 static void put_transaction(struct btrfs_transaction
*transaction
)
10 transaction
->use_count
--;
11 if (transaction
->use_count
== 0)
15 static int join_transaction(struct btrfs_root
*root
)
17 struct btrfs_transaction
*cur_trans
;
18 cur_trans
= root
->fs_info
->running_transaction
;
20 cur_trans
= kmalloc(sizeof(*cur_trans
), GFP_NOFS
);
22 root
->fs_info
->running_transaction
= cur_trans
;
23 cur_trans
->num_writers
= 0;
24 cur_trans
->transid
= root
->root_key
.offset
+ 1;
25 init_waitqueue_head(&cur_trans
->writer_wait
);
26 init_waitqueue_head(&cur_trans
->commit_wait
);
27 cur_trans
->in_commit
= 0;
28 cur_trans
->use_count
= 1;
29 cur_trans
->commit_done
= 0;
31 cur_trans
->num_writers
++;
35 struct btrfs_trans_handle
*btrfs_start_transaction(struct btrfs_root
*root
,
38 struct btrfs_trans_handle
*h
= kmalloc(sizeof(*h
), GFP_NOFS
);
41 mutex_lock(&root
->fs_info
->trans_mutex
);
42 ret
= join_transaction(root
);
44 h
->transid
= root
->fs_info
->running_transaction
->transid
;
45 h
->transaction
= root
->fs_info
->running_transaction
;
46 h
->blocks_reserved
= num_blocks
;
48 root
->fs_info
->running_transaction
->use_count
++;
49 mutex_unlock(&root
->fs_info
->trans_mutex
);
53 int btrfs_end_transaction(struct btrfs_trans_handle
*trans
,
54 struct btrfs_root
*root
)
56 struct btrfs_transaction
*cur_trans
;
57 mutex_lock(&root
->fs_info
->trans_mutex
);
58 cur_trans
= root
->fs_info
->running_transaction
;
59 WARN_ON(cur_trans
->num_writers
< 1);
60 if (waitqueue_active(&cur_trans
->writer_wait
))
61 wake_up(&cur_trans
->writer_wait
);
62 cur_trans
->num_writers
--;
63 put_transaction(cur_trans
);
64 mutex_unlock(&root
->fs_info
->trans_mutex
);
70 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle
*trans
,
71 struct btrfs_root
*root
)
73 filemap_write_and_wait(root
->fs_info
->sb
->s_bdev
->bd_inode
->i_mapping
);
77 int btrfs_commit_tree_roots(struct btrfs_trans_handle
*trans
,
78 struct btrfs_root
*root
)
82 struct btrfs_fs_info
*fs_info
= root
->fs_info
;
83 struct btrfs_root
*tree_root
= fs_info
->tree_root
;
84 struct btrfs_root
*extent_root
= fs_info
->extent_root
;
85 struct btrfs_root
*inode_root
= fs_info
->inode_root
;
87 btrfs_set_root_blocknr(&inode_root
->root_item
,
88 inode_root
->node
->b_blocknr
);
89 ret
= btrfs_update_root(trans
, tree_root
,
90 &inode_root
->root_key
,
91 &inode_root
->root_item
);
94 old_extent_block
= btrfs_root_blocknr(&extent_root
->root_item
);
95 if (old_extent_block
== extent_root
->node
->b_blocknr
)
97 btrfs_set_root_blocknr(&extent_root
->root_item
,
98 extent_root
->node
->b_blocknr
);
99 ret
= btrfs_update_root(trans
, tree_root
,
100 &extent_root
->root_key
,
101 &extent_root
->root_item
);
107 static int wait_for_commit(struct btrfs_root
*root
,
108 struct btrfs_transaction
*commit
)
112 while(!commit
->commit_done
) {
113 prepare_to_wait(&commit
->commit_wait
, &wait
,
114 TASK_UNINTERRUPTIBLE
);
115 if (commit
->commit_done
)
117 mutex_unlock(&root
->fs_info
->trans_mutex
);
119 mutex_lock(&root
->fs_info
->trans_mutex
);
121 finish_wait(&commit
->commit_wait
, &wait
);
125 int btrfs_commit_transaction(struct btrfs_trans_handle
*trans
,
126 struct btrfs_root
*root
)
129 struct buffer_head
*snap
= root
->commit_root
;
130 struct btrfs_key snap_key
;
131 struct btrfs_transaction
*cur_trans
;
134 mutex_lock(&root
->fs_info
->trans_mutex
);
135 if (trans
->transaction
->in_commit
) {
136 cur_trans
= trans
->transaction
;
137 trans
->transaction
->use_count
++;
138 btrfs_end_transaction(trans
, root
);
139 ret
= wait_for_commit(root
, cur_trans
);
141 put_transaction(cur_trans
);
142 mutex_unlock(&root
->fs_info
->trans_mutex
);
145 while (trans
->transaction
->num_writers
> 1) {
146 prepare_to_wait(&trans
->transaction
->writer_wait
, &wait
,
147 TASK_UNINTERRUPTIBLE
);
148 if (trans
->transaction
->num_writers
<= 1)
150 mutex_unlock(&root
->fs_info
->trans_mutex
);
152 mutex_lock(&root
->fs_info
->trans_mutex
);
154 finish_wait(&trans
->transaction
->writer_wait
, &wait
);
156 cur_trans
= root
->fs_info
->running_transaction
;
157 root
->fs_info
->running_transaction
= NULL
;
159 if (root
->node
!= root
->commit_root
) {
160 memcpy(&snap_key
, &root
->root_key
, sizeof(snap_key
));
161 root
->root_key
.offset
++;
164 mutex_unlock(&root
->fs_info
->trans_mutex
);
166 if (btrfs_root_blocknr(&root
->root_item
) != root
->node
->b_blocknr
) {
167 btrfs_set_root_blocknr(&root
->root_item
, root
->node
->b_blocknr
);
168 ret
= btrfs_insert_root(trans
, root
->fs_info
->tree_root
,
169 &root
->root_key
, &root
->root_item
);
173 ret
= btrfs_commit_tree_roots(trans
, root
);
176 ret
= btrfs_write_and_wait_transaction(trans
, root
);
179 write_ctree_super(trans
, root
);
180 btrfs_finish_extent_commit(trans
, root
->fs_info
->extent_root
);
181 btrfs_finish_extent_commit(trans
, root
->fs_info
->tree_root
);
182 put_transaction(cur_trans
);
185 if (root
->node
!= root
->commit_root
) {
186 trans
= btrfs_start_transaction(root
, 1);
187 root
->commit_root
= root
->node
;
189 ret
= btrfs_drop_snapshot(trans
, root
, snap
);
192 ret
= btrfs_del_root(trans
, root
->fs_info
->tree_root
,
195 root
->fs_info
->generation
= root
->root_key
.offset
+ 1;
196 ret
= btrfs_end_transaction(trans
, root
);
This page took 0.039696 seconds and 5 git commands to generate.