aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2009-10-08 13:34:05 -0400
committerChris Mason <chris.mason@oracle.com>2009-10-08 15:21:10 -0400
commit32c00aff718bb54a214b39146bdd9ac01511cd25 (patch)
treec094ee494723a9ebc9d83cb95607f06351665639 /fs/btrfs/inode.c
parenta3429ab70b04363c6190964e82f04f44f3e34cf0 (diff)
Btrfs: release delalloc reservations on extent item insertion
This patch fixes an issue with the delalloc metadata space reservation code. The problem is we used to free the reservation as soon as we allocated the delalloc region. The problem with this is if we are not inserting an inline extent, we don't actually insert the extent item until after the ordered extent is written out. This patch does 3 things, 1) It moves the reservation clearing stuff into the ordered code, so when we remove the ordered extent we remove the reservation. 2) It adds a EXTENT_DO_ACCOUNTING flag that gets passed when we clear delalloc bits in the cases where we want to clear the metadata reservation when we clear the delalloc extent, in the case that we do an inline extent or we invalidate the page. 3) It adds another waitqueue to the space info so that when we start a fs wide delalloc flush, anybody else who also hits that area will simply wait for the flush to finish and then try to make their allocation. This has been tested thoroughly to make sure we did not regress on performance. Signed-off-by: Josef Bacik <jbacik@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c45
1 files changed, 31 insertions, 14 deletions
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);