Re: [PATCH] xfs_io: add fiemap -s flag to print number of extents

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

 



NACK haven't noticed that FIEMAP also doesn't count holes

ignore

On 2024-09-03 11:37:30, Andrey Albershteyn wrote:
> FS_IOC_FIEMAP has an option to return total number of extents
> without copying each one of them. This could be pretty handy for
> checking if large file is heavily fragmented. The same can be done
> with calling FS_IOC_FIEMAP and counting lines with wc but
> FS_IOC_FIEMAP is limited to ~76mil extents (FIEMAP_MAX_EXTENTS). The
> other option is FS_IOC_FSGETXATTR which is much faster than
> iterating through all extents, but it doesn't include holes.
> 
> Signed-off-by: Andrey Albershteyn <aalbersh@xxxxxxxxxx>
> ---
>  io/fiemap.c | 27 +++++++++++++++++++++++----
>  1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/io/fiemap.c b/io/fiemap.c
> index b41f71bfd027..d4e55a82f6db 100644
> --- a/io/fiemap.c
> +++ b/io/fiemap.c
> @@ -42,6 +42,13 @@ fiemap_help(void)
>  "\n"));
>  }
>  
> +static void
> +print_total(
> +	   struct fiemap	*fiemap)
> +{
> +	printf("Extents total: %d\n", fiemap->fm_mapped_extents);
> +}
> +
>  static void
>  print_hole(
>  	   int		foff_w,
> @@ -223,9 +230,11 @@ fiemap_f(
>  	int		done = 0;
>  	int		lflag = 0;
>  	int		vflag = 0;
> +	int		sflag = 0;
>  	int		fiemap_flags = FIEMAP_FLAG_SYNC;
>  	int		c;
>  	int		i;
> +	int		ext_arr_size = 0;
>  	int		map_size;
>  	int		ret;
>  	int		cur_extent = 0;
> @@ -242,7 +251,7 @@ fiemap_f(
>  
>  	init_cvtnum(&fsblocksize, &fssectsize);
>  
> -	while ((c = getopt(argc, argv, "aln:v")) != EOF) {
> +	while ((c = getopt(argc, argv, "aln:sv")) != EOF) {
>  		switch (c) {
>  		case 'a':
>  			fiemap_flags |= FIEMAP_FLAG_XATTR;
> @@ -253,6 +262,9 @@ fiemap_f(
>  		case 'n':
>  			max_extents = atoi(optarg);
>  			break;
> +		case 's':
> +			sflag++;
> +			break;
>  		case 'v':
>  			vflag++;
>  			break;
> @@ -285,8 +297,9 @@ fiemap_f(
>  		range_end = start_offset + length;
>  	}
>  
> -	map_size = sizeof(struct fiemap) +
> -		(EXTENT_BATCH * sizeof(struct fiemap_extent));
> +	if (!sflag)
> +		ext_arr_size = (EXTENT_BATCH * sizeof(struct fiemap_extent));
> +	map_size = sizeof(struct fiemap) + ext_arr_size;
>  	fiemap = malloc(map_size);
>  	if (!fiemap) {
>  		fprintf(stderr, _("%s: malloc of %d bytes failed.\n"),
> @@ -302,7 +315,8 @@ fiemap_f(
>  		fiemap->fm_flags = fiemap_flags;
>  		fiemap->fm_start = last_logical;
>  		fiemap->fm_length = range_end - last_logical;
> -		fiemap->fm_extent_count = EXTENT_BATCH;
> +		if (!sflag)
> +			fiemap->fm_extent_count = EXTENT_BATCH;
>  
>  		ret = ioctl(file->fd, FS_IOC_FIEMAP, (unsigned long)fiemap);
>  		if (ret < 0) {
> @@ -313,6 +327,11 @@ fiemap_f(
>  			return 0;
>  		}
>  
> +		if (sflag) {
> +			print_total(fiemap);
> +			goto out;
> +		}
> +
>  		/* No more extents to map, exit */
>  		if (!fiemap->fm_mapped_extents)
>  			break;
> -- 
> 2.44.1
> 

-- 
- Andrey





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux