diff options
-rw-r--r-- | fs/btrfs/ctree.c | 8 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/dir-item.c | 3 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 13 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 7 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 56 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 13 | ||||
-rw-r--r-- | fs/btrfs/inode-item.c | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 6 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 11 | ||||
-rw-r--r-- | fs/btrfs/root-tree.c | 6 | ||||
-rw-r--r-- | fs/btrfs/super.c | 4 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 36 | ||||
-rw-r--r-- | fs/btrfs/version.sh | 43 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 119 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 2 |
16 files changed, 187 insertions, 145 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b6cbeed226b1..b0e18d986e0a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -3211,7 +3211,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
3211 | struct btrfs_path *path, | 3211 | struct btrfs_path *path, |
3212 | u32 new_size, int from_end) | 3212 | u32 new_size, int from_end) |
3213 | { | 3213 | { |
3214 | int ret = 0; | ||
3215 | int slot; | 3214 | int slot; |
3216 | struct extent_buffer *leaf; | 3215 | struct extent_buffer *leaf; |
3217 | struct btrfs_item *item; | 3216 | struct btrfs_item *item; |
@@ -3309,12 +3308,11 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
3309 | btrfs_set_item_size(leaf, item, new_size); | 3308 | btrfs_set_item_size(leaf, item, new_size); |
3310 | btrfs_mark_buffer_dirty(leaf); | 3309 | btrfs_mark_buffer_dirty(leaf); |
3311 | 3310 | ||
3312 | ret = 0; | ||
3313 | if (btrfs_leaf_free_space(root, leaf) < 0) { | 3311 | if (btrfs_leaf_free_space(root, leaf) < 0) { |
3314 | btrfs_print_leaf(root, leaf); | 3312 | btrfs_print_leaf(root, leaf); |
3315 | BUG(); | 3313 | BUG(); |
3316 | } | 3314 | } |
3317 | return ret; | 3315 | return 0; |
3318 | } | 3316 | } |
3319 | 3317 | ||
3320 | /* | 3318 | /* |
@@ -3324,7 +3322,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
3324 | struct btrfs_root *root, struct btrfs_path *path, | 3322 | struct btrfs_root *root, struct btrfs_path *path, |
3325 | u32 data_size) | 3323 | u32 data_size) |
3326 | { | 3324 | { |
3327 | int ret = 0; | ||
3328 | int slot; | 3325 | int slot; |
3329 | struct extent_buffer *leaf; | 3326 | struct extent_buffer *leaf; |
3330 | struct btrfs_item *item; | 3327 | struct btrfs_item *item; |
@@ -3389,12 +3386,11 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
3389 | btrfs_set_item_size(leaf, item, old_size + data_size); | 3386 | btrfs_set_item_size(leaf, item, old_size + data_size); |
3390 | btrfs_mark_buffer_dirty(leaf); | 3387 | btrfs_mark_buffer_dirty(leaf); |
3391 | 3388 | ||
3392 | ret = 0; | ||
3393 | if (btrfs_leaf_free_space(root, leaf) < 0) { | 3389 | if (btrfs_leaf_free_space(root, leaf) < 0) { |
3394 | btrfs_print_leaf(root, leaf); | 3390 | btrfs_print_leaf(root, leaf); |
3395 | BUG(); | 3391 | BUG(); |
3396 | } | 3392 | } |
3397 | return ret; | 3393 | return 0; |
3398 | } | 3394 | } |
3399 | 3395 | ||
3400 | /* | 3396 | /* |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0d50c57caf5d..026fc47b42cf 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1113,9 +1113,6 @@ struct btrfs_fs_info { | |||
1113 | struct btrfs_root { | 1113 | struct btrfs_root { |
1114 | struct extent_buffer *node; | 1114 | struct extent_buffer *node; |
1115 | 1115 | ||
1116 | /* the node lock is held while changing the node pointer */ | ||
1117 | spinlock_t node_lock; | ||
1118 | |||
1119 | struct extent_buffer *commit_root; | 1116 | struct extent_buffer *commit_root; |
1120 | struct btrfs_root *log_root; | 1117 | struct btrfs_root *log_root; |
1121 | struct btrfs_root *reloc_root; | 1118 | struct btrfs_root *reloc_root; |
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 1ddfca78e910..685f2593c4f0 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c | |||
@@ -50,7 +50,6 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle | |||
50 | if (di) | 50 | if (di) |
51 | return ERR_PTR(-EEXIST); | 51 | return ERR_PTR(-EEXIST); |
52 | ret = btrfs_extend_item(trans, root, path, data_size); | 52 | ret = btrfs_extend_item(trans, root, path, data_size); |
53 | WARN_ON(ret > 0); | ||
54 | } | 53 | } |
55 | if (ret < 0) | 54 | if (ret < 0) |
56 | return ERR_PTR(ret); | 55 | return ERR_PTR(ret); |
@@ -438,7 +437,7 @@ int verify_dir_item(struct btrfs_root *root, | |||
438 | namelen = XATTR_NAME_MAX; | 437 | namelen = XATTR_NAME_MAX; |
439 | 438 | ||
440 | if (btrfs_dir_name_len(leaf, dir_item) > namelen) { | 439 | if (btrfs_dir_name_len(leaf, dir_item) > namelen) { |
441 | printk(KERN_CRIT "btrfS: invalid dir item name len: %u\n", | 440 | printk(KERN_CRIT "btrfs: invalid dir item name len: %u\n", |
442 | (unsigned)btrfs_dir_data_len(leaf, dir_item)); | 441 | (unsigned)btrfs_dir_data_len(leaf, dir_item)); |
443 | return 1; | 442 | return 1; |
444 | } | 443 | } |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 29a2475b9b14..16d335b342a2 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1053,7 +1053,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
1053 | INIT_LIST_HEAD(&root->dirty_list); | 1053 | INIT_LIST_HEAD(&root->dirty_list); |
1054 | INIT_LIST_HEAD(&root->orphan_list); | 1054 | INIT_LIST_HEAD(&root->orphan_list); |
1055 | INIT_LIST_HEAD(&root->root_list); | 1055 | INIT_LIST_HEAD(&root->root_list); |
1056 | spin_lock_init(&root->node_lock); | ||
1057 | spin_lock_init(&root->orphan_lock); | 1056 | spin_lock_init(&root->orphan_lock); |
1058 | spin_lock_init(&root->inode_lock); | 1057 | spin_lock_init(&root->inode_lock); |
1059 | spin_lock_init(&root->accounting_lock); | 1058 | spin_lock_init(&root->accounting_lock); |
@@ -1363,7 +1362,8 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
1363 | struct btrfs_device *device; | 1362 | struct btrfs_device *device; |
1364 | struct backing_dev_info *bdi; | 1363 | struct backing_dev_info *bdi; |
1365 | 1364 | ||
1366 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { | 1365 | rcu_read_lock(); |
1366 | list_for_each_entry_rcu(device, &info->fs_devices->devices, dev_list) { | ||
1367 | if (!device->bdev) | 1367 | if (!device->bdev) |
1368 | continue; | 1368 | continue; |
1369 | bdi = blk_get_backing_dev_info(device->bdev); | 1369 | bdi = blk_get_backing_dev_info(device->bdev); |
@@ -1372,6 +1372,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
1372 | break; | 1372 | break; |
1373 | } | 1373 | } |
1374 | } | 1374 | } |
1375 | rcu_read_unlock(); | ||
1375 | return ret; | 1376 | return ret; |
1376 | } | 1377 | } |
1377 | 1378 | ||
@@ -2305,9 +2306,9 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
2305 | sb = &root->fs_info->super_for_commit; | 2306 | sb = &root->fs_info->super_for_commit; |
2306 | dev_item = &sb->dev_item; | 2307 | dev_item = &sb->dev_item; |
2307 | 2308 | ||
2308 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | 2309 | rcu_read_lock(); |
2309 | head = &root->fs_info->fs_devices->devices; | 2310 | head = &root->fs_info->fs_devices->devices; |
2310 | list_for_each_entry(dev, head, dev_list) { | 2311 | list_for_each_entry_rcu(dev, head, dev_list) { |
2311 | if (!dev->bdev) { | 2312 | if (!dev->bdev) { |
2312 | total_errors++; | 2313 | total_errors++; |
2313 | continue; | 2314 | continue; |
@@ -2340,7 +2341,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
2340 | } | 2341 | } |
2341 | 2342 | ||
2342 | total_errors = 0; | 2343 | total_errors = 0; |
2343 | list_for_each_entry(dev, head, dev_list) { | 2344 | list_for_each_entry_rcu(dev, head, dev_list) { |
2344 | if (!dev->bdev) | 2345 | if (!dev->bdev) |
2345 | continue; | 2346 | continue; |
2346 | if (!dev->in_fs_metadata || !dev->writeable) | 2347 | if (!dev->in_fs_metadata || !dev->writeable) |
@@ -2350,7 +2351,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
2350 | if (ret) | 2351 | if (ret) |
2351 | total_errors++; | 2352 | total_errors++; |
2352 | } | 2353 | } |
2353 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | 2354 | rcu_read_unlock(); |
2354 | if (total_errors > max_errors) { | 2355 | if (total_errors > max_errors) { |
2355 | printk(KERN_ERR "btrfs: %d errors while writing supers\n", | 2356 | printk(KERN_ERR "btrfs: %d errors while writing supers\n", |
2356 | total_errors); | 2357 | total_errors); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 98ca149bdbc8..169bd62ce776 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -952,7 +952,6 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, | |||
952 | BUG_ON(ret); | 952 | BUG_ON(ret); |
953 | 953 | ||
954 | ret = btrfs_extend_item(trans, root, path, new_size); | 954 | ret = btrfs_extend_item(trans, root, path, new_size); |
955 | BUG_ON(ret); | ||
956 | 955 | ||
957 | leaf = path->nodes[0]; | 956 | leaf = path->nodes[0]; |
958 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | 957 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); |
@@ -1560,7 +1559,6 @@ int setup_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1560 | size = btrfs_extent_inline_ref_size(type); | 1559 | size = btrfs_extent_inline_ref_size(type); |
1561 | 1560 | ||
1562 | ret = btrfs_extend_item(trans, root, path, size); | 1561 | ret = btrfs_extend_item(trans, root, path, size); |
1563 | BUG_ON(ret); | ||
1564 | 1562 | ||
1565 | ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | 1563 | ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); |
1566 | refs = btrfs_extent_refs(leaf, ei); | 1564 | refs = btrfs_extent_refs(leaf, ei); |
@@ -1689,7 +1687,6 @@ int update_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1689 | end - ptr - size); | 1687 | end - ptr - size); |
1690 | item_size -= size; | 1688 | item_size -= size; |
1691 | ret = btrfs_truncate_item(trans, root, path, item_size, 1); | 1689 | ret = btrfs_truncate_item(trans, root, path, item_size, 1); |
1692 | BUG_ON(ret); | ||
1693 | } | 1690 | } |
1694 | btrfs_mark_buffer_dirty(leaf); | 1691 | btrfs_mark_buffer_dirty(leaf); |
1695 | return 0; | 1692 | return 0; |
@@ -3307,6 +3304,10 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3307 | if (reserved == 0) | 3304 | if (reserved == 0) |
3308 | return 0; | 3305 | return 0; |
3309 | 3306 | ||
3307 | /* nothing to shrink - nothing to reclaim */ | ||
3308 | if (root->fs_info->delalloc_bytes == 0) | ||
3309 | return 0; | ||
3310 | |||
3310 | max_reclaim = min(reserved, to_reclaim); | 3311 | max_reclaim = min(reserved, to_reclaim); |
3311 | 3312 | ||
3312 | while (loops < 1024) { | 3313 | while (loops < 1024) { |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 64c8b361b539..a90c4a12556b 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -439,6 +439,15 @@ static int clear_state_bit(struct extent_io_tree *tree, | |||
439 | return ret; | 439 | return ret; |
440 | } | 440 | } |
441 | 441 | ||
442 | static struct extent_state * | ||
443 | alloc_extent_state_atomic(struct extent_state *prealloc) | ||
444 | { | ||
445 | if (!prealloc) | ||
446 | prealloc = alloc_extent_state(GFP_ATOMIC); | ||
447 | |||
448 | return prealloc; | ||
449 | } | ||
450 | |||
442 | /* | 451 | /* |
443 | * clear some bits on a range in the tree. This may require splitting | 452 | * clear some bits on a range in the tree. This may require splitting |
444 | * or inserting elements in the tree, so the gfp mask is used to | 453 | * or inserting elements in the tree, so the gfp mask is used to |
@@ -476,8 +485,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
476 | again: | 485 | again: |
477 | if (!prealloc && (mask & __GFP_WAIT)) { | 486 | if (!prealloc && (mask & __GFP_WAIT)) { |
478 | prealloc = alloc_extent_state(mask); | 487 | prealloc = alloc_extent_state(mask); |
479 | if (!prealloc) | 488 | BUG_ON(!prealloc); |
480 | return -ENOMEM; | ||
481 | } | 489 | } |
482 | 490 | ||
483 | spin_lock(&tree->lock); | 491 | spin_lock(&tree->lock); |
@@ -529,8 +537,8 @@ hit_next: | |||
529 | */ | 537 | */ |
530 | 538 | ||
531 | if (state->start < start) { | 539 | if (state->start < start) { |
532 | if (!prealloc) | 540 | prealloc = alloc_extent_state_atomic(prealloc); |
533 | prealloc = alloc_extent_state(GFP_ATOMIC); | 541 | BUG_ON(!prealloc); |
534 | err = split_state(tree, state, prealloc, start); | 542 | err = split_state(tree, state, prealloc, start); |
535 | BUG_ON(err == -EEXIST); | 543 | BUG_ON(err == -EEXIST); |
536 | prealloc = NULL; | 544 | prealloc = NULL; |
@@ -551,8 +559,8 @@ hit_next: | |||
551 | * on the first half | 559 | * on the first half |
552 | */ | 560 | */ |
553 | if (state->start <= end && state->end > end) { | 561 | if (state->start <= end && state->end > end) { |
554 | if (!prealloc) | 562 | prealloc = alloc_extent_state_atomic(prealloc); |
555 | prealloc = alloc_extent_state(GFP_ATOMIC); | 563 | BUG_ON(!prealloc); |
556 | err = split_state(tree, state, prealloc, end + 1); | 564 | err = split_state(tree, state, prealloc, end + 1); |
557 | BUG_ON(err == -EEXIST); | 565 | BUG_ON(err == -EEXIST); |
558 | if (wake) | 566 | if (wake) |
@@ -725,8 +733,7 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
725 | again: | 733 | again: |
726 | if (!prealloc && (mask & __GFP_WAIT)) { | 734 | if (!prealloc && (mask & __GFP_WAIT)) { |
727 | prealloc = alloc_extent_state(mask); | 735 | prealloc = alloc_extent_state(mask); |
728 | if (!prealloc) | 736 | BUG_ON(!prealloc); |
729 | return -ENOMEM; | ||
730 | } | 737 | } |
731 | 738 | ||
732 | spin_lock(&tree->lock); | 739 | spin_lock(&tree->lock); |
@@ -743,6 +750,8 @@ again: | |||
743 | */ | 750 | */ |
744 | node = tree_search(tree, start); | 751 | node = tree_search(tree, start); |
745 | if (!node) { | 752 | if (!node) { |
753 | prealloc = alloc_extent_state_atomic(prealloc); | ||
754 | BUG_ON(!prealloc); | ||
746 | err = insert_state(tree, prealloc, start, end, &bits); | 755 | err = insert_state(tree, prealloc, start, end, &bits); |
747 | prealloc = NULL; | 756 | prealloc = NULL; |
748 | BUG_ON(err == -EEXIST); | 757 | BUG_ON(err == -EEXIST); |
@@ -771,20 +780,18 @@ hit_next: | |||
771 | if (err) | 780 | if (err) |
772 | goto out; | 781 | goto out; |
773 | 782 | ||
783 | next_node = rb_next(node); | ||
774 | cache_state(state, cached_state); | 784 | cache_state(state, cached_state); |
775 | merge_state(tree, state); | 785 | merge_state(tree, state); |
776 | if (last_end == (u64)-1) | 786 | if (last_end == (u64)-1) |
777 | goto out; | 787 | goto out; |
778 | 788 | ||
779 | start = last_end + 1; | 789 | start = last_end + 1; |
780 | if (start < end && prealloc && !need_resched()) { | 790 | if (next_node && start < end && prealloc && !need_resched()) { |
781 | next_node = rb_next(node); | 791 | state = rb_entry(next_node, struct extent_state, |
782 | if (next_node) { | 792 | rb_node); |
783 | state = rb_entry(next_node, struct extent_state, | 793 | if (state->start == start) |
784 | rb_node); | 794 | goto hit_next; |
785 | if (state->start == start) | ||
786 | goto hit_next; | ||
787 | } | ||
788 | } | 795 | } |
789 | goto search_again; | 796 | goto search_again; |
790 | } | 797 | } |
@@ -811,6 +818,9 @@ hit_next: | |||
811 | err = -EEXIST; | 818 | err = -EEXIST; |
812 | goto out; | 819 | goto out; |
813 | } | 820 | } |
821 | |||
822 | prealloc = alloc_extent_state_atomic(prealloc); | ||
823 | BUG_ON(!prealloc); | ||
814 | err = split_state(tree, state, prealloc, start); | 824 | err = split_state(tree, state, prealloc, start); |
815 | BUG_ON(err == -EEXIST); | 825 | BUG_ON(err == -EEXIST); |
816 | prealloc = NULL; | 826 | prealloc = NULL; |
@@ -841,14 +851,25 @@ hit_next: | |||
841 | this_end = end; | 851 | this_end = end; |
842 | else | 852 | else |
843 | this_end = last_start - 1; | 853 | this_end = last_start - 1; |
854 | |||
855 | prealloc = alloc_extent_state_atomic(prealloc); | ||
856 | BUG_ON(!prealloc); | ||
857 | |||
858 | /* | ||
859 | * Avoid to free 'prealloc' if it can be merged with | ||
860 | * the later extent. | ||
861 | */ | ||
862 | atomic_inc(&prealloc->refs); | ||
844 | err = insert_state(tree, prealloc, start, this_end, | 863 | err = insert_state(tree, prealloc, start, this_end, |
845 | &bits); | 864 | &bits); |
846 | BUG_ON(err == -EEXIST); | 865 | BUG_ON(err == -EEXIST); |
847 | if (err) { | 866 | if (err) { |
867 | free_extent_state(prealloc); | ||
848 | prealloc = NULL; | 868 | prealloc = NULL; |
849 | goto out; | 869 | goto out; |
850 | } | 870 | } |
851 | cache_state(prealloc, cached_state); | 871 | cache_state(prealloc, cached_state); |
872 | free_extent_state(prealloc); | ||
852 | prealloc = NULL; | 873 | prealloc = NULL; |
853 | start = this_end + 1; | 874 | start = this_end + 1; |
854 | goto search_again; | 875 | goto search_again; |
@@ -865,6 +886,9 @@ hit_next: | |||
865 | err = -EEXIST; | 886 | err = -EEXIST; |
866 | goto out; | 887 | goto out; |
867 | } | 888 | } |
889 | |||
890 | prealloc = alloc_extent_state_atomic(prealloc); | ||
891 | BUG_ON(!prealloc); | ||
868 | err = split_state(tree, state, prealloc, end + 1); | 892 | err = split_state(tree, state, prealloc, end + 1); |
869 | BUG_ON(err == -EEXIST); | 893 | BUG_ON(err == -EEXIST); |
870 | 894 | ||
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index b437cc790bfb..90d4ee52cd45 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -502,7 +502,6 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, | |||
502 | u32 new_size = (bytenr - key->offset) >> blocksize_bits; | 502 | u32 new_size = (bytenr - key->offset) >> blocksize_bits; |
503 | new_size *= csum_size; | 503 | new_size *= csum_size; |
504 | ret = btrfs_truncate_item(trans, root, path, new_size, 1); | 504 | ret = btrfs_truncate_item(trans, root, path, new_size, 1); |
505 | BUG_ON(ret); | ||
506 | } else if (key->offset >= bytenr && csum_end > end_byte && | 505 | } else if (key->offset >= bytenr && csum_end > end_byte && |
507 | end_byte > key->offset) { | 506 | end_byte > key->offset) { |
508 | /* | 507 | /* |
@@ -515,7 +514,6 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, | |||
515 | new_size *= csum_size; | 514 | new_size *= csum_size; |
516 | 515 | ||
517 | ret = btrfs_truncate_item(trans, root, path, new_size, 0); | 516 | ret = btrfs_truncate_item(trans, root, path, new_size, 0); |
518 | BUG_ON(ret); | ||
519 | 517 | ||
520 | key->offset = end_byte; | 518 | key->offset = end_byte; |
521 | ret = btrfs_set_item_key_safe(trans, root, path, key); | 519 | ret = btrfs_set_item_key_safe(trans, root, path, key); |
@@ -558,10 +556,10 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
558 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 556 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
559 | if (ret > 0) { | 557 | if (ret > 0) { |
560 | if (path->slots[0] == 0) | 558 | if (path->slots[0] == 0) |
561 | goto out; | 559 | break; |
562 | path->slots[0]--; | 560 | path->slots[0]--; |
563 | } else if (ret < 0) { | 561 | } else if (ret < 0) { |
564 | goto out; | 562 | break; |
565 | } | 563 | } |
566 | 564 | ||
567 | leaf = path->nodes[0]; | 565 | leaf = path->nodes[0]; |
@@ -586,7 +584,8 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
586 | /* delete the entire item, it is inside our range */ | 584 | /* delete the entire item, it is inside our range */ |
587 | if (key.offset >= bytenr && csum_end <= end_byte) { | 585 | if (key.offset >= bytenr && csum_end <= end_byte) { |
588 | ret = btrfs_del_item(trans, root, path); | 586 | ret = btrfs_del_item(trans, root, path); |
589 | BUG_ON(ret); | 587 | if (ret) |
588 | goto out; | ||
590 | if (key.offset == bytenr) | 589 | if (key.offset == bytenr) |
591 | break; | 590 | break; |
592 | } else if (key.offset < bytenr && csum_end > end_byte) { | 591 | } else if (key.offset < bytenr && csum_end > end_byte) { |
@@ -640,9 +639,10 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
640 | } | 639 | } |
641 | btrfs_release_path(path); | 640 | btrfs_release_path(path); |
642 | } | 641 | } |
642 | ret = 0; | ||
643 | out: | 643 | out: |
644 | btrfs_free_path(path); | 644 | btrfs_free_path(path); |
645 | return 0; | 645 | return ret; |
646 | } | 646 | } |
647 | 647 | ||
648 | int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, | 648 | int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, |
@@ -768,7 +768,6 @@ again: | |||
768 | goto insert; | 768 | goto insert; |
769 | 769 | ||
770 | ret = btrfs_extend_item(trans, root, path, diff); | 770 | ret = btrfs_extend_item(trans, root, path, diff); |
771 | BUG_ON(ret); | ||
772 | goto csum; | 771 | goto csum; |
773 | } | 772 | } |
774 | 773 | ||
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c index 64f1150bb48d..baa74f3db691 100644 --- a/fs/btrfs/inode-item.c +++ b/fs/btrfs/inode-item.c | |||
@@ -130,7 +130,6 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, | |||
130 | item_size - (ptr + sub_item_len - item_start)); | 130 | item_size - (ptr + sub_item_len - item_start)); |
131 | ret = btrfs_truncate_item(trans, root, path, | 131 | ret = btrfs_truncate_item(trans, root, path, |
132 | item_size - sub_item_len, 1); | 132 | item_size - sub_item_len, 1); |
133 | BUG_ON(ret); | ||
134 | out: | 133 | out: |
135 | btrfs_free_path(path); | 134 | btrfs_free_path(path); |
136 | return ret; | 135 | return ret; |
@@ -167,7 +166,6 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, | |||
167 | 166 | ||
168 | old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); | 167 | old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); |
169 | ret = btrfs_extend_item(trans, root, path, ins_len); | 168 | ret = btrfs_extend_item(trans, root, path, ins_len); |
170 | BUG_ON(ret); | ||
171 | ref = btrfs_item_ptr(path->nodes[0], path->slots[0], | 169 | ref = btrfs_item_ptr(path->nodes[0], path->slots[0], |
172 | struct btrfs_inode_ref); | 170 | struct btrfs_inode_ref); |
173 | ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size); | 171 | ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4d8ef95abf40..d378f8b70ef7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1323,7 +1323,7 @@ static int btrfs_set_bit_hook(struct inode *inode, | |||
1323 | 1323 | ||
1324 | /* | 1324 | /* |
1325 | * set_bit and clear bit hooks normally require _irqsave/restore | 1325 | * set_bit and clear bit hooks normally require _irqsave/restore |
1326 | * but in this case, we are only testeing for the DELALLOC | 1326 | * but in this case, we are only testing for the DELALLOC |
1327 | * bit, which is only set or cleared with irqs on | 1327 | * bit, which is only set or cleared with irqs on |
1328 | */ | 1328 | */ |
1329 | if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { | 1329 | if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { |
@@ -1356,7 +1356,7 @@ static int btrfs_clear_bit_hook(struct inode *inode, | |||
1356 | { | 1356 | { |
1357 | /* | 1357 | /* |
1358 | * set_bit and clear bit hooks normally require _irqsave/restore | 1358 | * set_bit and clear bit hooks normally require _irqsave/restore |
1359 | * but in this case, we are only testeing for the DELALLOC | 1359 | * but in this case, we are only testing for the DELALLOC |
1360 | * bit, which is only set or cleared with irqs on | 1360 | * bit, which is only set or cleared with irqs on |
1361 | */ | 1361 | */ |
1362 | if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { | 1362 | if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { |
@@ -3286,7 +3286,6 @@ search_again: | |||
3286 | btrfs_file_extent_calc_inline_size(size); | 3286 | btrfs_file_extent_calc_inline_size(size); |
3287 | ret = btrfs_truncate_item(trans, root, path, | 3287 | ret = btrfs_truncate_item(trans, root, path, |
3288 | size, 1); | 3288 | size, 1); |
3289 | BUG_ON(ret); | ||
3290 | } else if (root->ref_cows) { | 3289 | } else if (root->ref_cows) { |
3291 | inode_sub_bytes(inode, item_end + 1 - | 3290 | inode_sub_bytes(inode, item_end + 1 - |
3292 | found_key.offset); | 3291 | found_key.offset); |
@@ -7167,6 +7166,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
7167 | datasize); | 7166 | datasize); |
7168 | if (err) { | 7167 | if (err) { |
7169 | drop_inode = 1; | 7168 | drop_inode = 1; |
7169 | btrfs_free_path(path); | ||
7170 | goto out_unlock; | 7170 | goto out_unlock; |
7171 | } | 7171 | } |
7172 | leaf = path->nodes[0]; | 7172 | leaf = path->nodes[0]; |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e0a061db4353..c4f17e4e2c9c 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -282,8 +282,9 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
282 | if (!capable(CAP_SYS_ADMIN)) | 282 | if (!capable(CAP_SYS_ADMIN)) |
283 | return -EPERM; | 283 | return -EPERM; |
284 | 284 | ||
285 | mutex_lock(&fs_info->fs_devices->device_list_mutex); | 285 | rcu_read_lock(); |
286 | list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) { | 286 | list_for_each_entry_rcu(device, &fs_info->fs_devices->devices, |
287 | dev_list) { | ||
287 | if (!device->bdev) | 288 | if (!device->bdev) |
288 | continue; | 289 | continue; |
289 | q = bdev_get_queue(device->bdev); | 290 | q = bdev_get_queue(device->bdev); |
@@ -293,7 +294,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
293 | minlen); | 294 | minlen); |
294 | } | 295 | } |
295 | } | 296 | } |
296 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 297 | rcu_read_unlock(); |
297 | if (!num_devices) | 298 | if (!num_devices) |
298 | return -EOPNOTSUPP; | 299 | return -EOPNOTSUPP; |
299 | 300 | ||
@@ -1279,7 +1280,6 @@ static noinline int copy_to_sk(struct btrfs_root *root, | |||
1279 | int nritems; | 1280 | int nritems; |
1280 | int i; | 1281 | int i; |
1281 | int slot; | 1282 | int slot; |
1282 | int found = 0; | ||
1283 | int ret = 0; | 1283 | int ret = 0; |
1284 | 1284 | ||
1285 | leaf = path->nodes[0]; | 1285 | leaf = path->nodes[0]; |
@@ -1326,7 +1326,7 @@ static noinline int copy_to_sk(struct btrfs_root *root, | |||
1326 | item_off, item_len); | 1326 | item_off, item_len); |
1327 | *sk_offset += item_len; | 1327 | *sk_offset += item_len; |
1328 | } | 1328 | } |
1329 | found++; | 1329 | (*num_found)++; |
1330 | 1330 | ||
1331 | if (*num_found >= sk->nr_items) | 1331 | if (*num_found >= sk->nr_items) |
1332 | break; | 1332 | break; |
@@ -1345,7 +1345,6 @@ advance_key: | |||
1345 | } else | 1345 | } else |
1346 | ret = 1; | 1346 | ret = 1; |
1347 | overflow: | 1347 | overflow: |
1348 | *num_found += found; | ||
1349 | return ret; | 1348 | return ret; |
1350 | } | 1349 | } |
1351 | 1350 | ||
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 3bcfe5a7c330..ebe45443de06 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -338,7 +338,10 @@ again: | |||
338 | *sequence = btrfs_root_ref_sequence(leaf, ref); | 338 | *sequence = btrfs_root_ref_sequence(leaf, ref); |
339 | 339 | ||
340 | ret = btrfs_del_item(trans, tree_root, path); | 340 | ret = btrfs_del_item(trans, tree_root, path); |
341 | BUG_ON(ret); | 341 | if (ret) { |
342 | err = ret; | ||
343 | goto out; | ||
344 | } | ||
342 | } else | 345 | } else |
343 | err = -ENOENT; | 346 | err = -ENOENT; |
344 | 347 | ||
@@ -350,6 +353,7 @@ again: | |||
350 | goto again; | 353 | goto again; |
351 | } | 354 | } |
352 | 355 | ||
356 | out: | ||
353 | btrfs_free_path(path); | 357 | btrfs_free_path(path); |
354 | return err; | 358 | return err; |
355 | } | 359 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 006655c1d1f7..cd0c7cd2c8fb 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -507,8 +507,10 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
507 | */ | 507 | */ |
508 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | 508 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); |
509 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); | 509 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); |
510 | if (IS_ERR(di)) | 510 | if (IS_ERR(di)) { |
511 | btrfs_free_path(path); | ||
511 | return ERR_CAST(di); | 512 | return ERR_CAST(di); |
513 | } | ||
512 | if (!di) { | 514 | if (!di) { |
513 | /* | 515 | /* |
514 | * Ok the default dir item isn't there. This is weird since | 516 | * Ok the default dir item isn't there. This is weird since |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 0f5537e60bb4..592396c6dc47 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -382,7 +382,6 @@ insert: | |||
382 | } else if (found_size < item_size) { | 382 | } else if (found_size < item_size) { |
383 | ret = btrfs_extend_item(trans, root, path, | 383 | ret = btrfs_extend_item(trans, root, path, |
384 | item_size - found_size); | 384 | item_size - found_size); |
385 | BUG_ON(ret); | ||
386 | } | 385 | } |
387 | } else if (ret) { | 386 | } else if (ret) { |
388 | return ret; | 387 | return ret; |
@@ -590,6 +589,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
590 | ins.objectid, ins.offset, | 589 | ins.objectid, ins.offset, |
591 | 0, root->root_key.objectid, | 590 | 0, root->root_key.objectid, |
592 | key->objectid, offset); | 591 | key->objectid, offset); |
592 | BUG_ON(ret); | ||
593 | } else { | 593 | } else { |
594 | /* | 594 | /* |
595 | * insert the extent pointer in the extent | 595 | * insert the extent pointer in the extent |
@@ -678,7 +678,10 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, | |||
678 | btrfs_release_path(path); | 678 | btrfs_release_path(path); |
679 | 679 | ||
680 | inode = read_one_inode(root, location.objectid); | 680 | inode = read_one_inode(root, location.objectid); |
681 | BUG_ON(!inode); | 681 | if (!inode) { |
682 | kfree(name); | ||
683 | return -EIO; | ||
684 | } | ||
682 | 685 | ||
683 | ret = link_to_fixup_dir(trans, root, path, location.objectid); | 686 | ret = link_to_fixup_dir(trans, root, path, location.objectid); |
684 | BUG_ON(ret); | 687 | BUG_ON(ret); |
@@ -817,7 +820,10 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
817 | return -ENOENT; | 820 | return -ENOENT; |
818 | 821 | ||
819 | inode = read_one_inode(root, key->objectid); | 822 | inode = read_one_inode(root, key->objectid); |
820 | BUG_ON(!inode); | 823 | if (!inode) { |
824 | iput(dir); | ||
825 | return -EIO; | ||
826 | } | ||
821 | 827 | ||
822 | ref_ptr = btrfs_item_ptr_offset(eb, slot); | 828 | ref_ptr = btrfs_item_ptr_offset(eb, slot); |
823 | ref_end = ref_ptr + btrfs_item_size_nr(eb, slot); | 829 | ref_end = ref_ptr + btrfs_item_size_nr(eb, slot); |
@@ -1051,11 +1057,13 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, | |||
1051 | break; | 1057 | break; |
1052 | 1058 | ||
1053 | ret = btrfs_del_item(trans, root, path); | 1059 | ret = btrfs_del_item(trans, root, path); |
1054 | BUG_ON(ret); | 1060 | if (ret) |
1061 | goto out; | ||
1055 | 1062 | ||
1056 | btrfs_release_path(path); | 1063 | btrfs_release_path(path); |
1057 | inode = read_one_inode(root, key.offset); | 1064 | inode = read_one_inode(root, key.offset); |
1058 | BUG_ON(!inode); | 1065 | if (!inode) |
1066 | return -EIO; | ||
1059 | 1067 | ||
1060 | ret = fixup_inode_link_count(trans, root, inode); | 1068 | ret = fixup_inode_link_count(trans, root, inode); |
1061 | BUG_ON(ret); | 1069 | BUG_ON(ret); |
@@ -1069,8 +1077,10 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, | |||
1069 | */ | 1077 | */ |
1070 | key.offset = (u64)-1; | 1078 | key.offset = (u64)-1; |
1071 | } | 1079 | } |
1080 | ret = 0; | ||
1081 | out: | ||
1072 | btrfs_release_path(path); | 1082 | btrfs_release_path(path); |
1073 | return 0; | 1083 | return ret; |
1074 | } | 1084 | } |
1075 | 1085 | ||
1076 | 1086 | ||
@@ -1089,7 +1099,8 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, | |||
1089 | struct inode *inode; | 1099 | struct inode *inode; |
1090 | 1100 | ||
1091 | inode = read_one_inode(root, objectid); | 1101 | inode = read_one_inode(root, objectid); |
1092 | BUG_ON(!inode); | 1102 | if (!inode) |
1103 | return -EIO; | ||
1093 | 1104 | ||
1094 | key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID; | 1105 | key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID; |
1095 | btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); | 1106 | btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); |
@@ -1176,7 +1187,8 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, | |||
1176 | int ret; | 1187 | int ret; |
1177 | 1188 | ||
1178 | dir = read_one_inode(root, key->objectid); | 1189 | dir = read_one_inode(root, key->objectid); |
1179 | BUG_ON(!dir); | 1190 | if (!dir) |
1191 | return -EIO; | ||
1180 | 1192 | ||
1181 | name_len = btrfs_dir_name_len(eb, di); | 1193 | name_len = btrfs_dir_name_len(eb, di); |
1182 | name = kmalloc(name_len, GFP_NOFS); | 1194 | name = kmalloc(name_len, GFP_NOFS); |
@@ -1432,7 +1444,10 @@ again: | |||
1432 | btrfs_release_path(path); | 1444 | btrfs_release_path(path); |
1433 | btrfs_release_path(log_path); | 1445 | btrfs_release_path(log_path); |
1434 | inode = read_one_inode(root, location.objectid); | 1446 | inode = read_one_inode(root, location.objectid); |
1435 | BUG_ON(!inode); | 1447 | if (!inode) { |
1448 | kfree(name); | ||
1449 | return -EIO; | ||
1450 | } | ||
1436 | 1451 | ||
1437 | ret = link_to_fixup_dir(trans, root, | 1452 | ret = link_to_fixup_dir(trans, root, |
1438 | path, location.objectid); | 1453 | path, location.objectid); |
@@ -2589,7 +2604,8 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans, | |||
2589 | break; | 2604 | break; |
2590 | 2605 | ||
2591 | ret = btrfs_del_item(trans, log, path); | 2606 | ret = btrfs_del_item(trans, log, path); |
2592 | BUG_ON(ret); | 2607 | if (ret) |
2608 | break; | ||
2593 | btrfs_release_path(path); | 2609 | btrfs_release_path(path); |
2594 | } | 2610 | } |
2595 | btrfs_release_path(path); | 2611 | btrfs_release_path(path); |
diff --git a/fs/btrfs/version.sh b/fs/btrfs/version.sh deleted file mode 100644 index 1ca1952fd917..000000000000 --- a/fs/btrfs/version.sh +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # determine-version -- report a useful version for releases | ||
4 | # | ||
5 | # Copyright 2008, Aron Griffis <agriffis@n01se.net> | ||
6 | # Copyright 2008, Oracle | ||
7 | # Released under the GNU GPLv2 | ||
8 | |||
9 | v="v0.16" | ||
10 | |||
11 | which git &> /dev/null | ||
12 | if [ $? == 0 ]; then | ||
13 | git branch >& /dev/null | ||
14 | if [ $? == 0 ]; then | ||
15 | if head=`git rev-parse --verify HEAD 2>/dev/null`; then | ||
16 | if tag=`git describe --tags 2>/dev/null`; then | ||
17 | v="$tag" | ||
18 | fi | ||
19 | |||
20 | # Are there uncommitted changes? | ||
21 | git update-index --refresh --unmerged > /dev/null | ||
22 | if git diff-index --name-only HEAD | \ | ||
23 | grep -v "^scripts/package" \ | ||
24 | | read dummy; then | ||
25 | v="$v"-dirty | ||
26 | fi | ||
27 | fi | ||
28 | fi | ||
29 | fi | ||
30 | |||
31 | echo "#ifndef __BUILD_VERSION" > .build-version.h | ||
32 | echo "#define __BUILD_VERSION" >> .build-version.h | ||
33 | echo "#define BTRFS_BUILD_VERSION \"Btrfs $v\"" >> .build-version.h | ||
34 | echo "#endif" >> .build-version.h | ||
35 | |||
36 | diff -q version.h .build-version.h >& /dev/null | ||
37 | |||
38 | if [ $? == 0 ]; then | ||
39 | rm .build-version.h | ||
40 | exit 0 | ||
41 | fi | ||
42 | |||
43 | mv .build-version.h version.h | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index b8fc2fa91fdf..c48214ef5c09 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -350,7 +350,7 @@ static noinline int device_list_add(const char *path, | |||
350 | INIT_LIST_HEAD(&device->dev_alloc_list); | 350 | INIT_LIST_HEAD(&device->dev_alloc_list); |
351 | 351 | ||
352 | mutex_lock(&fs_devices->device_list_mutex); | 352 | mutex_lock(&fs_devices->device_list_mutex); |
353 | list_add(&device->dev_list, &fs_devices->devices); | 353 | list_add_rcu(&device->dev_list, &fs_devices->devices); |
354 | mutex_unlock(&fs_devices->device_list_mutex); | 354 | mutex_unlock(&fs_devices->device_list_mutex); |
355 | 355 | ||
356 | device->fs_devices = fs_devices; | 356 | device->fs_devices = fs_devices; |
@@ -393,7 +393,7 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig) | |||
393 | fs_devices->latest_trans = orig->latest_trans; | 393 | fs_devices->latest_trans = orig->latest_trans; |
394 | memcpy(fs_devices->fsid, orig->fsid, sizeof(fs_devices->fsid)); | 394 | memcpy(fs_devices->fsid, orig->fsid, sizeof(fs_devices->fsid)); |
395 | 395 | ||
396 | mutex_lock(&orig->device_list_mutex); | 396 | /* We have held the volume lock, it is safe to get the devices. */ |
397 | list_for_each_entry(orig_dev, &orig->devices, dev_list) { | 397 | list_for_each_entry(orig_dev, &orig->devices, dev_list) { |
398 | device = kzalloc(sizeof(*device), GFP_NOFS); | 398 | device = kzalloc(sizeof(*device), GFP_NOFS); |
399 | if (!device) | 399 | if (!device) |
@@ -416,10 +416,8 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig) | |||
416 | device->fs_devices = fs_devices; | 416 | device->fs_devices = fs_devices; |
417 | fs_devices->num_devices++; | 417 | fs_devices->num_devices++; |
418 | } | 418 | } |
419 | mutex_unlock(&orig->device_list_mutex); | ||
420 | return fs_devices; | 419 | return fs_devices; |
421 | error: | 420 | error: |
422 | mutex_unlock(&orig->device_list_mutex); | ||
423 | free_fs_devices(fs_devices); | 421 | free_fs_devices(fs_devices); |
424 | return ERR_PTR(-ENOMEM); | 422 | return ERR_PTR(-ENOMEM); |
425 | } | 423 | } |
@@ -430,7 +428,7 @@ int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) | |||
430 | 428 | ||
431 | mutex_lock(&uuid_mutex); | 429 | mutex_lock(&uuid_mutex); |
432 | again: | 430 | again: |
433 | mutex_lock(&fs_devices->device_list_mutex); | 431 | /* This is the initialized path, it is safe to release the devices. */ |
434 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { | 432 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { |
435 | if (device->in_fs_metadata) | 433 | if (device->in_fs_metadata) |
436 | continue; | 434 | continue; |
@@ -450,7 +448,6 @@ again: | |||
450 | kfree(device->name); | 448 | kfree(device->name); |
451 | kfree(device); | 449 | kfree(device); |
452 | } | 450 | } |
453 | mutex_unlock(&fs_devices->device_list_mutex); | ||
454 | 451 | ||
455 | if (fs_devices->seed) { | 452 | if (fs_devices->seed) { |
456 | fs_devices = fs_devices->seed; | 453 | fs_devices = fs_devices->seed; |
@@ -461,6 +458,29 @@ again: | |||
461 | return 0; | 458 | return 0; |
462 | } | 459 | } |
463 | 460 | ||
461 | static void __free_device(struct work_struct *work) | ||
462 | { | ||
463 | struct btrfs_device *device; | ||
464 | |||
465 | device = container_of(work, struct btrfs_device, rcu_work); | ||
466 | |||
467 | if (device->bdev) | ||
468 | blkdev_put(device->bdev, device->mode); | ||
469 | |||
470 | kfree(device->name); | ||
471 | kfree(device); | ||
472 | } | ||
473 | |||
474 | static void free_device(struct rcu_head *head) | ||
475 | { | ||
476 | struct btrfs_device *device; | ||
477 | |||
478 | device = container_of(head, struct btrfs_device, rcu); | ||
479 | |||
480 | INIT_WORK(&device->rcu_work, __free_device); | ||
481 | schedule_work(&device->rcu_work); | ||
482 | } | ||
483 | |||
464 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | 484 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
465 | { | 485 | { |
466 | struct btrfs_device *device; | 486 | struct btrfs_device *device; |
@@ -468,20 +488,32 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
468 | if (--fs_devices->opened > 0) | 488 | if (--fs_devices->opened > 0) |
469 | return 0; | 489 | return 0; |
470 | 490 | ||
491 | mutex_lock(&fs_devices->device_list_mutex); | ||
471 | list_for_each_entry(device, &fs_devices->devices, dev_list) { | 492 | list_for_each_entry(device, &fs_devices->devices, dev_list) { |
472 | if (device->bdev) { | 493 | struct btrfs_device *new_device; |
473 | blkdev_put(device->bdev, device->mode); | 494 | |
495 | if (device->bdev) | ||
474 | fs_devices->open_devices--; | 496 | fs_devices->open_devices--; |
475 | } | 497 | |
476 | if (device->writeable) { | 498 | if (device->writeable) { |
477 | list_del_init(&device->dev_alloc_list); | 499 | list_del_init(&device->dev_alloc_list); |
478 | fs_devices->rw_devices--; | 500 | fs_devices->rw_devices--; |
479 | } | 501 | } |
480 | 502 | ||
481 | device->bdev = NULL; | 503 | new_device = kmalloc(sizeof(*new_device), GFP_NOFS); |
482 | device->writeable = 0; | 504 | BUG_ON(!new_device); |
483 | device->in_fs_metadata = 0; | 505 | memcpy(new_device, device, sizeof(*new_device)); |
506 | new_device->name = kstrdup(device->name, GFP_NOFS); | ||
507 | BUG_ON(!new_device->name); | ||
508 | new_device->bdev = NULL; | ||
509 | new_device->writeable = 0; | ||
510 | new_device->in_fs_metadata = 0; | ||
511 | list_replace_rcu(&device->dev_list, &new_device->dev_list); | ||
512 | |||
513 | call_rcu(&device->rcu, free_device); | ||
484 | } | 514 | } |
515 | mutex_unlock(&fs_devices->device_list_mutex); | ||
516 | |||
485 | WARN_ON(fs_devices->open_devices); | 517 | WARN_ON(fs_devices->open_devices); |
486 | WARN_ON(fs_devices->rw_devices); | 518 | WARN_ON(fs_devices->rw_devices); |
487 | fs_devices->opened = 0; | 519 | fs_devices->opened = 0; |
@@ -584,6 +616,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
584 | list_add(&device->dev_alloc_list, | 616 | list_add(&device->dev_alloc_list, |
585 | &fs_devices->alloc_list); | 617 | &fs_devices->alloc_list); |
586 | } | 618 | } |
619 | brelse(bh); | ||
587 | continue; | 620 | continue; |
588 | 621 | ||
589 | error_brelse: | 622 | error_brelse: |
@@ -933,14 +966,14 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, | |||
933 | if (ret > 0) { | 966 | if (ret > 0) { |
934 | ret = btrfs_previous_item(root, path, key.objectid, | 967 | ret = btrfs_previous_item(root, path, key.objectid, |
935 | BTRFS_DEV_EXTENT_KEY); | 968 | BTRFS_DEV_EXTENT_KEY); |
936 | BUG_ON(ret); | 969 | if (ret) |
970 | goto out; | ||
937 | leaf = path->nodes[0]; | 971 | leaf = path->nodes[0]; |
938 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 972 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
939 | extent = btrfs_item_ptr(leaf, path->slots[0], | 973 | extent = btrfs_item_ptr(leaf, path->slots[0], |
940 | struct btrfs_dev_extent); | 974 | struct btrfs_dev_extent); |
941 | BUG_ON(found_key.offset > start || found_key.offset + | 975 | BUG_ON(found_key.offset > start || found_key.offset + |
942 | btrfs_dev_extent_length(leaf, extent) < start); | 976 | btrfs_dev_extent_length(leaf, extent) < start); |
943 | ret = 0; | ||
944 | } else if (ret == 0) { | 977 | } else if (ret == 0) { |
945 | leaf = path->nodes[0]; | 978 | leaf = path->nodes[0]; |
946 | extent = btrfs_item_ptr(leaf, path->slots[0], | 979 | extent = btrfs_item_ptr(leaf, path->slots[0], |
@@ -951,8 +984,8 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, | |||
951 | if (device->bytes_used > 0) | 984 | if (device->bytes_used > 0) |
952 | device->bytes_used -= btrfs_dev_extent_length(leaf, extent); | 985 | device->bytes_used -= btrfs_dev_extent_length(leaf, extent); |
953 | ret = btrfs_del_item(trans, root, path); | 986 | ret = btrfs_del_item(trans, root, path); |
954 | BUG_ON(ret); | ||
955 | 987 | ||
988 | out: | ||
956 | btrfs_free_path(path); | 989 | btrfs_free_path(path); |
957 | return ret; | 990 | return ret; |
958 | } | 991 | } |
@@ -1187,11 +1220,13 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1187 | struct block_device *bdev; | 1220 | struct block_device *bdev; |
1188 | struct buffer_head *bh = NULL; | 1221 | struct buffer_head *bh = NULL; |
1189 | struct btrfs_super_block *disk_super; | 1222 | struct btrfs_super_block *disk_super; |
1223 | struct btrfs_fs_devices *cur_devices; | ||
1190 | u64 all_avail; | 1224 | u64 all_avail; |
1191 | u64 devid; | 1225 | u64 devid; |
1192 | u64 num_devices; | 1226 | u64 num_devices; |
1193 | u8 *dev_uuid; | 1227 | u8 *dev_uuid; |
1194 | int ret = 0; | 1228 | int ret = 0; |
1229 | bool clear_super = false; | ||
1195 | 1230 | ||
1196 | mutex_lock(&uuid_mutex); | 1231 | mutex_lock(&uuid_mutex); |
1197 | mutex_lock(&root->fs_info->volume_mutex); | 1232 | mutex_lock(&root->fs_info->volume_mutex); |
@@ -1222,14 +1257,16 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1222 | 1257 | ||
1223 | device = NULL; | 1258 | device = NULL; |
1224 | devices = &root->fs_info->fs_devices->devices; | 1259 | devices = &root->fs_info->fs_devices->devices; |
1225 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | 1260 | /* |
1261 | * It is safe to read the devices since the volume_mutex | ||
1262 | * is held. | ||
1263 | */ | ||
1226 | list_for_each_entry(tmp, devices, dev_list) { | 1264 | list_for_each_entry(tmp, devices, dev_list) { |
1227 | if (tmp->in_fs_metadata && !tmp->bdev) { | 1265 | if (tmp->in_fs_metadata && !tmp->bdev) { |
1228 | device = tmp; | 1266 | device = tmp; |
1229 | break; | 1267 | break; |
1230 | } | 1268 | } |
1231 | } | 1269 | } |
1232 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | ||
1233 | bdev = NULL; | 1270 | bdev = NULL; |
1234 | bh = NULL; | 1271 | bh = NULL; |
1235 | disk_super = NULL; | 1272 | disk_super = NULL; |
@@ -1271,8 +1308,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1271 | } | 1308 | } |
1272 | 1309 | ||
1273 | if (device->writeable) { | 1310 | if (device->writeable) { |
1311 | lock_chunks(root); | ||
1274 | list_del_init(&device->dev_alloc_list); | 1312 | list_del_init(&device->dev_alloc_list); |
1313 | unlock_chunks(root); | ||
1275 | root->fs_info->fs_devices->rw_devices--; | 1314 | root->fs_info->fs_devices->rw_devices--; |
1315 | clear_super = true; | ||
1276 | } | 1316 | } |
1277 | 1317 | ||
1278 | ret = btrfs_shrink_device(device, 0); | 1318 | ret = btrfs_shrink_device(device, 0); |
@@ -1291,9 +1331,10 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1291 | * the device list while someone else is writing out all | 1331 | * the device list while someone else is writing out all |
1292 | * the device supers. | 1332 | * the device supers. |
1293 | */ | 1333 | */ |
1334 | |||
1335 | cur_devices = device->fs_devices; | ||
1294 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | 1336 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); |
1295 | list_del_init(&device->dev_list); | 1337 | list_del_rcu(&device->dev_list); |
1296 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | ||
1297 | 1338 | ||
1298 | device->fs_devices->num_devices--; | 1339 | device->fs_devices->num_devices--; |
1299 | 1340 | ||
@@ -1307,34 +1348,36 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1307 | if (device->bdev == root->fs_info->fs_devices->latest_bdev) | 1348 | if (device->bdev == root->fs_info->fs_devices->latest_bdev) |
1308 | root->fs_info->fs_devices->latest_bdev = next_device->bdev; | 1349 | root->fs_info->fs_devices->latest_bdev = next_device->bdev; |
1309 | 1350 | ||
1310 | if (device->bdev) { | 1351 | if (device->bdev) |
1311 | blkdev_put(device->bdev, device->mode); | ||
1312 | device->bdev = NULL; | ||
1313 | device->fs_devices->open_devices--; | 1352 | device->fs_devices->open_devices--; |
1314 | } | 1353 | |
1354 | call_rcu(&device->rcu, free_device); | ||
1355 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | ||
1315 | 1356 | ||
1316 | num_devices = btrfs_super_num_devices(&root->fs_info->super_copy) - 1; | 1357 | num_devices = btrfs_super_num_devices(&root->fs_info->super_copy) - 1; |
1317 | btrfs_set_super_num_devices(&root->fs_info->super_copy, num_devices); | 1358 | btrfs_set_super_num_devices(&root->fs_info->super_copy, num_devices); |
1318 | 1359 | ||
1319 | if (device->fs_devices->open_devices == 0) { | 1360 | if (cur_devices->open_devices == 0) { |
1320 | struct btrfs_fs_devices *fs_devices; | 1361 | struct btrfs_fs_devices *fs_devices; |
1321 | fs_devices = root->fs_info->fs_devices; | 1362 | fs_devices = root->fs_info->fs_devices; |
1322 | while (fs_devices) { | 1363 | while (fs_devices) { |
1323 | if (fs_devices->seed == device->fs_devices) | 1364 | if (fs_devices->seed == cur_devices) |
1324 | break; | 1365 | break; |
1325 | fs_devices = fs_devices->seed; | 1366 | fs_devices = fs_devices->seed; |
1326 | } | 1367 | } |
1327 | fs_devices->seed = device->fs_devices->seed; | 1368 | fs_devices->seed = cur_devices->seed; |
1328 | device->fs_devices->seed = NULL; | 1369 | cur_devices->seed = NULL; |
1329 | __btrfs_close_devices(device->fs_devices); | 1370 | lock_chunks(root); |
1330 | free_fs_devices(device->fs_devices); | 1371 | __btrfs_close_devices(cur_devices); |
1372 | unlock_chunks(root); | ||
1373 | free_fs_devices(cur_devices); | ||
1331 | } | 1374 | } |
1332 | 1375 | ||
1333 | /* | 1376 | /* |
1334 | * at this point, the device is zero sized. We want to | 1377 | * at this point, the device is zero sized. We want to |
1335 | * remove it from the devices list and zero out the old super | 1378 | * remove it from the devices list and zero out the old super |
1336 | */ | 1379 | */ |
1337 | if (device->writeable) { | 1380 | if (clear_super) { |
1338 | /* make sure this device isn't detected as part of | 1381 | /* make sure this device isn't detected as part of |
1339 | * the FS anymore | 1382 | * the FS anymore |
1340 | */ | 1383 | */ |
@@ -1343,8 +1386,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1343 | sync_dirty_buffer(bh); | 1386 | sync_dirty_buffer(bh); |
1344 | } | 1387 | } |
1345 | 1388 | ||
1346 | kfree(device->name); | ||
1347 | kfree(device); | ||
1348 | ret = 0; | 1389 | ret = 0; |
1349 | 1390 | ||
1350 | error_brelse: | 1391 | error_brelse: |
@@ -1358,8 +1399,10 @@ out: | |||
1358 | return ret; | 1399 | return ret; |
1359 | error_undo: | 1400 | error_undo: |
1360 | if (device->writeable) { | 1401 | if (device->writeable) { |
1402 | lock_chunks(root); | ||
1361 | list_add(&device->dev_alloc_list, | 1403 | list_add(&device->dev_alloc_list, |
1362 | &root->fs_info->fs_devices->alloc_list); | 1404 | &root->fs_info->fs_devices->alloc_list); |
1405 | unlock_chunks(root); | ||
1363 | root->fs_info->fs_devices->rw_devices++; | 1406 | root->fs_info->fs_devices->rw_devices++; |
1364 | } | 1407 | } |
1365 | goto error_brelse; | 1408 | goto error_brelse; |
@@ -1399,7 +1442,12 @@ static int btrfs_prepare_sprout(struct btrfs_trans_handle *trans, | |||
1399 | INIT_LIST_HEAD(&seed_devices->devices); | 1442 | INIT_LIST_HEAD(&seed_devices->devices); |
1400 | INIT_LIST_HEAD(&seed_devices->alloc_list); | 1443 | INIT_LIST_HEAD(&seed_devices->alloc_list); |
1401 | mutex_init(&seed_devices->device_list_mutex); | 1444 | mutex_init(&seed_devices->device_list_mutex); |
1402 | list_splice_init(&fs_devices->devices, &seed_devices->devices); | 1445 | |
1446 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | ||
1447 | list_splice_init_rcu(&fs_devices->devices, &seed_devices->devices, | ||
1448 | synchronize_rcu); | ||
1449 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | ||
1450 | |||
1403 | list_splice_init(&fs_devices->alloc_list, &seed_devices->alloc_list); | 1451 | list_splice_init(&fs_devices->alloc_list, &seed_devices->alloc_list); |
1404 | list_for_each_entry(device, &seed_devices->devices, dev_list) { | 1452 | list_for_each_entry(device, &seed_devices->devices, dev_list) { |
1405 | device->fs_devices = seed_devices; | 1453 | device->fs_devices = seed_devices; |
@@ -1596,7 +1644,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1596 | * half setup | 1644 | * half setup |
1597 | */ | 1645 | */ |
1598 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | 1646 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); |
1599 | list_add(&device->dev_list, &root->fs_info->fs_devices->devices); | 1647 | list_add_rcu(&device->dev_list, &root->fs_info->fs_devices->devices); |
1600 | list_add(&device->dev_alloc_list, | 1648 | list_add(&device->dev_alloc_list, |
1601 | &root->fs_info->fs_devices->alloc_list); | 1649 | &root->fs_info->fs_devices->alloc_list); |
1602 | root->fs_info->fs_devices->num_devices++; | 1650 | root->fs_info->fs_devices->num_devices++; |
@@ -1754,10 +1802,9 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans, | |||
1754 | BUG_ON(ret); | 1802 | BUG_ON(ret); |
1755 | 1803 | ||
1756 | ret = btrfs_del_item(trans, root, path); | 1804 | ret = btrfs_del_item(trans, root, path); |
1757 | BUG_ON(ret); | ||
1758 | 1805 | ||
1759 | btrfs_free_path(path); | 1806 | btrfs_free_path(path); |
1760 | return 0; | 1807 | return ret; |
1761 | } | 1808 | } |
1762 | 1809 | ||
1763 | static int btrfs_del_sys_chunk(struct btrfs_root *root, u64 chunk_objectid, u64 | 1810 | static int btrfs_del_sys_chunk(struct btrfs_root *root, u64 chunk_objectid, u64 |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 7c58a7b2d99f..7c12d61ae7ae 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -89,6 +89,8 @@ struct btrfs_device { | |||
89 | struct scrub_dev *scrub_device; | 89 | struct scrub_dev *scrub_device; |
90 | 90 | ||
91 | struct btrfs_work work; | 91 | struct btrfs_work work; |
92 | struct rcu_head rcu; | ||
93 | struct work_struct rcu_work; | ||
92 | }; | 94 | }; |
93 | 95 | ||
94 | struct btrfs_fs_devices { | 96 | struct btrfs_fs_devices { |