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
;
89 INIT_LIST_HEAD(&buf
->dirty
);
90 free_some_buffers(root
);
91 radix_tree_preload(GFP_KERNEL
);
92 ret
= radix_tree_insert(&root
->fs_info
->cache_radix
, bytenr
, buf
);
93 radix_tree_preload_end();
94 list_add_tail(&buf
->cache
, &root
->fs_info
->cache
);
95 root
->fs_info
->cache_size
+= blocksize
;
103 struct btrfs_buffer
*find_tree_block(struct btrfs_root
*root
, u64 bytenr
,
106 struct btrfs_buffer
*buf
;
107 buf
= radix_tree_lookup(&root
->fs_info
->cache_radix
, bytenr
);
111 buf
= alloc_tree_block(root
, bytenr
, blocksize
);
120 struct btrfs_buffer
*read_tree_block(struct btrfs_root
*root
, u64 bytenr
,
123 struct btrfs_buffer
*buf
;
125 buf
= radix_tree_lookup(&root
->fs_info
->cache_radix
, bytenr
);
128 if (check_tree_block(root
, buf
))
131 buf
= alloc_tree_block(root
, bytenr
, blocksize
);
134 btrfs_map_bh_to_logical(root
, buf
, bytenr
);
135 ret
= pread(buf
->fd
, &buf
->node
, blocksize
,
137 if (ret
!= blocksize
) {
141 if (check_tree_block(root
, buf
))
147 int dirty_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
148 struct btrfs_buffer
*buf
)
150 if (!list_empty(&buf
->dirty
))
152 list_add_tail(&buf
->dirty
, &root
->fs_info
->trans
);
154 if (check_tree_block(root
, buf
))
159 int clean_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
160 struct btrfs_buffer
*buf
)
162 if (!list_empty(&buf
->dirty
)) {
163 list_del_init(&buf
->dirty
);
164 btrfs_block_release(root
, buf
);
169 int btrfs_csum_node(struct btrfs_root
*root
, struct btrfs_node
*node
)
172 size_t len
= btrfs_level_size(root
, btrfs_header_level(&node
->header
)) -
175 crc
= crc32c(0, (char *)(node
) + BTRFS_CSUM_SIZE
, len
);
176 memcpy(node
->header
.csum
, &crc
, BTRFS_CRC32_SIZE
);
180 int btrfs_csum_super(struct btrfs_root
*root
, struct btrfs_super_block
*super
)
183 char block
[root
->sectorsize
];
184 size_t len
= root
->sectorsize
- BTRFS_CSUM_SIZE
;
186 memset(block
, 0, root
->sectorsize
);
187 memcpy(block
, super
, sizeof(*super
));
189 crc
= crc32c(0, block
+ BTRFS_CSUM_SIZE
, len
);
190 memcpy(super
->csum
, &crc
, BTRFS_CRC32_SIZE
);
194 int write_tree_block(struct btrfs_trans_handle
*trans
, struct btrfs_root
*root
,
195 struct btrfs_buffer
*buf
)
199 if (buf
->bytenr
!= btrfs_header_bytenr(&buf
->node
.header
))
201 btrfs_map_bh_to_logical(root
, buf
, buf
->bytenr
);
202 if (check_tree_block(root
, buf
))
205 btrfs_csum_node(root
, &buf
->node
);
207 ret
= pwrite(buf
->fd
, &buf
->node
, buf
->size
,
209 if (ret
!= buf
->size
)
214 static int __commit_transaction(struct btrfs_trans_handle
*trans
, struct
217 struct btrfs_buffer
*b
;
220 while(!list_empty(&root
->fs_info
->trans
)) {
221 b
= list_entry(root
->fs_info
->trans
.next
, struct btrfs_buffer
,
223 list_del_init(&b
->dirty
);
224 wret
= write_tree_block(trans
, root
, b
);
227 btrfs_block_release(root
, b
);
232 static int commit_tree_roots(struct btrfs_trans_handle
*trans
,
233 struct btrfs_fs_info
*fs_info
)
236 u64 old_extent_bytenr
;
237 struct btrfs_root
*tree_root
= fs_info
->tree_root
;
238 struct btrfs_root
*extent_root
= fs_info
->extent_root
;
240 btrfs_write_dirty_block_groups(trans
, fs_info
->extent_root
);
242 old_extent_bytenr
= btrfs_root_bytenr(&extent_root
->root_item
);
243 if (old_extent_bytenr
== extent_root
->node
->bytenr
)
245 btrfs_set_root_bytenr(&extent_root
->root_item
,
246 extent_root
->node
->bytenr
);
247 extent_root
->root_item
.level
=
248 btrfs_header_level(&extent_root
->node
->node
.header
);
249 ret
= btrfs_update_root(trans
, tree_root
,
250 &extent_root
->root_key
,
251 &extent_root
->root_item
);
253 btrfs_write_dirty_block_groups(trans
, fs_info
->extent_root
);
258 int btrfs_commit_transaction(struct btrfs_trans_handle
*trans
, struct
259 btrfs_root
*root
, struct btrfs_super_block
*s
)
262 struct btrfs_buffer
*snap
= root
->commit_root
;
263 struct btrfs_key snap_key
;
265 if (root
->commit_root
== root
->node
)
268 memcpy(&snap_key
, &root
->root_key
, sizeof(snap_key
));
269 root
->root_key
.offset
++;
271 btrfs_set_root_bytenr(&root
->root_item
, root
->node
->bytenr
);
272 root
->root_item
.level
=
273 btrfs_header_level(&root
->node
->node
.header
);
274 ret
= btrfs_insert_root(trans
, root
->fs_info
->tree_root
,
275 &root
->root_key
, &root
->root_item
);
278 ret
= commit_tree_roots(trans
, root
->fs_info
);
281 ret
= __commit_transaction(trans
, root
);
284 write_ctree_super(trans
, root
, s
);
285 btrfs_finish_extent_commit(trans
, root
->fs_info
->extent_root
);
286 btrfs_finish_extent_commit(trans
, root
->fs_info
->tree_root
);
288 root
->commit_root
= root
->node
;
290 ret
= btrfs_drop_snapshot(trans
, root
, snap
);
293 ret
= btrfs_del_root(trans
, root
->fs_info
->tree_root
, &snap_key
);
295 root
->fs_info
->generation
= root
->root_key
.offset
+ 1;
300 static int __setup_root(struct btrfs_super_block
*super
,
301 struct btrfs_root
*root
,
302 struct btrfs_fs_info
*fs_info
,
303 u64 objectid
, int fp
)
306 root
->commit_root
= NULL
;
307 root
->sectorsize
= btrfs_super_sectorsize(super
);
308 root
->nodesize
= btrfs_super_nodesize(super
);
309 root
->leafsize
= btrfs_super_leafsize(super
);
311 root
->fs_info
= fs_info
;
312 memset(&root
->root_key
, 0, sizeof(root
->root_key
));
313 memset(&root
->root_item
, 0, sizeof(root
->root_item
));
314 root
->root_key
.objectid
= objectid
;
318 struct btrfs_buffer
*read_root_block(struct btrfs_root
*root
, u64 bytenr
,
321 struct btrfs_buffer
*node
;
322 u32 size
= btrfs_level_size(root
, level
);
324 node
= read_tree_block(root
, bytenr
, size
);
329 static int find_and_setup_root(struct btrfs_super_block
*super
,
330 struct btrfs_root
*tree_root
,
331 struct btrfs_fs_info
*fs_info
,
333 struct btrfs_root
*root
, int fp
)
337 __setup_root(super
, root
, fs_info
, objectid
, fp
);
338 ret
= btrfs_find_last_root(tree_root
, objectid
,
339 &root
->root_item
, &root
->root_key
);
341 root
->node
= read_root_block(root
,
342 btrfs_root_bytenr(&root
->root_item
),
343 root
->root_item
.level
);
348 struct btrfs_root
*open_ctree(char *filename
, struct btrfs_super_block
*super
)
352 fp
= open(filename
, O_CREAT
| O_RDWR
, 0600);
356 return open_ctree_fd(fp
, super
);
359 struct btrfs_root
*open_ctree_fd(int fp
, struct btrfs_super_block
*super
)
361 struct btrfs_root
*root
= malloc(sizeof(struct btrfs_root
));
362 struct btrfs_root
*extent_root
= malloc(sizeof(struct btrfs_root
));
363 struct btrfs_root
*tree_root
= malloc(sizeof(struct btrfs_root
));
364 struct btrfs_fs_info
*fs_info
= malloc(sizeof(*fs_info
));
367 INIT_RADIX_TREE(&fs_info
->cache_radix
, GFP_KERNEL
);
368 INIT_RADIX_TREE(&fs_info
->block_group_radix
, GFP_KERNEL
);
369 INIT_LIST_HEAD(&fs_info
->trans
);
370 INIT_LIST_HEAD(&fs_info
->cache
);
371 pending_tree_init(&fs_info
->pending_tree
);
372 pending_tree_init(&fs_info
->pinned_tree
);
373 pending_tree_init(&fs_info
->del_pending
);
374 fs_info
->cache_size
= 0;
376 fs_info
->running_transaction
= NULL
;
377 fs_info
->fs_root
= root
;
378 fs_info
->tree_root
= tree_root
;
379 fs_info
->extent_root
= extent_root
;
380 fs_info
->last_inode_alloc
= 0;
381 fs_info
->last_inode_alloc_dirid
= 0;
382 fs_info
->disk_super
= super
;
383 memset(&fs_info
->last_insert
, 0, sizeof(fs_info
->last_insert
));
385 ret
= pread(fp
, super
, sizeof(struct btrfs_super_block
),
386 BTRFS_SUPER_INFO_OFFSET
);
387 if (ret
== 0 || btrfs_super_root(super
) == 0) {
393 __setup_root(super
, tree_root
, fs_info
, BTRFS_ROOT_TREE_OBJECTID
, fp
);
394 tree_root
->node
= read_root_block(tree_root
, btrfs_super_root(super
),
395 btrfs_super_root_level(super
));
396 BUG_ON(!tree_root
->node
);
398 ret
= find_and_setup_root(super
, tree_root
, fs_info
,
399 BTRFS_EXTENT_TREE_OBJECTID
, extent_root
, fp
);
402 ret
= find_and_setup_root(super
, tree_root
, fs_info
,
403 BTRFS_FS_TREE_OBJECTID
, root
, fp
);
406 root
->commit_root
= root
->node
;
409 root
->fs_info
->generation
= root
->root_key
.offset
+ 1;
410 btrfs_read_block_groups(root
);
414 int write_ctree_super(struct btrfs_trans_handle
*trans
, struct btrfs_root
415 *root
, struct btrfs_super_block
*s
)
419 btrfs_set_super_root(s
, root
->fs_info
->tree_root
->node
->bytenr
);
420 btrfs_set_super_root_level(s
,
421 btrfs_header_level(&root
->fs_info
->tree_root
->node
->node
.header
));
422 btrfs_csum_super(root
, s
);
424 ret
= pwrite(root
->fs_info
->fp
, s
, sizeof(*s
),
425 BTRFS_SUPER_INFO_OFFSET
);
426 if (ret
!= sizeof(*s
)) {
427 fprintf(stderr
, "failed to write new super block err %d\n", ret
);
433 static int drop_cache(struct btrfs_root
*root
)
435 while(!list_empty(&root
->fs_info
->cache
)) {
436 struct btrfs_buffer
*b
= list_entry(root
->fs_info
->cache
.next
,
439 list_del_init(&b
->cache
);
440 btrfs_block_release(root
, b
);
445 int close_ctree(struct btrfs_root
*root
, struct btrfs_super_block
*s
)
448 struct btrfs_trans_handle
*trans
;
450 trans
= root
->fs_info
->running_transaction
;
451 btrfs_commit_transaction(trans
, root
, s
);
452 ret
= commit_tree_roots(trans
, root
->fs_info
);
454 ret
= __commit_transaction(trans
, root
);
456 write_ctree_super(trans
, root
, s
);
458 BUG_ON(!list_empty(&root
->fs_info
->trans
));
460 btrfs_free_block_groups(root
->fs_info
);
461 close(root
->fs_info
->fp
);
463 btrfs_block_release(root
, root
->node
);
464 if (root
->fs_info
->extent_root
->node
)
465 btrfs_block_release(root
->fs_info
->extent_root
,
466 root
->fs_info
->extent_root
->node
);
467 if (root
->fs_info
->tree_root
->node
)
468 btrfs_block_release(root
->fs_info
->tree_root
,
469 root
->fs_info
->tree_root
->node
);
470 btrfs_block_release(root
, root
->commit_root
);
472 printf("on close %llu blocks are allocated\n",
473 (unsigned long long)allocated_bytes
);
477 void btrfs_block_release(struct btrfs_root
*root
, struct btrfs_buffer
*buf
)
482 if (buf
->count
== 0) {
483 BUG_ON(!list_empty(&buf
->cache
));
484 BUG_ON(!list_empty(&buf
->dirty
));
485 if (!radix_tree_lookup(&root
->fs_info
->cache_radix
,
489 radix_tree_delete(&root
->fs_info
->cache_radix
, buf
->bytenr
);
490 BUG_ON(allocated_bytes
== 0);
491 allocated_bytes
-= buf
->size
;
492 BUG_ON(root
->fs_info
->cache_size
== 0);
493 root
->fs_info
->cache_size
-= buf
->size
;
495 memset(buf
, 0, sizeof(*buf
));