fs/cachefiles/daemon.c | 78 +++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 12 deletions(-)
Convert the six <N>% percentage command handlers -
cachefiles_daemon_frun(), _fcull(), _fstop(), _brun(), _bcull(), and
_bstop() - from the deprecated simple_strtoul() to kstrtoul(). These
are the only handlers in this file that take a trailing '%' after
the number; other nearby commands take plain values and are
unaffected.
Since kstrtoul() requires the whole input to be a valid number, each
handler now walks the digit run itself, checks it's followed by '%'
and NUL, and temporarily null-terminates at the '%' to isolate the
number for kstrtoul(), restoring it afterwards.
Signed-off-by: Drif Abdelmalek Mohamed Said <drifabdelmalekmohamedsaid@gmail.com>
---
fs/cachefiles/daemon.c | 78 +++++++++++++++++++++++++++++++++++-------
1 file changed, 66 insertions(+), 12 deletions(-)
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
index 1a66e0af2837..12c38b366881 100644
--- a/fs/cachefiles/daemon.c
+++ b/fs/cachefiles/daemon.c
@@ -331,16 +331,25 @@ static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
{
unsigned long frun;
+ char *end = args;
+ int ret;
_enter(",%s", args);
if (!*args)
return -EINVAL;
- frun = simple_strtoul(args, &args, 10);
- if (args[0] != '%' || args[1] != '\0')
+ while (isdigit(*end))
+ end++;
+ if (end == args || *end != '%' || end[1] != '\0')
return -EINVAL;
+ *end = '\0';
+ ret = kstrtoul(args, 10, &frun);
+ *end = '%';
+ if (ret)
+ return ret;
+
if (frun <= cache->fcull_percent || frun >= 100)
return cachefiles_daemon_range_error(cache, args);
@@ -355,16 +364,25 @@ static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
{
unsigned long fcull;
+ char *end = args;
+ int ret;
_enter(",%s", args);
if (!*args)
return -EINVAL;
- fcull = simple_strtoul(args, &args, 10);
- if (args[0] != '%' || args[1] != '\0')
+ while (isdigit(*end))
+ end++;
+ if (end == args || *end != '%' || end[1] != '\0')
return -EINVAL;
+ *end = '\0';
+ ret = kstrtoul(args, 10, &fcull);
+ *end = '%';
+ if (ret)
+ return ret;
+
if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent)
return cachefiles_daemon_range_error(cache, args);
@@ -379,16 +397,25 @@ static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
{
unsigned long fstop;
+ char *end = args;
+ int ret;
_enter(",%s", args);
if (!*args)
return -EINVAL;
- fstop = simple_strtoul(args, &args, 10);
- if (args[0] != '%' || args[1] != '\0')
+ while (isdigit(*end))
+ end++;
+ if (end == args || *end != '%' || end[1] != '\0')
return -EINVAL;
+ *end = '\0';
+ ret = kstrtoul(args, 10, &fstop);
+ *end = '%';
+ if (ret)
+ return ret;
+
if (fstop >= cache->fcull_percent)
return cachefiles_daemon_range_error(cache, args);
@@ -403,16 +430,25 @@ static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
{
unsigned long brun;
+ char *end = args;
+ int ret;
_enter(",%s", args);
if (!*args)
return -EINVAL;
- brun = simple_strtoul(args, &args, 10);
- if (args[0] != '%' || args[1] != '\0')
+ while (isdigit(*end))
+ end++;
+ if (end == args || *end != '%' || end[1] != '\0')
return -EINVAL;
+ *end = '\0';
+ ret = kstrtoul(args, 10, &brun);
+ *end = '%';
+ if (ret)
+ return ret;
+
if (brun <= cache->bcull_percent || brun >= 100)
return cachefiles_daemon_range_error(cache, args);
@@ -427,16 +463,25 @@ static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
{
unsigned long bcull;
+ char *end = args;
+ int ret;
_enter(",%s", args);
if (!*args)
return -EINVAL;
- bcull = simple_strtoul(args, &args, 10);
- if (args[0] != '%' || args[1] != '\0')
+ while (isdigit(*end))
+ end++;
+ if (end == args || *end != '%' || end[1] != '\0')
return -EINVAL;
+ *end = '\0';
+ ret = kstrtoul(args, 10, &bcull);
+ *end = '%';
+ if (ret)
+ return ret;
+
if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
return cachefiles_daemon_range_error(cache, args);
@@ -451,16 +496,25 @@ static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args)
{
unsigned long bstop;
+ char *end = args;
+ int ret;
_enter(",%s", args);
if (!*args)
return -EINVAL;
- bstop = simple_strtoul(args, &args, 10);
- if (args[0] != '%' || args[1] != '\0')
+ while (isdigit(*end))
+ end++;
+ if (end == args || *end != '%' || end[1] != '\0')
return -EINVAL;
+ *end = '\0';
+ ret = kstrtoul(args, 10, &bstop);
+ *end = '%';
+ if (ret)
+ return ret;
+
if (bstop >= cache->bcull_percent)
return cachefiles_daemon_range_error(cache, args);
--
2.43.0
Gentle ping on this one — seems to have gotten buried during the merge window.
Thanks,
On Sat, Aug 29, 2026 at 11:45 PM Drif Abdelmalek Mohamed Said
<drifabdelmalekmohamedsaid@gmail.com> wrote:
>
> Convert the six <N>% percentage command handlers -
> cachefiles_daemon_frun(), _fcull(), _fstop(), _brun(), _bcull(), and
> _bstop() - from the deprecated simple_strtoul() to kstrtoul(). These
> are the only handlers in this file that take a trailing '%' after
> the number; other nearby commands take plain values and are
> unaffected.
>
> Since kstrtoul() requires the whole input to be a valid number, each
> handler now walks the digit run itself, checks it's followed by '%'
> and NUL, and temporarily null-terminates at the '%' to isolate the
> number for kstrtoul(), restoring it afterwards.
>
> Signed-off-by: Drif Abdelmalek Mohamed Said <drifabdelmalekmohamedsaid@gmail.com>
> ---
> fs/cachefiles/daemon.c | 78 +++++++++++++++++++++++++++++++++++-------
> 1 file changed, 66 insertions(+), 12 deletions(-)
>
> diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
> index 1a66e0af2837..12c38b366881 100644
> --- a/fs/cachefiles/daemon.c
> +++ b/fs/cachefiles/daemon.c
> @@ -331,16 +331,25 @@ static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
> static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
> {
> unsigned long frun;
> + char *end = args;
> + int ret;
>
> _enter(",%s", args);
>
> if (!*args)
> return -EINVAL;
>
> - frun = simple_strtoul(args, &args, 10);
> - if (args[0] != '%' || args[1] != '\0')
> + while (isdigit(*end))
> + end++;
> + if (end == args || *end != '%' || end[1] != '\0')
> return -EINVAL;
>
> + *end = '\0';
> + ret = kstrtoul(args, 10, &frun);
> + *end = '%';
> + if (ret)
> + return ret;
> +
> if (frun <= cache->fcull_percent || frun >= 100)
> return cachefiles_daemon_range_error(cache, args);
>
> @@ -355,16 +364,25 @@ static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
> static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
> {
> unsigned long fcull;
> + char *end = args;
> + int ret;
>
> _enter(",%s", args);
>
> if (!*args)
> return -EINVAL;
>
> - fcull = simple_strtoul(args, &args, 10);
> - if (args[0] != '%' || args[1] != '\0')
> + while (isdigit(*end))
> + end++;
> + if (end == args || *end != '%' || end[1] != '\0')
> return -EINVAL;
>
> + *end = '\0';
> + ret = kstrtoul(args, 10, &fcull);
> + *end = '%';
> + if (ret)
> + return ret;
> +
> if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent)
> return cachefiles_daemon_range_error(cache, args);
>
> @@ -379,16 +397,25 @@ static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
> static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
> {
> unsigned long fstop;
> + char *end = args;
> + int ret;
>
> _enter(",%s", args);
>
> if (!*args)
> return -EINVAL;
>
> - fstop = simple_strtoul(args, &args, 10);
> - if (args[0] != '%' || args[1] != '\0')
> + while (isdigit(*end))
> + end++;
> + if (end == args || *end != '%' || end[1] != '\0')
> return -EINVAL;
>
> + *end = '\0';
> + ret = kstrtoul(args, 10, &fstop);
> + *end = '%';
> + if (ret)
> + return ret;
> +
> if (fstop >= cache->fcull_percent)
> return cachefiles_daemon_range_error(cache, args);
>
> @@ -403,16 +430,25 @@ static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
> static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
> {
> unsigned long brun;
> + char *end = args;
> + int ret;
>
> _enter(",%s", args);
>
> if (!*args)
> return -EINVAL;
>
> - brun = simple_strtoul(args, &args, 10);
> - if (args[0] != '%' || args[1] != '\0')
> + while (isdigit(*end))
> + end++;
> + if (end == args || *end != '%' || end[1] != '\0')
> return -EINVAL;
>
> + *end = '\0';
> + ret = kstrtoul(args, 10, &brun);
> + *end = '%';
> + if (ret)
> + return ret;
> +
> if (brun <= cache->bcull_percent || brun >= 100)
> return cachefiles_daemon_range_error(cache, args);
>
> @@ -427,16 +463,25 @@ static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
> static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
> {
> unsigned long bcull;
> + char *end = args;
> + int ret;
>
> _enter(",%s", args);
>
> if (!*args)
> return -EINVAL;
>
> - bcull = simple_strtoul(args, &args, 10);
> - if (args[0] != '%' || args[1] != '\0')
> + while (isdigit(*end))
> + end++;
> + if (end == args || *end != '%' || end[1] != '\0')
> return -EINVAL;
>
> + *end = '\0';
> + ret = kstrtoul(args, 10, &bcull);
> + *end = '%';
> + if (ret)
> + return ret;
> +
> if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
> return cachefiles_daemon_range_error(cache, args);
>
> @@ -451,16 +496,25 @@ static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
> static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args)
> {
> unsigned long bstop;
> + char *end = args;
> + int ret;
>
> _enter(",%s", args);
>
> if (!*args)
> return -EINVAL;
>
> - bstop = simple_strtoul(args, &args, 10);
> - if (args[0] != '%' || args[1] != '\0')
> + while (isdigit(*end))
> + end++;
> + if (end == args || *end != '%' || end[1] != '\0')
> return -EINVAL;
>
> + *end = '\0';
> + ret = kstrtoul(args, 10, &bstop);
> + *end = '%';
> + if (ret)
> + return ret;
> +
> if (bstop >= cache->bcull_percent)
> return cachefiles_daemon_range_error(cache, args);
>
> --
> 2.43.0
>
© 2016 - 2026 Red Hat, Inc.