Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions lib/ext2fs/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,11 @@ errcode_t ext2fs_new_block3(ext2_filsys fs, blk64_t goal,

ext2fs_clear_block_uninit(fs, ext2fs_group_of_blk2(fs, b));
*ret = b;
fs->reserved[3] = (__u32)b; // not 64-bit safe
/* reserved[] is 32 bits wide; drop a hint that would be truncated */
if (b <= 0xFFFFFFFFULL)
fs->reserved[3] = (__u32) b;
else
fs->reserved[3] = 0;
return 0;
}

Expand Down Expand Up @@ -445,8 +449,7 @@ errcode_t ext2fs_new_range(ext2_filsys fs, int flags, blk64_t goal,
if (!map)
return EXT2_ET_NO_BLOCK_BITMAP;
if (!goal || goal >= ext2fs_blocks_count(fs->super))
goal = fs->reserved[3];
// goal = fs->super->s_first_data_block;
goal = fs->reserved[3] ? fs->reserved[3] : fs->super->s_first_data_block;

start = goal;
while (!looped || start <= goal) {
Expand Down Expand Up @@ -493,7 +496,16 @@ errcode_t ext2fs_new_range(ext2_filsys fs, int flags, blk64_t goal,
b += fs->super->s_blocks_per_group)
ext2fs_clear_block_uninit(fs,
ext2fs_group_of_blk2(fs, b));
fs->reserved[3] = (__u32) end;
/*
* Only keep a hint which can still be used as a
* search start: reserved[] is 32 bits wide, so a
* larger value would be truncated into an unrelated
* block number.
*/
if (end < ext2fs_blocks_count(fs->super) && end <= 0xFFFFFFFFULL)
fs->reserved[3] = (__u32) end;
else
fs->reserved[3] = 0;
return 0;
}

Expand Down
7 changes: 6 additions & 1 deletion lib/ext2fs/fallocate.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,12 @@ static errcode_t extent_fallocate(ext2_filsys fs, int flags, ext2_ino_t ino,
if (err == EXT2_ET_NO_CURRENT_NODE) {
blk64_t max_blocks = ext2fs_blocks_count(fs->super);

goal = fs->reserved[3];
/*
* Only follow the hint while it still points inside the file
* system, so that the ~0ULL goal sentinel keeps working.
*/
if (fs->reserved[3] && fs->reserved[3] < max_blocks)
goal = fs->reserved[3];
if (goal == ~0ULL)
goal = ext2fs_find_inode_goal(fs, ino, inode, start);
err = ext2fs_find_first_zero_block_bitmap2(fs->block_map,
Expand Down
Loading