diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-09-05 16:13:11 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:07 -0400 |
commit | e02119d5a7b4396c5a872582fddc8bd6d305a70a (patch) | |
tree | 825efe2a79dbca8d61256183f3526a5b5dc40dc6 /fs/btrfs/ctree.h | |
parent | a1b32a5932cfac7c38b442582285f3da2a09dfd8 (diff) |
Btrfs: Add a write ahead tree log to optimize synchronous operations
File syncs and directory syncs are optimized by copying their
items into a special (copy-on-write) log tree. There is one log tree per
subvolume and the btrfs super block points to a tree of log tree roots.
After a crash, items are copied out of the log tree and back into the
subvolume. See tree-log.c for all the details.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.h')
-rw-r--r-- | fs/btrfs/ctree.h | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index b305ae7e10b0..6532b60683ef 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -77,6 +77,10 @@ struct btrfs_ordered_sum; | |||
77 | /* orhpan objectid for tracking unlinked/truncated files */ | 77 | /* orhpan objectid for tracking unlinked/truncated files */ |
78 | #define BTRFS_ORPHAN_OBJECTID -5ULL | 78 | #define BTRFS_ORPHAN_OBJECTID -5ULL |
79 | 79 | ||
80 | /* does write ahead logging to speed up fsyncs */ | ||
81 | #define BTRFS_TREE_LOG_OBJECTID -6ULL | ||
82 | #define BTRFS_TREE_LOG_FIXUP_OBJECTID -7ULL | ||
83 | |||
80 | /* | 84 | /* |
81 | * All files have objectids higher than this. | 85 | * All files have objectids higher than this. |
82 | */ | 86 | */ |
@@ -276,6 +280,7 @@ struct btrfs_super_block { | |||
276 | __le64 generation; | 280 | __le64 generation; |
277 | __le64 root; | 281 | __le64 root; |
278 | __le64 chunk_root; | 282 | __le64 chunk_root; |
283 | __le64 log_root; | ||
279 | __le64 total_bytes; | 284 | __le64 total_bytes; |
280 | __le64 bytes_used; | 285 | __le64 bytes_used; |
281 | __le64 root_dir_objectid; | 286 | __le64 root_dir_objectid; |
@@ -287,6 +292,7 @@ struct btrfs_super_block { | |||
287 | __le32 sys_chunk_array_size; | 292 | __le32 sys_chunk_array_size; |
288 | u8 root_level; | 293 | u8 root_level; |
289 | u8 chunk_root_level; | 294 | u8 chunk_root_level; |
295 | u8 log_root_level; | ||
290 | struct btrfs_dev_item dev_item; | 296 | struct btrfs_dev_item dev_item; |
291 | char label[BTRFS_LABEL_SIZE]; | 297 | char label[BTRFS_LABEL_SIZE]; |
292 | u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; | 298 | u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; |
@@ -392,7 +398,10 @@ struct btrfs_timespec { | |||
392 | * make a new item type | 398 | * make a new item type |
393 | */ | 399 | */ |
394 | struct btrfs_inode_item { | 400 | struct btrfs_inode_item { |
401 | /* nfs style generation number */ | ||
395 | __le64 generation; | 402 | __le64 generation; |
403 | /* transid that last touched this inode */ | ||
404 | __le64 transid; | ||
396 | __le64 size; | 405 | __le64 size; |
397 | __le64 nblocks; | 406 | __le64 nblocks; |
398 | __le64 block_group; | 407 | __le64 block_group; |
@@ -409,8 +418,13 @@ struct btrfs_inode_item { | |||
409 | struct btrfs_timespec otime; | 418 | struct btrfs_timespec otime; |
410 | } __attribute__ ((__packed__)); | 419 | } __attribute__ ((__packed__)); |
411 | 420 | ||
421 | struct btrfs_dir_log_item { | ||
422 | __le64 end; | ||
423 | } __attribute__ ((__packed__)); | ||
424 | |||
412 | struct btrfs_dir_item { | 425 | struct btrfs_dir_item { |
413 | struct btrfs_disk_key location; | 426 | struct btrfs_disk_key location; |
427 | __le64 transid; | ||
414 | __le16 data_len; | 428 | __le16 data_len; |
415 | __le16 name_len; | 429 | __le16 name_len; |
416 | u8 type; | 430 | u8 type; |
@@ -505,6 +519,9 @@ struct btrfs_fs_info { | |||
505 | struct btrfs_root *tree_root; | 519 | struct btrfs_root *tree_root; |
506 | struct btrfs_root *chunk_root; | 520 | struct btrfs_root *chunk_root; |
507 | struct btrfs_root *dev_root; | 521 | struct btrfs_root *dev_root; |
522 | |||
523 | /* the log root tree is a directory of all the other log roots */ | ||
524 | struct btrfs_root *log_root_tree; | ||
508 | struct radix_tree_root fs_roots_radix; | 525 | struct radix_tree_root fs_roots_radix; |
509 | 526 | ||
510 | struct extent_io_tree free_space_cache; | 527 | struct extent_io_tree free_space_cache; |
@@ -518,6 +535,7 @@ struct btrfs_fs_info { | |||
518 | 535 | ||
519 | u64 generation; | 536 | u64 generation; |
520 | u64 last_trans_committed; | 537 | u64 last_trans_committed; |
538 | u64 last_trans_new_blockgroup; | ||
521 | u64 open_ioctl_trans; | 539 | u64 open_ioctl_trans; |
522 | unsigned long mount_opt; | 540 | unsigned long mount_opt; |
523 | u64 max_extent; | 541 | u64 max_extent; |
@@ -527,6 +545,9 @@ struct btrfs_fs_info { | |||
527 | wait_queue_head_t transaction_throttle; | 545 | wait_queue_head_t transaction_throttle; |
528 | wait_queue_head_t transaction_wait; | 546 | wait_queue_head_t transaction_wait; |
529 | wait_queue_head_t async_submit_wait; | 547 | wait_queue_head_t async_submit_wait; |
548 | |||
549 | wait_queue_head_t tree_log_wait; | ||
550 | |||
530 | struct btrfs_super_block super_copy; | 551 | struct btrfs_super_block super_copy; |
531 | struct btrfs_super_block super_for_commit; | 552 | struct btrfs_super_block super_for_commit; |
532 | struct block_device *__bdev; | 553 | struct block_device *__bdev; |
@@ -535,6 +556,7 @@ struct btrfs_fs_info { | |||
535 | struct backing_dev_info bdi; | 556 | struct backing_dev_info bdi; |
536 | spinlock_t hash_lock; | 557 | spinlock_t hash_lock; |
537 | struct mutex trans_mutex; | 558 | struct mutex trans_mutex; |
559 | struct mutex tree_log_mutex; | ||
538 | struct mutex transaction_kthread_mutex; | 560 | struct mutex transaction_kthread_mutex; |
539 | struct mutex cleaner_mutex; | 561 | struct mutex cleaner_mutex; |
540 | struct mutex alloc_mutex; | 562 | struct mutex alloc_mutex; |
@@ -544,8 +566,13 @@ struct btrfs_fs_info { | |||
544 | struct list_head trans_list; | 566 | struct list_head trans_list; |
545 | struct list_head hashers; | 567 | struct list_head hashers; |
546 | struct list_head dead_roots; | 568 | struct list_head dead_roots; |
569 | |||
547 | atomic_t nr_async_submits; | 570 | atomic_t nr_async_submits; |
548 | atomic_t nr_async_bios; | 571 | atomic_t nr_async_bios; |
572 | atomic_t tree_log_writers; | ||
573 | atomic_t tree_log_commit; | ||
574 | unsigned long tree_log_batch; | ||
575 | u64 tree_log_transid; | ||
549 | 576 | ||
550 | /* | 577 | /* |
551 | * this is used by the balancing code to wait for all the pending | 578 | * this is used by the balancing code to wait for all the pending |
@@ -583,6 +610,7 @@ struct btrfs_fs_info { | |||
583 | struct completion kobj_unregister; | 610 | struct completion kobj_unregister; |
584 | int do_barriers; | 611 | int do_barriers; |
585 | int closing; | 612 | int closing; |
613 | int log_root_recovering; | ||
586 | atomic_t throttles; | 614 | atomic_t throttles; |
587 | atomic_t throttle_gen; | 615 | atomic_t throttle_gen; |
588 | 616 | ||
@@ -596,6 +624,7 @@ struct btrfs_fs_info { | |||
596 | u64 delalloc_bytes; | 624 | u64 delalloc_bytes; |
597 | u64 last_alloc; | 625 | u64 last_alloc; |
598 | u64 last_data_alloc; | 626 | u64 last_data_alloc; |
627 | u64 last_log_alloc; | ||
599 | 628 | ||
600 | spinlock_t ref_cache_lock; | 629 | spinlock_t ref_cache_lock; |
601 | u64 total_ref_cache_size; | 630 | u64 total_ref_cache_size; |
@@ -632,6 +661,7 @@ struct btrfs_root { | |||
632 | struct btrfs_leaf_ref_tree *ref_tree; | 661 | struct btrfs_leaf_ref_tree *ref_tree; |
633 | struct btrfs_leaf_ref_tree ref_tree_struct; | 662 | struct btrfs_leaf_ref_tree ref_tree_struct; |
634 | struct btrfs_dirty_root *dirty_root; | 663 | struct btrfs_dirty_root *dirty_root; |
664 | struct btrfs_root *log_root; | ||
635 | 665 | ||
636 | struct btrfs_root_item root_item; | 666 | struct btrfs_root_item root_item; |
637 | struct btrfs_key root_key; | 667 | struct btrfs_key root_key; |
@@ -640,6 +670,7 @@ struct btrfs_root { | |||
640 | struct kobject root_kobj; | 670 | struct kobject root_kobj; |
641 | struct completion kobj_unregister; | 671 | struct completion kobj_unregister; |
642 | struct mutex objectid_mutex; | 672 | struct mutex objectid_mutex; |
673 | struct mutex log_mutex; | ||
643 | 674 | ||
644 | u64 objectid; | 675 | u64 objectid; |
645 | u64 last_trans; | 676 | u64 last_trans; |
@@ -692,6 +723,8 @@ struct btrfs_root { | |||
692 | * dir items are the name -> inode pointers in a directory. There is one | 723 | * dir items are the name -> inode pointers in a directory. There is one |
693 | * for every name in a directory. | 724 | * for every name in a directory. |
694 | */ | 725 | */ |
726 | #define BTRFS_DIR_LOG_ITEM_KEY 14 | ||
727 | #define BTRFS_DIR_LOG_INDEX_KEY 15 | ||
695 | #define BTRFS_DIR_ITEM_KEY 16 | 728 | #define BTRFS_DIR_ITEM_KEY 16 |
696 | #define BTRFS_DIR_INDEX_KEY 17 | 729 | #define BTRFS_DIR_INDEX_KEY 17 |
697 | /* | 730 | /* |
@@ -703,7 +736,8 @@ struct btrfs_root { | |||
703 | */ | 736 | */ |
704 | #define BTRFS_CSUM_ITEM_KEY 19 | 737 | #define BTRFS_CSUM_ITEM_KEY 19 |
705 | 738 | ||
706 | /* reserve 20-31 for other file stuff */ | 739 | |
740 | /* reserve 21-31 for other file/dir stuff */ | ||
707 | 741 | ||
708 | /* | 742 | /* |
709 | * root items point to tree roots. There are typically in the root | 743 | * root items point to tree roots. There are typically in the root |
@@ -938,6 +972,7 @@ BTRFS_SETGET_FUNCS(inode_ref_index, struct btrfs_inode_ref, index, 64); | |||
938 | 972 | ||
939 | /* struct btrfs_inode_item */ | 973 | /* struct btrfs_inode_item */ |
940 | BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64); | 974 | BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64); |
975 | BTRFS_SETGET_FUNCS(inode_transid, struct btrfs_inode_item, transid, 64); | ||
941 | BTRFS_SETGET_FUNCS(inode_size, struct btrfs_inode_item, size, 64); | 976 | BTRFS_SETGET_FUNCS(inode_size, struct btrfs_inode_item, size, 64); |
942 | BTRFS_SETGET_FUNCS(inode_nblocks, struct btrfs_inode_item, nblocks, 64); | 977 | BTRFS_SETGET_FUNCS(inode_nblocks, struct btrfs_inode_item, nblocks, 64); |
943 | BTRFS_SETGET_FUNCS(inode_block_group, struct btrfs_inode_item, block_group, 64); | 978 | BTRFS_SETGET_FUNCS(inode_block_group, struct btrfs_inode_item, block_group, 64); |
@@ -1126,10 +1161,13 @@ static inline void btrfs_set_item_key(struct extent_buffer *eb, | |||
1126 | write_eb_member(eb, item, struct btrfs_item, key, disk_key); | 1161 | write_eb_member(eb, item, struct btrfs_item, key, disk_key); |
1127 | } | 1162 | } |
1128 | 1163 | ||
1164 | BTRFS_SETGET_FUNCS(dir_log_end, struct btrfs_dir_log_item, end, 64); | ||
1165 | |||
1129 | /* struct btrfs_dir_item */ | 1166 | /* struct btrfs_dir_item */ |
1130 | BTRFS_SETGET_FUNCS(dir_data_len, struct btrfs_dir_item, data_len, 16); | 1167 | BTRFS_SETGET_FUNCS(dir_data_len, struct btrfs_dir_item, data_len, 16); |
1131 | BTRFS_SETGET_FUNCS(dir_type, struct btrfs_dir_item, type, 8); | 1168 | BTRFS_SETGET_FUNCS(dir_type, struct btrfs_dir_item, type, 8); |
1132 | BTRFS_SETGET_FUNCS(dir_name_len, struct btrfs_dir_item, name_len, 16); | 1169 | BTRFS_SETGET_FUNCS(dir_name_len, struct btrfs_dir_item, name_len, 16); |
1170 | BTRFS_SETGET_FUNCS(dir_transid, struct btrfs_dir_item, transid, 64); | ||
1133 | 1171 | ||
1134 | static inline void btrfs_dir_item_key(struct extent_buffer *eb, | 1172 | static inline void btrfs_dir_item_key(struct extent_buffer *eb, |
1135 | struct btrfs_dir_item *item, | 1173 | struct btrfs_dir_item *item, |
@@ -1301,7 +1339,11 @@ BTRFS_SETGET_STACK_FUNCS(super_root_level, struct btrfs_super_block, | |||
1301 | BTRFS_SETGET_STACK_FUNCS(super_chunk_root, struct btrfs_super_block, | 1339 | BTRFS_SETGET_STACK_FUNCS(super_chunk_root, struct btrfs_super_block, |
1302 | chunk_root, 64); | 1340 | chunk_root, 64); |
1303 | BTRFS_SETGET_STACK_FUNCS(super_chunk_root_level, struct btrfs_super_block, | 1341 | BTRFS_SETGET_STACK_FUNCS(super_chunk_root_level, struct btrfs_super_block, |
1304 | chunk_root_level, 64); | 1342 | chunk_root_level, 8); |
1343 | BTRFS_SETGET_STACK_FUNCS(super_log_root, struct btrfs_super_block, | ||
1344 | log_root, 64); | ||
1345 | BTRFS_SETGET_STACK_FUNCS(super_log_root_level, struct btrfs_super_block, | ||
1346 | log_root_level, 8); | ||
1305 | BTRFS_SETGET_STACK_FUNCS(super_total_bytes, struct btrfs_super_block, | 1347 | BTRFS_SETGET_STACK_FUNCS(super_total_bytes, struct btrfs_super_block, |
1306 | total_bytes, 64); | 1348 | total_bytes, 64); |
1307 | BTRFS_SETGET_STACK_FUNCS(super_bytes_used, struct btrfs_super_block, | 1349 | BTRFS_SETGET_STACK_FUNCS(super_bytes_used, struct btrfs_super_block, |
@@ -1405,6 +1447,12 @@ static inline struct dentry *fdentry(struct file *file) { | |||
1405 | } | 1447 | } |
1406 | 1448 | ||
1407 | /* extent-tree.c */ | 1449 | /* extent-tree.c */ |
1450 | int btrfs_lookup_extent(struct btrfs_root *root, struct btrfs_path *path, | ||
1451 | u64 start, u64 len); | ||
1452 | int btrfs_update_pinned_extents(struct btrfs_root *root, | ||
1453 | u64 bytenr, u64 num, int pin); | ||
1454 | int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | ||
1455 | struct btrfs_root *root, struct extent_buffer *leaf); | ||
1408 | int btrfs_cross_ref_exists(struct btrfs_trans_handle *trans, | 1456 | int btrfs_cross_ref_exists(struct btrfs_trans_handle *trans, |
1409 | struct btrfs_root *root, | 1457 | struct btrfs_root *root, |
1410 | struct btrfs_key *key, u64 bytenr); | 1458 | struct btrfs_key *key, u64 bytenr); |
@@ -1448,6 +1496,11 @@ int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
1448 | u64 root_objectid, u64 ref_generation, | 1496 | u64 root_objectid, u64 ref_generation, |
1449 | u64 owner, u64 owner_offset, | 1497 | u64 owner, u64 owner_offset, |
1450 | struct btrfs_key *ins); | 1498 | struct btrfs_key *ins); |
1499 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | ||
1500 | struct btrfs_root *root, | ||
1501 | u64 root_objectid, u64 ref_generation, | ||
1502 | u64 owner, u64 owner_offset, | ||
1503 | struct btrfs_key *ins); | ||
1451 | int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | 1504 | int btrfs_reserve_extent(struct btrfs_trans_handle *trans, |
1452 | struct btrfs_root *root, | 1505 | struct btrfs_root *root, |
1453 | u64 num_bytes, u64 min_alloc_size, | 1506 | u64 num_bytes, u64 min_alloc_size, |
@@ -1488,9 +1541,9 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, | |||
1488 | struct btrfs_key *key, int lowest_level, | 1541 | struct btrfs_key *key, int lowest_level, |
1489 | int cache_only, u64 min_trans); | 1542 | int cache_only, u64 min_trans); |
1490 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, | 1543 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, |
1544 | struct btrfs_key *max_key, | ||
1491 | struct btrfs_path *path, int cache_only, | 1545 | struct btrfs_path *path, int cache_only, |
1492 | u64 min_trans); | 1546 | u64 min_trans); |
1493 | |||
1494 | int btrfs_cow_block(struct btrfs_trans_handle *trans, | 1547 | int btrfs_cow_block(struct btrfs_trans_handle *trans, |
1495 | struct btrfs_root *root, struct extent_buffer *buf, | 1548 | struct btrfs_root *root, struct extent_buffer *buf, |
1496 | struct extent_buffer *parent, int parent_slot, | 1549 | struct extent_buffer *parent, int parent_slot, |
@@ -1656,6 +1709,18 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | |||
1656 | #define PageChecked PageFsMisc | 1709 | #define PageChecked PageFsMisc |
1657 | #endif | 1710 | #endif |
1658 | 1711 | ||
1712 | int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | ||
1713 | struct btrfs_root *root, | ||
1714 | struct inode *dir, struct inode *inode, | ||
1715 | const char *name, int name_len); | ||
1716 | int btrfs_add_link(struct btrfs_trans_handle *trans, | ||
1717 | struct inode *parent_inode, struct inode *inode, | ||
1718 | const char *name, int name_len, int add_backref, u64 index); | ||
1719 | int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, | ||
1720 | struct btrfs_root *root, | ||
1721 | struct inode *inode, u64 new_size, | ||
1722 | u32 min_type); | ||
1723 | |||
1659 | int btrfs_start_delalloc_inodes(struct btrfs_root *root); | 1724 | int btrfs_start_delalloc_inodes(struct btrfs_root *root); |
1660 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); | 1725 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); |
1661 | int btrfs_writepages(struct address_space *mapping, | 1726 | int btrfs_writepages(struct address_space *mapping, |
@@ -1715,6 +1780,7 @@ int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
1715 | long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 1780 | long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
1716 | 1781 | ||
1717 | /* file.c */ | 1782 | /* file.c */ |
1783 | int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync); | ||
1718 | int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end); | 1784 | int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end); |
1719 | int btrfs_check_file(struct btrfs_root *root, struct inode *inode); | 1785 | int btrfs_check_file(struct btrfs_root *root, struct inode *inode); |
1720 | extern struct file_operations btrfs_file_operations; | 1786 | extern struct file_operations btrfs_file_operations; |