Skip to content

Commit a1fbc67

Browse files
Matthew Wilcox (Oracle)kdave
authored andcommitted
btrfs: fix potential overflow in cluster_pages_for_defrag on 32bit arch
On 32-bit systems, this shift will overflow for files larger than 4GB as start_index is unsigned long while the calls to btrfs_delalloc_*_space expect u64. CC: stable@vger.kernel.org # 4.4+ Fixes: df48063 ("btrfs: extent-tree: Switch to new delalloc space reserve and release") Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: David Sterba <dsterba@suse.com> [ define the variable instead of repeating the shift ] Signed-off-by: David Sterba <dsterba@suse.com>
1 parent d5c8238 commit a1fbc67

1 file changed

Lines changed: 4 additions & 6 deletions

File tree

fs/btrfs/ioctl.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
12741274
u64 page_start;
12751275
u64 page_end;
12761276
u64 page_cnt;
1277+
u64 start = (u64)start_index << PAGE_SHIFT;
12771278
int ret;
12781279
int i;
12791280
int i_done;
@@ -1290,8 +1291,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
12901291
page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1);
12911292

12921293
ret = btrfs_delalloc_reserve_space(BTRFS_I(inode), &data_reserved,
1293-
start_index << PAGE_SHIFT,
1294-
page_cnt << PAGE_SHIFT);
1294+
start, page_cnt << PAGE_SHIFT);
12951295
if (ret)
12961296
return ret;
12971297
i_done = 0;
@@ -1380,8 +1380,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
13801380
btrfs_mod_outstanding_extents(BTRFS_I(inode), 1);
13811381
spin_unlock(&BTRFS_I(inode)->lock);
13821382
btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
1383-
start_index << PAGE_SHIFT,
1384-
(page_cnt - i_done) << PAGE_SHIFT, true);
1383+
start, (page_cnt - i_done) << PAGE_SHIFT, true);
13851384
}
13861385

13871386

@@ -1408,8 +1407,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
14081407
put_page(pages[i]);
14091408
}
14101409
btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
1411-
start_index << PAGE_SHIFT,
1412-
page_cnt << PAGE_SHIFT, true);
1410+
start, page_cnt << PAGE_SHIFT, true);
14131411
btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT);
14141412
extent_changeset_free(data_reserved);
14151413
return ret;

0 commit comments

Comments
 (0)