Date: Sun, 23 Sep 2007 15:51:15 GMT From: Karl Andersson <karland@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/116583: System freezes for short time when using mmap on full filesystem Message-ID: <200709231551.l8NFpFmm091779@www.freebsd.org> Resent-Message-ID: <200709231600.l8NG07p5092880@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709231551.l8NFpFmm091779>