aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2011-06-03 01:26:53 -0400
committerChris Mason <chris.mason@oracle.com>2011-06-04 08:03:43 -0400
commit211f96c24f117fcc6e9e2431e40d92f4de22625e (patch)
tree9f73c5419e905066653660ec33f8d5efeaa3a148 /fs
parent17aca1c987cff89dc4279371857035da902c8854 (diff)
Btrfs: make sure we don't overflow the free space cache crc page
The free space cache uses only one page for crcs right now, which means we can't have a cache file bigger than the crcs we can fit in the first page. This adds a check to enforce that restriction. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/free-space-cache.c27
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
874out_free: 883out_free:
884 kfree(checksums);
885 kfree(pages);
886
887out_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}