summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-05-15 03:48:22 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-06-14 11:29:40 -0400
commiteb73c1b7cea7d533288ef5297a0ea0e159db85b0 (patch)
treecb6e26e79ab0c11eed7f1db8967e37dbf770f974 /fs/btrfs/disk-io.c
parentb0feb9d96e71a88d7eec56f41b8f23e92af889b0 (diff)
Btrfs: introduce per-subvolume delalloc inode list
When we create a snapshot, we need flush all delalloc inodes in the fs, just flushing the inodes in the source tree is OK. So we introduce per-subvolume delalloc inode list. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 90b643e07f3c..2748c7ccdd51 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1191,6 +1191,7 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
1191 root->objectid = objectid; 1191 root->objectid = objectid;
1192 root->last_trans = 0; 1192 root->last_trans = 0;
1193 root->highest_objectid = 0; 1193 root->highest_objectid = 0;
1194 root->nr_delalloc_inodes = 0;
1194 root->name = NULL; 1195 root->name = NULL;
1195 root->inode_tree = RB_ROOT; 1196 root->inode_tree = RB_ROOT;
1196 INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC); 1197 INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC);
@@ -1199,10 +1200,13 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
1199 1200
1200 INIT_LIST_HEAD(&root->dirty_list); 1201 INIT_LIST_HEAD(&root->dirty_list);
1201 INIT_LIST_HEAD(&root->root_list); 1202 INIT_LIST_HEAD(&root->root_list);
1203 INIT_LIST_HEAD(&root->delalloc_inodes);
1204 INIT_LIST_HEAD(&root->delalloc_root);
1202 INIT_LIST_HEAD(&root->logged_list[0]); 1205 INIT_LIST_HEAD(&root->logged_list[0]);
1203 INIT_LIST_HEAD(&root->logged_list[1]); 1206 INIT_LIST_HEAD(&root->logged_list[1]);
1204 spin_lock_init(&root->orphan_lock); 1207 spin_lock_init(&root->orphan_lock);
1205 spin_lock_init(&root->inode_lock); 1208 spin_lock_init(&root->inode_lock);
1209 spin_lock_init(&root->delalloc_lock);
1206 spin_lock_init(&root->accounting_lock); 1210 spin_lock_init(&root->accounting_lock);
1207 spin_lock_init(&root->log_extents_lock[0]); 1211 spin_lock_init(&root->log_extents_lock[0]);
1208 spin_lock_init(&root->log_extents_lock[1]); 1212 spin_lock_init(&root->log_extents_lock[1]);
@@ -2140,9 +2144,9 @@ int open_ctree(struct super_block *sb,
2140 INIT_LIST_HEAD(&fs_info->trans_list); 2144 INIT_LIST_HEAD(&fs_info->trans_list);
2141 INIT_LIST_HEAD(&fs_info->dead_roots); 2145 INIT_LIST_HEAD(&fs_info->dead_roots);
2142 INIT_LIST_HEAD(&fs_info->delayed_iputs); 2146 INIT_LIST_HEAD(&fs_info->delayed_iputs);
2143 INIT_LIST_HEAD(&fs_info->delalloc_inodes); 2147 INIT_LIST_HEAD(&fs_info->delalloc_roots);
2144 INIT_LIST_HEAD(&fs_info->caching_block_groups); 2148 INIT_LIST_HEAD(&fs_info->caching_block_groups);
2145 spin_lock_init(&fs_info->delalloc_lock); 2149 spin_lock_init(&fs_info->delalloc_root_lock);
2146 spin_lock_init(&fs_info->trans_lock); 2150 spin_lock_init(&fs_info->trans_lock);
2147 spin_lock_init(&fs_info->fs_roots_radix_lock); 2151 spin_lock_init(&fs_info->fs_roots_radix_lock);
2148 spin_lock_init(&fs_info->delayed_iput_lock); 2152 spin_lock_init(&fs_info->delayed_iput_lock);
@@ -3803,24 +3807,49 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root)
3803 3807
3804 INIT_LIST_HEAD(&splice); 3808 INIT_LIST_HEAD(&splice);
3805 3809
3806 spin_lock(&root->fs_info->delalloc_lock); 3810 spin_lock(&root->delalloc_lock);
3807 list_splice_init(&root->fs_info->delalloc_inodes, &splice); 3811 list_splice_init(&root->delalloc_inodes, &splice);
3808 3812
3809 while (!list_empty(&splice)) { 3813 while (!list_empty(&splice)) {
3810 btrfs_inode = list_entry(splice.next, struct btrfs_inode, 3814 btrfs_inode = list_first_entry(&splice, struct btrfs_inode,
3811 delalloc_inodes); 3815 delalloc_inodes);
3812 3816
3813 list_del_init(&btrfs_inode->delalloc_inodes); 3817 list_del_init(&btrfs_inode->delalloc_inodes);
3814 clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, 3818 clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
3815 &btrfs_inode->runtime_flags); 3819 &btrfs_inode->runtime_flags);
3816 spin_unlock(&root->fs_info->delalloc_lock); 3820 spin_unlock(&root->delalloc_lock);
3817 3821
3818 btrfs_invalidate_inodes(btrfs_inode->root); 3822 btrfs_invalidate_inodes(btrfs_inode->root);
3819 3823
3820 spin_lock(&root->fs_info->delalloc_lock); 3824 spin_lock(&root->delalloc_lock);
3821 } 3825 }
3822 3826
3823 spin_unlock(&root->fs_info->delalloc_lock); 3827 spin_unlock(&root->delalloc_lock);
3828}
3829
3830static void btrfs_destroy_all_delalloc_inodes(struct btrfs_fs_info *fs_info)
3831{
3832 struct btrfs_root *root;
3833 struct list_head splice;
3834
3835 INIT_LIST_HEAD(&splice);
3836
3837 spin_lock(&fs_info->delalloc_root_lock);
3838 list_splice_init(&fs_info->delalloc_roots, &splice);
3839 while (!list_empty(&splice)) {
3840 root = list_first_entry(&splice, struct btrfs_root,
3841 delalloc_root);
3842 list_del_init(&root->delalloc_root);
3843 root = btrfs_grab_fs_root(root);
3844 BUG_ON(!root);
3845 spin_unlock(&fs_info->delalloc_root_lock);
3846
3847 btrfs_destroy_delalloc_inodes(root);
3848 btrfs_put_fs_root(root);
3849
3850 spin_lock(&fs_info->delalloc_root_lock);
3851 }
3852 spin_unlock(&fs_info->delalloc_root_lock);
3824} 3853}
3825 3854
3826static int btrfs_destroy_marked_extents(struct btrfs_root *root, 3855static int btrfs_destroy_marked_extents(struct btrfs_root *root,
@@ -3974,7 +4003,7 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
3974 btrfs_destroy_delayed_inodes(root); 4003 btrfs_destroy_delayed_inodes(root);
3975 btrfs_assert_delayed_root_empty(root); 4004 btrfs_assert_delayed_root_empty(root);
3976 4005
3977 btrfs_destroy_delalloc_inodes(root); 4006 btrfs_destroy_all_delalloc_inodes(root->fs_info);
3978 4007
3979 spin_lock(&root->fs_info->trans_lock); 4008 spin_lock(&root->fs_info->trans_lock);
3980 root->fs_info->running_transaction = NULL; 4009 root->fs_info->running_transaction = NULL;