diff options
author | Chris Mason <chris.mason@fusionio.com> | 2013-02-05 10:04:03 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-02-05 10:04:03 -0500 |
commit | 0e4e02636611dbf89a2f36320a32054f9936d6cb (patch) | |
tree | 18b4ecc6c3812770b29729d7abbdc673ffd73a41 /fs | |
parent | 1f0905ec156eec8f12cd593bc564551770319720 (diff) | |
parent | 1eafa6c73791e4f312324ddad9cbcaf6a1b6052b (diff) |
Merge branch 'for-linus' into raid56-experimental
Conflicts:
fs/btrfs/volumes.c
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 6 | ||||
-rw-r--r-- | fs/btrfs/extent_map.c | 13 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 1 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 4 | ||||
-rw-r--r-- | fs/btrfs/file.c | 10 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 20 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 137 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 129 | ||||
-rw-r--r-- | fs/btrfs/qgroup.c | 20 | ||||
-rw-r--r-- | fs/btrfs/send.c | 4 | ||||
-rw-r--r-- | fs/btrfs/super.c | 2 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 19 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 10 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 23 |
14 files changed, 300 insertions, 98 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 87b0e856b6d0..7e801ada6695 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4061,7 +4061,7 @@ again: | |||
4061 | * We make the other tasks wait for the flush only when we can flush | 4061 | * We make the other tasks wait for the flush only when we can flush |
4062 | * all things. | 4062 | * all things. |
4063 | */ | 4063 | */ |
4064 | if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) { | 4064 | if (ret && flush != BTRFS_RESERVE_NO_FLUSH) { |
4065 | flushing = true; | 4065 | flushing = true; |
4066 | space_info->flush = 1; | 4066 | space_info->flush = 1; |
4067 | } | 4067 | } |
@@ -5631,7 +5631,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5631 | int empty_cluster = 2 * 1024 * 1024; | 5631 | int empty_cluster = 2 * 1024 * 1024; |
5632 | struct btrfs_space_info *space_info; | 5632 | struct btrfs_space_info *space_info; |
5633 | int loop = 0; | 5633 | int loop = 0; |
5634 | int index = 0; | 5634 | int index = __get_raid_index(data); |
5635 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? | 5635 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? |
5636 | RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; | 5636 | RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; |
5637 | bool found_uncached_bg = false; | 5637 | bool found_uncached_bg = false; |
@@ -6867,11 +6867,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
6867 | &wc->flags[level]); | 6867 | &wc->flags[level]); |
6868 | if (ret < 0) { | 6868 | if (ret < 0) { |
6869 | btrfs_tree_unlock_rw(eb, path->locks[level]); | 6869 | btrfs_tree_unlock_rw(eb, path->locks[level]); |
6870 | path->locks[level] = 0; | ||
6870 | return ret; | 6871 | return ret; |
6871 | } | 6872 | } |
6872 | BUG_ON(wc->refs[level] == 0); | 6873 | BUG_ON(wc->refs[level] == 0); |
6873 | if (wc->refs[level] == 1) { | 6874 | if (wc->refs[level] == 1) { |
6874 | btrfs_tree_unlock_rw(eb, path->locks[level]); | 6875 | btrfs_tree_unlock_rw(eb, path->locks[level]); |
6876 | path->locks[level] = 0; | ||
6875 | return 1; | 6877 | return 1; |
6876 | } | 6878 | } |
6877 | } | 6879 | } |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index fff2c28497b6..ed88f5ee4bea 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -171,6 +171,10 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) | |||
171 | if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) | 171 | if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) |
172 | return 0; | 172 | return 0; |
173 | 173 | ||
174 | if (test_bit(EXTENT_FLAG_LOGGING, &prev->flags) || | ||
175 | test_bit(EXTENT_FLAG_LOGGING, &next->flags)) | ||
176 | return 0; | ||
177 | |||
174 | if (extent_map_end(prev) == next->start && | 178 | if (extent_map_end(prev) == next->start && |
175 | prev->flags == next->flags && | 179 | prev->flags == next->flags && |
176 | prev->bdev == next->bdev && | 180 | prev->bdev == next->bdev && |
@@ -256,7 +260,8 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, | |||
256 | if (!em) | 260 | if (!em) |
257 | goto out; | 261 | goto out; |
258 | 262 | ||
259 | list_move(&em->list, &tree->modified_extents); | 263 | if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags)) |
264 | list_move(&em->list, &tree->modified_extents); | ||
260 | em->generation = gen; | 265 | em->generation = gen; |
261 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); | 266 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); |
262 | em->mod_start = em->start; | 267 | em->mod_start = em->start; |
@@ -281,6 +286,12 @@ out: | |||
281 | 286 | ||
282 | } | 287 | } |
283 | 288 | ||
289 | void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em) | ||
290 | { | ||
291 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); | ||
292 | try_merge_map(tree, em); | ||
293 | } | ||
294 | |||
284 | /** | 295 | /** |
285 | * add_extent_mapping - add new extent map to the extent tree | 296 | * add_extent_mapping - add new extent map to the extent tree |
286 | * @tree: tree to insert new map in | 297 | * @tree: tree to insert new map in |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 922943ce29e8..c6598c89cff8 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -69,6 +69,7 @@ void free_extent_map(struct extent_map *em); | |||
69 | int __init extent_map_init(void); | 69 | int __init extent_map_init(void); |
70 | void extent_map_exit(void); | 70 | void extent_map_exit(void); |
71 | int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); | 71 | int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); |
72 | void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em); | ||
72 | struct extent_map *search_extent_mapping(struct extent_map_tree *tree, | 73 | struct extent_map *search_extent_mapping(struct extent_map_tree *tree, |
73 | u64 start, u64 len); | 74 | u64 start, u64 len); |
74 | #endif | 75 | #endif |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index bd38cef42358..94aa53b38721 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -460,8 +460,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, | |||
460 | if (!contig) | 460 | if (!contig) |
461 | offset = page_offset(bvec->bv_page) + bvec->bv_offset; | 461 | offset = page_offset(bvec->bv_page) + bvec->bv_offset; |
462 | 462 | ||
463 | if (!contig && (offset >= ordered->file_offset + ordered->len || | 463 | if (offset >= ordered->file_offset + ordered->len || |
464 | offset < ordered->file_offset)) { | 464 | offset < ordered->file_offset) { |
465 | unsigned long bytes_left; | 465 | unsigned long bytes_left; |
466 | sums->len = this_sum_bytes; | 466 | sums->len = this_sum_bytes; |
467 | this_sum_bytes = 0; | 467 | this_sum_bytes = 0; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 20452c110d7d..841cfe3be0e0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2242,6 +2242,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) | |||
2242 | if (lockend <= lockstart) | 2242 | if (lockend <= lockstart) |
2243 | lockend = lockstart + root->sectorsize; | 2243 | lockend = lockstart + root->sectorsize; |
2244 | 2244 | ||
2245 | lockend--; | ||
2245 | len = lockend - lockstart + 1; | 2246 | len = lockend - lockstart + 1; |
2246 | 2247 | ||
2247 | len = max_t(u64, len, root->sectorsize); | 2248 | len = max_t(u64, len, root->sectorsize); |
@@ -2308,9 +2309,12 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) | |||
2308 | } | 2309 | } |
2309 | } | 2310 | } |
2310 | 2311 | ||
2311 | *offset = start; | 2312 | if (!test_bit(EXTENT_FLAG_PREALLOC, |
2312 | free_extent_map(em); | 2313 | &em->flags)) { |
2313 | break; | 2314 | *offset = start; |
2315 | free_extent_map(em); | ||
2316 | break; | ||
2317 | } | ||
2314 | } | 2318 | } |
2315 | } | 2319 | } |
2316 | 2320 | ||
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 62020b7f7036..e067cae15e3d 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -1885,11 +1885,13 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group, | |||
1885 | { | 1885 | { |
1886 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 1886 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
1887 | struct btrfs_free_space *info; | 1887 | struct btrfs_free_space *info; |
1888 | int ret = 0; | 1888 | int ret; |
1889 | bool re_search = false; | ||
1889 | 1890 | ||
1890 | spin_lock(&ctl->tree_lock); | 1891 | spin_lock(&ctl->tree_lock); |
1891 | 1892 | ||
1892 | again: | 1893 | again: |
1894 | ret = 0; | ||
1893 | if (!bytes) | 1895 | if (!bytes) |
1894 | goto out_lock; | 1896 | goto out_lock; |
1895 | 1897 | ||
@@ -1902,17 +1904,17 @@ again: | |||
1902 | info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), | 1904 | info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), |
1903 | 1, 0); | 1905 | 1, 0); |
1904 | if (!info) { | 1906 | if (!info) { |
1905 | /* the tree logging code might be calling us before we | 1907 | /* |
1906 | * have fully loaded the free space rbtree for this | 1908 | * If we found a partial bit of our free space in a |
1907 | * block group. So it is possible the entry won't | 1909 | * bitmap but then couldn't find the other part this may |
1908 | * be in the rbtree yet at all. The caching code | 1910 | * be a problem, so WARN about it. |
1909 | * will make sure not to put it in the rbtree if | ||
1910 | * the logging code has pinned it. | ||
1911 | */ | 1911 | */ |
1912 | WARN_ON(re_search); | ||
1912 | goto out_lock; | 1913 | goto out_lock; |
1913 | } | 1914 | } |
1914 | } | 1915 | } |
1915 | 1916 | ||
1917 | re_search = false; | ||
1916 | if (!info->bitmap) { | 1918 | if (!info->bitmap) { |
1917 | unlink_free_space(ctl, info); | 1919 | unlink_free_space(ctl, info); |
1918 | if (offset == info->offset) { | 1920 | if (offset == info->offset) { |
@@ -1958,8 +1960,10 @@ again: | |||
1958 | } | 1960 | } |
1959 | 1961 | ||
1960 | ret = remove_from_bitmap(ctl, info, &offset, &bytes); | 1962 | ret = remove_from_bitmap(ctl, info, &offset, &bytes); |
1961 | if (ret == -EAGAIN) | 1963 | if (ret == -EAGAIN) { |
1964 | re_search = true; | ||
1962 | goto again; | 1965 | goto again; |
1966 | } | ||
1963 | BUG_ON(ret); /* logic error */ | 1967 | BUG_ON(ret); /* logic error */ |
1964 | out_lock: | 1968 | out_lock: |
1965 | spin_unlock(&ctl->tree_lock); | 1969 | spin_unlock(&ctl->tree_lock); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6f4e41dca970..492ee0ee8c64 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -89,7 +89,7 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = { | |||
89 | [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, | 89 | [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, |
90 | }; | 90 | }; |
91 | 91 | ||
92 | static int btrfs_setsize(struct inode *inode, loff_t newsize); | 92 | static int btrfs_setsize(struct inode *inode, struct iattr *attr); |
93 | static int btrfs_truncate(struct inode *inode); | 93 | static int btrfs_truncate(struct inode *inode); |
94 | static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); | 94 | static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); |
95 | static noinline int cow_file_range(struct inode *inode, | 95 | static noinline int cow_file_range(struct inode *inode, |
@@ -2479,6 +2479,18 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
2479 | continue; | 2479 | continue; |
2480 | } | 2480 | } |
2481 | nr_truncate++; | 2481 | nr_truncate++; |
2482 | |||
2483 | /* 1 for the orphan item deletion. */ | ||
2484 | trans = btrfs_start_transaction(root, 1); | ||
2485 | if (IS_ERR(trans)) { | ||
2486 | ret = PTR_ERR(trans); | ||
2487 | goto out; | ||
2488 | } | ||
2489 | ret = btrfs_orphan_add(trans, inode); | ||
2490 | btrfs_end_transaction(trans, root); | ||
2491 | if (ret) | ||
2492 | goto out; | ||
2493 | |||
2482 | ret = btrfs_truncate(inode); | 2494 | ret = btrfs_truncate(inode); |
2483 | } else { | 2495 | } else { |
2484 | nr_unlink++; | 2496 | nr_unlink++; |
@@ -3666,6 +3678,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) | |||
3666 | block_end - cur_offset, 0); | 3678 | block_end - cur_offset, 0); |
3667 | if (IS_ERR(em)) { | 3679 | if (IS_ERR(em)) { |
3668 | err = PTR_ERR(em); | 3680 | err = PTR_ERR(em); |
3681 | em = NULL; | ||
3669 | break; | 3682 | break; |
3670 | } | 3683 | } |
3671 | last_byte = min(extent_map_end(em), block_end); | 3684 | last_byte = min(extent_map_end(em), block_end); |
@@ -3749,16 +3762,27 @@ next: | |||
3749 | return err; | 3762 | return err; |
3750 | } | 3763 | } |
3751 | 3764 | ||
3752 | static int btrfs_setsize(struct inode *inode, loff_t newsize) | 3765 | static int btrfs_setsize(struct inode *inode, struct iattr *attr) |
3753 | { | 3766 | { |
3754 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3767 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3755 | struct btrfs_trans_handle *trans; | 3768 | struct btrfs_trans_handle *trans; |
3756 | loff_t oldsize = i_size_read(inode); | 3769 | loff_t oldsize = i_size_read(inode); |
3770 | loff_t newsize = attr->ia_size; | ||
3771 | int mask = attr->ia_valid; | ||
3757 | int ret; | 3772 | int ret; |
3758 | 3773 | ||
3759 | if (newsize == oldsize) | 3774 | if (newsize == oldsize) |
3760 | return 0; | 3775 | return 0; |
3761 | 3776 | ||
3777 | /* | ||
3778 | * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a | ||
3779 | * special case where we need to update the times despite not having | ||
3780 | * these flags set. For all other operations the VFS set these flags | ||
3781 | * explicitly if it wants a timestamp update. | ||
3782 | */ | ||
3783 | if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME)))) | ||
3784 | inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); | ||
3785 | |||
3762 | if (newsize > oldsize) { | 3786 | if (newsize > oldsize) { |
3763 | truncate_pagecache(inode, oldsize, newsize); | 3787 | truncate_pagecache(inode, oldsize, newsize); |
3764 | ret = btrfs_cont_expand(inode, oldsize, newsize); | 3788 | ret = btrfs_cont_expand(inode, oldsize, newsize); |
@@ -3784,9 +3808,34 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize) | |||
3784 | set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, | 3808 | set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, |
3785 | &BTRFS_I(inode)->runtime_flags); | 3809 | &BTRFS_I(inode)->runtime_flags); |
3786 | 3810 | ||
3811 | /* | ||
3812 | * 1 for the orphan item we're going to add | ||
3813 | * 1 for the orphan item deletion. | ||
3814 | */ | ||
3815 | trans = btrfs_start_transaction(root, 2); | ||
3816 | if (IS_ERR(trans)) | ||
3817 | return PTR_ERR(trans); | ||
3818 | |||
3819 | /* | ||
3820 | * We need to do this in case we fail at _any_ point during the | ||
3821 | * actual truncate. Once we do the truncate_setsize we could | ||
3822 | * invalidate pages which forces any outstanding ordered io to | ||
3823 | * be instantly completed which will give us extents that need | ||
3824 | * to be truncated. If we fail to get an orphan inode down we | ||
3825 | * could have left over extents that were never meant to live, | ||
3826 | * so we need to garuntee from this point on that everything | ||
3827 | * will be consistent. | ||
3828 | */ | ||
3829 | ret = btrfs_orphan_add(trans, inode); | ||
3830 | btrfs_end_transaction(trans, root); | ||
3831 | if (ret) | ||
3832 | return ret; | ||
3833 | |||
3787 | /* we don't support swapfiles, so vmtruncate shouldn't fail */ | 3834 | /* we don't support swapfiles, so vmtruncate shouldn't fail */ |
3788 | truncate_setsize(inode, newsize); | 3835 | truncate_setsize(inode, newsize); |
3789 | ret = btrfs_truncate(inode); | 3836 | ret = btrfs_truncate(inode); |
3837 | if (ret && inode->i_nlink) | ||
3838 | btrfs_orphan_del(NULL, inode); | ||
3790 | } | 3839 | } |
3791 | 3840 | ||
3792 | return ret; | 3841 | return ret; |
@@ -3806,7 +3855,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3806 | return err; | 3855 | return err; |
3807 | 3856 | ||
3808 | if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { | 3857 | if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { |
3809 | err = btrfs_setsize(inode, attr->ia_size); | 3858 | err = btrfs_setsize(inode, attr); |
3810 | if (err) | 3859 | if (err) |
3811 | return err; | 3860 | return err; |
3812 | } | 3861 | } |
@@ -5587,10 +5636,13 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag | |||
5587 | return em; | 5636 | return em; |
5588 | if (em) { | 5637 | if (em) { |
5589 | /* | 5638 | /* |
5590 | * if our em maps to a hole, there might | 5639 | * if our em maps to |
5591 | * actually be delalloc bytes behind it | 5640 | * - a hole or |
5641 | * - a pre-alloc extent, | ||
5642 | * there might actually be delalloc bytes behind it. | ||
5592 | */ | 5643 | */ |
5593 | if (em->block_start != EXTENT_MAP_HOLE) | 5644 | if (em->block_start != EXTENT_MAP_HOLE && |
5645 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) | ||
5594 | return em; | 5646 | return em; |
5595 | else | 5647 | else |
5596 | hole_em = em; | 5648 | hole_em = em; |
@@ -5672,6 +5724,8 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag | |||
5672 | */ | 5724 | */ |
5673 | em->block_start = hole_em->block_start; | 5725 | em->block_start = hole_em->block_start; |
5674 | em->block_len = hole_len; | 5726 | em->block_len = hole_len; |
5727 | if (test_bit(EXTENT_FLAG_PREALLOC, &hole_em->flags)) | ||
5728 | set_bit(EXTENT_FLAG_PREALLOC, &em->flags); | ||
5675 | } else { | 5729 | } else { |
5676 | em->start = range_start; | 5730 | em->start = range_start; |
5677 | em->len = found; | 5731 | em->len = found; |
@@ -6937,11 +6991,9 @@ static int btrfs_truncate(struct inode *inode) | |||
6937 | 6991 | ||
6938 | /* | 6992 | /* |
6939 | * 1 for the truncate slack space | 6993 | * 1 for the truncate slack space |
6940 | * 1 for the orphan item we're going to add | ||
6941 | * 1 for the orphan item deletion | ||
6942 | * 1 for updating the inode. | 6994 | * 1 for updating the inode. |
6943 | */ | 6995 | */ |
6944 | trans = btrfs_start_transaction(root, 4); | 6996 | trans = btrfs_start_transaction(root, 2); |
6945 | if (IS_ERR(trans)) { | 6997 | if (IS_ERR(trans)) { |
6946 | err = PTR_ERR(trans); | 6998 | err = PTR_ERR(trans); |
6947 | goto out; | 6999 | goto out; |
@@ -6952,12 +7004,6 @@ static int btrfs_truncate(struct inode *inode) | |||
6952 | min_size); | 7004 | min_size); |
6953 | BUG_ON(ret); | 7005 | BUG_ON(ret); |
6954 | 7006 | ||
6955 | ret = btrfs_orphan_add(trans, inode); | ||
6956 | if (ret) { | ||
6957 | btrfs_end_transaction(trans, root); | ||
6958 | goto out; | ||
6959 | } | ||
6960 | |||
6961 | /* | 7007 | /* |
6962 | * setattr is responsible for setting the ordered_data_close flag, | 7008 | * setattr is responsible for setting the ordered_data_close flag, |
6963 | * but that is only tested during the last file release. That | 7009 | * but that is only tested during the last file release. That |
@@ -7026,12 +7072,6 @@ static int btrfs_truncate(struct inode *inode) | |||
7026 | ret = btrfs_orphan_del(trans, inode); | 7072 | ret = btrfs_orphan_del(trans, inode); |
7027 | if (ret) | 7073 | if (ret) |
7028 | err = ret; | 7074 | err = ret; |
7029 | } else if (ret && inode->i_nlink > 0) { | ||
7030 | /* | ||
7031 | * Failed to do the truncate, remove us from the in memory | ||
7032 | * orphan list. | ||
7033 | */ | ||
7034 | ret = btrfs_orphan_del(NULL, inode); | ||
7035 | } | 7075 | } |
7036 | 7076 | ||
7037 | if (trans) { | 7077 | if (trans) { |
@@ -7553,41 +7593,61 @@ void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work) | |||
7553 | */ | 7593 | */ |
7554 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) | 7594 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) |
7555 | { | 7595 | { |
7556 | struct list_head *head = &root->fs_info->delalloc_inodes; | ||
7557 | struct btrfs_inode *binode; | 7596 | struct btrfs_inode *binode; |
7558 | struct inode *inode; | 7597 | struct inode *inode; |
7559 | struct btrfs_delalloc_work *work, *next; | 7598 | struct btrfs_delalloc_work *work, *next; |
7560 | struct list_head works; | 7599 | struct list_head works; |
7600 | struct list_head splice; | ||
7561 | int ret = 0; | 7601 | int ret = 0; |
7562 | 7602 | ||
7563 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 7603 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
7564 | return -EROFS; | 7604 | return -EROFS; |
7565 | 7605 | ||
7566 | INIT_LIST_HEAD(&works); | 7606 | INIT_LIST_HEAD(&works); |
7567 | 7607 | INIT_LIST_HEAD(&splice); | |
7608 | again: | ||
7568 | spin_lock(&root->fs_info->delalloc_lock); | 7609 | spin_lock(&root->fs_info->delalloc_lock); |
7569 | while (!list_empty(head)) { | 7610 | list_splice_init(&root->fs_info->delalloc_inodes, &splice); |
7570 | binode = list_entry(head->next, struct btrfs_inode, | 7611 | while (!list_empty(&splice)) { |
7612 | binode = list_entry(splice.next, struct btrfs_inode, | ||
7571 | delalloc_inodes); | 7613 | delalloc_inodes); |
7614 | |||
7615 | list_del_init(&binode->delalloc_inodes); | ||
7616 | |||
7572 | inode = igrab(&binode->vfs_inode); | 7617 | inode = igrab(&binode->vfs_inode); |
7573 | if (!inode) | 7618 | if (!inode) |
7574 | list_del_init(&binode->delalloc_inodes); | 7619 | continue; |
7620 | |||
7621 | list_add_tail(&binode->delalloc_inodes, | ||
7622 | &root->fs_info->delalloc_inodes); | ||
7575 | spin_unlock(&root->fs_info->delalloc_lock); | 7623 | spin_unlock(&root->fs_info->delalloc_lock); |
7576 | if (inode) { | 7624 | |
7577 | work = btrfs_alloc_delalloc_work(inode, 0, delay_iput); | 7625 | work = btrfs_alloc_delalloc_work(inode, 0, delay_iput); |
7578 | if (!work) { | 7626 | if (unlikely(!work)) { |
7579 | ret = -ENOMEM; | 7627 | ret = -ENOMEM; |
7580 | goto out; | 7628 | goto out; |
7581 | } | ||
7582 | list_add_tail(&work->list, &works); | ||
7583 | btrfs_queue_worker(&root->fs_info->flush_workers, | ||
7584 | &work->work); | ||
7585 | } | 7629 | } |
7630 | list_add_tail(&work->list, &works); | ||
7631 | btrfs_queue_worker(&root->fs_info->flush_workers, | ||
7632 | &work->work); | ||
7633 | |||
7586 | cond_resched(); | 7634 | cond_resched(); |
7587 | spin_lock(&root->fs_info->delalloc_lock); | 7635 | spin_lock(&root->fs_info->delalloc_lock); |
7588 | } | 7636 | } |
7589 | spin_unlock(&root->fs_info->delalloc_lock); | 7637 | spin_unlock(&root->fs_info->delalloc_lock); |
7590 | 7638 | ||
7639 | list_for_each_entry_safe(work, next, &works, list) { | ||
7640 | list_del_init(&work->list); | ||
7641 | btrfs_wait_and_free_delalloc_work(work); | ||
7642 | } | ||
7643 | |||
7644 | spin_lock(&root->fs_info->delalloc_lock); | ||
7645 | if (!list_empty(&root->fs_info->delalloc_inodes)) { | ||
7646 | spin_unlock(&root->fs_info->delalloc_lock); | ||
7647 | goto again; | ||
7648 | } | ||
7649 | spin_unlock(&root->fs_info->delalloc_lock); | ||
7650 | |||
7591 | /* the filemap_flush will queue IO into the worker threads, but | 7651 | /* the filemap_flush will queue IO into the worker threads, but |
7592 | * we have to make sure the IO is actually started and that | 7652 | * we have to make sure the IO is actually started and that |
7593 | * ordered extents get created before we return | 7653 | * ordered extents get created before we return |
@@ -7600,11 +7660,18 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) | |||
7600 | atomic_read(&root->fs_info->async_delalloc_pages) == 0)); | 7660 | atomic_read(&root->fs_info->async_delalloc_pages) == 0)); |
7601 | } | 7661 | } |
7602 | atomic_dec(&root->fs_info->async_submit_draining); | 7662 | atomic_dec(&root->fs_info->async_submit_draining); |
7663 | return 0; | ||
7603 | out: | 7664 | out: |
7604 | list_for_each_entry_safe(work, next, &works, list) { | 7665 | list_for_each_entry_safe(work, next, &works, list) { |
7605 | list_del_init(&work->list); | 7666 | list_del_init(&work->list); |
7606 | btrfs_wait_and_free_delalloc_work(work); | 7667 | btrfs_wait_and_free_delalloc_work(work); |
7607 | } | 7668 | } |
7669 | |||
7670 | if (!list_empty_careful(&splice)) { | ||
7671 | spin_lock(&root->fs_info->delalloc_lock); | ||
7672 | list_splice_tail(&splice, &root->fs_info->delalloc_inodes); | ||
7673 | spin_unlock(&root->fs_info->delalloc_lock); | ||
7674 | } | ||
7608 | return ret; | 7675 | return ret; |
7609 | } | 7676 | } |
7610 | 7677 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7624212ae926..afbf3ac2079d 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1339,7 +1339,8 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1339 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | 1339 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, |
1340 | 1)) { | 1340 | 1)) { |
1341 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | 1341 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); |
1342 | return -EINPROGRESS; | 1342 | mnt_drop_write_file(file); |
1343 | return -EINVAL; | ||
1343 | } | 1344 | } |
1344 | 1345 | ||
1345 | mutex_lock(&root->fs_info->volume_mutex); | 1346 | mutex_lock(&root->fs_info->volume_mutex); |
@@ -1362,6 +1363,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1362 | printk(KERN_INFO "btrfs: resizing devid %llu\n", | 1363 | printk(KERN_INFO "btrfs: resizing devid %llu\n", |
1363 | (unsigned long long)devid); | 1364 | (unsigned long long)devid); |
1364 | } | 1365 | } |
1366 | |||
1365 | device = btrfs_find_device(root->fs_info, devid, NULL, NULL); | 1367 | device = btrfs_find_device(root->fs_info, devid, NULL, NULL); |
1366 | if (!device) { | 1368 | if (!device) { |
1367 | printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", | 1369 | printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", |
@@ -1369,9 +1371,10 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1369 | ret = -EINVAL; | 1371 | ret = -EINVAL; |
1370 | goto out_free; | 1372 | goto out_free; |
1371 | } | 1373 | } |
1372 | if (device->fs_devices && device->fs_devices->seeding) { | 1374 | |
1375 | if (!device->writeable) { | ||
1373 | printk(KERN_INFO "btrfs: resizer unable to apply on " | 1376 | printk(KERN_INFO "btrfs: resizer unable to apply on " |
1374 | "seeding device %llu\n", | 1377 | "readonly device %llu\n", |
1375 | (unsigned long long)devid); | 1378 | (unsigned long long)devid); |
1376 | ret = -EINVAL; | 1379 | ret = -EINVAL; |
1377 | goto out_free; | 1380 | goto out_free; |
@@ -1443,8 +1446,8 @@ out_free: | |||
1443 | kfree(vol_args); | 1446 | kfree(vol_args); |
1444 | out: | 1447 | out: |
1445 | mutex_unlock(&root->fs_info->volume_mutex); | 1448 | mutex_unlock(&root->fs_info->volume_mutex); |
1446 | mnt_drop_write_file(file); | ||
1447 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); | 1449 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); |
1450 | mnt_drop_write_file(file); | ||
1448 | return ret; | 1451 | return ret; |
1449 | } | 1452 | } |
1450 | 1453 | ||
@@ -2095,13 +2098,13 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2095 | err = inode_permission(inode, MAY_WRITE | MAY_EXEC); | 2098 | err = inode_permission(inode, MAY_WRITE | MAY_EXEC); |
2096 | if (err) | 2099 | if (err) |
2097 | goto out_dput; | 2100 | goto out_dput; |
2098 | |||
2099 | /* check if subvolume may be deleted by a non-root user */ | ||
2100 | err = btrfs_may_delete(dir, dentry, 1); | ||
2101 | if (err) | ||
2102 | goto out_dput; | ||
2103 | } | 2101 | } |
2104 | 2102 | ||
2103 | /* check if subvolume may be deleted by a user */ | ||
2104 | err = btrfs_may_delete(dir, dentry, 1); | ||
2105 | if (err) | ||
2106 | goto out_dput; | ||
2107 | |||
2105 | if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { | 2108 | if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { |
2106 | err = -EINVAL; | 2109 | err = -EINVAL; |
2107 | goto out_dput; | 2110 | goto out_dput; |
@@ -2183,19 +2186,20 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) | |||
2183 | struct btrfs_ioctl_defrag_range_args *range; | 2186 | struct btrfs_ioctl_defrag_range_args *range; |
2184 | int ret; | 2187 | int ret; |
2185 | 2188 | ||
2186 | if (btrfs_root_readonly(root)) | 2189 | ret = mnt_want_write_file(file); |
2187 | return -EROFS; | 2190 | if (ret) |
2191 | return ret; | ||
2188 | 2192 | ||
2189 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | 2193 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, |
2190 | 1)) { | 2194 | 1)) { |
2191 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | 2195 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); |
2192 | return -EINPROGRESS; | 2196 | mnt_drop_write_file(file); |
2197 | return -EINVAL; | ||
2193 | } | 2198 | } |
2194 | ret = mnt_want_write_file(file); | 2199 | |
2195 | if (ret) { | 2200 | if (btrfs_root_readonly(root)) { |
2196 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, | 2201 | ret = -EROFS; |
2197 | 0); | 2202 | goto out; |
2198 | return ret; | ||
2199 | } | 2203 | } |
2200 | 2204 | ||
2201 | switch (inode->i_mode & S_IFMT) { | 2205 | switch (inode->i_mode & S_IFMT) { |
@@ -2247,8 +2251,8 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) | |||
2247 | ret = -EINVAL; | 2251 | ret = -EINVAL; |
2248 | } | 2252 | } |
2249 | out: | 2253 | out: |
2250 | mnt_drop_write_file(file); | ||
2251 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); | 2254 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); |
2255 | mnt_drop_write_file(file); | ||
2252 | return ret; | 2256 | return ret; |
2253 | } | 2257 | } |
2254 | 2258 | ||
@@ -2263,7 +2267,7 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) | |||
2263 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | 2267 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, |
2264 | 1)) { | 2268 | 1)) { |
2265 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | 2269 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); |
2266 | return -EINPROGRESS; | 2270 | return -EINVAL; |
2267 | } | 2271 | } |
2268 | 2272 | ||
2269 | mutex_lock(&root->fs_info->volume_mutex); | 2273 | mutex_lock(&root->fs_info->volume_mutex); |
@@ -2300,7 +2304,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
2300 | 1)) { | 2304 | 1)) { |
2301 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | 2305 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); |
2302 | mnt_drop_write_file(file); | 2306 | mnt_drop_write_file(file); |
2303 | return -EINPROGRESS; | 2307 | return -EINVAL; |
2304 | } | 2308 | } |
2305 | 2309 | ||
2306 | mutex_lock(&root->fs_info->volume_mutex); | 2310 | mutex_lock(&root->fs_info->volume_mutex); |
@@ -2316,8 +2320,8 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
2316 | kfree(vol_args); | 2320 | kfree(vol_args); |
2317 | out: | 2321 | out: |
2318 | mutex_unlock(&root->fs_info->volume_mutex); | 2322 | mutex_unlock(&root->fs_info->volume_mutex); |
2319 | mnt_drop_write_file(file); | ||
2320 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); | 2323 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); |
2324 | mnt_drop_write_file(file); | ||
2321 | return ret; | 2325 | return ret; |
2322 | } | 2326 | } |
2323 | 2327 | ||
@@ -3437,8 +3441,8 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) | |||
3437 | struct btrfs_fs_info *fs_info = root->fs_info; | 3441 | struct btrfs_fs_info *fs_info = root->fs_info; |
3438 | struct btrfs_ioctl_balance_args *bargs; | 3442 | struct btrfs_ioctl_balance_args *bargs; |
3439 | struct btrfs_balance_control *bctl; | 3443 | struct btrfs_balance_control *bctl; |
3444 | bool need_unlock; /* for mut. excl. ops lock */ | ||
3440 | int ret; | 3445 | int ret; |
3441 | int need_to_clear_lock = 0; | ||
3442 | 3446 | ||
3443 | if (!capable(CAP_SYS_ADMIN)) | 3447 | if (!capable(CAP_SYS_ADMIN)) |
3444 | return -EPERM; | 3448 | return -EPERM; |
@@ -3447,14 +3451,61 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) | |||
3447 | if (ret) | 3451 | if (ret) |
3448 | return ret; | 3452 | return ret; |
3449 | 3453 | ||
3450 | mutex_lock(&fs_info->volume_mutex); | 3454 | again: |
3455 | if (!atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) { | ||
3456 | mutex_lock(&fs_info->volume_mutex); | ||
3457 | mutex_lock(&fs_info->balance_mutex); | ||
3458 | need_unlock = true; | ||
3459 | goto locked; | ||
3460 | } | ||
3461 | |||
3462 | /* | ||
3463 | * mut. excl. ops lock is locked. Three possibilites: | ||
3464 | * (1) some other op is running | ||
3465 | * (2) balance is running | ||
3466 | * (3) balance is paused -- special case (think resume) | ||
3467 | */ | ||
3451 | mutex_lock(&fs_info->balance_mutex); | 3468 | mutex_lock(&fs_info->balance_mutex); |
3469 | if (fs_info->balance_ctl) { | ||
3470 | /* this is either (2) or (3) */ | ||
3471 | if (!atomic_read(&fs_info->balance_running)) { | ||
3472 | mutex_unlock(&fs_info->balance_mutex); | ||
3473 | if (!mutex_trylock(&fs_info->volume_mutex)) | ||
3474 | goto again; | ||
3475 | mutex_lock(&fs_info->balance_mutex); | ||
3476 | |||
3477 | if (fs_info->balance_ctl && | ||
3478 | !atomic_read(&fs_info->balance_running)) { | ||
3479 | /* this is (3) */ | ||
3480 | need_unlock = false; | ||
3481 | goto locked; | ||
3482 | } | ||
3483 | |||
3484 | mutex_unlock(&fs_info->balance_mutex); | ||
3485 | mutex_unlock(&fs_info->volume_mutex); | ||
3486 | goto again; | ||
3487 | } else { | ||
3488 | /* this is (2) */ | ||
3489 | mutex_unlock(&fs_info->balance_mutex); | ||
3490 | ret = -EINPROGRESS; | ||
3491 | goto out; | ||
3492 | } | ||
3493 | } else { | ||
3494 | /* this is (1) */ | ||
3495 | mutex_unlock(&fs_info->balance_mutex); | ||
3496 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | ||
3497 | ret = -EINVAL; | ||
3498 | goto out; | ||
3499 | } | ||
3500 | |||
3501 | locked: | ||
3502 | BUG_ON(!atomic_read(&fs_info->mutually_exclusive_operation_running)); | ||
3452 | 3503 | ||
3453 | if (arg) { | 3504 | if (arg) { |
3454 | bargs = memdup_user(arg, sizeof(*bargs)); | 3505 | bargs = memdup_user(arg, sizeof(*bargs)); |
3455 | if (IS_ERR(bargs)) { | 3506 | if (IS_ERR(bargs)) { |
3456 | ret = PTR_ERR(bargs); | 3507 | ret = PTR_ERR(bargs); |
3457 | goto out; | 3508 | goto out_unlock; |
3458 | } | 3509 | } |
3459 | 3510 | ||
3460 | if (bargs->flags & BTRFS_BALANCE_RESUME) { | 3511 | if (bargs->flags & BTRFS_BALANCE_RESUME) { |
@@ -3474,13 +3525,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) | |||
3474 | bargs = NULL; | 3525 | bargs = NULL; |
3475 | } | 3526 | } |
3476 | 3527 | ||
3477 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | 3528 | if (fs_info->balance_ctl) { |
3478 | 1)) { | ||
3479 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | ||
3480 | ret = -EINPROGRESS; | 3529 | ret = -EINPROGRESS; |
3481 | goto out_bargs; | 3530 | goto out_bargs; |
3482 | } | 3531 | } |
3483 | need_to_clear_lock = 1; | ||
3484 | 3532 | ||
3485 | bctl = kzalloc(sizeof(*bctl), GFP_NOFS); | 3533 | bctl = kzalloc(sizeof(*bctl), GFP_NOFS); |
3486 | if (!bctl) { | 3534 | if (!bctl) { |
@@ -3501,11 +3549,17 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) | |||
3501 | } | 3549 | } |
3502 | 3550 | ||
3503 | do_balance: | 3551 | do_balance: |
3504 | ret = btrfs_balance(bctl, bargs); | ||
3505 | /* | 3552 | /* |
3506 | * bctl is freed in __cancel_balance or in free_fs_info if | 3553 | * Ownership of bctl and mutually_exclusive_operation_running |
3507 | * restriper was paused all the way until unmount | 3554 | * goes to to btrfs_balance. bctl is freed in __cancel_balance, |
3555 | * or, if restriper was paused all the way until unmount, in | ||
3556 | * free_fs_info. mutually_exclusive_operation_running is | ||
3557 | * cleared in __cancel_balance. | ||
3508 | */ | 3558 | */ |
3559 | need_unlock = false; | ||
3560 | |||
3561 | ret = btrfs_balance(bctl, bargs); | ||
3562 | |||
3509 | if (arg) { | 3563 | if (arg) { |
3510 | if (copy_to_user(arg, bargs, sizeof(*bargs))) | 3564 | if (copy_to_user(arg, bargs, sizeof(*bargs))) |
3511 | ret = -EFAULT; | 3565 | ret = -EFAULT; |
@@ -3513,12 +3567,12 @@ do_balance: | |||
3513 | 3567 | ||
3514 | out_bargs: | 3568 | out_bargs: |
3515 | kfree(bargs); | 3569 | kfree(bargs); |
3516 | out: | 3570 | out_unlock: |
3517 | if (need_to_clear_lock) | ||
3518 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, | ||
3519 | 0); | ||
3520 | mutex_unlock(&fs_info->balance_mutex); | 3571 | mutex_unlock(&fs_info->balance_mutex); |
3521 | mutex_unlock(&fs_info->volume_mutex); | 3572 | mutex_unlock(&fs_info->volume_mutex); |
3573 | if (need_unlock) | ||
3574 | atomic_set(&fs_info->mutually_exclusive_operation_running, 0); | ||
3575 | out: | ||
3522 | mnt_drop_write_file(file); | 3576 | mnt_drop_write_file(file); |
3523 | return ret; | 3577 | return ret; |
3524 | } | 3578 | } |
@@ -3698,6 +3752,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) | |||
3698 | goto drop_write; | 3752 | goto drop_write; |
3699 | } | 3753 | } |
3700 | 3754 | ||
3755 | if (!sa->qgroupid) { | ||
3756 | ret = -EINVAL; | ||
3757 | goto out; | ||
3758 | } | ||
3759 | |||
3701 | trans = btrfs_join_transaction(root); | 3760 | trans = btrfs_join_transaction(root); |
3702 | if (IS_ERR(trans)) { | 3761 | if (IS_ERR(trans)) { |
3703 | ret = PTR_ERR(trans); | 3762 | ret = PTR_ERR(trans); |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index fe9d02c45f8e..a5c856234323 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -379,6 +379,13 @@ next1: | |||
379 | 379 | ||
380 | ret = add_relation_rb(fs_info, found_key.objectid, | 380 | ret = add_relation_rb(fs_info, found_key.objectid, |
381 | found_key.offset); | 381 | found_key.offset); |
382 | if (ret == -ENOENT) { | ||
383 | printk(KERN_WARNING | ||
384 | "btrfs: orphan qgroup relation 0x%llx->0x%llx\n", | ||
385 | (unsigned long long)found_key.objectid, | ||
386 | (unsigned long long)found_key.offset); | ||
387 | ret = 0; /* ignore the error */ | ||
388 | } | ||
382 | if (ret) | 389 | if (ret) |
383 | goto out; | 390 | goto out; |
384 | next2: | 391 | next2: |
@@ -956,17 +963,28 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, | |||
956 | struct btrfs_fs_info *fs_info, u64 qgroupid) | 963 | struct btrfs_fs_info *fs_info, u64 qgroupid) |
957 | { | 964 | { |
958 | struct btrfs_root *quota_root; | 965 | struct btrfs_root *quota_root; |
966 | struct btrfs_qgroup *qgroup; | ||
959 | int ret = 0; | 967 | int ret = 0; |
960 | 968 | ||
961 | quota_root = fs_info->quota_root; | 969 | quota_root = fs_info->quota_root; |
962 | if (!quota_root) | 970 | if (!quota_root) |
963 | return -EINVAL; | 971 | return -EINVAL; |
964 | 972 | ||
973 | /* check if there are no relations to this qgroup */ | ||
974 | spin_lock(&fs_info->qgroup_lock); | ||
975 | qgroup = find_qgroup_rb(fs_info, qgroupid); | ||
976 | if (qgroup) { | ||
977 | if (!list_empty(&qgroup->groups) || !list_empty(&qgroup->members)) { | ||
978 | spin_unlock(&fs_info->qgroup_lock); | ||
979 | return -EBUSY; | ||
980 | } | ||
981 | } | ||
982 | spin_unlock(&fs_info->qgroup_lock); | ||
983 | |||
965 | ret = del_qgroup_item(trans, quota_root, qgroupid); | 984 | ret = del_qgroup_item(trans, quota_root, qgroupid); |
966 | 985 | ||
967 | spin_lock(&fs_info->qgroup_lock); | 986 | spin_lock(&fs_info->qgroup_lock); |
968 | del_qgroup_rb(quota_root->fs_info, qgroupid); | 987 | del_qgroup_rb(quota_root->fs_info, qgroupid); |
969 | |||
970 | spin_unlock(&fs_info->qgroup_lock); | 988 | spin_unlock(&fs_info->qgroup_lock); |
971 | 989 | ||
972 | return ret; | 990 | return ret; |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 54454542ad40..321b7fb4e441 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -1814,8 +1814,10 @@ static int name_cache_insert(struct send_ctx *sctx, | |||
1814 | (unsigned long)nce->ino); | 1814 | (unsigned long)nce->ino); |
1815 | if (!nce_head) { | 1815 | if (!nce_head) { |
1816 | nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS); | 1816 | nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS); |
1817 | if (!nce_head) | 1817 | if (!nce_head) { |
1818 | kfree(nce); | ||
1818 | return -ENOMEM; | 1819 | return -ENOMEM; |
1820 | } | ||
1819 | INIT_LIST_HEAD(nce_head); | 1821 | INIT_LIST_HEAD(nce_head); |
1820 | 1822 | ||
1821 | ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); | 1823 | ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 99545df1b86c..d8982e9601d3 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -267,7 +267,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, | |||
267 | function, line, errstr); | 267 | function, line, errstr); |
268 | return; | 268 | return; |
269 | } | 269 | } |
270 | trans->transaction->aborted = errno; | 270 | ACCESS_ONCE(trans->transaction->aborted) = errno; |
271 | __btrfs_std_error(root->fs_info, function, line, errno, NULL); | 271 | __btrfs_std_error(root->fs_info, function, line, errno, NULL); |
272 | } | 272 | } |
273 | /* | 273 | /* |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 1e7f176bd211..c56b9d436204 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -1475,7 +1475,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1475 | goto cleanup_transaction; | 1475 | goto cleanup_transaction; |
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | if (cur_trans->aborted) { | 1478 | /* Stop the commit early if ->aborted is set */ |
1479 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { | ||
1479 | ret = cur_trans->aborted; | 1480 | ret = cur_trans->aborted; |
1480 | goto cleanup_transaction; | 1481 | goto cleanup_transaction; |
1481 | } | 1482 | } |
@@ -1581,6 +1582,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1581 | wait_event(cur_trans->writer_wait, | 1582 | wait_event(cur_trans->writer_wait, |
1582 | atomic_read(&cur_trans->num_writers) == 1); | 1583 | atomic_read(&cur_trans->num_writers) == 1); |
1583 | 1584 | ||
1585 | /* ->aborted might be set after the previous check, so check it */ | ||
1586 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { | ||
1587 | ret = cur_trans->aborted; | ||
1588 | goto cleanup_transaction; | ||
1589 | } | ||
1584 | /* | 1590 | /* |
1585 | * the reloc mutex makes sure that we stop | 1591 | * the reloc mutex makes sure that we stop |
1586 | * the balancing code from coming in and moving | 1592 | * the balancing code from coming in and moving |
@@ -1664,6 +1670,17 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1664 | goto cleanup_transaction; | 1670 | goto cleanup_transaction; |
1665 | } | 1671 | } |
1666 | 1672 | ||
1673 | /* | ||
1674 | * The tasks which save the space cache and inode cache may also | ||
1675 | * update ->aborted, check it. | ||
1676 | */ | ||
1677 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { | ||
1678 | ret = cur_trans->aborted; | ||
1679 | mutex_unlock(&root->fs_info->tree_log_mutex); | ||
1680 | mutex_unlock(&root->fs_info->reloc_mutex); | ||
1681 | goto cleanup_transaction; | ||
1682 | } | ||
1683 | |||
1667 | btrfs_prepare_extent_commit(trans, root); | 1684 | btrfs_prepare_extent_commit(trans, root); |
1668 | 1685 | ||
1669 | cur_trans = root->fs_info->running_transaction; | 1686 | cur_trans = root->fs_info->running_transaction; |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 83186c7e45d4..9027bb1e7466 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -3357,6 +3357,11 @@ static int log_one_extent(struct btrfs_trans_handle *trans, | |||
3357 | if (skip_csum) | 3357 | if (skip_csum) |
3358 | return 0; | 3358 | return 0; |
3359 | 3359 | ||
3360 | if (em->compress_type) { | ||
3361 | csum_offset = 0; | ||
3362 | csum_len = block_len; | ||
3363 | } | ||
3364 | |||
3360 | /* block start is already adjusted for the file extent offset. */ | 3365 | /* block start is already adjusted for the file extent offset. */ |
3361 | ret = btrfs_lookup_csums_range(log->fs_info->csum_root, | 3366 | ret = btrfs_lookup_csums_range(log->fs_info->csum_root, |
3362 | em->block_start + csum_offset, | 3367 | em->block_start + csum_offset, |
@@ -3410,13 +3415,13 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | |||
3410 | em = list_entry(extents.next, struct extent_map, list); | 3415 | em = list_entry(extents.next, struct extent_map, list); |
3411 | 3416 | ||
3412 | list_del_init(&em->list); | 3417 | list_del_init(&em->list); |
3413 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); | ||
3414 | 3418 | ||
3415 | /* | 3419 | /* |
3416 | * If we had an error we just need to delete everybody from our | 3420 | * If we had an error we just need to delete everybody from our |
3417 | * private list. | 3421 | * private list. |
3418 | */ | 3422 | */ |
3419 | if (ret) { | 3423 | if (ret) { |
3424 | clear_em_logging(tree, em); | ||
3420 | free_extent_map(em); | 3425 | free_extent_map(em); |
3421 | continue; | 3426 | continue; |
3422 | } | 3427 | } |
@@ -3424,8 +3429,9 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | |||
3424 | write_unlock(&tree->lock); | 3429 | write_unlock(&tree->lock); |
3425 | 3430 | ||
3426 | ret = log_one_extent(trans, inode, root, em, path); | 3431 | ret = log_one_extent(trans, inode, root, em, path); |
3427 | free_extent_map(em); | ||
3428 | write_lock(&tree->lock); | 3432 | write_lock(&tree->lock); |
3433 | clear_em_logging(tree, em); | ||
3434 | free_extent_map(em); | ||
3429 | } | 3435 | } |
3430 | WARN_ON(!list_empty(&extents)); | 3436 | WARN_ON(!list_empty(&extents)); |
3431 | write_unlock(&tree->lock); | 3437 | write_unlock(&tree->lock); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 77620f2d8af9..8818dc34c199 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1449,7 +1449,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1449 | } | 1449 | } |
1450 | } else { | 1450 | } else { |
1451 | ret = btrfs_get_bdev_and_sb(device_path, | 1451 | ret = btrfs_get_bdev_and_sb(device_path, |
1452 | FMODE_READ | FMODE_EXCL, | 1452 | FMODE_WRITE | FMODE_EXCL, |
1453 | root->fs_info->bdev_holder, 0, | 1453 | root->fs_info->bdev_holder, 0, |
1454 | &bdev, &bh); | 1454 | &bdev, &bh); |
1455 | if (ret) | 1455 | if (ret) |
@@ -2633,7 +2633,14 @@ static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset, | |||
2633 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); | 2633 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); |
2634 | chunk_used = btrfs_block_group_used(&cache->item); | 2634 | chunk_used = btrfs_block_group_used(&cache->item); |
2635 | 2635 | ||
2636 | user_thresh = div_factor_fine(cache->key.offset, bargs->usage); | 2636 | if (bargs->usage == 0) |
2637 | user_thresh = 0; | ||
2638 | else if (bargs->usage > 100) | ||
2639 | user_thresh = cache->key.offset; | ||
2640 | else | ||
2641 | user_thresh = div_factor_fine(cache->key.offset, | ||
2642 | bargs->usage); | ||
2643 | |||
2637 | if (chunk_used < user_thresh) | 2644 | if (chunk_used < user_thresh) |
2638 | ret = 0; | 2645 | ret = 0; |
2639 | 2646 | ||
@@ -2982,6 +2989,8 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info) | |||
2982 | unset_balance_control(fs_info); | 2989 | unset_balance_control(fs_info); |
2983 | ret = del_balance_item(fs_info->tree_root); | 2990 | ret = del_balance_item(fs_info->tree_root); |
2984 | BUG_ON(ret); | 2991 | BUG_ON(ret); |
2992 | |||
2993 | atomic_set(&fs_info->mutually_exclusive_operation_running, 0); | ||
2985 | } | 2994 | } |
2986 | 2995 | ||
2987 | void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock, | 2996 | void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock, |
@@ -3169,8 +3178,10 @@ int btrfs_balance(struct btrfs_balance_control *bctl, | |||
3169 | out: | 3178 | out: |
3170 | if (bctl->flags & BTRFS_BALANCE_RESUME) | 3179 | if (bctl->flags & BTRFS_BALANCE_RESUME) |
3171 | __cancel_balance(fs_info); | 3180 | __cancel_balance(fs_info); |
3172 | else | 3181 | else { |
3173 | kfree(bctl); | 3182 | kfree(bctl); |
3183 | atomic_set(&fs_info->mutually_exclusive_operation_running, 0); | ||
3184 | } | ||
3174 | return ret; | 3185 | return ret; |
3175 | } | 3186 | } |
3176 | 3187 | ||
@@ -3187,7 +3198,6 @@ static int balance_kthread(void *data) | |||
3187 | ret = btrfs_balance(fs_info->balance_ctl, NULL); | 3198 | ret = btrfs_balance(fs_info->balance_ctl, NULL); |
3188 | } | 3199 | } |
3189 | 3200 | ||
3190 | atomic_set(&fs_info->mutually_exclusive_operation_running, 0); | ||
3191 | mutex_unlock(&fs_info->balance_mutex); | 3201 | mutex_unlock(&fs_info->balance_mutex); |
3192 | mutex_unlock(&fs_info->volume_mutex); | 3202 | mutex_unlock(&fs_info->volume_mutex); |
3193 | 3203 | ||
@@ -3210,7 +3220,6 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info) | |||
3210 | return 0; | 3220 | return 0; |
3211 | } | 3221 | } |
3212 | 3222 | ||
3213 | WARN_ON(atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)); | ||
3214 | tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance"); | 3223 | tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance"); |
3215 | if (IS_ERR(tsk)) | 3224 | if (IS_ERR(tsk)) |
3216 | return PTR_ERR(tsk); | 3225 | return PTR_ERR(tsk); |
@@ -3264,6 +3273,8 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info) | |||
3264 | btrfs_balance_sys(leaf, item, &disk_bargs); | 3273 | btrfs_balance_sys(leaf, item, &disk_bargs); |
3265 | btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs); | 3274 | btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs); |
3266 | 3275 | ||
3276 | WARN_ON(atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)); | ||
3277 | |||
3267 | mutex_lock(&fs_info->volume_mutex); | 3278 | mutex_lock(&fs_info->volume_mutex); |
3268 | mutex_lock(&fs_info->balance_mutex); | 3279 | mutex_lock(&fs_info->balance_mutex); |
3269 | 3280 | ||
@@ -3535,7 +3546,7 @@ struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = { | |||
3535 | { 1, 1, 2, 2, 2, 2 /* raid1 */ }, | 3546 | { 1, 1, 2, 2, 2, 2 /* raid1 */ }, |
3536 | { 1, 2, 1, 1, 1, 2 /* dup */ }, | 3547 | { 1, 2, 1, 1, 1, 2 /* dup */ }, |
3537 | { 1, 1, 0, 2, 1, 1 /* raid0 */ }, | 3548 | { 1, 1, 0, 2, 1, 1 /* raid0 */ }, |
3538 | { 1, 1, 0, 1, 1, 1 /* single */ }, | 3549 | { 1, 1, 1, 1, 1, 1 /* single */ }, |
3539 | { 1, 1, 0, 2, 1, 2 /* raid5 */ }, | 3550 | { 1, 1, 0, 2, 1, 2 /* raid5 */ }, |
3540 | { 1, 1, 0, 3, 1, 3 /* raid6 */ }, | 3551 | { 1, 1, 0, 3, 1, 3 /* raid6 */ }, |
3541 | }; | 3552 | }; |