aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent_io.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 5392c3b12fc1..7b60f621e761 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3268,6 +3268,22 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree,
3268 return was_dirty; 3268 return was_dirty;
3269} 3269}
3270 3270
3271static int __eb_straddles_pages(u64 start, u64 len)
3272{
3273 if (len < PAGE_CACHE_SIZE)
3274 return 1;
3275 if (start & (PAGE_CACHE_SIZE - 1))
3276 return 1;
3277 if ((start + len) & (PAGE_CACHE_SIZE - 1))
3278 return 1;
3279 return 0;
3280}
3281
3282static int eb_straddles_pages(struct extent_buffer *eb)
3283{
3284 return __eb_straddles_pages(eb->start, eb->len);
3285}
3286
3271int clear_extent_buffer_uptodate(struct extent_io_tree *tree, 3287int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
3272 struct extent_buffer *eb, 3288 struct extent_buffer *eb,
3273 struct extent_state **cached_state) 3289 struct extent_state **cached_state)
@@ -3279,8 +3295,10 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
3279 num_pages = num_extent_pages(eb->start, eb->len); 3295 num_pages = num_extent_pages(eb->start, eb->len);
3280 clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); 3296 clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
3281 3297
3282 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, 3298 if (eb_straddles_pages(eb)) {
3283 cached_state, GFP_NOFS); 3299 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
3300 cached_state, GFP_NOFS);
3301 }
3284 for (i = 0; i < num_pages; i++) { 3302 for (i = 0; i < num_pages; i++) {
3285 page = extent_buffer_page(eb, i); 3303 page = extent_buffer_page(eb, i);
3286 if (page) 3304 if (page)
@@ -3298,8 +3316,10 @@ int set_extent_buffer_uptodate(struct extent_io_tree *tree,
3298 3316
3299 num_pages = num_extent_pages(eb->start, eb->len); 3317 num_pages = num_extent_pages(eb->start, eb->len);
3300 3318
3301 set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, 3319 if (eb_straddles_pages(eb)) {
3302 NULL, GFP_NOFS); 3320 set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
3321 NULL, GFP_NOFS);
3322 }
3303 for (i = 0; i < num_pages; i++) { 3323 for (i = 0; i < num_pages; i++) {
3304 page = extent_buffer_page(eb, i); 3324 page = extent_buffer_page(eb, i);
3305 if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || 3325 if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) ||
@@ -3322,9 +3342,12 @@ int extent_range_uptodate(struct extent_io_tree *tree,
3322 int uptodate; 3342 int uptodate;
3323 unsigned long index; 3343 unsigned long index;
3324 3344
3325 ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL); 3345 if (__eb_straddles_pages(start, end - start + 1)) {
3326 if (ret) 3346 ret = test_range_bit(tree, start, end,
3327 return 1; 3347 EXTENT_UPTODATE, 1, NULL);
3348 if (ret)
3349 return 1;
3350 }
3328 while (start <= end) { 3351 while (start <= end) {
3329 index = start >> PAGE_CACHE_SHIFT; 3352 index = start >> PAGE_CACHE_SHIFT;
3330 page = find_get_page(tree->mapping, index); 3353 page = find_get_page(tree->mapping, index);
@@ -3352,10 +3375,12 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
3352 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) 3375 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
3353 return 1; 3376 return 1;
3354 3377
3355 ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, 3378 if (eb_straddles_pages(eb)) {
3356 EXTENT_UPTODATE, 1, cached_state); 3379 ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
3357 if (ret) 3380 EXTENT_UPTODATE, 1, cached_state);
3358 return ret; 3381 if (ret)
3382 return ret;
3383 }
3359 3384
3360 num_pages = num_extent_pages(eb->start, eb->len); 3385 num_pages = num_extent_pages(eb->start, eb->len);
3361 for (i = 0; i < num_pages; i++) { 3386 for (i = 0; i < num_pages; i++) {
@@ -3388,9 +3413,11 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
3388 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) 3413 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
3389 return 0; 3414 return 0;
3390 3415
3391 if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, 3416 if (eb_straddles_pages(eb)) {
3392 EXTENT_UPTODATE, 1, NULL)) { 3417 if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
3393 return 0; 3418 EXTENT_UPTODATE, 1, NULL)) {
3419 return 0;
3420 }
3394 } 3421 }
3395 3422
3396 if (start) { 3423 if (start) {