aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h7
-rw-r--r--fs/btrfs/disk-io.c18
-rw-r--r--fs/btrfs/extent-tree.c6
-rw-r--r--fs/btrfs/inode.c6
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);
2741fail_delalloc_bytes:
2742 percpu_counter_destroy(&fs_info->delalloc_bytes);
2734fail_dirty_metadata_bytes: 2743fail_dirty_metadata_bytes:
2735 percpu_counter_destroy(&fs_info->dirty_metadata_bytes); 2744 percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
2736fail_bdi: 2745fail_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 &&