diff options
Diffstat (limited to 'fs/btrfs')
| -rw-r--r-- | fs/btrfs/ctree.h | 4 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/extent_map.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 84 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 31 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 8 | ||||
| -rw-r--r-- | fs/btrfs/relocation.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/root-tree.c | 18 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 19 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 2 |
11 files changed, 148 insertions, 28 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index d47ce8307854..3458b5725540 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -1284,6 +1284,8 @@ struct btrfs_root { | |||
| 1284 | #define BTRFS_INODE_DIRSYNC (1 << 10) | 1284 | #define BTRFS_INODE_DIRSYNC (1 << 10) |
| 1285 | #define BTRFS_INODE_COMPRESS (1 << 11) | 1285 | #define BTRFS_INODE_COMPRESS (1 << 11) |
| 1286 | 1286 | ||
| 1287 | #define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) | ||
| 1288 | |||
| 1287 | /* some macros to generate set/get funcs for the struct fields. This | 1289 | /* some macros to generate set/get funcs for the struct fields. This |
| 1288 | * assumes there is a lefoo_to_cpu for every type, so lets make a simple | 1290 | * assumes there is a lefoo_to_cpu for every type, so lets make a simple |
| 1289 | * one for u8: | 1291 | * one for u8: |
| @@ -2359,6 +2361,8 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); | |||
| 2359 | int btrfs_find_orphan_roots(struct btrfs_root *tree_root); | 2361 | int btrfs_find_orphan_roots(struct btrfs_root *tree_root); |
| 2360 | int btrfs_set_root_node(struct btrfs_root_item *item, | 2362 | int btrfs_set_root_node(struct btrfs_root_item *item, |
| 2361 | struct extent_buffer *node); | 2363 | struct extent_buffer *node); |
| 2364 | void btrfs_check_and_init_root_item(struct btrfs_root_item *item); | ||
| 2365 | |||
| 2362 | /* dir-item.c */ | 2366 | /* dir-item.c */ |
| 2363 | int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, | 2367 | int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, |
| 2364 | struct btrfs_root *root, const char *name, | 2368 | struct btrfs_root *root, const char *name, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d7a7315bd031..8f1d44ba332f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1275,8 +1275,10 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
| 1275 | root->commit_root = btrfs_root_node(root); | 1275 | root->commit_root = btrfs_root_node(root); |
| 1276 | BUG_ON(!root->node); | 1276 | BUG_ON(!root->node); |
| 1277 | out: | 1277 | out: |
| 1278 | if (location->objectid != BTRFS_TREE_LOG_OBJECTID) | 1278 | if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { |
| 1279 | root->ref_cows = 1; | 1279 | root->ref_cows = 1; |
| 1280 | btrfs_check_and_init_root_item(&root->root_item); | ||
| 1281 | } | ||
| 1280 | 1282 | ||
| 1281 | return root; | 1283 | return root; |
| 1282 | } | 1284 | } |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 2b6c12e983b3..a24a3f2fa13e 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
| @@ -243,7 +243,7 @@ out: | |||
| 243 | * Insert @em into @tree or perform a simple forward/backward merge with | 243 | * Insert @em into @tree or perform a simple forward/backward merge with |
| 244 | * existing mappings. The extent_map struct passed in will be inserted | 244 | * existing mappings. The extent_map struct passed in will be inserted |
| 245 | * into the tree directly, with an additional reference taken, or a | 245 | * into the tree directly, with an additional reference taken, or a |
| 246 | * reference dropped if the merge attempt was successfull. | 246 | * reference dropped if the merge attempt was successful. |
| 247 | */ | 247 | */ |
| 248 | int add_extent_mapping(struct extent_map_tree *tree, | 248 | int add_extent_mapping(struct extent_map_tree *tree, |
| 249 | struct extent_map *em) | 249 | struct extent_map *em) |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 656bc0a892b1..e621ea54a3fd 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -906,7 +906,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
| 906 | unsigned long last_index; | 906 | unsigned long last_index; |
| 907 | size_t num_written = 0; | 907 | size_t num_written = 0; |
| 908 | int nrptrs; | 908 | int nrptrs; |
| 909 | int ret; | 909 | int ret = 0; |
| 910 | 910 | ||
| 911 | nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / | 911 | nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / |
| 912 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / | 912 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 0037427d8a9d..f561c953205b 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include "free-space-cache.h" | 24 | #include "free-space-cache.h" |
| 25 | #include "transaction.h" | 25 | #include "transaction.h" |
| 26 | #include "disk-io.h" | 26 | #include "disk-io.h" |
| 27 | #include "extent_io.h" | ||
| 27 | 28 | ||
| 28 | #define BITS_PER_BITMAP (PAGE_CACHE_SIZE * 8) | 29 | #define BITS_PER_BITMAP (PAGE_CACHE_SIZE * 8) |
| 29 | #define MAX_CACHE_BYTES_PER_GIG (32 * 1024) | 30 | #define MAX_CACHE_BYTES_PER_GIG (32 * 1024) |
| @@ -81,6 +82,8 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root, | |||
| 81 | return ERR_PTR(-ENOENT); | 82 | return ERR_PTR(-ENOENT); |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 85 | inode->i_mapping->flags &= ~__GFP_FS; | ||
| 86 | |||
| 84 | spin_lock(&block_group->lock); | 87 | spin_lock(&block_group->lock); |
| 85 | if (!root->fs_info->closing) { | 88 | if (!root->fs_info->closing) { |
| 86 | block_group->inode = igrab(inode); | 89 | block_group->inode = igrab(inode); |
| @@ -222,6 +225,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
| 222 | u64 num_entries; | 225 | u64 num_entries; |
| 223 | u64 num_bitmaps; | 226 | u64 num_bitmaps; |
| 224 | u64 generation; | 227 | u64 generation; |
| 228 | u64 used = btrfs_block_group_used(&block_group->item); | ||
| 225 | u32 cur_crc = ~(u32)0; | 229 | u32 cur_crc = ~(u32)0; |
| 226 | pgoff_t index = 0; | 230 | pgoff_t index = 0; |
| 227 | unsigned long first_page_offset; | 231 | unsigned long first_page_offset; |
| @@ -467,6 +471,17 @@ next: | |||
| 467 | index++; | 471 | index++; |
| 468 | } | 472 | } |
| 469 | 473 | ||
| 474 | spin_lock(&block_group->tree_lock); | ||
| 475 | if (block_group->free_space != (block_group->key.offset - used - | ||
| 476 | block_group->bytes_super)) { | ||
| 477 | spin_unlock(&block_group->tree_lock); | ||
| 478 | printk(KERN_ERR "block group %llu has an wrong amount of free " | ||
| 479 | "space\n", block_group->key.objectid); | ||
| 480 | ret = 0; | ||
| 481 | goto free_cache; | ||
| 482 | } | ||
| 483 | spin_unlock(&block_group->tree_lock); | ||
| 484 | |||
| 470 | ret = 1; | 485 | ret = 1; |
| 471 | out: | 486 | out: |
| 472 | kfree(checksums); | 487 | kfree(checksums); |
| @@ -495,8 +510,11 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 495 | struct list_head *pos, *n; | 510 | struct list_head *pos, *n; |
| 496 | struct page *page; | 511 | struct page *page; |
| 497 | struct extent_state *cached_state = NULL; | 512 | struct extent_state *cached_state = NULL; |
| 513 | struct btrfs_free_cluster *cluster = NULL; | ||
| 514 | struct extent_io_tree *unpin = NULL; | ||
| 498 | struct list_head bitmap_list; | 515 | struct list_head bitmap_list; |
| 499 | struct btrfs_key key; | 516 | struct btrfs_key key; |
| 517 | u64 start, end, len; | ||
| 500 | u64 bytes = 0; | 518 | u64 bytes = 0; |
| 501 | u32 *crc, *checksums; | 519 | u32 *crc, *checksums; |
| 502 | pgoff_t index = 0, last_index = 0; | 520 | pgoff_t index = 0, last_index = 0; |
| @@ -505,6 +523,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 505 | int entries = 0; | 523 | int entries = 0; |
| 506 | int bitmaps = 0; | 524 | int bitmaps = 0; |
| 507 | int ret = 0; | 525 | int ret = 0; |
| 526 | bool next_page = false; | ||
| 508 | 527 | ||
| 509 | root = root->fs_info->tree_root; | 528 | root = root->fs_info->tree_root; |
| 510 | 529 | ||
| @@ -551,6 +570,18 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 551 | */ | 570 | */ |
| 552 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); | 571 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); |
| 553 | 572 | ||
| 573 | /* Get the cluster for this block_group if it exists */ | ||
| 574 | if (!list_empty(&block_group->cluster_list)) | ||
| 575 | cluster = list_entry(block_group->cluster_list.next, | ||
| 576 | struct btrfs_free_cluster, | ||
| 577 | block_group_list); | ||
| 578 | |||
| 579 | /* | ||
| 580 | * We shouldn't have switched the pinned extents yet so this is the | ||
| 581 | * right one | ||
| 582 | */ | ||
| 583 | unpin = root->fs_info->pinned_extents; | ||
| 584 | |||
| 554 | /* | 585 | /* |
| 555 | * Lock all pages first so we can lock the extent safely. | 586 | * Lock all pages first so we can lock the extent safely. |
| 556 | * | 587 | * |
| @@ -580,6 +611,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 580 | lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, | 611 | lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, |
| 581 | 0, &cached_state, GFP_NOFS); | 612 | 0, &cached_state, GFP_NOFS); |
| 582 | 613 | ||
| 614 | /* | ||
| 615 | * When searching for pinned extents, we need to start at our start | ||
| 616 | * offset. | ||
| 617 | */ | ||
| 618 | start = block_group->key.objectid; | ||
| 619 | |||
| 583 | /* Write out the extent entries */ | 620 | /* Write out the extent entries */ |
| 584 | do { | 621 | do { |
| 585 | struct btrfs_free_space_entry *entry; | 622 | struct btrfs_free_space_entry *entry; |
| @@ -587,6 +624,8 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 587 | unsigned long offset = 0; | 624 | unsigned long offset = 0; |
| 588 | unsigned long start_offset = 0; | 625 | unsigned long start_offset = 0; |
| 589 | 626 | ||
| 627 | next_page = false; | ||
| 628 | |||
| 590 | if (index == 0) { | 629 | if (index == 0) { |
| 591 | start_offset = first_page_offset; | 630 | start_offset = first_page_offset; |
| 592 | offset = start_offset; | 631 | offset = start_offset; |
| @@ -598,7 +637,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 598 | entry = addr + start_offset; | 637 | entry = addr + start_offset; |
| 599 | 638 | ||
| 600 | memset(addr, 0, PAGE_CACHE_SIZE); | 639 | memset(addr, 0, PAGE_CACHE_SIZE); |
| 601 | while (1) { | 640 | while (node && !next_page) { |
| 602 | struct btrfs_free_space *e; | 641 | struct btrfs_free_space *e; |
| 603 | 642 | ||
| 604 | e = rb_entry(node, struct btrfs_free_space, offset_index); | 643 | e = rb_entry(node, struct btrfs_free_space, offset_index); |
| @@ -614,12 +653,49 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 614 | entry->type = BTRFS_FREE_SPACE_EXTENT; | 653 | entry->type = BTRFS_FREE_SPACE_EXTENT; |
| 615 | } | 654 | } |
| 616 | node = rb_next(node); | 655 | node = rb_next(node); |
| 617 | if (!node) | 656 | if (!node && cluster) { |
| 618 | break; | 657 | node = rb_first(&cluster->root); |
| 658 | cluster = NULL; | ||
| 659 | } | ||
| 619 | offset += sizeof(struct btrfs_free_space_entry); | 660 | offset += sizeof(struct btrfs_free_space_entry); |
| 620 | if (offset + sizeof(struct btrfs_free_space_entry) >= | 661 | if (offset + sizeof(struct btrfs_free_space_entry) >= |
| 621 | PAGE_CACHE_SIZE) | 662 | PAGE_CACHE_SIZE) |
| 663 | next_page = true; | ||
| 664 | entry++; | ||
| 665 | } | ||
| 666 | |||
| 667 | /* | ||
| 668 | * We want to add any pinned extents to our free space cache | ||
| 669 | * so we don't leak the space | ||
| 670 | */ | ||
| 671 | while (!next_page && (start < block_group->key.objectid + | ||
| 672 | block_group->key.offset)) { | ||
| 673 | ret = find_first_extent_bit(unpin, start, &start, &end, | ||
| 674 | EXTENT_DIRTY); | ||
| 675 | if (ret) { | ||
| 676 | ret = 0; | ||
| 677 | break; | ||
| 678 | } | ||
| 679 | |||
| 680 | /* This pinned extent is out of our range */ | ||
| 681 | if (start >= block_group->key.objectid + | ||
| 682 | block_group->key.offset) | ||
| 622 | break; | 683 | break; |
| 684 | |||
| 685 | len = block_group->key.objectid + | ||
| 686 | block_group->key.offset - start; | ||
| 687 | len = min(len, end + 1 - start); | ||
| 688 | |||
| 689 | entries++; | ||
| 690 | entry->offset = cpu_to_le64(start); | ||
| 691 | entry->bytes = cpu_to_le64(len); | ||
| 692 | entry->type = BTRFS_FREE_SPACE_EXTENT; | ||
| 693 | |||
| 694 | start = end + 1; | ||
| 695 | offset += sizeof(struct btrfs_free_space_entry); | ||
| 696 | if (offset + sizeof(struct btrfs_free_space_entry) >= | ||
| 697 | PAGE_CACHE_SIZE) | ||
| 698 | next_page = true; | ||
| 623 | entry++; | 699 | entry++; |
| 624 | } | 700 | } |
| 625 | *crc = ~(u32)0; | 701 | *crc = ~(u32)0; |
| @@ -650,7 +726,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 650 | page_cache_release(page); | 726 | page_cache_release(page); |
| 651 | 727 | ||
| 652 | index++; | 728 | index++; |
| 653 | } while (node); | 729 | } while (node || next_page); |
| 654 | 730 | ||
| 655 | /* Write out the bitmaps */ | 731 | /* Write out the bitmaps */ |
| 656 | list_for_each_safe(pos, n, &bitmap_list) { | 732 | list_for_each_safe(pos, n, &bitmap_list) { |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 93c28a1d6bdc..5cc64ab9c485 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -112,6 +112,7 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, | |||
| 112 | static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, | 112 | static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, |
| 113 | struct btrfs_root *root, struct inode *inode, | 113 | struct btrfs_root *root, struct inode *inode, |
| 114 | u64 start, size_t size, size_t compressed_size, | 114 | u64 start, size_t size, size_t compressed_size, |
| 115 | int compress_type, | ||
| 115 | struct page **compressed_pages) | 116 | struct page **compressed_pages) |
| 116 | { | 117 | { |
| 117 | struct btrfs_key key; | 118 | struct btrfs_key key; |
| @@ -126,12 +127,9 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
| 126 | size_t cur_size = size; | 127 | size_t cur_size = size; |
| 127 | size_t datasize; | 128 | size_t datasize; |
| 128 | unsigned long offset; | 129 | unsigned long offset; |
| 129 | int compress_type = BTRFS_COMPRESS_NONE; | ||
| 130 | 130 | ||
| 131 | if (compressed_size && compressed_pages) { | 131 | if (compressed_size && compressed_pages) |
| 132 | compress_type = root->fs_info->compress_type; | ||
| 133 | cur_size = compressed_size; | 132 | cur_size = compressed_size; |
| 134 | } | ||
| 135 | 133 | ||
| 136 | path = btrfs_alloc_path(); | 134 | path = btrfs_alloc_path(); |
| 137 | if (!path) | 135 | if (!path) |
| @@ -221,7 +219,7 @@ fail: | |||
| 221 | static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, | 219 | static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, |
| 222 | struct btrfs_root *root, | 220 | struct btrfs_root *root, |
| 223 | struct inode *inode, u64 start, u64 end, | 221 | struct inode *inode, u64 start, u64 end, |
| 224 | size_t compressed_size, | 222 | size_t compressed_size, int compress_type, |
| 225 | struct page **compressed_pages) | 223 | struct page **compressed_pages) |
| 226 | { | 224 | { |
| 227 | u64 isize = i_size_read(inode); | 225 | u64 isize = i_size_read(inode); |
| @@ -254,7 +252,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, | |||
| 254 | inline_len = min_t(u64, isize, actual_end); | 252 | inline_len = min_t(u64, isize, actual_end); |
| 255 | ret = insert_inline_extent(trans, root, inode, start, | 253 | ret = insert_inline_extent(trans, root, inode, start, |
| 256 | inline_len, compressed_size, | 254 | inline_len, compressed_size, |
| 257 | compressed_pages); | 255 | compress_type, compressed_pages); |
| 258 | BUG_ON(ret); | 256 | BUG_ON(ret); |
| 259 | btrfs_delalloc_release_metadata(inode, end + 1 - start); | 257 | btrfs_delalloc_release_metadata(inode, end + 1 - start); |
| 260 | btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); | 258 | btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); |
| @@ -433,12 +431,13 @@ again: | |||
| 433 | * to make an uncompressed inline extent. | 431 | * to make an uncompressed inline extent. |
| 434 | */ | 432 | */ |
| 435 | ret = cow_file_range_inline(trans, root, inode, | 433 | ret = cow_file_range_inline(trans, root, inode, |
| 436 | start, end, 0, NULL); | 434 | start, end, 0, 0, NULL); |
| 437 | } else { | 435 | } else { |
| 438 | /* try making a compressed inline extent */ | 436 | /* try making a compressed inline extent */ |
| 439 | ret = cow_file_range_inline(trans, root, inode, | 437 | ret = cow_file_range_inline(trans, root, inode, |
| 440 | start, end, | 438 | start, end, |
| 441 | total_compressed, pages); | 439 | total_compressed, |
| 440 | compress_type, pages); | ||
| 442 | } | 441 | } |
| 443 | if (ret == 0) { | 442 | if (ret == 0) { |
| 444 | /* | 443 | /* |
| @@ -792,7 +791,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 792 | if (start == 0) { | 791 | if (start == 0) { |
| 793 | /* lets try to make an inline extent */ | 792 | /* lets try to make an inline extent */ |
| 794 | ret = cow_file_range_inline(trans, root, inode, | 793 | ret = cow_file_range_inline(trans, root, inode, |
| 795 | start, end, 0, NULL); | 794 | start, end, 0, 0, NULL); |
| 796 | if (ret == 0) { | 795 | if (ret == 0) { |
| 797 | extent_clear_unlock_delalloc(inode, | 796 | extent_clear_unlock_delalloc(inode, |
| 798 | &BTRFS_I(inode)->io_tree, | 797 | &BTRFS_I(inode)->io_tree, |
| @@ -2222,8 +2221,6 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) | |||
| 2222 | insert = 1; | 2221 | insert = 1; |
| 2223 | #endif | 2222 | #endif |
| 2224 | insert = 1; | 2223 | insert = 1; |
| 2225 | } else { | ||
| 2226 | WARN_ON(!BTRFS_I(inode)->orphan_meta_reserved); | ||
| 2227 | } | 2224 | } |
| 2228 | 2225 | ||
| 2229 | if (!BTRFS_I(inode)->orphan_meta_reserved) { | 2226 | if (!BTRFS_I(inode)->orphan_meta_reserved) { |
| @@ -2324,7 +2321,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
| 2324 | 2321 | ||
| 2325 | /* | 2322 | /* |
| 2326 | * if ret == 0 means we found what we were searching for, which | 2323 | * if ret == 0 means we found what we were searching for, which |
| 2327 | * is weird, but possible, so only screw with path if we didnt | 2324 | * is weird, but possible, so only screw with path if we didn't |
| 2328 | * find the key and see if we have stuff that matches | 2325 | * find the key and see if we have stuff that matches |
| 2329 | */ | 2326 | */ |
| 2330 | if (ret > 0) { | 2327 | if (ret > 0) { |
| @@ -2537,8 +2534,6 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
| 2537 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); | 2534 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); |
| 2538 | 2535 | ||
| 2539 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); | 2536 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); |
| 2540 | if (location.objectid == BTRFS_FREE_SPACE_OBJECTID) | ||
| 2541 | inode->i_mapping->flags &= ~__GFP_FS; | ||
| 2542 | 2537 | ||
| 2543 | /* | 2538 | /* |
| 2544 | * try to precache a NULL acl entry for files that don't have | 2539 | * try to precache a NULL acl entry for files that don't have |
| @@ -6960,8 +6955,10 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 6960 | * should cover the worst case number of items we'll modify. | 6955 | * should cover the worst case number of items we'll modify. |
| 6961 | */ | 6956 | */ |
| 6962 | trans = btrfs_start_transaction(root, 20); | 6957 | trans = btrfs_start_transaction(root, 20); |
| 6963 | if (IS_ERR(trans)) | 6958 | if (IS_ERR(trans)) { |
| 6964 | return PTR_ERR(trans); | 6959 | ret = PTR_ERR(trans); |
| 6960 | goto out_notrans; | ||
| 6961 | } | ||
| 6965 | 6962 | ||
| 6966 | btrfs_set_trans_block_group(trans, new_dir); | 6963 | btrfs_set_trans_block_group(trans, new_dir); |
| 6967 | 6964 | ||
| @@ -7061,7 +7058,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 7061 | } | 7058 | } |
| 7062 | out_fail: | 7059 | out_fail: |
| 7063 | btrfs_end_transaction_throttle(trans, root); | 7060 | btrfs_end_transaction_throttle(trans, root); |
| 7064 | 7061 | out_notrans: | |
| 7065 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | 7062 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) |
| 7066 | up_read(&root->fs_info->subvol_sem); | 7063 | up_read(&root->fs_info->subvol_sem); |
| 7067 | 7064 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7c07fe26b7cf..cfc264fefdb0 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -373,6 +373,10 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 373 | inode_item->nbytes = cpu_to_le64(root->leafsize); | 373 | inode_item->nbytes = cpu_to_le64(root->leafsize); |
| 374 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | 374 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); |
| 375 | 375 | ||
| 376 | root_item.flags = 0; | ||
| 377 | root_item.byte_limit = 0; | ||
| 378 | inode_item->flags = cpu_to_le64(BTRFS_INODE_ROOT_ITEM_INIT); | ||
| 379 | |||
| 376 | btrfs_set_root_bytenr(&root_item, leaf->start); | 380 | btrfs_set_root_bytenr(&root_item, leaf->start); |
| 377 | btrfs_set_root_generation(&root_item, trans->transid); | 381 | btrfs_set_root_generation(&root_item, trans->transid); |
| 378 | btrfs_set_root_level(&root_item, 0); | 382 | btrfs_set_root_level(&root_item, 0); |
| @@ -2436,8 +2440,10 @@ static noinline long btrfs_ioctl_start_sync(struct file *file, void __user *argp | |||
| 2436 | return PTR_ERR(trans); | 2440 | return PTR_ERR(trans); |
| 2437 | transid = trans->transid; | 2441 | transid = trans->transid; |
| 2438 | ret = btrfs_commit_transaction_async(trans, root, 0); | 2442 | ret = btrfs_commit_transaction_async(trans, root, 0); |
| 2439 | if (ret) | 2443 | if (ret) { |
| 2444 | btrfs_end_transaction(trans, root); | ||
| 2440 | return ret; | 2445 | return ret; |
| 2446 | } | ||
| 2441 | 2447 | ||
| 2442 | if (argp) | 2448 | if (argp) |
| 2443 | if (copy_to_user(argp, &transid, sizeof(transid))) | 2449 | if (copy_to_user(argp, &transid, sizeof(transid))) |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 58250e09eb05..199a80134312 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -2346,7 +2346,7 @@ struct btrfs_root *select_one_root(struct btrfs_trans_handle *trans, | |||
| 2346 | root = next->root; | 2346 | root = next->root; |
| 2347 | BUG_ON(!root); | 2347 | BUG_ON(!root); |
| 2348 | 2348 | ||
| 2349 | /* no other choice for non-refernce counted tree */ | 2349 | /* no other choice for non-references counted tree */ |
| 2350 | if (!root->ref_cows) | 2350 | if (!root->ref_cows) |
| 2351 | return root; | 2351 | return root; |
| 2352 | 2352 | ||
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 29b2d7c930eb..6928bff62daa 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
| @@ -473,3 +473,21 @@ again: | |||
| 473 | btrfs_free_path(path); | 473 | btrfs_free_path(path); |
| 474 | return 0; | 474 | return 0; |
| 475 | } | 475 | } |
| 476 | |||
| 477 | /* | ||
| 478 | * Old btrfs forgets to init root_item->flags and root_item->byte_limit | ||
| 479 | * for subvolumes. To work around this problem, we steal a bit from | ||
| 480 | * root_item->inode_item->flags, and use it to indicate if those fields | ||
| 481 | * have been properly initialized. | ||
| 482 | */ | ||
| 483 | void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item) | ||
| 484 | { | ||
| 485 | u64 inode_flags = le64_to_cpu(root_item->inode.flags); | ||
| 486 | |||
| 487 | if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) { | ||
| 488 | inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT; | ||
| 489 | root_item->inode.flags = cpu_to_le64(inode_flags); | ||
| 490 | root_item->flags = 0; | ||
| 491 | root_item->byte_limit = 0; | ||
| 492 | } | ||
| 493 | } | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 2edfc039f098..58e7de9cc90c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -644,6 +644,7 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 644 | { | 644 | { |
| 645 | struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); | 645 | struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); |
| 646 | struct btrfs_fs_info *info = root->fs_info; | 646 | struct btrfs_fs_info *info = root->fs_info; |
| 647 | char *compress_type; | ||
| 647 | 648 | ||
| 648 | if (btrfs_test_opt(root, DEGRADED)) | 649 | if (btrfs_test_opt(root, DEGRADED)) |
| 649 | seq_puts(seq, ",degraded"); | 650 | seq_puts(seq, ",degraded"); |
| @@ -662,8 +663,16 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 662 | if (info->thread_pool_size != min_t(unsigned long, | 663 | if (info->thread_pool_size != min_t(unsigned long, |
| 663 | num_online_cpus() + 2, 8)) | 664 | num_online_cpus() + 2, 8)) |
| 664 | seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); | 665 | seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); |
| 665 | if (btrfs_test_opt(root, COMPRESS)) | 666 | if (btrfs_test_opt(root, COMPRESS)) { |
| 666 | seq_puts(seq, ",compress"); | 667 | if (info->compress_type == BTRFS_COMPRESS_ZLIB) |
| 668 | compress_type = "zlib"; | ||
| 669 | else | ||
| 670 | compress_type = "lzo"; | ||
| 671 | if (btrfs_test_opt(root, FORCE_COMPRESS)) | ||
| 672 | seq_printf(seq, ",compress-force=%s", compress_type); | ||
| 673 | else | ||
| 674 | seq_printf(seq, ",compress=%s", compress_type); | ||
| 675 | } | ||
| 667 | if (btrfs_test_opt(root, NOSSD)) | 676 | if (btrfs_test_opt(root, NOSSD)) |
| 668 | seq_puts(seq, ",nossd"); | 677 | seq_puts(seq, ",nossd"); |
| 669 | if (btrfs_test_opt(root, SSD_SPREAD)) | 678 | if (btrfs_test_opt(root, SSD_SPREAD)) |
| @@ -678,6 +687,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 678 | seq_puts(seq, ",discard"); | 687 | seq_puts(seq, ",discard"); |
| 679 | if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) | 688 | if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) |
| 680 | seq_puts(seq, ",noacl"); | 689 | seq_puts(seq, ",noacl"); |
| 690 | if (btrfs_test_opt(root, SPACE_CACHE)) | ||
| 691 | seq_puts(seq, ",space_cache"); | ||
| 692 | if (btrfs_test_opt(root, CLEAR_CACHE)) | ||
| 693 | seq_puts(seq, ",clear_cache"); | ||
| 694 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | ||
| 695 | seq_puts(seq, ",user_subvol_rm_allowed"); | ||
| 681 | return 0; | 696 | return 0; |
| 682 | } | 697 | } |
| 683 | 698 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index ce48eb59d615..5b158da7e0bb 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -197,6 +197,7 @@ again: | |||
| 197 | 197 | ||
| 198 | ret = join_transaction(root); | 198 | ret = join_transaction(root); |
| 199 | if (ret < 0) { | 199 | if (ret < 0) { |
| 200 | kmem_cache_free(btrfs_trans_handle_cachep, h); | ||
| 200 | if (type != TRANS_JOIN_NOLOCK) | 201 | if (type != TRANS_JOIN_NOLOCK) |
| 201 | mutex_unlock(&root->fs_info->trans_mutex); | 202 | mutex_unlock(&root->fs_info->trans_mutex); |
| 202 | return ERR_PTR(ret); | 203 | return ERR_PTR(ret); |
| @@ -975,6 +976,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 975 | record_root_in_trans(trans, root); | 976 | record_root_in_trans(trans, root); |
| 976 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); | 977 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); |
| 977 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); | 978 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); |
| 979 | btrfs_check_and_init_root_item(new_root_item); | ||
| 978 | 980 | ||
| 979 | root_flags = btrfs_root_flags(new_root_item); | 981 | root_flags = btrfs_root_flags(new_root_item); |
| 980 | if (pending->readonly) | 982 | if (pending->readonly) |
