diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index dd38d4c3a599..1cb72394498c 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -590,10 +590,25 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
| 590 | 590 | ||
| 591 | num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> | 591 | num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> |
| 592 | PAGE_CACHE_SHIFT; | 592 | PAGE_CACHE_SHIFT; |
| 593 | |||
| 594 | /* Since the first page has all of our checksums and our generation we | ||
| 595 | * need to calculate the offset into the page that we can start writing | ||
| 596 | * our entries. | ||
| 597 | */ | ||
| 598 | first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64); | ||
| 599 | |||
| 593 | filemap_write_and_wait(inode->i_mapping); | 600 | filemap_write_and_wait(inode->i_mapping); |
| 594 | btrfs_wait_ordered_range(inode, inode->i_size & | 601 | btrfs_wait_ordered_range(inode, inode->i_size & |
| 595 | ~(root->sectorsize - 1), (u64)-1); | 602 | ~(root->sectorsize - 1), (u64)-1); |
| 596 | 603 | ||
| 604 | /* make sure we don't overflow that first page */ | ||
| 605 | if (first_page_offset + sizeof(struct btrfs_free_space_entry) >= PAGE_CACHE_SIZE) { | ||
| 606 | /* this is really the same as running out of space, where we also return 0 */ | ||
| 607 | printk(KERN_CRIT "Btrfs: free space cache was too big for the crc page\n"); | ||
| 608 | ret = 0; | ||
| 609 | goto out_update; | ||
| 610 | } | ||
| 611 | |||
| 597 | /* We need a checksum per page. */ | 612 | /* We need a checksum per page. */ |
| 598 | crc = checksums = kzalloc(sizeof(u32) * num_pages, GFP_NOFS); | 613 | crc = checksums = kzalloc(sizeof(u32) * num_pages, GFP_NOFS); |
| 599 | if (!crc) | 614 | if (!crc) |
| @@ -605,12 +620,6 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
| 605 | return -1; | 620 | return -1; |
| 606 | } | 621 | } |
| 607 | 622 | ||
| 608 | /* Since the first page has all of our checksums and our generation we | ||
| 609 | * need to calculate the offset into the page that we can start writing | ||
| 610 | * our entries. | ||
| 611 | */ | ||
| 612 | first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64); | ||
| 613 | |||
| 614 | /* Get the cluster for this block_group if it exists */ | 623 | /* Get the cluster for this block_group if it exists */ |
| 615 | if (block_group && !list_empty(&block_group->cluster_list)) | 624 | if (block_group && !list_empty(&block_group->cluster_list)) |
| 616 | cluster = list_entry(block_group->cluster_list.next, | 625 | cluster = list_entry(block_group->cluster_list.next, |
| @@ -872,12 +881,14 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
| 872 | ret = 1; | 881 | ret = 1; |
| 873 | 882 | ||
| 874 | out_free: | 883 | out_free: |
| 884 | kfree(checksums); | ||
| 885 | kfree(pages); | ||
| 886 | |||
| 887 | out_update: | ||
| 875 | if (ret != 1) { | 888 | if (ret != 1) { |
| 876 | invalidate_inode_pages2_range(inode->i_mapping, 0, index); | 889 | invalidate_inode_pages2_range(inode->i_mapping, 0, index); |
| 877 | BTRFS_I(inode)->generation = 0; | 890 | BTRFS_I(inode)->generation = 0; |
| 878 | } | 891 | } |
| 879 | kfree(checksums); | ||
| 880 | kfree(pages); | ||
| 881 | btrfs_update_inode(trans, root, inode); | 892 | btrfs_update_inode(trans, root, inode); |
| 882 | return ret; | 893 | return ret; |
| 883 | } | 894 | } |
