diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/compression.c | 4 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 11 | ||||
-rw-r--r-- | fs/btrfs/file.c | 21 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 8 |
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); |
574 | free_pages_out: | 576 | free_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 | ||