aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2011-10-03 23:22:32 -0400
committerDavid Sterba <dsterba@suse.cz>2012-03-21 20:45:30 -0400
commitc2d904e086b6f707b73bf065e4d18ded4b86ae9e (patch)
tree44ab2acff4eaefca2abd3273bd31fbc74f73f96c /fs/btrfs/extent_io.c
parent8c3429300181be44b30f9f017d53dc717da56caa (diff)
btrfs: Catch locking failures in {set,clear,convert}_extent_bit
The *_state functions can only return 0 or -EEXIST. This patch addresses the cases where those functions returning -EEXIST represent a locking failure. It handles them by panicking with an appropriate error message. Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index a55fbe6252de..601f23bddea8 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -53,6 +53,12 @@ struct extent_page_data {
53 unsigned int sync_io:1; 53 unsigned int sync_io:1;
54}; 54};
55 55
56static inline struct btrfs_fs_info *
57tree_fs_info(struct extent_io_tree *tree)
58{
59 return btrfs_sb(tree->mapping->host->i_sb);
60}
61
56int __init extent_io_init(void) 62int __init extent_io_init(void)
57{ 63{
58 extent_state_cache = kmem_cache_create("extent_state", 64 extent_state_cache = kmem_cache_create("extent_state",
@@ -439,6 +445,13 @@ alloc_extent_state_atomic(struct extent_state *prealloc)
439 return prealloc; 445 return prealloc;
440} 446}
441 447
448void extent_io_tree_panic(struct extent_io_tree *tree, int err)
449{
450 btrfs_panic(tree_fs_info(tree), err, "Locking error: "
451 "Extent tree was modified by another "
452 "thread while locked.");
453}
454
442/* 455/*
443 * clear some bits on a range in the tree. This may require splitting 456 * 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 457 * or inserting elements in the tree, so the gfp mask is used to
@@ -542,7 +555,9 @@ hit_next:
542 prealloc = alloc_extent_state_atomic(prealloc); 555 prealloc = alloc_extent_state_atomic(prealloc);
543 BUG_ON(!prealloc); 556 BUG_ON(!prealloc);
544 err = split_state(tree, state, prealloc, start); 557 err = split_state(tree, state, prealloc, start);
545 BUG_ON(err == -EEXIST); 558 if (err)
559 extent_io_tree_panic(tree, err);
560
546 prealloc = NULL; 561 prealloc = NULL;
547 if (err) 562 if (err)
548 goto out; 563 goto out;
@@ -564,7 +579,9 @@ hit_next:
564 prealloc = alloc_extent_state_atomic(prealloc); 579 prealloc = alloc_extent_state_atomic(prealloc);
565 BUG_ON(!prealloc); 580 BUG_ON(!prealloc);
566 err = split_state(tree, state, prealloc, end + 1); 581 err = split_state(tree, state, prealloc, end + 1);
567 BUG_ON(err == -EEXIST); 582 if (err)
583 extent_io_tree_panic(tree, err);
584
568 if (wake) 585 if (wake)
569 wake_up(&state->wq); 586 wake_up(&state->wq);
570 587
@@ -742,8 +759,10 @@ again:
742 prealloc = alloc_extent_state_atomic(prealloc); 759 prealloc = alloc_extent_state_atomic(prealloc);
743 BUG_ON(!prealloc); 760 BUG_ON(!prealloc);
744 err = insert_state(tree, prealloc, start, end, &bits); 761 err = insert_state(tree, prealloc, start, end, &bits);
762 if (err)
763 extent_io_tree_panic(tree, err);
764
745 prealloc = NULL; 765 prealloc = NULL;
746 BUG_ON(err == -EEXIST);
747 goto out; 766 goto out;
748 } 767 }
749 state = rb_entry(node, struct extent_state, rb_node); 768 state = rb_entry(node, struct extent_state, rb_node);
@@ -809,7 +828,9 @@ hit_next:
809 prealloc = alloc_extent_state_atomic(prealloc); 828 prealloc = alloc_extent_state_atomic(prealloc);
810 BUG_ON(!prealloc); 829 BUG_ON(!prealloc);
811 err = split_state(tree, state, prealloc, start); 830 err = split_state(tree, state, prealloc, start);
812 BUG_ON(err == -EEXIST); 831 if (err)
832 extent_io_tree_panic(tree, err);
833
813 prealloc = NULL; 834 prealloc = NULL;
814 if (err) 835 if (err)
815 goto out; 836 goto out;
@@ -846,12 +867,9 @@ hit_next:
846 */ 867 */
847 err = insert_state(tree, prealloc, start, this_end, 868 err = insert_state(tree, prealloc, start, this_end,
848 &bits); 869 &bits);
849 BUG_ON(err == -EEXIST); 870 if (err)
850 if (err) { 871 extent_io_tree_panic(tree, err);
851 free_extent_state(prealloc); 872
852 prealloc = NULL;
853 goto out;
854 }
855 cache_state(prealloc, cached_state); 873 cache_state(prealloc, cached_state);
856 prealloc = NULL; 874 prealloc = NULL;
857 start = this_end + 1; 875 start = this_end + 1;
@@ -873,7 +891,8 @@ hit_next:
873 prealloc = alloc_extent_state_atomic(prealloc); 891 prealloc = alloc_extent_state_atomic(prealloc);
874 BUG_ON(!prealloc); 892 BUG_ON(!prealloc);
875 err = split_state(tree, state, prealloc, end + 1); 893 err = split_state(tree, state, prealloc, end + 1);
876 BUG_ON(err == -EEXIST); 894 if (err)
895 extent_io_tree_panic(tree, err);
877 896
878 set_state_bits(tree, prealloc, &bits); 897 set_state_bits(tree, prealloc, &bits);
879 cache_state(prealloc, cached_state); 898 cache_state(prealloc, cached_state);
@@ -946,7 +965,8 @@ again:
946 } 965 }
947 err = insert_state(tree, prealloc, start, end, &bits); 966 err = insert_state(tree, prealloc, start, end, &bits);
948 prealloc = NULL; 967 prealloc = NULL;
949 BUG_ON(err == -EEXIST); 968 if (err)
969 extent_io_tree_panic(tree, err);
950 goto out; 970 goto out;
951 } 971 }
952 state = rb_entry(node, struct extent_state, rb_node); 972 state = rb_entry(node, struct extent_state, rb_node);
@@ -1002,7 +1022,8 @@ hit_next:
1002 goto out; 1022 goto out;
1003 } 1023 }
1004 err = split_state(tree, state, prealloc, start); 1024 err = split_state(tree, state, prealloc, start);
1005 BUG_ON(err == -EEXIST); 1025 if (err)
1026 extent_io_tree_panic(tree, err);
1006 prealloc = NULL; 1027 prealloc = NULL;
1007 if (err) 1028 if (err)
1008 goto out; 1029 goto out;
@@ -1041,12 +1062,8 @@ hit_next:
1041 */ 1062 */
1042 err = insert_state(tree, prealloc, start, this_end, 1063 err = insert_state(tree, prealloc, start, this_end,
1043 &bits); 1064 &bits);
1044 BUG_ON(err == -EEXIST); 1065 if (err)
1045 if (err) { 1066 extent_io_tree_panic(tree, err);
1046 free_extent_state(prealloc);
1047 prealloc = NULL;
1048 goto out;
1049 }
1050 prealloc = NULL; 1067 prealloc = NULL;
1051 start = this_end + 1; 1068 start = this_end + 1;
1052 goto search_again; 1069 goto search_again;
@@ -1065,7 +1082,8 @@ hit_next:
1065 } 1082 }
1066 1083
1067 err = split_state(tree, state, prealloc, end + 1); 1084 err = split_state(tree, state, prealloc, end + 1);
1068 BUG_ON(err == -EEXIST); 1085 if (err)
1086 extent_io_tree_panic(tree, err);
1069 1087
1070 set_state_bits(tree, prealloc, &bits); 1088 set_state_bits(tree, prealloc, &bits);
1071 clear_state_bit(tree, prealloc, &clear_bits, 0); 1089 clear_state_bit(tree, prealloc, &clear_bits, 0);