Re: [PATCH v2] fallocate: Add support for fixed goal extent allocations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Dec 19, 2024 at 07:46:13PM -0800, Sarthak Kukreti wrote:
> Add a new flag to add support for fixed goal allocations in
> ext_falloc_helper. For fixed goal allocations, omit merging extents and
> return an error unless the exact extent is found.
> 
> Use case:
> On ChromiumOS, we'd like to add the capability of resetting a filesystem
> while preserving a set of files in-place. This will be used during
> filesystem reset flows where everything apart from select files (which
> contain system applications) should be removed: the combined size of the
> files can exceed the amount of available space in other
> partitions/memory. The reset process will look something like:
> 
> 1. Reset code dumps the FIEMAP of the set of preserved files into a
> file.
> 2. Mkfs.ext4 is called on the filesystem with -E nodiscard.
> 3. Post mkfs, the reset code will utilize ext2fs_fallocate w/
> EXT2_FALLOCATE_FIXED_GOAL | EXT2_FALLOCATE_FORCE_INIT on the extent list
> created in step 1.
> 
> Signed-off-by: Sarthak Kukreti <sarthakkukreti@xxxxxxxxxx>
> 
> Changes from v1 (https://lists.openwall.net/linux-ext4/2024/12/12/38):
> - s/EXT2_NEWRANGE_EXACT_GOAL/EXT2_NEWRANGE_FIXED_GOAL

Looks good Sarthak, feel free to add:

Reviewed-by: Ojaswin Mujoo <ojaswin@xxxxxxxxxxxxx>

Regards,
ojaswin
> 
> ---
>  lib/ext2fs/alloc.c     |  2 +-
>  lib/ext2fs/ext2fs.h    |  3 ++-
>  lib/ext2fs/fallocate.c | 21 +++++++++++++++++++--
>  3 files changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c
> index 3fd92167..ba5b1c5e 100644
> --- a/lib/ext2fs/alloc.c
> +++ b/lib/ext2fs/alloc.c
> @@ -390,7 +390,7 @@ no_blocks:
>  /*
>   * Starting at _goal_, scan around the filesystem to find a run of free blocks
>   * that's at least _len_ blocks long.  Possible flags:
> - * - EXT2_NEWRANGE_EXACT_GOAL: The range of blocks must start at _goal_.
> + * - EXT2_NEWRANGE_FIXED_GOAL: The range of blocks must start at _goal_.
>   * - EXT2_NEWRANGE_MIN_LENGTH: do not return a allocation shorter than _len_.
>   * - EXT2_NEWRANGE_ZERO_BLOCKS: Zero blocks pblk to pblk+plen before returning.
>   *
> diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
> index 6e87829f..313c5981 100644
> --- a/lib/ext2fs/ext2fs.h
> +++ b/lib/ext2fs/ext2fs.h
> @@ -1446,7 +1446,8 @@ extern errcode_t ext2fs_decode_extent(struct ext2fs_extent *to, void *from,
>  #define EXT2_FALLOCATE_FORCE_INIT	(0x2)
>  #define EXT2_FALLOCATE_FORCE_UNINIT	(0x4)
>  #define EXT2_FALLOCATE_INIT_BEYOND_EOF	(0x8)
> -#define EXT2_FALLOCATE_ALL_FLAGS	(0xF)
> +#define EXT2_FALLOCATE_FIXED_GOAL	(0x10)
> +#define EXT2_FALLOCATE_ALL_FLAGS	(0x1F)
>  errcode_t ext2fs_fallocate(ext2_filsys fs, int flags, ext2_ino_t ino,
>  			   struct ext2_inode *inode, blk64_t goal,
>  			   blk64_t start, blk64_t len);
> diff --git a/lib/ext2fs/fallocate.c b/lib/ext2fs/fallocate.c
> index 5cde7d5c..20aa9c9f 100644
> --- a/lib/ext2fs/fallocate.c
> +++ b/lib/ext2fs/fallocate.c
> @@ -103,7 +103,7 @@ static errcode_t ext_falloc_helper(ext2_filsys fs,
>  				   blk64_t alloc_goal)
>  {
>  	struct ext2fs_extent	newex, ex;
> -	int			op;
> +	int			op, new_range_flags = 0;
>  	blk64_t			fillable, pblk, plen, x, y;
>  	blk64_t			eof_blk = 0, cluster_fill = 0;
>  	errcode_t		err;
> @@ -132,6 +132,9 @@ static errcode_t ext_falloc_helper(ext2_filsys fs,
>  	max_uninit_len = EXT_UNINIT_MAX_LEN & ~EXT2FS_CLUSTER_MASK(fs);
>  	max_init_len = EXT_INIT_MAX_LEN & ~EXT2FS_CLUSTER_MASK(fs);
>  
> +	if (flags & EXT2_FALLOCATE_FIXED_GOAL)
> +		goto no_implied;
> +
>  	/* We must lengthen the left extent to the end of the cluster */
>  	if (left_ext && EXT2FS_CLUSTER_RATIO(fs) > 1) {
>  		/* How many more blocks can be attached to left_ext? */
> @@ -605,12 +608,15 @@ no_implied:
>  		max_extent_len = max_uninit_len;
>  		newex.e_flags = EXT2_EXTENT_FLAGS_UNINIT;
>  	}
> +
> +	if (flags & EXT2_FALLOCATE_FIXED_GOAL)
> +		new_range_flags = EXT2_NEWRANGE_FIXED_GOAL | EXT2_NEWRANGE_MIN_LENGTH;
>  	pblk = alloc_goal;
>  	y = range_len;
>  	for (x = 0; x < y;) {
>  		cluster_fill = newex.e_lblk & EXT2FS_CLUSTER_MASK(fs);
>  		fillable = min(range_len + cluster_fill, max_extent_len);
> -		err = ext2fs_new_range(fs, 0, pblk & ~EXT2FS_CLUSTER_MASK(fs),
> +		err = ext2fs_new_range(fs, new_range_flags, pblk & ~EXT2FS_CLUSTER_MASK(fs),
>  				       fillable,
>  				       NULL, &pblk, &plen);
>  		if (err)
> @@ -681,6 +687,16 @@ static errcode_t extent_fallocate(ext2_filsys fs, int flags, ext2_ino_t ino,
>  	if (err)
>  		return err;
>  
> +	/*
> +	 * For fixed goal allocations, let the allocations fail iff we can't
> +	 * find the exact goal extent.
> +	 */
> +	if (flags & EXT2_FALLOCATE_FIXED_GOAL) {
> +		err = ext_falloc_helper(fs, flags, ino, inode, handle, NULL,
> +					NULL, start, len, goal);
> +		goto errout;
> +	}
> +
>  	/*
>  	 * Find the extent closest to the start of the alloc range.  We don't
>  	 * check the return value because _goto() sets the current node to the
> @@ -796,6 +812,7 @@ errout:
>   * - EXT2_FALLOCATE_FORCE_INIT: Create only initialized extents.
>   * - EXT2_FALLOCATE_FORCE_UNINIT: Create only uninitialized extents.
>   * - EXT2_FALLOCATE_INIT_BEYOND_EOF: Create extents beyond EOF.
> + * - EXT2_FALLOCATE_FIXED_GOAL: Ensure range starts at goal.
>   *
>   * If neither FORCE_INIT nor FORCE_UNINIT are specified, this function will
>   * try to expand any extents it finds, zeroing blocks as necessary.
> -- 
> 2.47.1.613.gc27f4b7a9f-goog
> 




[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux