From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxxx> Since MPOL_F_NUMA_BALANCING was added some time ago, lets also recognise it as a valid tmpfs mount option. As an extension to the exiting format: mpol=<mode>[=<flag>][:nodelist] Multiple flags are added in a list separated by vertical bars, such as: mpol=<mode>[=<flag>[|<flag>]...][:nodelist] For example: $ mount none -t tmpfs mnt -o mpol=bind=balancing:2,0 $ mount | grep mpol none on ... type tmpfs (rw,relatime,mpol=bind=balancing:0,2) Or: $ mount none mnt -t tmpfs -o "mpol=bind=balancing|static:1,0" $ mount | grep mpol none on ... type tmpfs (rw,relatime,mpol=bind=balancing|static:0-1) I am not sure to be honest if this is useful for tmpfs, but is just an asymmetry I noticed while doing stuff in this area. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxxx> Cc: Huang Ying <ying.huang@xxxxxxxxx> Cc: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/mempolicy.c | 55 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 77488878d8ca..c69bf5438731 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -3162,6 +3162,47 @@ static const char * const policy_flags[] = { }; #ifdef CONFIG_TMPFS +static int mpol_lookup_flag(char *str) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(policy_flags); i++) { + if (policy_flags[i] && !strcmp(str, policy_flags[i])) + return BIT(i + __ffs(MPOL_MODE_FLAGS)); + } + + return -1; +} + +static bool mpol_parse_flags(char *str, int *mode, unsigned short *flags) +{ + char buf[128], *opt; + int flag; + + /* Make a local copy since caller wants the original untouched. */ + if (WARN_ON_ONCE(strscpy(buf, str, sizeof(buf)) < 0)) + return false; + + str = buf; + for (;;) { + opt = strsep(&str, "|"); + + if (!opt) + break; + else if (*opt == '\0') + continue; + + flag = mpol_lookup_flag(opt); + if (flag < 0) + return false; + *flags |= flag; + } + + *mode |= *flags; + + return sanitize_mpol_flags(mode, flags) == 0; +} + /** * mpol_parse_str - parse string to mempolicy, for tmpfs mpol mount option. * @str: string containing mempolicy to parse @@ -3247,18 +3288,8 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) } mode_flags = 0; - if (flags) { - /* - * Currently, we only support two mutually exclusive - * mode flags. - */ - if (!strcmp(flags, "static")) - mode_flags |= MPOL_F_STATIC_NODES; - else if (!strcmp(flags, "relative")) - mode_flags |= MPOL_F_RELATIVE_NODES; - else - goto out; - } + if (flags && !mpol_parse_flags(flags, &mode, &mode_flags)) + goto out; new = mpol_new(mode, mode_flags, &nodes); if (IS_ERR(new)) -- 2.44.0