diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index de1793ba004a..96577e8bf9fd 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -460,7 +460,8 @@ static int clear_state_bit(struct extent_io_tree *tree, | |||
460 | struct extent_state *state, int bits, int wake, | 460 | struct extent_state *state, int bits, int wake, |
461 | int delete) | 461 | int delete) |
462 | { | 462 | { |
463 | int ret = state->state & bits; | 463 | int bits_to_clear = bits & ~EXTENT_DO_ACCOUNTING; |
464 | int ret = state->state & bits_to_clear; | ||
464 | 465 | ||
465 | if ((bits & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { | 466 | if ((bits & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { |
466 | u64 range = state->end - state->start + 1; | 467 | u64 range = state->end - state->start + 1; |
@@ -468,7 +469,7 @@ static int clear_state_bit(struct extent_io_tree *tree, | |||
468 | tree->dirty_bytes -= range; | 469 | tree->dirty_bytes -= range; |
469 | } | 470 | } |
470 | clear_state_cb(tree, state, bits); | 471 | clear_state_cb(tree, state, bits); |
471 | state->state &= ~bits; | 472 | state->state &= ~bits_to_clear; |
472 | if (wake) | 473 | if (wake) |
473 | wake_up(&state->wq); | 474 | wake_up(&state->wq); |
474 | if (delete || state->state == 0) { | 475 | if (delete || state->state == 0) { |
@@ -956,7 +957,8 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | |||
956 | gfp_t mask) | 957 | gfp_t mask) |
957 | { | 958 | { |
958 | return clear_extent_bit(tree, start, end, | 959 | return clear_extent_bit(tree, start, end, |
959 | EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, | 960 | EXTENT_DIRTY | EXTENT_DELALLOC | |
961 | EXTENT_DO_ACCOUNTING, 0, 0, | ||
960 | NULL, mask); | 962 | NULL, mask); |
961 | } | 963 | } |
962 | 964 | ||
@@ -1401,12 +1403,7 @@ out_failed: | |||
1401 | int extent_clear_unlock_delalloc(struct inode *inode, | 1403 | int extent_clear_unlock_delalloc(struct inode *inode, |
1402 | struct extent_io_tree *tree, | 1404 | struct extent_io_tree *tree, |
1403 | u64 start, u64 end, struct page *locked_page, | 1405 | u64 start, u64 end, struct page *locked_page, |
1404 | int unlock_pages, | 1406 | unsigned long op) |
1405 | int clear_unlock, | ||
1406 | int clear_delalloc, int clear_dirty, | ||
1407 | int set_writeback, | ||
1408 | int end_writeback, | ||
1409 | int set_private2) | ||
1410 | { | 1407 | { |
1411 | int ret; | 1408 | int ret; |
1412 | struct page *pages[16]; | 1409 | struct page *pages[16]; |
@@ -1416,17 +1413,21 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1416 | int i; | 1413 | int i; |
1417 | int clear_bits = 0; | 1414 | int clear_bits = 0; |
1418 | 1415 | ||
1419 | if (clear_unlock) | 1416 | if (op & EXTENT_CLEAR_UNLOCK) |
1420 | clear_bits |= EXTENT_LOCKED; | 1417 | clear_bits |= EXTENT_LOCKED; |
1421 | if (clear_dirty) | 1418 | if (op & EXTENT_CLEAR_DIRTY) |
1422 | clear_bits |= EXTENT_DIRTY; | 1419 | clear_bits |= EXTENT_DIRTY; |
1423 | 1420 | ||
1424 | if (clear_delalloc) | 1421 | if (op & EXTENT_CLEAR_DELALLOC) |
1425 | clear_bits |= EXTENT_DELALLOC; | 1422 | clear_bits |= EXTENT_DELALLOC; |
1426 | 1423 | ||
1424 | if (op & EXTENT_CLEAR_ACCOUNTING) | ||
1425 | clear_bits |= EXTENT_DO_ACCOUNTING; | ||
1426 | |||
1427 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); | 1427 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); |
1428 | if (!(unlock_pages || clear_dirty || set_writeback || end_writeback || | 1428 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | |
1429 | set_private2)) | 1429 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK | |
1430 | EXTENT_SET_PRIVATE2))) | ||
1430 | return 0; | 1431 | return 0; |
1431 | 1432 | ||
1432 | while (nr_pages > 0) { | 1433 | while (nr_pages > 0) { |
@@ -1435,20 +1436,20 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1435 | nr_pages, ARRAY_SIZE(pages)), pages); | 1436 | nr_pages, ARRAY_SIZE(pages)), pages); |
1436 | for (i = 0; i < ret; i++) { | 1437 | for (i = 0; i < ret; i++) { |
1437 | 1438 | ||
1438 | if (set_private2) | 1439 | if (op & EXTENT_SET_PRIVATE2) |
1439 | SetPagePrivate2(pages[i]); | 1440 | SetPagePrivate2(pages[i]); |
1440 | 1441 | ||
1441 | if (pages[i] == locked_page) { | 1442 | if (pages[i] == locked_page) { |
1442 | page_cache_release(pages[i]); | 1443 | page_cache_release(pages[i]); |
1443 | continue; | 1444 | continue; |
1444 | } | 1445 | } |
1445 | if (clear_dirty) | 1446 | if (op & EXTENT_CLEAR_DIRTY) |
1446 | clear_page_dirty_for_io(pages[i]); | 1447 | clear_page_dirty_for_io(pages[i]); |
1447 | if (set_writeback) | 1448 | if (op & EXTENT_SET_WRITEBACK) |
1448 | set_page_writeback(pages[i]); | 1449 | set_page_writeback(pages[i]); |
1449 | if (end_writeback) | 1450 | if (op & EXTENT_END_WRITEBACK) |
1450 | end_page_writeback(pages[i]); | 1451 | end_page_writeback(pages[i]); |
1451 | if (unlock_pages) | 1452 | if (op & EXTENT_CLEAR_UNLOCK_PAGE) |
1452 | unlock_page(pages[i]); | 1453 | unlock_page(pages[i]); |
1453 | page_cache_release(pages[i]); | 1454 | page_cache_release(pages[i]); |
1454 | } | 1455 | } |
@@ -2714,7 +2715,8 @@ int extent_invalidatepage(struct extent_io_tree *tree, | |||
2714 | lock_extent(tree, start, end, GFP_NOFS); | 2715 | lock_extent(tree, start, end, GFP_NOFS); |
2715 | wait_on_page_writeback(page); | 2716 | wait_on_page_writeback(page); |
2716 | clear_extent_bit(tree, start, end, | 2717 | clear_extent_bit(tree, start, end, |
2717 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, | 2718 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | |
2719 | EXTENT_DO_ACCOUNTING, | ||
2718 | 1, 1, NULL, GFP_NOFS); | 2720 | 1, 1, NULL, GFP_NOFS); |
2719 | return 0; | 2721 | return 0; |
2720 | } | 2722 | } |