aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-10-31 12:46:39 -0400
committerChris Mason <chris.mason@oracle.com>2008-10-31 12:46:39 -0400
commit70b99e6959a4c28ae1b314985eca731f3db72f1d (patch)
tree81578759fe422f7b17a734b8bf16b042aa02a046 /fs/btrfs/inode.c
parentd899e05215178fed903ad0e7fc1cb4d8e0cc0a88 (diff)
Btrfs: Compression corner fixes
Make sure we keep page->mapping NULL on the pages we're getting via alloc_page. It gets set so a few of the callbacks can do the right thing, but in general these pages don't have a mapping. Don't try to truncate compressed inline items in btrfs_drop_extents. The whole compressed item must be preserved. Don't try to create multipage inline compressed items. When we try to overwrite just the first page of the file, we would have to read in and recow all the pages after it in the same compressed inline items. For now, only create single page inline items. Make sure we lock pages in the correct order during delalloc. The search into the state tree for delalloc bytes can return bytes before the page we already have locked. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c8
1 files changed, 6 insertions, 2 deletions
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