Re: [PATCH v3 2/2] fiemap: Implement ranged query

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

 




On 13.11.2017 23:44, Dave Chinner wrote:
> On Mon, Nov 13, 2017 at 05:47:53PM +0200, Nikolay Borisov wrote:
>> Currently the fiemap implementation of xfs_io doesn't support making ranged
>> queries. This patch implements the '-r' parameter, taking up to 2 arguments - 
>> the starting offset and the length of the region to be queried. This also 
>> requires changing of the final hole range is calculated. Namely, it's now being
>> done as [last_logical, logical addres of next extent] rather than being
>> statically determined by [last_logical, filesize].
>>
>> Signed-off-by: Nikolay Borisov <nborisov@xxxxxxxx>
>> ---
>> V3: 
>>  * Fixed a bug where incorrect extent index was shown if we didn't print a 
>>  hole. This was due to statically returning 2 at the end of print_(plain|verbose)
>>  Now, the actual number of printed extents inside the 2 functions is used. 
>>  This bug is visible only with the -r parameter
>>
>>  * Fixed a bug where 1 additional extent would be printed. This was a result of 
>>  the aforementioned bug fix, since now printing function can return 1 and still
>>  have printed an extent and no hole. This can happen when you use -r parameter,
>>  this is now fixed and a comment explaining it is put. 
>>
>>  * Reworked the handling of the new params by making them arguments to the 
>>  -r parameter. 
>>
>> V2:
>>  * Incorporated Daricks feedback - removed variables which weren't introduced
>>   until the next patch as a result the build with this patch was broken. This is 
>>   fixed now
> .....
> 
>> @@ -256,9 +269,12 @@ fiemap_f(
>>  	int		tot_w = 5;	/* 5 since its just one number */
>>  	int		flg_w = 5;
>>  	__u64		last_logical = 0;
>> +	size_t		fsblocksize, fssectsize;
>>  	struct stat	st;
>>  
>> -	while ((c = getopt(argc, argv, "aln:v")) != EOF) {
>> +	init_cvtnum(&fsblocksize, &fssectsize);
>> +
>> +	while ((c = getopt(argc, argv, "aln:vr")) != EOF) {
> 
> Ok, you're not telling gotopt that "-r" has parameters, so....
> 
>>  		switch (c) {
>>  		case 'a':
>>  			fiemap_flags |= FIEMAP_FLAG_XATTR;
>> @@ -272,6 +288,50 @@ fiemap_f(
>>  		case 'v':
>>  			vflag++;
>>  			break;
>> +		case 'r':
>> +			/* Parse the first option which is mandatory */
>> +			if (optind < argc && argv[optind][0] != '-') {
>> +				off64_t start_offset = cvtnum(fsblocksize,
>> +							      fssectsize,
>> +							      argv[optind]);
>> +				if (start_offset < 0) {
>> +					printf("non-numeric offset argument -- "
>> +					       "%s\n", argv[optind]);
>> +					return 0;
>> +				}
>> +				last_logical = start_offset;
>> +				optind++;
>> +			} else {
>> +				fprintf(stderr, _("Invalid offset argument for"
>> +						  " -r\n"));
>> +				exitcode = 1;
>> +				return 0;
>> +			}
>> +
>> +			if (optind < argc) {
>> +				/* first check if what follows doesn't begin
>> +				 * with '-' which means it would be a param and
>> +				 * not an argument
>> +				 */
>> +				if (argv[optind][0] == '-') {
>> +					optind--;
>> +					break;
>> +
>> +				}
>> +
>> +				off64_t length = cvtnum(fsblocksize,
>> +							fssectsize,
>> +							argv[optind]);
>> +				if (length < 0) {
>> +					printf("non-numeric len argument --"
>> +					       " %s\n", argv[optind]);
>> +					return 0;
>> +				}
>> +				len = length;
>> +				range_limit = true;
>> +			}
>> +			break;
> 
> .... this is pretty nasty because you're having to check if the next
> option should be parsed by the main loop or not. This assumes that
> getopt is giving us the options in the order they were presented on
> the command line, which is not a good assumption to make as glibc
> can mutate the order as it parses the listi of know options and
> arguments.
> 
> Given that "-r" is the only option that has parameters, then this
> can be massively simplified just by noting we've seen the rflag, and
> leaving the non-arg parameter parsing to after the end of the loop.
> i.e.:


You are right this is a bit ugly, but it seems more consistend to me,
rather than something like

xfs_io -c "fiemap -r -n 10 -v 4k 10k" for example. And the reason why
I'm using this hackish way and not declaring r as r: in getopt is
because getopt doesn't recognise when a parameter takes more than 1
argument.

> 
> 
> 		case 'r':
> 			range_limit = true;
> 			break;
> ......
> 
> 	if (!range_limit) {
> 		/* no extra parameters */
> 		if (optind != argc)
> 			usage();
> 	} else if (optind != argc - 2) {
> 		/* wrong number of parameters for rflag */
> 		usage();
> 	} else {
> 		/* parse range variables */
> 		offset = cvtnum(fsblocksize, fssectsize, argv[optind++]);
> 		length = cvtnum(fsblocksize, fssectsize, argv[optind]);
> 		if (offset < 0 || length < 0) {
> 			/* invalid options */
> 			usage();
> 		}
> 	}

True, this is very simple but it imposes the constraints that if we want
to use -r then we must absolutely give 2 args always, which is not a big
deal but it seems a bit limiting. If that's what you desire then I'm
fine doing it that way but it just seems a bit iffy. Given that the -r
method has tests which ensure that parsing is correct I'm more inclined
to have the more consistent -r followed by 1 or 2 arguments.

> 
> 
> 
>>  
>>  			cur_extent += num_printed;
>>  			last_logical = extent->fe_logical + extent->fe_length;
>> +			/* If num_printed > 0 then we dunno if we have printed
>> +			 * a hole or an extent and a hole but we don't really
>> +			 * care. Termination of the loop is still going to be
>> +			 * correct
>> +			 */
> 
> /*
>  * Please use the standard comment format.
>  */
> 
> Cheers,
> 
> Dave.
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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