1 #include <linux/module.h>
5 #include "transaction.h"
7 static int check_tree_block(struct btrfs_root
*root
, struct buffer_head
*buf
)
9 struct btrfs_node
*node
= btrfs_buffer_node(buf
);
10 if (buf
->b_blocknr
!= btrfs_header_blocknr(&node
->header
))
12 if (root
->node
&& btrfs_header_parentid(&node
->header
) !=
13 btrfs_header_parentid(btrfs_buffer_header(root
->node
))) {
19 struct buffer_head
*alloc_tree_block(struct btrfs_root
*root
, u64 blocknr
)
21 return sb_getblk(root
->fs_info
->sb
, blocknr
);
24 struct buffer_head
*find_tree_block(struct btrfs_root
*root
, u64 blocknr
)
26 return sb_getblk(root
->fs_info
->sb
, blocknr
);
29 struct buffer_head
*read_tree_block(struct btrfs_root
*root
, u64 blocknr
)
31 struct buffer_head
*buf
= sb_bread(root
->fs_info
->sb
, blocknr
);
35 if (check_tree_block(root
, buf
))
40 int dirty_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
41 struct buffer_head
*buf
)
43 mark_buffer_dirty(buf
);
47 int clean_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
48 struct buffer_head
*buf
)
50 clear_buffer_dirty(buf
);
54 static int __setup_root(struct btrfs_super_block
*super
,
55 struct btrfs_root
*root
,
56 struct btrfs_fs_info
*fs_info
,
60 root
->commit_root
= NULL
;
61 root
->blocksize
= btrfs_super_blocksize(super
);
63 root
->fs_info
= fs_info
;
64 memset(&root
->root_key
, 0, sizeof(root
->root_key
));
65 memset(&root
->root_item
, 0, sizeof(root
->root_item
));
69 static int find_and_setup_root(struct btrfs_super_block
*super
,
70 struct btrfs_root
*tree_root
,
71 struct btrfs_fs_info
*fs_info
,
73 struct btrfs_root
*root
)
77 __setup_root(super
, root
, fs_info
, objectid
);
78 ret
= btrfs_find_last_root(tree_root
, objectid
,
79 &root
->root_item
, &root
->root_key
);
82 root
->node
= read_tree_block(root
,
83 btrfs_root_blocknr(&root
->root_item
));
88 struct btrfs_root
*open_ctree(struct super_block
*sb
,
89 struct buffer_head
*sb_buffer
,
90 struct btrfs_super_block
*disk_super
)
92 struct btrfs_root
*root
= kmalloc(sizeof(struct btrfs_root
),
94 struct btrfs_root
*extent_root
= kmalloc(sizeof(struct btrfs_root
),
96 struct btrfs_root
*tree_root
= kmalloc(sizeof(struct btrfs_root
),
98 struct btrfs_root
*inode_root
= kmalloc(sizeof(struct btrfs_root
),
100 struct btrfs_fs_info
*fs_info
= kmalloc(sizeof(*fs_info
),
104 /* FIXME: don't be stupid */
105 if (!btrfs_super_root(disk_super
))
107 init_bit_radix(&fs_info
->pinned_radix
);
108 init_bit_radix(&fs_info
->pending_del_radix
);
109 fs_info
->running_transaction
= NULL
;
110 fs_info
->fs_root
= root
;
111 fs_info
->tree_root
= tree_root
;
112 fs_info
->extent_root
= extent_root
;
113 fs_info
->inode_root
= inode_root
;
114 fs_info
->last_inode_alloc
= 0;
115 fs_info
->last_inode_alloc_dirid
= 0;
116 fs_info
->disk_super
= disk_super
;
117 fs_info
->sb_buffer
= sb_buffer
;
119 mutex_init(&fs_info
->trans_mutex
);
120 mutex_init(&fs_info
->fs_mutex
);
121 memset(&fs_info
->current_insert
, 0, sizeof(fs_info
->current_insert
));
122 memset(&fs_info
->last_insert
, 0, sizeof(fs_info
->last_insert
));
124 __setup_root(disk_super
, tree_root
, fs_info
, BTRFS_ROOT_TREE_OBJECTID
);
125 tree_root
->node
= read_tree_block(tree_root
,
126 btrfs_super_root(disk_super
));
127 BUG_ON(!tree_root
->node
);
129 ret
= find_and_setup_root(disk_super
, tree_root
, fs_info
,
130 BTRFS_EXTENT_TREE_OBJECTID
, extent_root
);
133 ret
= find_and_setup_root(disk_super
, tree_root
, fs_info
,
134 BTRFS_INODE_MAP_OBJECTID
, inode_root
);
137 ret
= find_and_setup_root(disk_super
, tree_root
, fs_info
,
138 BTRFS_FS_TREE_OBJECTID
, root
);
141 root
->commit_root
= root
->node
;
144 root
->fs_info
->generation
= root
->root_key
.offset
+ 1;
148 int write_ctree_super(struct btrfs_trans_handle
*trans
, struct btrfs_root
151 struct buffer_head
*bh
= root
->fs_info
->sb_buffer
;
152 btrfs_set_super_root(root
->fs_info
->disk_super
,
153 root
->fs_info
->tree_root
->node
->b_blocknr
);
155 clear_buffer_dirty(bh
);
156 bh
->b_end_io
= end_buffer_write_sync
;
158 submit_bh(WRITE
, bh
);
160 if (!buffer_uptodate(bh
)) {
167 int close_ctree(struct btrfs_root
*root
)
170 struct btrfs_trans_handle
*trans
;
172 trans
= btrfs_start_transaction(root
, 1);
173 btrfs_commit_transaction(trans
, root
);
174 /* run commit again to drop the original snapshot */
175 trans
= btrfs_start_transaction(root
, 1);
176 btrfs_commit_transaction(trans
, root
);
177 ret
= btrfs_write_and_wait_transaction(NULL
, root
);
179 write_ctree_super(NULL
, root
);
182 btrfs_block_release(root
, root
->node
);
183 if (root
->fs_info
->extent_root
->node
)
184 btrfs_block_release(root
->fs_info
->extent_root
,
185 root
->fs_info
->extent_root
->node
);
186 if (root
->fs_info
->inode_root
->node
)
187 btrfs_block_release(root
->fs_info
->inode_root
,
188 root
->fs_info
->inode_root
->node
);
189 if (root
->fs_info
->tree_root
->node
)
190 btrfs_block_release(root
->fs_info
->tree_root
,
191 root
->fs_info
->tree_root
->node
);
192 btrfs_block_release(root
, root
->commit_root
);
193 btrfs_block_release(root
, root
->fs_info
->sb_buffer
);
194 kfree(root
->fs_info
->extent_root
);
195 kfree(root
->fs_info
->inode_root
);
196 kfree(root
->fs_info
->tree_root
);
197 kfree(root
->fs_info
);
202 void btrfs_block_release(struct btrfs_root
*root
, struct buffer_head
*buf
)