It seems to be a problem in vm/vm_fault() and
vnode_pager_generic_putpages() in FreeBSD 3.x & 4.0.
The following code illustrates the problem:
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#define COUNT 1024
#define SIZE 10*1024*1024
int main () {
int i,j,fd;
char *fptr, fname [16];
for (i=0;i<COUNT;i++) {
sprintf (fname, "%d", i);
printf ("DEBUG: fname: %s\n", fname);
fd=open (fname, O_RDWR|O_CREAT, 644);
lseek (fd, SIZE, SEEK_SET);
write (fd, "-", 1);
if ((fptr=mmap (NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
0))==MAP_FAILED) {
printf ("mmap() failed !\n");
return 0;
}
for (j=0;j<SIZE;j++)
fptr[j]='o';
}
return 0;
}
So, if we haven't required disk space on partition with mmap'ed files,
system deadlock in vm_fault() appears.
This is part of vnode_pager.c/vnode_pager_generic_putpages() :
aiov.iov_base = (caddr_t) 0;
aiov.iov_len = maxsize;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = poffset;
auio.uio_segflg = UIO_NOCOPY;
auio.uio_rw = UIO_WRITE;
auio.uio_resid = maxsize;
auio.uio_procp = (struct proc *) 0;
error = VOP_WRITE(vp, &auio, ioflags, curproc->p_ucred);
cnt.v_vnodeout++;
cnt.v_vnodepgsout += ncount;
if (error) {
printf("vnode_pager_putpages: I/O error %d\n", error);
}
if (auio.uio_resid) {
printf("vnode_pager_putpages: residual I/O %d at %lu\n",
auio.uio_resid, (u_long)m[0]->pindex);
}
for (i = 0; i < ncount; i++) {
rtvals[i] = VM_PAGER_OK; /* ???? */
}
return rtvals[0]; /* ???? */
So, such errors as I/O errors, are not handled there.
This seems to be a serious problem in FreeBSD VM subsystem, isn't it ?
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message