When trying to write to a memorymapped file on a filesystem that is full the system 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 runing 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. Fix: Possibly letting msync return an error when the disk is full, or not having syncer sync at so low prio. 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; }
Responsible Changed From-To: freebsd-bugs->freebsd-fs Over to maintainer(s).
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped