2 * Copyright (C) 2007 Oracle. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
19 #define _XOPEN_SOURCE 600
23 #include <sys/types.h>
27 #include "kerncompat.h"
28 #include "radix-tree.h"
31 #include "transaction.h"
34 static u64 allocated_bytes
= 0;
35 int cache_max
= 10000;
37 int btrfs_map_bh_to_logical(struct btrfs_root
*root
, struct btrfs_buffer
*bh
,
40 bh
->fd
= root
->fs_info
->fp
;
41 bh
->dev_bytenr
= logical
;
45 static int check_tree_block(struct btrfs_root
*root
, struct btrfs_buffer
*buf
)
47 if (buf
->bytenr
!= btrfs_header_bytenr(&buf
->node
.header
))
49 if (memcmp(root
->fs_info
->disk_super
->fsid
, buf
->node
.header
.fsid
,
50 sizeof(buf
->node
.header
.fsid
)))
55 static int free_some_buffers(struct btrfs_root
*root
)
57 struct list_head
*node
, *next
;
58 struct btrfs_buffer
*b
;
59 if (root
->fs_info
->cache_size
< cache_max
)
61 list_for_each_safe(node
, next
, &root
->fs_info
->cache
) {
62 b
= list_entry(node
, struct btrfs_buffer
, cache
);
64 BUG_ON(!list_empty(&b
->dirty
));
65 list_del_init(&b
->cache
);
66 btrfs_block_release(root
, b
);
67 if (root
->fs_info
->cache_size
< cache_max
)
74 struct btrfs_buffer
*alloc_tree_block(struct btrfs_root
*root
, u64 bytenr
,
77 struct btrfs_buffer
*buf
;
80 buf
= malloc(sizeof(struct btrfs_buffer
) + blocksize
);
83 allocated_bytes
+= blocksize
;
87 buf
->size
= blocksize
;
88 buf
->cache_node
.start
= bytenr
;
89 buf
->cache_node
.size
= blocksize
;
91 INIT_LIST_HEAD(&buf
->dirty
);
92 free_some_buffers(root
);
94 ret
= insert_existing_cache_extent(&root
->fs_info
->extent_cache
,
97 list_add_tail(&buf
->cache
, &root
->fs_info
->cache
);
98 root
->fs_info
->cache_size
+= blocksize
;
106 struct btrfs_buffer
*find_tree_block(struct btrfs_root
*root
, u64 bytenr
,
109 struct btrfs_buffer
*buf
;
110 struct cache_extent
*cache
;
112 cache
= find_cache_extent(&root
->fs_info
->extent_cache
,
115 buf
= container_of(cache
, struct btrfs_buffer
, cache_node
);
118 buf
= alloc_tree_block(root
, bytenr
, blocksize
);
127 struct btrfs_buffer
*read_tree_block(struct btrfs_root
*root
, u64 bytenr
,
130 struct btrfs_buffer
*buf
;
132 struct cache_extent
*cache
;
134 cache
= find_cache_extent(&root
->fs_info
->extent_cache
,
137 buf
= container_of(cache
, struct btrfs_buffer
, cache_node
);
139 if (check_tree_block(root
, buf
))
142 buf
= alloc_tree_block(root
, bytenr
, blocksize
);
145 btrfs_map_bh_to_logical(root
, buf
, bytenr
);
146 ret
= pread(buf
->fd
, &buf
->node
, blocksize
,
148 if (ret
!= blocksize
) {
152 if (check_tree_block(root
, buf
))
158 int dirty_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
159 struct btrfs_buffer
*buf
)
161 if (!list_empty(&buf
->dirty
))
163 list_add_tail(&buf
->dirty
, &root
->fs_info
->trans
);
165 if (check_tree_block(root
, buf
))
170 int clean_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
171 struct btrfs_buffer
*buf
)
173 if (!list_empty(&buf
->dirty
)) {
174 list_del_init(&buf
->dirty
);
175 btrfs_block_release(root
, buf
);
180 int btrfs_csum_node(struct btrfs_root
*root
, struct btrfs_node
*node
)
183 size_t len
= btrfs_level_size(root
, btrfs_header_level(&node
->header
)) -
186 crc
= crc32c(crc
, (char *)(node
) + BTRFS_CSUM_SIZE
, len
);
187 crc
= ~cpu_to_le32(crc
);
188 memcpy(node
->header
.csum
, &crc
, BTRFS_CRC32_SIZE
);
192 int btrfs_csum_super(struct btrfs_root
*root
, struct btrfs_super_block
*super
)
196 size_t len
= 512 - BTRFS_CSUM_SIZE
;
198 memset(block
, 0, 512);
199 memcpy(block
, super
, sizeof(*super
));
201 crc
= crc32c(crc
, block
+ BTRFS_CSUM_SIZE
, len
);
202 crc
= ~cpu_to_le32(crc
);
203 memcpy(super
->csum
, &crc
, BTRFS_CRC32_SIZE
);
207 int write_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
208 struct btrfs_buffer
*buf
)
212 if (buf
->bytenr
!= btrfs_header_bytenr(&buf
->node
.header
))
214 btrfs_map_bh_to_logical(root
, buf
, buf
->bytenr
);
215 if (check_tree_block(root
, buf
))
218 btrfs_csum_node(root
, &buf
->node
);
220 ret
= pwrite(buf
->fd
, &buf
->node
, buf
->size
,
222 if (ret
!= buf
->size
)
227 static int __commit_transaction(struct btrfs_trans_handle
*trans
, struct
230 struct btrfs_buffer
*b
;
233 while(!list_empty(&root
->fs_info
->trans
)) {
234 b
= list_entry(root
->fs_info
->trans
.next
, struct btrfs_buffer
,
236 list_del_init(&b
->dirty
);
237 wret
= write_tree_block(trans
, root
, b
);
240 btrfs_block_release(root
, b
);
245 static int commit_tree_roots(struct btrfs_trans_handle
*trans
,
246 struct btrfs_fs_info
*fs_info
)
249 u64 old_extent_bytenr
;
250 struct btrfs_root
*tree_root
= fs_info
->tree_root
;
251 struct btrfs_root
*extent_root
= fs_info
->extent_root
;
253 btrfs_write_dirty_block_groups(trans
, fs_info
->extent_root
);
255 old_extent_bytenr
= btrfs_root_bytenr(&extent_root
->root_item
);
256 if (old_extent_bytenr
== extent_root
->node
->bytenr
)
258 btrfs_set_root_bytenr(&extent_root
->root_item
,
259 extent_root
->node
->bytenr
);
260 extent_root
->root_item
.level
=
261 btrfs_header_level(&extent_root
->node
->node
.header
);
262 ret
= btrfs_update_root(trans
, tree_root
,
263 &extent_root
->root_key
,
264 &extent_root
->root_item
);
266 btrfs_write_dirty_block_groups(trans
, fs_info
->extent_root
);
271 int btrfs_commit_transaction(struct btrfs_trans_handle
*trans
, struct
272 btrfs_root
*root
, struct btrfs_super_block
*s
)
275 struct btrfs_buffer
*snap
= root
->commit_root
;
276 struct btrfs_key snap_key
;
278 if (root
->commit_root
== root
->node
)
281 memcpy(&snap_key
, &root
->root_key
, sizeof(snap_key
));
282 root
->root_key
.offset
++;
284 btrfs_set_root_bytenr(&root
->root_item
, root
->node
->bytenr
);
285 root
->root_item
.level
=
286 btrfs_header_level(&root
->node
->node
.header
);
287 ret
= btrfs_insert_root(trans
, root
->fs_info
->tree_root
,
288 &root
->root_key
, &root
->root_item
);
291 ret
= commit_tree_roots(trans
, root
->fs_info
);
294 ret
= __commit_transaction(trans
, root
);
297 write_ctree_super(trans
, root
, s
);
298 btrfs_finish_extent_commit(trans
, root
->fs_info
->extent_root
);
299 btrfs_finish_extent_commit(trans
, root
->fs_info
->tree_root
);
301 root
->commit_root
= root
->node
;
303 ret
= btrfs_drop_snapshot(trans
, root
, snap
);
306 ret
= btrfs_del_root(trans
, root
->fs_info
->tree_root
, &snap_key
);
308 root
->fs_info
->generation
= root
->root_key
.offset
+ 1;
313 static int __setup_root(struct btrfs_super_block
*super
,
314 struct btrfs_root
*root
,
315 struct btrfs_fs_info
*fs_info
,
316 u64 objectid
, int fp
)
319 root
->commit_root
= NULL
;
320 root
->sectorsize
= btrfs_super_sectorsize(super
);
321 root
->nodesize
= btrfs_super_nodesize(super
);
322 root
->leafsize
= btrfs_super_leafsize(super
);
324 root
->fs_info
= fs_info
;
325 memset(&root
->root_key
, 0, sizeof(root
->root_key
));
326 memset(&root
->root_item
, 0, sizeof(root
->root_item
));
327 root
->root_key
.objectid
= objectid
;
331 struct btrfs_buffer
*read_root_block(struct btrfs_root
*root
, u64 bytenr
,
334 struct btrfs_buffer
*node
;
335 u32 size
= btrfs_level_size(root
, level
);
337 node
= read_tree_block(root
, bytenr
, size
);
342 static int find_and_setup_root(struct btrfs_super_block
*super
,
343 struct btrfs_root
*tree_root
,
344 struct btrfs_fs_info
*fs_info
,
346 struct btrfs_root
*root
, int fp
)
350 __setup_root(super
, root
, fs_info
, objectid
, fp
);
351 ret
= btrfs_find_last_root(tree_root
, objectid
,
352 &root
->root_item
, &root
->root_key
);
354 root
->node
= read_root_block(root
,
355 btrfs_root_bytenr(&root
->root_item
),
356 root
->root_item
.level
);
361 struct btrfs_root
*open_ctree(char *filename
, struct btrfs_super_block
*super
)
365 fp
= open(filename
, O_CREAT
| O_RDWR
, 0600);
369 return open_ctree_fd(fp
, super
);
372 struct btrfs_root
*open_ctree_fd(int fp
, struct btrfs_super_block
*super
)
374 struct btrfs_root
*root
= malloc(sizeof(struct btrfs_root
));
375 struct btrfs_root
*extent_root
= malloc(sizeof(struct btrfs_root
));
376 struct btrfs_root
*tree_root
= malloc(sizeof(struct btrfs_root
));
377 struct btrfs_fs_info
*fs_info
= malloc(sizeof(*fs_info
));
380 INIT_LIST_HEAD(&fs_info
->trans
);
381 INIT_LIST_HEAD(&fs_info
->cache
);
382 cache_tree_init(&fs_info
->extent_cache
);
383 cache_tree_init(&fs_info
->pending_tree
);
384 cache_tree_init(&fs_info
->pinned_tree
);
385 cache_tree_init(&fs_info
->del_pending
);
386 cache_tree_init(&fs_info
->block_group_cache
);
387 fs_info
->cache_size
= 0;
389 fs_info
->running_transaction
= NULL
;
390 fs_info
->fs_root
= root
;
391 fs_info
->tree_root
= tree_root
;
392 fs_info
->extent_root
= extent_root
;
393 fs_info
->last_inode_alloc
= 0;
394 fs_info
->last_inode_alloc_dirid
= 0;
395 fs_info
->disk_super
= super
;
396 memset(&fs_info
->last_insert
, 0, sizeof(fs_info
->last_insert
));
398 ret
= pread(fp
, super
, sizeof(struct btrfs_super_block
),
399 BTRFS_SUPER_INFO_OFFSET
);
400 if (ret
== 0 || btrfs_super_root(super
) == 0) {
406 __setup_root(super
, tree_root
, fs_info
, BTRFS_ROOT_TREE_OBJECTID
, fp
);
407 tree_root
->node
= read_root_block(tree_root
, btrfs_super_root(super
),
408 btrfs_super_root_level(super
));
409 BUG_ON(!tree_root
->node
);
411 ret
= find_and_setup_root(super
, tree_root
, fs_info
,
412 BTRFS_EXTENT_TREE_OBJECTID
, extent_root
, fp
);
415 ret
= find_and_setup_root(super
, tree_root
, fs_info
,
416 BTRFS_FS_TREE_OBJECTID
, root
, fp
);
419 root
->commit_root
= root
->node
;
422 root
->fs_info
->generation
= root
->root_key
.offset
+ 1;
423 btrfs_read_block_groups(root
);
427 int write_ctree_super(struct btrfs_trans_handle
*trans
, struct btrfs_root
428 *root
, struct btrfs_super_block
*s
)
432 btrfs_set_super_root(s
, root
->fs_info
->tree_root
->node
->bytenr
);
433 btrfs_set_super_root_level(s
,
434 btrfs_header_level(&root
->fs_info
->tree_root
->node
->node
.header
));
435 btrfs_csum_super(root
, s
);
437 ret
= pwrite(root
->fs_info
->fp
, s
, sizeof(*s
),
438 BTRFS_SUPER_INFO_OFFSET
);
439 if (ret
!= sizeof(*s
)) {
440 fprintf(stderr
, "failed to write new super block err %d\n", ret
);
446 static int drop_cache(struct btrfs_root
*root
)
448 while(!list_empty(&root
->fs_info
->cache
)) {
449 struct btrfs_buffer
*b
= list_entry(root
->fs_info
->cache
.next
,
452 list_del_init(&b
->cache
);
453 btrfs_block_release(root
, b
);
458 int close_ctree(struct btrfs_root
*root
, struct btrfs_super_block
*s
)
461 struct btrfs_trans_handle
*trans
;
463 trans
= root
->fs_info
->running_transaction
;
464 btrfs_commit_transaction(trans
, root
, s
);
465 ret
= commit_tree_roots(trans
, root
->fs_info
);
467 ret
= __commit_transaction(trans
, root
);
469 write_ctree_super(trans
, root
, s
);
471 BUG_ON(!list_empty(&root
->fs_info
->trans
));
473 btrfs_free_block_groups(root
->fs_info
);
474 close(root
->fs_info
->fp
);
476 btrfs_block_release(root
, root
->node
);
477 if (root
->fs_info
->extent_root
->node
)
478 btrfs_block_release(root
->fs_info
->extent_root
,
479 root
->fs_info
->extent_root
->node
);
480 if (root
->fs_info
->tree_root
->node
)
481 btrfs_block_release(root
->fs_info
->tree_root
,
482 root
->fs_info
->tree_root
->node
);
483 btrfs_block_release(root
, root
->commit_root
);
485 printf("on close %llu blocks are allocated\n",
486 (unsigned long long)allocated_bytes
);
490 void btrfs_block_release(struct btrfs_root
*root
, struct btrfs_buffer
*buf
)
495 if (buf
->count
== 0) {
496 BUG_ON(!list_empty(&buf
->cache
));
497 BUG_ON(!list_empty(&buf
->dirty
));
499 remove_cache_extent(&root
->fs_info
->extent_cache
,
501 BUG_ON(allocated_bytes
== 0);
502 allocated_bytes
-= buf
->size
;
503 BUG_ON(root
->fs_info
->cache_size
== 0);
504 root
->fs_info
->cache_size
-= buf
->size
;
506 memset(buf
, 0, sizeof(*buf
));