/proc/pid/patch for 2.1.49

Alain.Knaff@poboxes.com ("Alain.Knaff@poboxes.com")
Thu, 14 Aug 1997 23:21:17 +0200


[...]
>Also, I think that /proc/pid/maps would be improved by not
>allocating a page every time for each line, but allocating the page once
>per invocation and scribbling the whole line directly to that page and
>then copying to user mode one line at a time (now it copies in two sets:
>first the "old" string, and then it appends the name separately).
>
>
> Linus
>

Here is a newer version of it, which uses this advice:

--- 2.1.49/linux/fs/proc/array.c Thu Aug 14 22:33:32 1997
+++ linux/fs/proc/array.c Thu Aug 14 23:10:34 1997
@@ -894,18 +894,18 @@
* For the /proc/<pid>/maps file, we use fixed length records, each containing
* a single line.
*/
-#define MAPS_LINE_LENGTH 1024
-#define MAPS_LINE_SHIFT 10
+#define MAPS_LINE_LENGTH 4096
+#define MAPS_LINE_SHIFT 12
/*
* f_pos = (number of the vma in the task->mm->mmap list) * MAPS_LINE_LENGTH
* + (index into the line)
*/
/* for systems with sizeof(void*) == 4: */
-#define MAPS_LINE_FORMAT4 "%08lx-%08lx %s %08lx %s %lu\n"
+#define MAPS_LINE_FORMAT4 "%08lx-%08lx %s %08lx %s %lu"
#define MAPS_LINE_MAX4 49 /* sum of 8 1 8 1 4 1 8 1 5 1 10 1 */

/* for systems with sizeof(void*) == 8: */
-#define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %s %lu\n"
+#define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %s %lu"
#define MAPS_LINE_MAX8 73 /* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */

#define MAPS_LINE_MAX MAPS_LINE_MAX8
@@ -920,6 +920,7 @@
int column;
struct vm_area_struct * map;
int i;
+ char * tmp = (char*)__get_free_page(GFP_KERNEL);

if (!p)
return -EINVAL;
@@ -939,11 +940,13 @@

for ( ; map ; ) {
/* produce the next line */
- char line[MAPS_LINE_MAX+1];
+ char *line;
char str[5], *cp = str;
int flags;
kdev_t dev;
unsigned long ino;
+ int maxlen = (sizeof(void*) == 4) ?
+ MAPS_LINE_MAX4 : MAPS_LINE_MAX8;
int len;

flags = map->vm_flags;
@@ -959,13 +962,26 @@
if (map->vm_dentry != NULL) {
dev = map->vm_dentry->d_inode->i_dev;
ino = map->vm_dentry->d_inode->i_ino;
- }
+ line = d_path(map->vm_dentry, tmp, PAGE_SIZE);
+ tmp[PAGE_SIZE-1] = '\n';
+ line -= maxlen;
+ if(line < tmp)
+ line = tmp;
+ } else
+ line = tmp;

len = sprintf(line,
sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8,
map->vm_start, map->vm_end, str, map->vm_offset,
kdevname(dev), ino);

+ if(map->vm_dentry) {
+ int i;
+ for(i = len; i < maxlen; i++)
+ line[i] = ' ';
+ len = tmp + PAGE_SIZE - line;
+ } else
+ line[len++] = '\n';
if (column >= len) {
column = 0; /* continue with next line at column 0 */
lineno++;
@@ -999,6 +1015,7 @@
/* encode f_pos */
file->f_pos = (lineno << MAPS_LINE_SHIFT) + column;

+ free_page((unsigned long)tmp);
return destptr-buf;
}