Subject: kern/30811: mmap (?) regression
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <j+nbsd@2005.salmi.ch>
List: netbsd-bugs
Date: 07/22/2005 11:34:00
>Number: 30811
>Category: kern
>Synopsis: mmap (?) regression
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jul 22 11:34:00 +0000 2005
>Originator: Jukka Salmi
>Release: NetBSD 3.99.7
>Environment:
System: NetBSD moray.salmi.ch 3.99.7 NetBSD 3.99.7 (GENERIC) #0: Fri Jul 22 12:32:24 CEST 2005 jukka@moray.salmi.ch:/opt/temp/jukka/GENERIC i386
Architecture: i386
Machine: i386
>Description:
While building graphics/ImageMagick from pkgsrc on a i386 system I noticed
a problem which I traced it down to the following:
Executing the attached program on a null-mounted filesystem hangs forever.
Executing it on a non-null-mounted filesystem succeeds.
This problem was introduced by this commit:
http://mail-index.netbsd.org/source-changes/2005/07/17/0015.html
>How-To-Repeat:
Execute the attached program on null-mounted and non-null-mounted
filesystems:
$ mount
[...]
/dev/ccd0a on /ffs type ffs (local)
/ffs on /null type null (local)
Executing it on the ffs works fine:
$ cd /ffs
$ ./a.out
$ echo $?
0
But executing it on the (same but) null-mounted filesystem takes forever:
$ cd /null
$ ./a.out
^C
$ echo $?
130
>Fix:
Unknown.
Workaround: after reverting the four files from the commit posted above
the problem was gone. Diff()ed ident output from the two kernels:
$ diff working non-working | grep '^[<>]'
< $NetBSD: genfs_vnops.c,v 1.100 2005/07/17 09:13:35 yamt Exp $
> $NetBSD: genfs_vnops.c,v 1.102 2005/07/17 16:07:19 yamt Exp $
< $NetBSD: uvm_fault.c,v 1.95 2005/06/27 02:19:48 thorpej Exp $
> $NetBSD: uvm_fault.c,v 1.96 2005/07/17 12:27:47 yamt Exp $
--- cut here ---
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stddef.h>
#include <memory.h>
#include <string.h>
#include <strings.h>
#include <inttypes.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
int
main ()
{
char *data, *data2, *data3;
int i, pagesize;
int fd;
pagesize = getpagesize ();
/* First, make a file with some known garbage in it. */
data = (char *) malloc (pagesize);
if (!data)
exit (1);
for (i = 0; i < pagesize; ++i)
*(data + i) = rand ();
umask (0);
fd = creat ("conftest.mmap", 0600);
if (fd < 0)
exit (1);
if (write (fd, data, pagesize) != pagesize)
exit (1);
close (fd);
/* Mmap the file as read/write/shared and verify that we see the
same garbage. */
fd = open ("conftest.mmap", O_RDWR);
if (fd < 0)
exit (1);
data2 = mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0L);
if (data2 == 0)
exit (1);
for (i = 0; i < pagesize; ++i)
if (*(data + i) != *(data2 + i))
exit (1);
/* Finally, make sure that changes to the mapped area
percolate back to the file as seen by read(). */
for (i = 0; i < pagesize; ++i)
*(data2 + i) = *(data2 + i) + 1;
data3 = (char *) malloc (pagesize);
if (!data3)
exit (1);
if (read (fd, data3, pagesize) != pagesize)
exit (1);
for (i = 0; i < pagesize; ++i)
if (*(data2 + i) != *(data3 + i))
exit (1);
close (fd);
exit (0);
}