diff options
| author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2025-10-30 12:44:22 +0100 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2025-11-20 14:03:40 -0800 |
| commit | 9125163273f8033af5d38907b483c1d9f99d781b (patch) | |
| tree | 816bc61042f3b4a9eb32e0734d007a39c5f8ae7e /lib | |
| parent | f791dcc842cb1cb3777ae4122be4cd37624ad53d (diff) | |
| download | linux-next-9125163273f8033af5d38907b483c1d9f99d781b.tar.gz linux-next-9125163273f8033af5d38907b483c1d9f99d781b.zip | |
panic: sys_info: factor out read and write handlers
For the sake of the code readability and easier maintenance factor out
read and write sys_info handlers.
[akpm@linux-foundation.org: coding-style cleanups]
Link: https://lkml.kernel.org/r/20251030132007.3742368-7-andriy.shevchenko@linux.intel.com
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Cc: Feng Tang <feng.tang@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sys_info.c | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/lib/sys_info.c b/lib/sys_info.c index 94526de8482b..323624093e54 100644 --- a/lib/sys_info.c +++ b/lib/sys_info.c @@ -43,18 +43,56 @@ unsigned long sys_info_parse_param(char *str) #ifdef CONFIG_SYSCTL +static int sys_info_write_handler(const struct ctl_table *table, + void *buffer, size_t *lenp, loff_t *ppos, + unsigned long *si_bits_global) +{ + unsigned long si_bits; + int ret; + + ret = proc_dostring(table, 1, buffer, lenp, ppos); + if (ret) + return ret; + + si_bits = sys_info_parse_param(table->data); + + /* The access to the global value is not synchronized. */ + WRITE_ONCE(*si_bits_global, si_bits); + + return 0; +} + +static int sys_info_read_handler(const struct ctl_table *table, + void *buffer, size_t *lenp, loff_t *ppos, + unsigned long *si_bits_global) +{ + unsigned long si_bits; + unsigned int len = 0; + char *delim = ""; + unsigned int i; + + /* The access to the global value is not synchronized. */ + si_bits = READ_ONCE(*si_bits_global); + + for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) { + if (*si_names[i]) { + len += scnprintf(table->data + len, table->maxlen - len, + "%s%s", delim, si_names[i]); + delim = ","; + } + } + + return proc_dostring(table, 0, buffer, lenp, ppos); +} + int sysctl_sys_info_handler(const struct ctl_table *ro_table, int write, void *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table table; - unsigned long *si_bits_global; - unsigned long si_bits; unsigned int i; size_t maxlen; - si_bits_global = ro_table->data; - maxlen = 0; for (i = 0; i < ARRAY_SIZE(si_names); i++) maxlen += strlen(si_names[i]) + 1; @@ -67,35 +105,10 @@ int sysctl_sys_info_handler(const struct ctl_table *ro_table, int write, table.data = names; table.maxlen = maxlen; - if (write) { - int ret; - - ret = proc_dostring(&table, write, buffer, lenp, ppos); - if (ret) - return ret; - - si_bits = sys_info_parse_param(names); - /* The access to the global value is not synchronized. */ - WRITE_ONCE(*si_bits_global, si_bits); - return 0; - } else { - /* for 'read' operation */ - unsigned int len = 0; - char *delim = ""; - - /* The access to the global value is not synchronized. */ - si_bits = READ_ONCE(*si_bits_global); - - for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) { - if (*si_names[i]) { - len += scnprintf(names + len, maxlen - len, - "%s%s", delim, si_names[i]); - delim = ","; - } - } - - return proc_dostring(&table, write, buffer, lenp, ppos); - } + if (write) + return sys_info_write_handler(&table, buffer, lenp, ppos, ro_table->data); + else + return sys_info_read_handler(&table, buffer, lenp, ppos, ro_table->data); } #endif |
