aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/compression.c4
-rw-r--r--fs/btrfs/extent_io.c11
-rw-r--r--fs/btrfs/file.c21
-rw-r--r--fs/btrfs/inode.c8
4 files changed, 35 insertions, 9 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 9adaa79adad9..354913177ba6 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -220,10 +220,12 @@ static void end_compressed_bio_write(struct bio *bio, int err)
220 */ 220 */
221 inode = cb->inode; 221 inode = cb->inode;
222 tree = &BTRFS_I(inode)->io_tree; 222 tree = &BTRFS_I(inode)->io_tree;
223 cb->compressed_pages[0]->mapping = cb->inode->i_mapping;
223 tree->ops->writepage_end_io_hook(cb->compressed_pages[0], 224 tree->ops->writepage_end_io_hook(cb->compressed_pages[0],
224 cb->start, 225 cb->start,
225 cb->start + cb->len - 1, 226 cb->start + cb->len - 1,
226 NULL, 1); 227 NULL, 1);
228 cb->compressed_pages[0]->mapping = NULL;
227 229
228 end_compressed_writeback(inode, cb->start, cb->len); 230 end_compressed_writeback(inode, cb->start, cb->len);
229 /* note, our inode could be gone now */ 231 /* note, our inode could be gone now */
@@ -306,6 +308,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
306 else 308 else
307 ret = 0; 309 ret = 0;
308 310
311 page->mapping = NULL;
309 if (ret || bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < 312 if (ret || bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) <
310 PAGE_CACHE_SIZE) { 313 PAGE_CACHE_SIZE) {
311 bio_get(bio); 314 bio_get(bio);
@@ -423,6 +426,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
423 else 426 else
424 ret = 0; 427 ret = 0;
425 428
429 page->mapping = NULL;
426 if (ret || bio_add_page(comp_bio, page, PAGE_CACHE_SIZE, 0) < 430 if (ret || bio_add_page(comp_bio, page, PAGE_CACHE_SIZE, 0) <
427 PAGE_CACHE_SIZE) { 431 PAGE_CACHE_SIZE) {
428 bio_get(comp_bio); 432 bio_get(comp_bio);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index eb3c12e7beaf..9b37ce6e5168 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1242,13 +1242,22 @@ again:
1242 delalloc_end = 0; 1242 delalloc_end = 0;
1243 found = find_delalloc_range(tree, &delalloc_start, &delalloc_end, 1243 found = find_delalloc_range(tree, &delalloc_start, &delalloc_end,
1244 max_bytes); 1244 max_bytes);
1245 if (!found) { 1245 if (!found || delalloc_end <= *start) {
1246 *start = delalloc_start; 1246 *start = delalloc_start;
1247 *end = delalloc_end; 1247 *end = delalloc_end;
1248 return found; 1248 return found;
1249 } 1249 }
1250 1250
1251 /* 1251 /*
1252 * start comes from the offset of locked_page. We have to lock
1253 * pages in order, so we can't process delalloc bytes before
1254 * locked_page
1255 */
1256 if (delalloc_start < *start) {
1257 delalloc_start = *start;
1258 }
1259
1260 /*
1252 * make sure to limit the number of pages we try to lock down 1261 * make sure to limit the number of pages we try to lock down
1253 * if we're looping. 1262 * if we're looping.
1254 */ 1263 */
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 238a8e215eb9..0c8cc35a8b97 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -368,8 +368,8 @@ int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans,
368 u64 search_start = start; 368 u64 search_start = start;
369 u64 leaf_start; 369 u64 leaf_start;
370 u64 ram_bytes = 0; 370 u64 ram_bytes = 0;
371 u8 compression = 0; 371 u8 compression;
372 u8 encryption = 0; 372 u8 encryption;
373 u16 other_encoding = 0; 373 u16 other_encoding = 0;
374 u64 root_gen; 374 u64 root_gen;
375 u64 root_owner; 375 u64 root_owner;
@@ -415,6 +415,8 @@ next_slot:
415 leaf_start = 0; 415 leaf_start = 0;
416 root_gen = 0; 416 root_gen = 0;
417 root_owner = 0; 417 root_owner = 0;
418 compression = 0;
419 encryption = 0;
418 extent = NULL; 420 extent = NULL;
419 leaf = path->nodes[0]; 421 leaf = path->nodes[0];
420 slot = path->slots[0]; 422 slot = path->slots[0];
@@ -546,8 +548,12 @@ next_slot:
546 inline_limit - key.offset); 548 inline_limit - key.offset);
547 inode_sub_bytes(inode, extent_end - 549 inode_sub_bytes(inode, extent_end -
548 inline_limit); 550 inline_limit);
549 btrfs_truncate_item(trans, root, path, 551 btrfs_set_file_extent_ram_bytes(leaf, extent,
550 new_size, 1); 552 new_size);
553 if (!compression && !encryption) {
554 btrfs_truncate_item(trans, root, path,
555 new_size, 1);
556 }
551 } 557 }
552 } 558 }
553 /* delete the entire extent */ 559 /* delete the entire extent */
@@ -567,8 +573,11 @@ next_slot:
567 new_size = btrfs_file_extent_calc_inline_size( 573 new_size = btrfs_file_extent_calc_inline_size(
568 extent_end - end); 574 extent_end - end);
569 inode_sub_bytes(inode, end - key.offset); 575 inode_sub_bytes(inode, end - key.offset);
570 ret = btrfs_truncate_item(trans, root, path, 576 btrfs_set_file_extent_ram_bytes(leaf, extent,
571 new_size, 0); 577 new_size);
578 if (!compression && !encryption)
579 ret = btrfs_truncate_item(trans, root, path,
580 new_size, 0);
572 BUG_ON(ret); 581 BUG_ON(ret);
573 } 582 }
574 /* create bookend, splitting the extent in two */ 583 /* create bookend, splitting the extent in two */
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 789c376157f9..806708dd7e38 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -239,6 +239,7 @@ static int cow_file_range_inline(struct btrfs_trans_handle *trans,
239 data_len = compressed_size; 239 data_len = compressed_size;
240 240
241 if (start > 0 || 241 if (start > 0 ||
242 actual_end >= PAGE_CACHE_SIZE ||
242 data_len >= BTRFS_MAX_INLINE_DATA_SIZE(root) || 243 data_len >= BTRFS_MAX_INLINE_DATA_SIZE(root) ||
243 (!compressed_size && 244 (!compressed_size &&
244 (actual_end & (root->sectorsize - 1)) == 0) || 245 (actual_end & (root->sectorsize - 1)) == 0) ||
@@ -248,7 +249,7 @@ static int cow_file_range_inline(struct btrfs_trans_handle *trans,
248 } 249 }
249 250
250 ret = btrfs_drop_extents(trans, root, inode, start, 251 ret = btrfs_drop_extents(trans, root, inode, start,
251 aligned_end, aligned_end, &hint_byte); 252 aligned_end, start, &hint_byte);
252 BUG_ON(ret); 253 BUG_ON(ret);
253 254
254 if (isize > actual_end) 255 if (isize > actual_end)
@@ -423,6 +424,7 @@ again:
423 * free any pages it allocated and our page pointer array 424 * free any pages it allocated and our page pointer array
424 */ 425 */
425 for (i = 0; i < nr_pages_ret; i++) { 426 for (i = 0; i < nr_pages_ret; i++) {
427 WARN_ON(pages[i]->mapping);
426 page_cache_release(pages[i]); 428 page_cache_release(pages[i]);
427 } 429 }
428 kfree(pages); 430 kfree(pages);
@@ -572,8 +574,10 @@ free_pages_out_fail:
572 extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, 574 extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree,
573 start, end, locked_page, 0, 0, 0); 575 start, end, locked_page, 0, 0, 0);
574free_pages_out: 576free_pages_out:
575 for (i = 0; i < nr_pages_ret; i++) 577 for (i = 0; i < nr_pages_ret; i++) {
578 WARN_ON(pages[i]->mapping);
576 page_cache_release(pages[i]); 579 page_cache_release(pages[i]);
580 }
577 if (pages) 581 if (pages)
578 kfree(pages); 582 kfree(pages);
579 583