Btrfs: use the inode's mapping mask for allocating pages
PATCH 1/1 Btrfs: use the inode's mapping mask for allocating pages
Johannes pointed out we were allocating only kernel pages for doing writes, which is kind of a big deal if you are on 32bit and have more than a gig of ram. So fix our allocations to use the mapping's gfp but still clear __GFP_FS so we don't re-enter. Thanks,
Reported-by Johannes Weiner <[email protected]>
Signed-off-by Josef Bacik <[email protected]>
--- fs/btrfs/ctree.h | 6 ++++++ fs/btrfs/file.c | 3 ++- fs/btrfs/free-space-cache.c | 6 ++++-- fs/btrfs/inode.c | 3 ++- fs/btrfs/ioctl.c | 3 ++- fs/btrfs/relocation.c | 3 ++- 6 files changed, 18 insertions(+), 6 deletions(-)
fs/btrfs/ctree.h +6 -0
@@ -30,6 +30,7 @@#include <linux/kobject.h> #include <trace/events/btrfs.h> #include <asm/kmap_types.h> +#include <linux/pagemap.h> #include "extent_io.h" #include "extent_map.h" #include "async-thread.h"
@@ -2117,6 +2118,11 @@ static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info) (space_info->flags & BTRFS_BLOCK_GROUP_DATA)); } +static inline gfp_t btrfs_alloc_write_mask (struct address_space *mapping) +{ +return mapping_gfp_mask (mapping) & ~__GFP_FS; +} +/* extent-tree.c */ static inline u64 btrfs_calc_trans_metadata_size (struct btrfs_root *root,unsigned num_items)
fs/btrfs/file.c +2 -1
@@ -1067,6 +1067,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,int i;unsigned long index = pos >>PAGE_CACHE_SHIFT ;struct inode *inode =fdentry (file)->d_inode; +gfp_t mask =btrfs_alloc_write_mask (inode->i_mapping);int err =0 ;int faili =0 ;u64 start_pos;
@@ -1084,7 +1085,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, again:for (i =0 ; i < num_pages; i++) { pages[i] =find_or_create_page (inode->i_mapping, index + i, -GFP_NOFS ); + mask);if (!pages[i]) { faili = i -1 ; err = -ENOMEM ;
fs/btrfs/free-space-cache.c +4 -2
@@ -250,6 +250,7 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,u64 num_bitmaps;u64 generation;pgoff_t index =0 ; +gfp_t mask =btrfs_alloc_write_mask (inode->i_mapping);int ret =0 ;INIT_LIST_HEAD (&bitmaps);
@@ -306,7 +307,7 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,if (!num_entries && !num_bitmaps)break ; - page =find_or_create_page (inode->i_mapping, index,GFP_NOFS ); + page =find_or_create_page (inode->i_mapping, index, mask);if (!page) goto free_cache;
@@ -559,6 +560,7 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,u64 start, end, len;u64 bytes =0 ;u32 crc = ~(u32 )0 ; +gfp_t mask =btrfs_alloc_write_mask (inode->i_mapping);int index =0 , num_pages =0 ;int entries =0 ;int bitmaps =0 ;
@@ -608,7 +610,7 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,* know and don't freak out. */ while (index < num_pages) { - page =find_or_create_page (inode->i_mapping, index,GFP_NOFS ); + page =find_or_create_page (inode->i_mapping, index, mask);if (!page) {int i;
fs/btrfs/inode.c +2 -1
@@ -3282,6 +3282,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)pgoff_t index = from >>PAGE_CACHE_SHIFT ;unsigned offset = from & (PAGE_CACHE_SIZE -1 );struct page *page; +gfp_t mask =btrfs_alloc_write_mask (mapping);int ret =0 ;u64 page_start;u64 page_end;
@@ -3294,7 +3295,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) ret = -ENOMEM ; again: - page =find_or_create_page (mapping, index,GFP_NOFS ); + page =find_or_create_page (mapping, index, mask);if (!page) {btrfs_delalloc_release_space (inode,PAGE_CACHE_SIZE ); goto out;
fs/btrfs/ioctl.c +2 -1
@@ -843,6 +843,7 @@ static int cluster_pages_for_defrag(struct inode *inode,int i_done;struct btrfs_ordered_extent *ordered;struct extent_state *cached_state =NULL ; +gfp_t mask =btrfs_alloc_write_mask (inode->i_mapping);if (isize ==0 )return 0 ;
@@ -860,7 +861,7 @@ again:for (i =0 ; i < num_pages; i++) {struct page *page; page =find_or_create_page (inode->i_mapping, - start_index + i,GFP_NOFS ); + start_index + i, mask);if (!page)break ;
fs/btrfs/relocation.c +2 -1
@@ -2921,6 +2921,7 @@ static int relocate_file_extent_cluster(struct inode *inode,unsigned long last_index;struct page *page;struct file_ra_state *ra; +gfp_t mask =btrfs_alloc_write_mask (inode->i_mapping);int nr =0 ;int ret =0 ;
@@ -2955,7 +2956,7 @@ static int relocate_file_extent_cluster(struct inode *inode, ra,NULL , index, last_index + 1 - index); page =find_or_create_page (inode->i_mapping, index, -GFP_NOFS ); + mask);if (!page) {btrfs_delalloc_release_metadata (inode,PAGE_CACHE_SIZE );
Signature · 1 line
1.7.5.2