aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-07-29 13:22:24 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:04:39 -0400
commit151a41bc46df2a9cb5e05c3b3265cedc1f65a86f (patch)
tree574b41c09c2890e7a6eeda18dedb5e37c1aac98c
parentc2790a2e2bc824084717fde031a8e0d370fc8650 (diff)
Btrfs: fix what bits we clear when erroring out from delalloc
First of all we no longer set EXTENT_DIRTY when we dirty an extent so this patch removes the clearing of EXTENT_DIRTY since it confuses me. This patch also adds clearing EXTENT_DEFRAG and also doing EXTENT_DO_ACCOUNTING when we have errors. This is because if we are clearing delalloc without adding an ordered extent then we need to make sure the enospc handling stuff is accounted for. Also if this range was DEFRAG we need to make sure that bit is cleared so we dont leak it. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r--fs/btrfs/inode.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d6c915d82b4a..27fa81977f86 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -484,15 +484,17 @@ cont:
484 compress_type, pages); 484 compress_type, pages);
485 } 485 }
486 if (ret <= 0) { 486 if (ret <= 0) {
487 unsigned long clear_flags = EXTENT_DELALLOC |
488 EXTENT_DEFRAG;
489 clear_flags |= (ret < 0) ? EXTENT_DO_ACCOUNTING : 0;
490
487 /* 491 /*
488 * inline extent creation worked or returned error, 492 * inline extent creation worked or returned error,
489 * we don't need to create any more async work items. 493 * we don't need to create any more async work items.
490 * Unlock and free up our temp pages. 494 * Unlock and free up our temp pages.
491 */ 495 */
492 extent_clear_unlock_delalloc(inode, start, end, NULL, 496 extent_clear_unlock_delalloc(inode, start, end, NULL,
493 EXTENT_DIRTY | 497 clear_flags, PAGE_UNLOCK |
494 EXTENT_DELALLOC,
495 PAGE_UNLOCK |
496 PAGE_CLEAR_DIRTY | 498 PAGE_CLEAR_DIRTY |
497 PAGE_SET_WRITEBACK | 499 PAGE_SET_WRITEBACK |
498 PAGE_END_WRITEBACK); 500 PAGE_END_WRITEBACK);
@@ -593,9 +595,10 @@ free_pages_out:
593 595
594cleanup_and_out: 596cleanup_and_out:
595 extent_clear_unlock_delalloc(inode, start, end, NULL, 597 extent_clear_unlock_delalloc(inode, start, end, NULL,
596 EXTENT_DIRTY | EXTENT_DELALLOC, 598 EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING |
597 PAGE_UNLOCK | PAGE_CLEAR_DIRTY | 599 EXTENT_DEFRAG, PAGE_UNLOCK |
598 PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK); 600 PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK |
601 PAGE_END_WRITEBACK);
599 if (!trans || IS_ERR(trans)) 602 if (!trans || IS_ERR(trans))
600 btrfs_error(root->fs_info, ret, "Failed to join transaction"); 603 btrfs_error(root->fs_info, ret, "Failed to join transaction");
601 else 604 else
@@ -770,8 +773,8 @@ retry:
770 extent_clear_unlock_delalloc(inode, async_extent->start, 773 extent_clear_unlock_delalloc(inode, async_extent->start,
771 async_extent->start + 774 async_extent->start +
772 async_extent->ram_size - 1, 775 async_extent->ram_size - 1,
773 NULL, EXTENT_LOCKED | EXTENT_DELALLOC | 776 NULL, EXTENT_LOCKED | EXTENT_DELALLOC,
774 EXTENT_DIRTY, PAGE_UNLOCK | PAGE_CLEAR_DIRTY | 777 PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
775 PAGE_SET_WRITEBACK); 778 PAGE_SET_WRITEBACK);
776 ret = btrfs_submit_compressed_write(inode, 779 ret = btrfs_submit_compressed_write(inode,
777 async_extent->start, 780 async_extent->start,
@@ -795,9 +798,9 @@ out_free:
795 async_extent->start + 798 async_extent->start +
796 async_extent->ram_size - 1, 799 async_extent->ram_size - 1,
797 NULL, EXTENT_LOCKED | EXTENT_DELALLOC | 800 NULL, EXTENT_LOCKED | EXTENT_DELALLOC |
798 EXTENT_DIRTY, PAGE_UNLOCK | 801 EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING,
799 PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | 802 PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
800 PAGE_END_WRITEBACK); 803 PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK);
801 kfree(async_extent); 804 kfree(async_extent);
802 goto again; 805 goto again;
803} 806}
@@ -884,7 +887,7 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
884 if (ret == 0) { 887 if (ret == 0) {
885 extent_clear_unlock_delalloc(inode, start, end, NULL, 888 extent_clear_unlock_delalloc(inode, start, end, NULL,
886 EXTENT_LOCKED | EXTENT_DELALLOC | 889 EXTENT_LOCKED | EXTENT_DELALLOC |
887 EXTENT_DIRTY, PAGE_UNLOCK | 890 EXTENT_DEFRAG, PAGE_UNLOCK |
888 PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | 891 PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK |
889 PAGE_END_WRITEBACK); 892 PAGE_END_WRITEBACK);
890 893
@@ -995,10 +998,10 @@ out_reserve:
995 btrfs_free_reserved_extent(root, ins.objectid, ins.offset); 998 btrfs_free_reserved_extent(root, ins.objectid, ins.offset);
996out_unlock: 999out_unlock:
997 extent_clear_unlock_delalloc(inode, start, end, locked_page, 1000 extent_clear_unlock_delalloc(inode, start, end, locked_page,
998 EXTENT_LOCKED | EXTENT_DIRTY | 1001 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
999 EXTENT_DELALLOC, PAGE_UNLOCK | 1002 EXTENT_DELALLOC | EXTENT_DEFRAG,
1000 PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | 1003 PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
1001 PAGE_END_WRITEBACK); 1004 PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK);
1002 goto out; 1005 goto out;
1003} 1006}
1004 1007
@@ -1016,7 +1019,8 @@ static noinline int cow_file_range(struct inode *inode,
1016 if (IS_ERR(trans)) { 1019 if (IS_ERR(trans)) {
1017 extent_clear_unlock_delalloc(inode, start, end, locked_page, 1020 extent_clear_unlock_delalloc(inode, start, end, locked_page,
1018 EXTENT_LOCKED | EXTENT_DELALLOC | 1021 EXTENT_LOCKED | EXTENT_DELALLOC |
1019 EXTENT_DIRTY, PAGE_UNLOCK | 1022 EXTENT_DO_ACCOUNTING |
1023 EXTENT_DEFRAG, PAGE_UNLOCK |
1020 PAGE_CLEAR_DIRTY | 1024 PAGE_CLEAR_DIRTY |
1021 PAGE_SET_WRITEBACK | 1025 PAGE_SET_WRITEBACK |
1022 PAGE_END_WRITEBACK); 1026 PAGE_END_WRITEBACK);
@@ -1201,7 +1205,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1201 if (!path) { 1205 if (!path) {
1202 extent_clear_unlock_delalloc(inode, start, end, locked_page, 1206 extent_clear_unlock_delalloc(inode, start, end, locked_page,
1203 EXTENT_LOCKED | EXTENT_DELALLOC | 1207 EXTENT_LOCKED | EXTENT_DELALLOC |
1204 EXTENT_DIRTY, PAGE_UNLOCK | 1208 EXTENT_DO_ACCOUNTING |
1209 EXTENT_DEFRAG, PAGE_UNLOCK |
1205 PAGE_CLEAR_DIRTY | 1210 PAGE_CLEAR_DIRTY |
1206 PAGE_SET_WRITEBACK | 1211 PAGE_SET_WRITEBACK |
1207 PAGE_END_WRITEBACK); 1212 PAGE_END_WRITEBACK);
@@ -1218,7 +1223,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1218 if (IS_ERR(trans)) { 1223 if (IS_ERR(trans)) {
1219 extent_clear_unlock_delalloc(inode, start, end, locked_page, 1224 extent_clear_unlock_delalloc(inode, start, end, locked_page,
1220 EXTENT_LOCKED | EXTENT_DELALLOC | 1225 EXTENT_LOCKED | EXTENT_DELALLOC |
1221 EXTENT_DIRTY, PAGE_UNLOCK | 1226 EXTENT_DO_ACCOUNTING |
1227 EXTENT_DEFRAG, PAGE_UNLOCK |
1222 PAGE_CLEAR_DIRTY | 1228 PAGE_CLEAR_DIRTY |
1223 PAGE_SET_WRITEBACK | 1229 PAGE_SET_WRITEBACK |
1224 PAGE_END_WRITEBACK); 1230 PAGE_END_WRITEBACK);
@@ -1434,8 +1440,9 @@ error:
1434 if (ret && cur_offset < end) 1440 if (ret && cur_offset < end)
1435 extent_clear_unlock_delalloc(inode, cur_offset, end, 1441 extent_clear_unlock_delalloc(inode, cur_offset, end,
1436 locked_page, EXTENT_LOCKED | 1442 locked_page, EXTENT_LOCKED |
1437 EXTENT_DELALLOC | EXTENT_DIRTY, 1443 EXTENT_DELALLOC | EXTENT_DEFRAG |
1438 PAGE_UNLOCK | PAGE_CLEAR_DIRTY | 1444 EXTENT_DO_ACCOUNTING, PAGE_UNLOCK |
1445 PAGE_CLEAR_DIRTY |
1439 PAGE_SET_WRITEBACK | 1446 PAGE_SET_WRITEBACK |
1440 PAGE_END_WRITEBACK); 1447 PAGE_END_WRITEBACK);
1441 btrfs_free_path(path); 1448 btrfs_free_path(path);