diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 12 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 54 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 19 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/file.c | 3 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 45 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.c | 6 |
8 files changed, 107 insertions, 37 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index a54d354cefcb..c71abec0ab90 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -128,12 +128,14 @@ struct btrfs_inode { | |||
128 | u64 last_unlink_trans; | 128 | u64 last_unlink_trans; |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * These two counters are for delalloc metadata reservations. We keep | 131 | * Counters to keep track of the number of extent item's we may use due |
132 | * track of how many extents we've accounted for vs how many extents we | 132 | * to delalloc and such. outstanding_extents is the number of extent |
133 | * have. | 133 | * items we think we'll end up using, and reserved_extents is the number |
134 | * of extent items we've reserved metadata for. | ||
134 | */ | 135 | */ |
135 | int delalloc_reserved_extents; | 136 | spinlock_t accounting_lock; |
136 | int delalloc_extents; | 137 | int reserved_extents; |
138 | int outstanding_extents; | ||
137 | 139 | ||
138 | /* | 140 | /* |
139 | * ordered_data_close is set by truncate when a file that used | 141 | * ordered_data_close is set by truncate when a file that used |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 1b920ffc6a59..dbdada569507 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -699,6 +699,9 @@ struct btrfs_space_info { | |||
699 | 699 | ||
700 | int allocating_chunk; | 700 | int allocating_chunk; |
701 | wait_queue_head_t wait; | 701 | wait_queue_head_t wait; |
702 | |||
703 | int flushing; | ||
704 | wait_queue_head_t flush_wait; | ||
702 | }; | 705 | }; |
703 | 706 | ||
704 | /* | 707 | /* |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 2f82fabd7011..3d1be0b77f8f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2823,14 +2823,17 @@ int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root, | |||
2823 | num_items); | 2823 | num_items); |
2824 | 2824 | ||
2825 | spin_lock(&meta_sinfo->lock); | 2825 | spin_lock(&meta_sinfo->lock); |
2826 | if (BTRFS_I(inode)->delalloc_reserved_extents <= | 2826 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
2827 | BTRFS_I(inode)->delalloc_extents) { | 2827 | if (BTRFS_I(inode)->reserved_extents <= |
2828 | BTRFS_I(inode)->outstanding_extents) { | ||
2829 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
2828 | spin_unlock(&meta_sinfo->lock); | 2830 | spin_unlock(&meta_sinfo->lock); |
2829 | return 0; | 2831 | return 0; |
2830 | } | 2832 | } |
2833 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
2831 | 2834 | ||
2832 | BTRFS_I(inode)->delalloc_reserved_extents--; | 2835 | BTRFS_I(inode)->reserved_extents--; |
2833 | BUG_ON(BTRFS_I(inode)->delalloc_reserved_extents < 0); | 2836 | BUG_ON(BTRFS_I(inode)->reserved_extents < 0); |
2834 | 2837 | ||
2835 | if (meta_sinfo->bytes_delalloc < num_bytes) { | 2838 | if (meta_sinfo->bytes_delalloc < num_bytes) { |
2836 | bug = true; | 2839 | bug = true; |
@@ -2863,6 +2866,37 @@ static void check_force_delalloc(struct btrfs_space_info *meta_sinfo) | |||
2863 | meta_sinfo->force_delalloc = 0; | 2866 | meta_sinfo->force_delalloc = 0; |
2864 | } | 2867 | } |
2865 | 2868 | ||
2869 | static void flush_delalloc(struct btrfs_root *root, | ||
2870 | struct btrfs_space_info *info) | ||
2871 | { | ||
2872 | bool wait = false; | ||
2873 | |||
2874 | spin_lock(&info->lock); | ||
2875 | |||
2876 | if (!info->flushing) { | ||
2877 | info->flushing = 1; | ||
2878 | init_waitqueue_head(&info->flush_wait); | ||
2879 | } else { | ||
2880 | wait = true; | ||
2881 | } | ||
2882 | |||
2883 | spin_unlock(&info->lock); | ||
2884 | |||
2885 | if (wait) { | ||
2886 | wait_event(info->flush_wait, | ||
2887 | !info->flushing); | ||
2888 | return; | ||
2889 | } | ||
2890 | |||
2891 | btrfs_start_delalloc_inodes(root); | ||
2892 | btrfs_wait_ordered_extents(root, 0); | ||
2893 | |||
2894 | spin_lock(&info->lock); | ||
2895 | info->flushing = 0; | ||
2896 | spin_unlock(&info->lock); | ||
2897 | wake_up(&info->flush_wait); | ||
2898 | } | ||
2899 | |||
2866 | static int maybe_allocate_chunk(struct btrfs_root *root, | 2900 | static int maybe_allocate_chunk(struct btrfs_root *root, |
2867 | struct btrfs_space_info *info) | 2901 | struct btrfs_space_info *info) |
2868 | { | 2902 | { |
@@ -2980,21 +3014,20 @@ again: | |||
2980 | filemap_flush(inode->i_mapping); | 3014 | filemap_flush(inode->i_mapping); |
2981 | goto again; | 3015 | goto again; |
2982 | } else if (flushed == 3) { | 3016 | } else if (flushed == 3) { |
2983 | btrfs_start_delalloc_inodes(root); | 3017 | flush_delalloc(root, meta_sinfo); |
2984 | btrfs_wait_ordered_extents(root, 0); | ||
2985 | goto again; | 3018 | goto again; |
2986 | } | 3019 | } |
2987 | spin_lock(&meta_sinfo->lock); | 3020 | spin_lock(&meta_sinfo->lock); |
2988 | meta_sinfo->bytes_delalloc -= num_bytes; | 3021 | meta_sinfo->bytes_delalloc -= num_bytes; |
2989 | spin_unlock(&meta_sinfo->lock); | 3022 | spin_unlock(&meta_sinfo->lock); |
2990 | printk(KERN_ERR "enospc, has %d, reserved %d\n", | 3023 | printk(KERN_ERR "enospc, has %d, reserved %d\n", |
2991 | BTRFS_I(inode)->delalloc_extents, | 3024 | BTRFS_I(inode)->outstanding_extents, |
2992 | BTRFS_I(inode)->delalloc_reserved_extents); | 3025 | BTRFS_I(inode)->reserved_extents); |
2993 | dump_space_info(meta_sinfo, 0, 0); | 3026 | dump_space_info(meta_sinfo, 0, 0); |
2994 | return -ENOSPC; | 3027 | return -ENOSPC; |
2995 | } | 3028 | } |
2996 | 3029 | ||
2997 | BTRFS_I(inode)->delalloc_reserved_extents++; | 3030 | BTRFS_I(inode)->reserved_extents++; |
2998 | check_force_delalloc(meta_sinfo); | 3031 | check_force_delalloc(meta_sinfo); |
2999 | spin_unlock(&meta_sinfo->lock); | 3032 | spin_unlock(&meta_sinfo->lock); |
3000 | 3033 | ||
@@ -3093,8 +3126,7 @@ again: | |||
3093 | } | 3126 | } |
3094 | 3127 | ||
3095 | if (retries == 2) { | 3128 | if (retries == 2) { |
3096 | btrfs_start_delalloc_inodes(root); | 3129 | flush_delalloc(root, meta_sinfo); |
3097 | btrfs_wait_ordered_extents(root, 0); | ||
3098 | goto again; | 3130 | goto again; |
3099 | } | 3131 | } |
3100 | spin_lock(&meta_sinfo->lock); | 3132 | spin_lock(&meta_sinfo->lock); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index f9708bd01669..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 | ||
@@ -1419,9 +1421,13 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1419 | if (op & EXTENT_CLEAR_DELALLOC) | 1421 | if (op & EXTENT_CLEAR_DELALLOC) |
1420 | clear_bits |= EXTENT_DELALLOC; | 1422 | clear_bits |= EXTENT_DELALLOC; |
1421 | 1423 | ||
1424 | if (op & EXTENT_CLEAR_ACCOUNTING) | ||
1425 | clear_bits |= EXTENT_DO_ACCOUNTING; | ||
1426 | |||
1422 | 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); |
1423 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK | | 1428 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | |
1424 | EXTENT_END_WRITEBACK | EXTENT_SET_PRIVATE2))) | 1429 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK | |
1430 | EXTENT_SET_PRIVATE2))) | ||
1425 | return 0; | 1431 | return 0; |
1426 | 1432 | ||
1427 | while (nr_pages > 0) { | 1433 | while (nr_pages > 0) { |
@@ -2709,7 +2715,8 @@ int extent_invalidatepage(struct extent_io_tree *tree, | |||
2709 | lock_extent(tree, start, end, GFP_NOFS); | 2715 | lock_extent(tree, start, end, GFP_NOFS); |
2710 | wait_on_page_writeback(page); | 2716 | wait_on_page_writeback(page); |
2711 | clear_extent_bit(tree, start, end, | 2717 | clear_extent_bit(tree, start, end, |
2712 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, | 2718 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | |
2719 | EXTENT_DO_ACCOUNTING, | ||
2713 | 1, 1, NULL, GFP_NOFS); | 2720 | 1, 1, NULL, GFP_NOFS); |
2714 | return 0; | 2721 | return 0; |
2715 | } | 2722 | } |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 41d2a47ecf38..36de250a7b2b 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #define EXTENT_BUFFER_FILLED (1 << 8) | 15 | #define EXTENT_BUFFER_FILLED (1 << 8) |
16 | #define EXTENT_BOUNDARY (1 << 9) | 16 | #define EXTENT_BOUNDARY (1 << 9) |
17 | #define EXTENT_NODATASUM (1 << 10) | 17 | #define EXTENT_NODATASUM (1 << 10) |
18 | #define EXTENT_DO_ACCOUNTING (1 << 11) | ||
18 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) | 19 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) |
19 | 20 | ||
20 | /* flags for bio submission */ | 21 | /* flags for bio submission */ |
@@ -33,6 +34,7 @@ | |||
33 | #define EXTENT_SET_WRITEBACK 0x10 | 34 | #define EXTENT_SET_WRITEBACK 0x10 |
34 | #define EXTENT_END_WRITEBACK 0x20 | 35 | #define EXTENT_END_WRITEBACK 0x20 |
35 | #define EXTENT_SET_PRIVATE2 0x40 | 36 | #define EXTENT_SET_PRIVATE2 0x40 |
37 | #define EXTENT_CLEAR_ACCOUNTING 0x80 | ||
36 | 38 | ||
37 | /* | 39 | /* |
38 | * page->private values. Every page that is controlled by the extent | 40 | * page->private values. Every page that is controlled by the extent |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f155179877a6..53fb1c997f0e 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -878,7 +878,8 @@ again: | |||
878 | btrfs_put_ordered_extent(ordered); | 878 | btrfs_put_ordered_extent(ordered); |
879 | 879 | ||
880 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, | 880 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, |
881 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC, | 881 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | |
882 | EXTENT_DO_ACCOUNTING, | ||
882 | GFP_NOFS); | 883 | GFP_NOFS); |
883 | unlock_extent(&BTRFS_I(inode)->io_tree, | 884 | unlock_extent(&BTRFS_I(inode)->io_tree, |
884 | start_pos, last_pos - 1, GFP_NOFS); | 885 | start_pos, last_pos - 1, GFP_NOFS); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 401dfb2a94e8..ccc4f1121210 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -428,6 +428,7 @@ again: | |||
428 | start, end, NULL, | 428 | start, end, NULL, |
429 | EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | | 429 | EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | |
430 | EXTENT_CLEAR_DELALLOC | | 430 | EXTENT_CLEAR_DELALLOC | |
431 | EXTENT_CLEAR_ACCOUNTING | | ||
431 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); | 432 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); |
432 | ret = 0; | 433 | ret = 0; |
433 | goto free_pages_out; | 434 | goto free_pages_out; |
@@ -722,6 +723,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
722 | EXTENT_CLEAR_UNLOCK_PAGE | | 723 | EXTENT_CLEAR_UNLOCK_PAGE | |
723 | EXTENT_CLEAR_UNLOCK | | 724 | EXTENT_CLEAR_UNLOCK | |
724 | EXTENT_CLEAR_DELALLOC | | 725 | EXTENT_CLEAR_DELALLOC | |
726 | EXTENT_CLEAR_ACCOUNTING | | ||
725 | EXTENT_CLEAR_DIRTY | | 727 | EXTENT_CLEAR_DIRTY | |
726 | EXTENT_SET_WRITEBACK | | 728 | EXTENT_SET_WRITEBACK | |
727 | EXTENT_END_WRITEBACK); | 729 | EXTENT_END_WRITEBACK); |
@@ -1195,15 +1197,17 @@ static int btrfs_split_extent_hook(struct inode *inode, | |||
1195 | root->fs_info->max_extent); | 1197 | root->fs_info->max_extent); |
1196 | 1198 | ||
1197 | /* | 1199 | /* |
1198 | * if we break a large extent up then leave delalloc_extents be, | 1200 | * if we break a large extent up then leave oustanding_extents |
1199 | * since we've already accounted for the large extent. | 1201 | * be, since we've already accounted for the large extent. |
1200 | */ | 1202 | */ |
1201 | if (div64_u64(new_size + root->fs_info->max_extent - 1, | 1203 | if (div64_u64(new_size + root->fs_info->max_extent - 1, |
1202 | root->fs_info->max_extent) < num_extents) | 1204 | root->fs_info->max_extent) < num_extents) |
1203 | return 0; | 1205 | return 0; |
1204 | } | 1206 | } |
1205 | 1207 | ||
1206 | BTRFS_I(inode)->delalloc_extents++; | 1208 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1209 | BTRFS_I(inode)->outstanding_extents++; | ||
1210 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
1207 | 1211 | ||
1208 | return 0; | 1212 | return 0; |
1209 | } | 1213 | } |
@@ -1234,7 +1238,9 @@ static int btrfs_merge_extent_hook(struct inode *inode, | |||
1234 | 1238 | ||
1235 | /* we're not bigger than the max, unreserve the space and go */ | 1239 | /* we're not bigger than the max, unreserve the space and go */ |
1236 | if (new_size <= root->fs_info->max_extent) { | 1240 | if (new_size <= root->fs_info->max_extent) { |
1237 | BTRFS_I(inode)->delalloc_extents--; | 1241 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1242 | BTRFS_I(inode)->outstanding_extents--; | ||
1243 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
1238 | return 0; | 1244 | return 0; |
1239 | } | 1245 | } |
1240 | 1246 | ||
@@ -1248,7 +1254,9 @@ static int btrfs_merge_extent_hook(struct inode *inode, | |||
1248 | root->fs_info->max_extent) > num_extents) | 1254 | root->fs_info->max_extent) > num_extents) |
1249 | return 0; | 1255 | return 0; |
1250 | 1256 | ||
1251 | BTRFS_I(inode)->delalloc_extents--; | 1257 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1258 | BTRFS_I(inode)->outstanding_extents--; | ||
1259 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
1252 | 1260 | ||
1253 | return 0; | 1261 | return 0; |
1254 | } | 1262 | } |
@@ -1270,7 +1278,9 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | |||
1270 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { | 1278 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { |
1271 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1279 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1272 | 1280 | ||
1273 | BTRFS_I(inode)->delalloc_extents++; | 1281 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1282 | BTRFS_I(inode)->outstanding_extents++; | ||
1283 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
1274 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); | 1284 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); |
1275 | spin_lock(&root->fs_info->delalloc_lock); | 1285 | spin_lock(&root->fs_info->delalloc_lock); |
1276 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 1286 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; |
@@ -1298,8 +1308,12 @@ static int btrfs_clear_bit_hook(struct inode *inode, | |||
1298 | if ((state->state & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { | 1308 | if ((state->state & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { |
1299 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1309 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1300 | 1310 | ||
1301 | BTRFS_I(inode)->delalloc_extents--; | 1311 | if (bits & EXTENT_DO_ACCOUNTING) { |
1302 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | 1312 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1313 | BTRFS_I(inode)->outstanding_extents--; | ||
1314 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
1315 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
1316 | } | ||
1303 | 1317 | ||
1304 | spin_lock(&root->fs_info->delalloc_lock); | 1318 | spin_lock(&root->fs_info->delalloc_lock); |
1305 | if (state->end - state->start + 1 > | 1319 | if (state->end - state->start + 1 > |
@@ -4825,7 +4839,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
4825 | */ | 4839 | */ |
4826 | clear_extent_bit(tree, page_start, page_end, | 4840 | clear_extent_bit(tree, page_start, page_end, |
4827 | EXTENT_DIRTY | EXTENT_DELALLOC | | 4841 | EXTENT_DIRTY | EXTENT_DELALLOC | |
4828 | EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS); | 4842 | EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0, |
4843 | NULL, GFP_NOFS); | ||
4829 | /* | 4844 | /* |
4830 | * whoever cleared the private bit is responsible | 4845 | * whoever cleared the private bit is responsible |
4831 | * for the finish_ordered_io | 4846 | * for the finish_ordered_io |
@@ -4838,8 +4853,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
4838 | lock_extent(tree, page_start, page_end, GFP_NOFS); | 4853 | lock_extent(tree, page_start, page_end, GFP_NOFS); |
4839 | } | 4854 | } |
4840 | clear_extent_bit(tree, page_start, page_end, | 4855 | clear_extent_bit(tree, page_start, page_end, |
4841 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, | 4856 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | |
4842 | 1, 1, NULL, GFP_NOFS); | 4857 | EXTENT_DO_ACCOUNTING, 1, 1, NULL, GFP_NOFS); |
4843 | __btrfs_releasepage(page, GFP_NOFS); | 4858 | __btrfs_releasepage(page, GFP_NOFS); |
4844 | 4859 | ||
4845 | ClearPageChecked(page); | 4860 | ClearPageChecked(page); |
@@ -4934,7 +4949,8 @@ again: | |||
4934 | * prepare_pages in the normal write path. | 4949 | * prepare_pages in the normal write path. |
4935 | */ | 4950 | */ |
4936 | clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, | 4951 | clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, |
4937 | EXTENT_DIRTY | EXTENT_DELALLOC, GFP_NOFS); | 4952 | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, |
4953 | GFP_NOFS); | ||
4938 | 4954 | ||
4939 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); | 4955 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); |
4940 | if (ret) { | 4956 | if (ret) { |
@@ -5082,8 +5098,9 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
5082 | return NULL; | 5098 | return NULL; |
5083 | ei->last_trans = 0; | 5099 | ei->last_trans = 0; |
5084 | ei->logged_trans = 0; | 5100 | ei->logged_trans = 0; |
5085 | ei->delalloc_extents = 0; | 5101 | ei->outstanding_extents = 0; |
5086 | ei->delalloc_reserved_extents = 0; | 5102 | ei->reserved_extents = 0; |
5103 | spin_lock_init(&ei->accounting_lock); | ||
5087 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); | 5104 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); |
5088 | INIT_LIST_HEAD(&ei->i_orphan); | 5105 | INIT_LIST_HEAD(&ei->i_orphan); |
5089 | INIT_LIST_HEAD(&ei->ordered_operations); | 5106 | INIT_LIST_HEAD(&ei->ordered_operations); |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 4a9c8c4cec25..ab21c29f2247 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -306,6 +306,12 @@ int btrfs_remove_ordered_extent(struct inode *inode, | |||
306 | tree->last = NULL; | 306 | tree->last = NULL; |
307 | set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); | 307 | set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); |
308 | 308 | ||
309 | spin_lock(&BTRFS_I(inode)->accounting_lock); | ||
310 | BTRFS_I(inode)->outstanding_extents--; | ||
311 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
312 | btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root, | ||
313 | inode, 1); | ||
314 | |||
309 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 315 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); |
310 | list_del_init(&entry->root_extent_list); | 316 | list_del_init(&entry->root_extent_list); |
311 | 317 | ||