diff options
| -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 | ||
