kern/116583: System freezes for short time when using mmap on full
filesystem
Karl Andersson
karland at gmail.com
Sun Sep 23 09:00:08 PDT 2007
>Number: 116583
>Category: kern
>Synopsis: System freezes for short time when using mmap on full filesystem
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Sep 23 16:00:07 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Karl Andersson
>Release: FreeBSD 6.2-RELEASE-p7 i386
>Organization:
>Environment:
FreeBSD tiron.iiice.net 6.2-RELEASE-p7 FreeBSD 6.2-RELEASE-p7 #1: Thu Se
p 20 17:12:47 CEST 2007 i386
>Description:
When trying to write to a memorymapped file on a filesystem that is full the sys
tem locks up as the syncer tries to put the page on disk.
As far as I can see there is no error returned to the userapplication when runin
g msync, so there is no way for the application to know that something is wrong.
The logs fill up with:
Sep 23 17:23:44 tiron kernel: pid 25573 (mmap_testing), uid 0 inumber 4 on /tmp/
mnt: filesystem full
Sep 23 17:23:44 tiron kernel: vnode_pager_putpages: I/O error 28
Sep 23 17:23:44 tiron kernel: vnode_pager_putpages: residual I/O 32768 at 4512
Sep 23 17:23:44 tiron kernel: pid 25573 (mmap_testing), uid 0 inumber 4 on /tmp/
mnt: filesystem full
Sep 23 17:23:44 tiron kernel: vnode_pager_putpages: I/O error 28
Sep 23 17:23:44 tiron kernel: vnode_pager_putpages: residual I/O 65536 at 5003
The problem resulted in a server being almost inaccessable.
>How-To-Repeat:
Using the following code on a filesystem with less then 20MB free space.
(Could be a memorydisk/vnodedisk)
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int fp;
void *p;
size_t len = 90 * 1024 * 1024;
int ret;
fp = open(argv[1], O_RDWR);
if(fp == 0) {
perror("open failed");
exit(1);
}
p = mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, fp, 0);
if(p == NULL) {
perror("mmap failed");
exit(2);
}
// write at least 20MB of data
const size_t bufsize = 1024*1024;
char buf[bufsize];
for(int i = 0; i < bufsize; i++) {
buf[i] = rand();
}
for(int i = 0; i < 25; i++) {
printf("memcpy(%p + %i = %p, %p, %d)\n",
p, i * bufsize, p + i * bufsize, buf, bufsize);
memcpy(p + i * bufsize, buf, bufsize);
}
printf("syncing pages\n");
ret = msync(p, 0, MS_SYNC);
if(ret != 0) {
perror("msync failed");
exit(3);
}
ret = munmap(p, len);
if(ret != 0) {
perror("munmap failed");
exit(3);
}
ret = close(fp);
if(ret != 0) {
perror("fclose failed");
exit(4);
}
return 0;
}
>Fix:
Possibly letting msync return an error when the disk is full, or not having sync
er sync at so low prio.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list