proc: less code duplication in /proc/*/cmdline
PATCH 1/1 proc: less code duplication in /proc/*/cmdline
After staring at this code for a while I've figured using small 2-entry array describing ARGV and ENVP is the way to address code duplication critique.
Signed-off-by Alexey Dobriyan <[email protected]>
---
fs/proc/base.c | 144 ++++++++++++++++++++++----------------------------------- 1 file changed, 56 insertions(+), 88 deletions(-)
fs/proc/base.c +56 -88
@@ -292,101 +292,69 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, } }else {/* -* Command line (1 string) occupies ARGV and maybe -* extends into ENVP. -*/ -if (len1 + len2 <= *pos) - goto skip_argv_envp; -if (len1 <= *pos) - goto skip_argv; - - p = arg_start + *pos; - len = len1 - *pos; -while (count >0 && len >0 ) { -unsigned int _count, l; -int nr_read; -bool final; - - _count =min3 (count, len,PAGE_SIZE ); - nr_read =access_remote_vm (mm, p, page, _count,0 ); -if (nr_read <0 ) - rv = nr_read; -if (nr_read <=0 ) - goto out_free_page; - -/* -* Command line can be shorter than whole ARGV -* even if last "marker" byte says it is not. -*/ - final = false; - l =strnlen (page, nr_read); -if (l < nr_read) { - nr_read = l; - final = true; - } - -if (copy_to_user (buf, page, nr_read)) { - rv = -EFAULT ; - goto out_free_page; - } - - p += nr_read; - len -= nr_read; - buf += nr_read; - count -= nr_read; - rv += nr_read; - -if (final) - goto out_free_page; - } -skip_argv: -/* * Command line (1 string) occupies ARGV and * extends into ENVP. */ -if (len1 <= *pos) { - p = env_start + *pos - len1; - len = len1 + len2 - *pos; - }else { - p = env_start; - len = len2; +struct { +unsigned long p; +unsigned long len; + } cmdline[2 ] = { + { .p = arg_start, .len = len1 }, + { .p = env_start, .len = len2 }, + }; +loff_t pos1 = *pos; +unsigned int i; + + i =0 ; +while (i <2 && pos1 >= cmdline[i].len) { + pos1 -= cmdline[i].len; + i++; } -while (count >0 && len >0 ) { -unsigned int _count, l; -int nr_read; -bool final; - - _count =min3 (count, len,PAGE_SIZE ); - nr_read =access_remote_vm (mm, p, page, _count,0 ); -if (nr_read <0 ) - rv = nr_read; -if (nr_read <=0 ) - goto out_free_page; - -/* Find EOS. */ - final = false; - l =strnlen (page, nr_read); -if (l < nr_read) { - nr_read = l; - final = true; - } - -if (copy_to_user (buf, page, nr_read)) { - rv = -EFAULT ; - goto out_free_page; +while (i <2 ) { + p = cmdline[i].p + pos1; + len = cmdline[i].len - pos1; +while (count >0 && len >0 ) { +unsigned int _count, l; +int nr_read; +bool final; + + _count =min3 (count, len,PAGE_SIZE ); + nr_read =access_remote_vm (mm, p, page, _count,0 ); +if (nr_read <0 ) + rv = nr_read; +if (nr_read <=0 ) + goto out_free_page; + +/* +* Command line can be shorter than whole ARGV +* even if last "marker" byte says it is not. +*/ + final = false; + l =strnlen (page, nr_read); +if (l < nr_read) { + nr_read = l; + final = true; + } + +if (copy_to_user (buf, page, nr_read)) { + rv = -EFAULT ; + goto out_free_page; + } + + p += nr_read; + len -= nr_read; + buf += nr_read; + count -= nr_read; + rv += nr_read; + +if (final) + goto out_free_page; } - p += nr_read; - len -= nr_read; - buf += nr_read; - count -= nr_read; - rv += nr_read; - -if (final) - goto out_free_page; +/* Only first chunk can be read partially. */ + pos1 =0 ; + i++; } -skip_argv_envp: - ; } out_free_page: