btrfs: fix defrag 32-bit integer overflow
When defragging a very large file, the cluster variable can wrap its 32-bit signed int type and become negative, which eventually gets passed to btrfs_force_ra() as a very large unsigned long value. On 32-bit platforms, this eventually results in an Oops from the SLAB allocator. Change the cluster and max_cluster signed int variables to unsigned long to match the readahead functions. This also allows the min() comparison in btrfs_defrag_file() to work as intended. Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
c736c095de
commit
c41570c9d2
|
@ -1036,7 +1036,7 @@ out:
|
||||||
static int cluster_pages_for_defrag(struct inode *inode,
|
static int cluster_pages_for_defrag(struct inode *inode,
|
||||||
struct page **pages,
|
struct page **pages,
|
||||||
unsigned long start_index,
|
unsigned long start_index,
|
||||||
int num_pages)
|
unsigned long num_pages)
|
||||||
{
|
{
|
||||||
unsigned long file_end;
|
unsigned long file_end;
|
||||||
u64 isize = i_size_read(inode);
|
u64 isize = i_size_read(inode);
|
||||||
|
@ -1194,8 +1194,8 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||||
int defrag_count = 0;
|
int defrag_count = 0;
|
||||||
int compress_type = BTRFS_COMPRESS_ZLIB;
|
int compress_type = BTRFS_COMPRESS_ZLIB;
|
||||||
int extent_thresh = range->extent_thresh;
|
int extent_thresh = range->extent_thresh;
|
||||||
int max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
|
unsigned long max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
|
||||||
int cluster = max_cluster;
|
unsigned long cluster = max_cluster;
|
||||||
u64 new_align = ~((u64)128 * 1024 - 1);
|
u64 new_align = ~((u64)128 * 1024 - 1);
|
||||||
struct page **pages = NULL;
|
struct page **pages = NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue