2005-01-14 21:30:14

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: 2.6.10-mm3: lseek broken on /proc/self/maps

lseek doesn't seem to have any effect on /proc/<pid>/maps. It should
either work as expected, or fail.

I've attached a test program which uses a doubling buffer policy to try
to read the whole buffer. If it runs out of buffer, it simply allocates
a new one, lseeks back to the beginning of the buffer, and tries again.
However, the lseek seems to have no effect, because the next read
continues from where the previous one (before the lseek) left off.

Re-opening the file between each attempt works as expected.

$ tm &
$ ./readmap $!
b7dea000-b7deb000 r-xp b7dea000 00:00 0
b7deb000-b7dec000 ---p b7deb000 00:00 0
b7dec000-b7ded000 r-xp b7dec000 00:00 0
b7ded000-b7dee000 ---p b7ded000 00:00 0
b7dee000-b7def000 r-xp b7dee000 00:00 0
b7def000-b7df0000 ---p b7def000 00:00 0
b7df0000-b7df1000 r-xp b7df0000 00:00 0
[...]
$ gcc -o readmap -DREOPEN readmap.c
$ ./readmap $!
08048000-08049000 r-xp 00000000 03:07 3868140 /home/jeremy/tm
08049000-0804a000 rwxp 00000000 03:07 3868140 /home/jeremy/tm
b7ae6000-b7ae7000 r-xp b7ae6000 00:00 0
b7ae7000-b7ae8000 ---p b7ae7000 00:00 0
b7ae8000-b7ae9000 r-xp b7ae8000 00:00 0
b7ae9000-b7aea000 ---p b7ae9000 00:00 0
b7aea000-b7aeb000 r-xp b7aea000 00:00 0
b7aeb000-b7aec000 ---p b7aeb000 00:00 0

J


Attachments:
readmap.c (1.03 kB)
tm.c (257.00 B)
Download all attachments

2005-01-15 00:43:00

by Prasanna Meda

[permalink] [raw]
Subject: Re: 2.6.10-mm3: lseek broken on /proc/self/maps


I missed the point that seq_lseek did not reset the f_version,
like generic_lseek did, until Jeremy proved with an example.

Signed-off-by: Prasanna Meda <[email protected]>

--- fs/seq_file.c Fri Jan 14 23:51:27 2005
+++ fs/seq_file.c Fri Jan 14 23:51:59 2005
@@ -117,6 +117,7 @@ ssize_t seq_read(struct file *file, char
if (!m->buf)
goto Enomem;
m->count = 0;
+ m->version = 0;
}
m->op->stop(m, p);
m->count = 0;
@@ -173,6 +174,7 @@ static int traverse(struct seq_file *m,
int error = 0;
void *p;

+ m->version = 0;
m->index = 0;
m->count = m->from = 0;
if (!offset)
@@ -227,6 +229,7 @@ loff_t seq_lseek(struct file *file, loff
long long retval = -EINVAL;

down(&m->sem);
+ m->version = file->f_version;
switch (origin) {
case 1:
offset += file->f_pos;
@@ -240,6 +243,7 @@ loff_t seq_lseek(struct file *file, loff
if (retval) {
/* with extreme prejudice... */
file->f_pos = 0;
+ m->version = 0;
m->index = 0;
m->count = 0;
} else {
@@ -248,6 +252,7 @@ loff_t seq_lseek(struct file *file, loff
}
}
up(&m->sem);
+ file->f_version = m->version;
return retval;
}
EXPORT_SYMBOL(seq_lseek);


Attachments:
seq_version.patch (1.15 kB)

2005-01-15 01:17:03

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: 2.6.10-mm3: lseek broken on /proc/self/maps

On Fri, 2005-01-14 at 16:46 -0800, Prasanna Meda wrote:
> Thanks a lot for testing all the corner cases.

I'm actually trying to find bugs in Valgrind's memory map tracking code,
but so far all the problems have been in /proc/self/maps (which I had
been treating as a golden reference...).

I'll give this a go shortly.

BTW, your last patch fixed the >4k read problem, so I'm hoping this will
be the last one.

J