diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2013-05-15 03:48:22 -0400 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-06-14 11:29:40 -0400 |
commit | eb73c1b7cea7d533288ef5297a0ea0e159db85b0 (patch) | |
tree | cb6e26e79ab0c11eed7f1db8967e37dbf770f974 /fs/btrfs/disk-io.c | |
parent | b0feb9d96e71a88d7eec56f41b8f23e92af889b0 (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.c | 49 |
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 | |||
3830 | static 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 | ||
3826 | static int btrfs_destroy_marked_extents(struct btrfs_root *root, | 3855 | static 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; |