diff options
-rw-r--r-- | fs/btrfs/ctree.h | 7 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 18 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 6 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 6 |
4 files changed, 26 insertions, 11 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 4c476281b66b..50def99f5379 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1392,6 +1392,7 @@ struct btrfs_fs_info { | |||
1392 | */ | 1392 | */ |
1393 | struct list_head ordered_extents; | 1393 | struct list_head ordered_extents; |
1394 | 1394 | ||
1395 | spinlock_t delalloc_lock; | ||
1395 | /* | 1396 | /* |
1396 | * all of the inodes that have delalloc bytes. It is possible for | 1397 | * all of the inodes that have delalloc bytes. It is possible for |
1397 | * this list to be empty even when there is still dirty data=ordered | 1398 | * this list to be empty even when there is still dirty data=ordered |
@@ -1452,7 +1453,10 @@ struct btrfs_fs_info { | |||
1452 | 1453 | ||
1453 | /* used to keep from writing metadata until there is a nice batch */ | 1454 | /* used to keep from writing metadata until there is a nice batch */ |
1454 | struct percpu_counter dirty_metadata_bytes; | 1455 | struct percpu_counter dirty_metadata_bytes; |
1456 | struct percpu_counter delalloc_bytes; | ||
1455 | s32 dirty_metadata_batch; | 1457 | s32 dirty_metadata_batch; |
1458 | s32 delalloc_batch; | ||
1459 | |||
1456 | struct list_head dirty_cowonly_roots; | 1460 | struct list_head dirty_cowonly_roots; |
1457 | 1461 | ||
1458 | struct btrfs_fs_devices *fs_devices; | 1462 | struct btrfs_fs_devices *fs_devices; |
@@ -1468,9 +1472,6 @@ struct btrfs_fs_info { | |||
1468 | 1472 | ||
1469 | struct reloc_control *reloc_ctl; | 1473 | struct reloc_control *reloc_ctl; |
1470 | 1474 | ||
1471 | spinlock_t delalloc_lock; | ||
1472 | u64 delalloc_bytes; | ||
1473 | |||
1474 | /* data_alloc_cluster is only used in ssd mode */ | 1475 | /* data_alloc_cluster is only used in ssd mode */ |
1475 | struct btrfs_free_cluster data_alloc_cluster; | 1476 | struct btrfs_free_cluster data_alloc_cluster; |
1476 | 1477 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 34ace168eebc..2c9498aefe86 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2010,10 +2010,16 @@ int open_ctree(struct super_block *sb, | |||
2010 | fs_info->dirty_metadata_batch = PAGE_CACHE_SIZE * | 2010 | fs_info->dirty_metadata_batch = PAGE_CACHE_SIZE * |
2011 | (1 + ilog2(nr_cpu_ids)); | 2011 | (1 + ilog2(nr_cpu_ids)); |
2012 | 2012 | ||
2013 | ret = percpu_counter_init(&fs_info->delalloc_bytes, 0); | ||
2014 | if (ret) { | ||
2015 | err = ret; | ||
2016 | goto fail_dirty_metadata_bytes; | ||
2017 | } | ||
2018 | |||
2013 | fs_info->btree_inode = new_inode(sb); | 2019 | fs_info->btree_inode = new_inode(sb); |
2014 | if (!fs_info->btree_inode) { | 2020 | if (!fs_info->btree_inode) { |
2015 | err = -ENOMEM; | 2021 | err = -ENOMEM; |
2016 | goto fail_dirty_metadata_bytes; | 2022 | goto fail_delalloc_bytes; |
2017 | } | 2023 | } |
2018 | 2024 | ||
2019 | mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); | 2025 | mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); |
@@ -2269,6 +2275,7 @@ int open_ctree(struct super_block *sb, | |||
2269 | sectorsize = btrfs_super_sectorsize(disk_super); | 2275 | sectorsize = btrfs_super_sectorsize(disk_super); |
2270 | stripesize = btrfs_super_stripesize(disk_super); | 2276 | stripesize = btrfs_super_stripesize(disk_super); |
2271 | fs_info->dirty_metadata_batch = leafsize * (1 + ilog2(nr_cpu_ids)); | 2277 | fs_info->dirty_metadata_batch = leafsize * (1 + ilog2(nr_cpu_ids)); |
2278 | fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids)); | ||
2272 | 2279 | ||
2273 | /* | 2280 | /* |
2274 | * mixed block groups end up with duplicate but slightly offset | 2281 | * mixed block groups end up with duplicate but slightly offset |
@@ -2731,6 +2738,8 @@ fail_iput: | |||
2731 | 2738 | ||
2732 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 2739 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
2733 | iput(fs_info->btree_inode); | 2740 | iput(fs_info->btree_inode); |
2741 | fail_delalloc_bytes: | ||
2742 | percpu_counter_destroy(&fs_info->delalloc_bytes); | ||
2734 | fail_dirty_metadata_bytes: | 2743 | fail_dirty_metadata_bytes: |
2735 | percpu_counter_destroy(&fs_info->dirty_metadata_bytes); | 2744 | percpu_counter_destroy(&fs_info->dirty_metadata_bytes); |
2736 | fail_bdi: | 2745 | fail_bdi: |
@@ -3362,9 +3371,9 @@ int close_ctree(struct btrfs_root *root) | |||
3362 | 3371 | ||
3363 | btrfs_free_qgroup_config(root->fs_info); | 3372 | btrfs_free_qgroup_config(root->fs_info); |
3364 | 3373 | ||
3365 | if (fs_info->delalloc_bytes) { | 3374 | if (percpu_counter_sum(&fs_info->delalloc_bytes)) { |
3366 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", | 3375 | printk(KERN_INFO "btrfs: at unmount delalloc count %lld\n", |
3367 | (unsigned long long)fs_info->delalloc_bytes); | 3376 | percpu_counter_sum(&fs_info->delalloc_bytes)); |
3368 | } | 3377 | } |
3369 | 3378 | ||
3370 | free_extent_buffer(fs_info->extent_root->node); | 3379 | free_extent_buffer(fs_info->extent_root->node); |
@@ -3412,6 +3421,7 @@ int close_ctree(struct btrfs_root *root) | |||
3412 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 3421 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
3413 | 3422 | ||
3414 | percpu_counter_destroy(&fs_info->dirty_metadata_bytes); | 3423 | percpu_counter_destroy(&fs_info->dirty_metadata_bytes); |
3424 | percpu_counter_destroy(&fs_info->delalloc_bytes); | ||
3415 | bdi_destroy(&fs_info->bdi); | 3425 | bdi_destroy(&fs_info->bdi); |
3416 | cleanup_srcu_struct(&fs_info->subvol_srcu); | 3426 | cleanup_srcu_struct(&fs_info->subvol_srcu); |
3417 | 3427 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 174c4d5c692c..115d1646bf50 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3760,7 +3760,8 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, | |||
3760 | space_info = block_rsv->space_info; | 3760 | space_info = block_rsv->space_info; |
3761 | 3761 | ||
3762 | smp_mb(); | 3762 | smp_mb(); |
3763 | delalloc_bytes = root->fs_info->delalloc_bytes; | 3763 | delalloc_bytes = percpu_counter_sum_positive( |
3764 | &root->fs_info->delalloc_bytes); | ||
3764 | if (delalloc_bytes == 0) { | 3765 | if (delalloc_bytes == 0) { |
3765 | if (trans) | 3766 | if (trans) |
3766 | return; | 3767 | return; |
@@ -3799,7 +3800,8 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, | |||
3799 | break; | 3800 | break; |
3800 | } | 3801 | } |
3801 | smp_mb(); | 3802 | smp_mb(); |
3802 | delalloc_bytes = root->fs_info->delalloc_bytes; | 3803 | delalloc_bytes = percpu_counter_sum_positive( |
3804 | &root->fs_info->delalloc_bytes); | ||
3803 | } | 3805 | } |
3804 | } | 3806 | } |
3805 | 3807 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fc8aa8bf80a1..24c0b7805fe1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1516,7 +1516,8 @@ static void btrfs_set_bit_hook(struct inode *inode, | |||
1516 | 1516 | ||
1517 | spin_lock(&root->fs_info->delalloc_lock); | 1517 | spin_lock(&root->fs_info->delalloc_lock); |
1518 | BTRFS_I(inode)->delalloc_bytes += len; | 1518 | BTRFS_I(inode)->delalloc_bytes += len; |
1519 | root->fs_info->delalloc_bytes += len; | 1519 | __percpu_counter_add(&root->fs_info->delalloc_bytes, len, |
1520 | root->fs_info->delalloc_batch); | ||
1520 | if (do_list && list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | 1521 | if (do_list && list_empty(&BTRFS_I(inode)->delalloc_inodes)) { |
1521 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, | 1522 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, |
1522 | &root->fs_info->delalloc_inodes); | 1523 | &root->fs_info->delalloc_inodes); |
@@ -1557,7 +1558,8 @@ static void btrfs_clear_bit_hook(struct inode *inode, | |||
1557 | btrfs_free_reserved_data_space(inode, len); | 1558 | btrfs_free_reserved_data_space(inode, len); |
1558 | 1559 | ||
1559 | spin_lock(&root->fs_info->delalloc_lock); | 1560 | spin_lock(&root->fs_info->delalloc_lock); |
1560 | root->fs_info->delalloc_bytes -= len; | 1561 | __percpu_counter_add(&root->fs_info->delalloc_bytes, -len, |
1562 | root->fs_info->delalloc_batch); | ||
1561 | BTRFS_I(inode)->delalloc_bytes -= len; | 1563 | BTRFS_I(inode)->delalloc_bytes -= len; |
1562 | 1564 | ||
1563 | if (do_list && BTRFS_I(inode)->delalloc_bytes == 0 && | 1565 | if (do_list && BTRFS_I(inode)->delalloc_bytes == 0 && |