aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2011-03-28 04:30:38 -0400
committerChris Mason <chris.mason@oracle.com>2011-04-05 01:19:42 -0400
commitfe3f566cd19bb6d787c92b2e202c85f929abf3ac (patch)
tree216c33bb0ed94e7791141939ea763620576d82b0 /fs
parent200da64e0b039f873f0f20481e6a7d056e7cc6c9 (diff)
Btrfs: Fix oops for defrag with compression turned on
When we defrag a file, whose size can be fit into an inline extent, with compression enabled, the compress type is set to be fs_info->compress_type, which is 0 if the btrfs filesystem is mounted without compress option. This leads to oops. Reported-by: Daniel Blueman <daniel.blueman@gmail.com> Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 06274186b290..62ae9d5da806 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -111,6 +111,7 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
111static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, 111static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
112 struct btrfs_root *root, struct inode *inode, 112 struct btrfs_root *root, struct inode *inode,
113 u64 start, size_t size, size_t compressed_size, 113 u64 start, size_t size, size_t compressed_size,
114 int compress_type,
114 struct page **compressed_pages) 115 struct page **compressed_pages)
115{ 116{
116 struct btrfs_key key; 117 struct btrfs_key key;
@@ -125,12 +126,9 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
125 size_t cur_size = size; 126 size_t cur_size = size;
126 size_t datasize; 127 size_t datasize;
127 unsigned long offset; 128 unsigned long offset;
128 int compress_type = BTRFS_COMPRESS_NONE;
129 129
130 if (compressed_size && compressed_pages) { 130 if (compressed_size && compressed_pages)
131 compress_type = root->fs_info->compress_type;
132 cur_size = compressed_size; 131 cur_size = compressed_size;
133 }
134 132
135 path = btrfs_alloc_path(); 133 path = btrfs_alloc_path();
136 if (!path) 134 if (!path)
@@ -220,7 +218,7 @@ fail:
220static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, 218static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans,
221 struct btrfs_root *root, 219 struct btrfs_root *root,
222 struct inode *inode, u64 start, u64 end, 220 struct inode *inode, u64 start, u64 end,
223 size_t compressed_size, 221 size_t compressed_size, int compress_type,
224 struct page **compressed_pages) 222 struct page **compressed_pages)
225{ 223{
226 u64 isize = i_size_read(inode); 224 u64 isize = i_size_read(inode);
@@ -253,7 +251,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans,
253 inline_len = min_t(u64, isize, actual_end); 251 inline_len = min_t(u64, isize, actual_end);
254 ret = insert_inline_extent(trans, root, inode, start, 252 ret = insert_inline_extent(trans, root, inode, start,
255 inline_len, compressed_size, 253 inline_len, compressed_size,
256 compressed_pages); 254 compress_type, compressed_pages);
257 BUG_ON(ret); 255 BUG_ON(ret);
258 btrfs_delalloc_release_metadata(inode, end + 1 - start); 256 btrfs_delalloc_release_metadata(inode, end + 1 - start);
259 btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); 257 btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0);
@@ -432,12 +430,13 @@ again:
432 * to make an uncompressed inline extent. 430 * to make an uncompressed inline extent.
433 */ 431 */
434 ret = cow_file_range_inline(trans, root, inode, 432 ret = cow_file_range_inline(trans, root, inode,
435 start, end, 0, NULL); 433 start, end, 0, 0, NULL);
436 } else { 434 } else {
437 /* try making a compressed inline extent */ 435 /* try making a compressed inline extent */
438 ret = cow_file_range_inline(trans, root, inode, 436 ret = cow_file_range_inline(trans, root, inode,
439 start, end, 437 start, end,
440 total_compressed, pages); 438 total_compressed,
439 compress_type, pages);
441 } 440 }
442 if (ret == 0) { 441 if (ret == 0) {
443 /* 442 /*
@@ -791,7 +790,7 @@ static noinline int cow_file_range(struct inode *inode,
791 if (start == 0) { 790 if (start == 0) {
792 /* lets try to make an inline extent */ 791 /* lets try to make an inline extent */
793 ret = cow_file_range_inline(trans, root, inode, 792 ret = cow_file_range_inline(trans, root, inode,
794 start, end, 0, NULL); 793 start, end, 0, 0, NULL);
795 if (ret == 0) { 794 if (ret == 0) {
796 extent_clear_unlock_delalloc(inode, 795 extent_clear_unlock_delalloc(inode,
797 &BTRFS_I(inode)->io_tree, 796 &BTRFS_I(inode)->io_tree,