diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 392592dc7010..76a0c8597d98 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -206,10 +206,8 @@ void extent_io_exit(void) | |||
206 | * destroy caches. | 206 | * destroy caches. |
207 | */ | 207 | */ |
208 | rcu_barrier(); | 208 | rcu_barrier(); |
209 | if (extent_state_cache) | 209 | kmem_cache_destroy(extent_state_cache); |
210 | kmem_cache_destroy(extent_state_cache); | 210 | kmem_cache_destroy(extent_buffer_cache); |
211 | if (extent_buffer_cache) | ||
212 | kmem_cache_destroy(extent_buffer_cache); | ||
213 | if (btrfs_bioset) | 211 | if (btrfs_bioset) |
214 | bioset_free(btrfs_bioset); | 212 | bioset_free(btrfs_bioset); |
215 | } | 213 | } |
@@ -232,7 +230,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask) | |||
232 | if (!state) | 230 | if (!state) |
233 | return state; | 231 | return state; |
234 | state->state = 0; | 232 | state->state = 0; |
235 | state->private = 0; | 233 | state->failrec = NULL; |
236 | RB_CLEAR_NODE(&state->rb_node); | 234 | RB_CLEAR_NODE(&state->rb_node); |
237 | btrfs_leak_debug_add(&state->leak_list, &states); | 235 | btrfs_leak_debug_add(&state->leak_list, &states); |
238 | atomic_set(&state->refs, 1); | 236 | atomic_set(&state->refs, 1); |
@@ -1844,7 +1842,8 @@ out: | |||
1844 | * set the private field for a given byte offset in the tree. If there isn't | 1842 | * set the private field for a given byte offset in the tree. If there isn't |
1845 | * an extent_state there already, this does nothing. | 1843 | * an extent_state there already, this does nothing. |
1846 | */ | 1844 | */ |
1847 | static int set_state_private(struct extent_io_tree *tree, u64 start, u64 private) | 1845 | static noinline int set_state_failrec(struct extent_io_tree *tree, u64 start, |
1846 | struct io_failure_record *failrec) | ||
1848 | { | 1847 | { |
1849 | struct rb_node *node; | 1848 | struct rb_node *node; |
1850 | struct extent_state *state; | 1849 | struct extent_state *state; |
@@ -1865,13 +1864,14 @@ static int set_state_private(struct extent_io_tree *tree, u64 start, u64 private | |||
1865 | ret = -ENOENT; | 1864 | ret = -ENOENT; |
1866 | goto out; | 1865 | goto out; |
1867 | } | 1866 | } |
1868 | state->private = private; | 1867 | state->failrec = failrec; |
1869 | out: | 1868 | out: |
1870 | spin_unlock(&tree->lock); | 1869 | spin_unlock(&tree->lock); |
1871 | return ret; | 1870 | return ret; |
1872 | } | 1871 | } |
1873 | 1872 | ||
1874 | int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private) | 1873 | static noinline int get_state_failrec(struct extent_io_tree *tree, u64 start, |
1874 | struct io_failure_record **failrec) | ||
1875 | { | 1875 | { |
1876 | struct rb_node *node; | 1876 | struct rb_node *node; |
1877 | struct extent_state *state; | 1877 | struct extent_state *state; |
@@ -1892,7 +1892,7 @@ int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private) | |||
1892 | ret = -ENOENT; | 1892 | ret = -ENOENT; |
1893 | goto out; | 1893 | goto out; |
1894 | } | 1894 | } |
1895 | *private = state->private; | 1895 | *failrec = state->failrec; |
1896 | out: | 1896 | out: |
1897 | spin_unlock(&tree->lock); | 1897 | spin_unlock(&tree->lock); |
1898 | return ret; | 1898 | return ret; |
@@ -1972,7 +1972,7 @@ int free_io_failure(struct inode *inode, struct io_failure_record *rec) | |||
1972 | int err = 0; | 1972 | int err = 0; |
1973 | struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree; | 1973 | struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree; |
1974 | 1974 | ||
1975 | set_state_private(failure_tree, rec->start, 0); | 1975 | set_state_failrec(failure_tree, rec->start, NULL); |
1976 | ret = clear_extent_bits(failure_tree, rec->start, | 1976 | ret = clear_extent_bits(failure_tree, rec->start, |
1977 | rec->start + rec->len - 1, | 1977 | rec->start + rec->len - 1, |
1978 | EXTENT_LOCKED | EXTENT_DIRTY, GFP_NOFS); | 1978 | EXTENT_LOCKED | EXTENT_DIRTY, GFP_NOFS); |
@@ -2089,7 +2089,6 @@ int clean_io_failure(struct inode *inode, u64 start, struct page *page, | |||
2089 | unsigned int pg_offset) | 2089 | unsigned int pg_offset) |
2090 | { | 2090 | { |
2091 | u64 private; | 2091 | u64 private; |
2092 | u64 private_failure; | ||
2093 | struct io_failure_record *failrec; | 2092 | struct io_failure_record *failrec; |
2094 | struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; | 2093 | struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; |
2095 | struct extent_state *state; | 2094 | struct extent_state *state; |
@@ -2102,12 +2101,11 @@ int clean_io_failure(struct inode *inode, u64 start, struct page *page, | |||
2102 | if (!ret) | 2101 | if (!ret) |
2103 | return 0; | 2102 | return 0; |
2104 | 2103 | ||
2105 | ret = get_state_private(&BTRFS_I(inode)->io_failure_tree, start, | 2104 | ret = get_state_failrec(&BTRFS_I(inode)->io_failure_tree, start, |
2106 | &private_failure); | 2105 | &failrec); |
2107 | if (ret) | 2106 | if (ret) |
2108 | return 0; | 2107 | return 0; |
2109 | 2108 | ||
2110 | failrec = (struct io_failure_record *)(unsigned long) private_failure; | ||
2111 | BUG_ON(!failrec->this_mirror); | 2109 | BUG_ON(!failrec->this_mirror); |
2112 | 2110 | ||
2113 | if (failrec->in_validation) { | 2111 | if (failrec->in_validation) { |
@@ -2167,7 +2165,7 @@ void btrfs_free_io_failure_record(struct inode *inode, u64 start, u64 end) | |||
2167 | 2165 | ||
2168 | next = next_state(state); | 2166 | next = next_state(state); |
2169 | 2167 | ||
2170 | failrec = (struct io_failure_record *)(unsigned long)state->private; | 2168 | failrec = state->failrec; |
2171 | free_extent_state(state); | 2169 | free_extent_state(state); |
2172 | kfree(failrec); | 2170 | kfree(failrec); |
2173 | 2171 | ||
@@ -2177,10 +2175,9 @@ void btrfs_free_io_failure_record(struct inode *inode, u64 start, u64 end) | |||
2177 | } | 2175 | } |
2178 | 2176 | ||
2179 | int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end, | 2177 | int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end, |
2180 | struct io_failure_record **failrec_ret) | 2178 | struct io_failure_record **failrec_ret) |
2181 | { | 2179 | { |
2182 | struct io_failure_record *failrec; | 2180 | struct io_failure_record *failrec; |
2183 | u64 private; | ||
2184 | struct extent_map *em; | 2181 | struct extent_map *em; |
2185 | struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree; | 2182 | struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree; |
2186 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; | 2183 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; |
@@ -2188,7 +2185,7 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end, | |||
2188 | int ret; | 2185 | int ret; |
2189 | u64 logical; | 2186 | u64 logical; |
2190 | 2187 | ||
2191 | ret = get_state_private(failure_tree, start, &private); | 2188 | ret = get_state_failrec(failure_tree, start, &failrec); |
2192 | if (ret) { | 2189 | if (ret) { |
2193 | failrec = kzalloc(sizeof(*failrec), GFP_NOFS); | 2190 | failrec = kzalloc(sizeof(*failrec), GFP_NOFS); |
2194 | if (!failrec) | 2191 | if (!failrec) |
@@ -2237,8 +2234,7 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end, | |||
2237 | ret = set_extent_bits(failure_tree, start, end, | 2234 | ret = set_extent_bits(failure_tree, start, end, |
2238 | EXTENT_LOCKED | EXTENT_DIRTY, GFP_NOFS); | 2235 | EXTENT_LOCKED | EXTENT_DIRTY, GFP_NOFS); |
2239 | if (ret >= 0) | 2236 | if (ret >= 0) |
2240 | ret = set_state_private(failure_tree, start, | 2237 | ret = set_state_failrec(failure_tree, start, failrec); |
2241 | (u64)(unsigned long)failrec); | ||
2242 | /* set the bits in the inode's tree */ | 2238 | /* set the bits in the inode's tree */ |
2243 | if (ret >= 0) | 2239 | if (ret >= 0) |
2244 | ret = set_extent_bits(tree, start, end, EXTENT_DAMAGED, | 2240 | ret = set_extent_bits(tree, start, end, EXTENT_DAMAGED, |
@@ -2248,7 +2244,6 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end, | |||
2248 | return ret; | 2244 | return ret; |
2249 | } | 2245 | } |
2250 | } else { | 2246 | } else { |
2251 | failrec = (struct io_failure_record *)(unsigned long)private; | ||
2252 | pr_debug("Get IO Failure Record: (found) logical=%llu, start=%llu, len=%llu, validation=%d\n", | 2247 | pr_debug("Get IO Failure Record: (found) logical=%llu, start=%llu, len=%llu, validation=%d\n", |
2253 | failrec->logical, failrec->start, failrec->len, | 2248 | failrec->logical, failrec->start, failrec->len, |
2254 | failrec->in_validation); | 2249 | failrec->in_validation); |
@@ -3177,7 +3172,8 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
3177 | 3172 | ||
3178 | while (1) { | 3173 | while (1) { |
3179 | lock_extent(tree, start, end); | 3174 | lock_extent(tree, start, end); |
3180 | ordered = btrfs_lookup_ordered_extent(inode, start); | 3175 | ordered = btrfs_lookup_ordered_range(inode, start, |
3176 | PAGE_CACHE_SIZE); | ||
3181 | if (!ordered) | 3177 | if (!ordered) |
3182 | break; | 3178 | break; |
3183 | unlock_extent(tree, start, end); | 3179 | unlock_extent(tree, start, end); |