Re: [PATCH v6 1/6] selftests/mm: make file helpers return errors

Sarthak Sharma <[email protected]>
Newsgroups gmane.linux.documentation,gmane.linux.kernel.mm,gmane.linux.kernel
Message-ID <[email protected]>
Hi Mike!

On 8/3/26 2:30 PM, Mike Rapoport wrote:
>> Change read_file(), write_file(), read_num() and write_num() in vm_util.c
>> to report failures to callers instead of exiting from the helper.
>>
>> Make read_file() return a negative errno on failure instead of 0, so
>> callers can distinguish a successful read from an I/O error. Also make
>> read_num() reject negative and malformed values.
>>
>> Update callers to print diagnostics and fail wherever required. This
>> patch prepares the helpers to be moved to tools/lib/mm without
>> kselftest dependency.
>>
>> Signed-off-by: Sarthak Sharma <[email protected]>
>>
>> diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
>> index 2eab2110ac6a..db0db8a3df7c 100644
>> --- a/tools/testing/selftests/mm/hugepage_settings.c
>> +++ b/tools/testing/selftests/mm/hugepage_settings.c
>> @@ -8,6 +8,7 @@
>>  #include <stdlib.h>
>>  #include <string.h>
>>  #include <unistd.h>
>> +#include <errno.h>
>>  
>>  #include "vm_util.h"
>>  #include "hugepage_settings.h"
>> @@ -61,8 +62,10 @@ int thp_read_string(const char *name, const char * const strings[])
>>  		exit(EXIT_FAILURE);
>>  	}
>>  
>> -	if (!read_file(path, buf, sizeof(buf))) {
>> -		perror(path);
>> +	ret = read_file(path, buf, sizeof(buf));
>> +	if (ret < 0) {
>> +		errno = -ret;
>> +		ksft_perror(path);
> 
> I'm not a fan of changing errno, why can't we use
> 
> 	ksft_print_msg("%s: %s\n", path, strerror(ret));

Ack

> 
>>  		exit(EXIT_FAILURE);
>>  	}
>>  
>> @@ -700,91 +700,139 @@ int unpoison_memory(unsigned long pfn)
>>  
>>  int read_file(const char *path, char *buf, size_t buflen)
>>  {
>> -	int fd;
>> +	int fd, err;
>>  	ssize_t numread;
>>  
>>  	fd = open(path, O_RDONLY);
>>  	if (fd == -1)
>> -		return 0;
>> +		return -errno;
>>  
>>  	numread = read(fd, buf, buflen - 1);
>>  	if (numread < 1) {
>> +		err = numread ? errno : ENODATA;
>>  		close(fd);
>> -		return 0;
>> +		return -err;
>>  	}
>>  
>>  	buf[numread] = '\0';
>>  	close(fd);
>>  
>> -	return (unsigned int) numread;
>> +	return (int)numread;
> 
> Do we really care about how many bytes we read?
> Can't we return 0 for success and -error code for failure?
> 
> Will also make checks for read_file() return value neater.

Yeah, no caller actually uses the number of bytes read. Will make this
change.

> 
>>  }
>>  
>> -unsigned long read_num(const char *path)
>> +int read_num(const char *path, unsigned long *num)
>>  {
>> +	unsigned long val;
>> +	int ret;
>>  	char buf[21];
>> +	char *end;
>>  
>> -	if (read_file(path, buf, sizeof(buf)) < 0)
>> -		ksft_exit_fail_perror("read_file()");
>> +	if (!num)
>> +		return -EINVAL;
>>  
>> -	return strtoul(buf, NULL, 10);
>> +	ret = read_file(path, buf, sizeof(buf));
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	errno = 0;
>> +	val = strtoul(buf, &end, 10);
>> +	if (errno)
>> +		return -errno;
>> +
>> +	if (end == buf || buf[0] == '-')
>> +		return -EINVAL;
> 
> We can check the sign right after read_file() and skip errno dance
> around strtoul().

Yes, we can check the sign after read_file(), but still we would have to
check errno after strtoul() to see if an unsigned long overflow happened.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.