From owner-freebsd-bugs Sat Apr 4 17:30:02 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id RAA04436 for freebsd-bugs-outgoing; Sat, 4 Apr 1998 17:30:02 -0800 (PST) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: (from gnats@localhost) by hub.freebsd.org (8.8.8/8.8.8) id RAA04430; Sat, 4 Apr 1998 17:30:02 -0800 (PST) (envelope-from gnats) Received: from apollo.backplane.com (apollo.backplane.com [207.33.240.2]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id RAA04139 for ; Sat, 4 Apr 1998 17:23:25 -0800 (PST) (envelope-from dillon@backplane.com) Received: (root@localhost) by apollo.backplane.com (8.8.8/8.6.5) id RAA07844; Sat, 4 Apr 1998 17:23:20 -0800 (PST) Message-Id: <199804050123.RAA07844@apollo.backplane.com> Date: Sat, 4 Apr 1998 17:23:20 -0800 (PST) From: Matthew Dillon Reply-To: dillon@backplane.com To: FreeBSD-gnats-submit@FreeBSD.ORG X-Send-Pr-Version: 3.2 Subject: kern/6212: MFS msync bug, MFS-related pager bug (with fixes) Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 6212 >Category: kern >Synopsis: Two bugs with MFS filesystems fixed, one feature added >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Apr 4 17:30:01 PST 1998 >Last-Modified: >Originator: Matthew Dillon >Organization: Best Internet Communications >Release: FreeBSD 3.0-CURRENT i386 >Environment: Pentium based diskless FreeBSD box. >Description: The kernel does not set the P_SYSTEM flag for the MFS filesystem processes. Due to the size of the processes this will result in the kernel attempting to kill the process over and over again if it runs out of swap, which really screws the machine up. (note: my one-liner fix to this is probably not in the right place) The MFS kernel process needs to msync() the memory map to backing store (which only effects MFS mounts that use a file for backing store). If it fails to do so, the kernel syncer will *never* *see* the dirty pages. (note: I change the tsleep() to tsleep() with a timeout and check the time, calling msync() every 30 seconds). The mount_mfs program (the mkfs.c code) insists on clearing the backing store file if one has been specified. There are lots of people who probably would like to be able to use an NFS mounted file for backing store, and this clearing results in a massive amount of network I/O (especially if you are mounting huge filesystems). Also included in my bug fixes is a modification to the program to check the size of the file and only truncate/pre-initialize it if it does not match the size of the requested filesystem. If it does match, mount_mfs does not bother to clear it and simply newfs's over whatever data was previously there. >How-To-Repeat: >Fix: Index: mfs_vfsops.c =================================================================== RCS file: /src/FreeBSD-CVS/ncvs/src/sys/ufs/mfs/mfs_vfsops.c,v retrieving revision 1.41 diff -r1.41 mfs_vfsops.c 48a49,50 > #include /* for msync_args */ > #include /* for msync_args */ 432a435,441 > /* > * must mark the calling process as a system process > * so the pager doesn't try to kill it. Doh! And the > * pager may because the resident set size may be huge. > */ > p->p_flag |= P_SYSTEM; > 483c492 < else if (tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) --- > else if (tsleep((caddr_t)vp, mfs_pri, "mfsidl", hz * 10)) 484a494,518 > > /* > * we should call msync on the backing store every 30 seconds, > * otherwise the pages are not associated with the file and guess > * what! the syncer never sees them. msync has no effect > * if the backing store is swap, but a big effect if it's a file > * (e.g. an NFS mounted file). > */ > { > static long lsec; > int dt = time_second - lsec; > > if (dt < -30 || dt > 30) { > struct msync_args uap; > > lsec = time_second; > > uap.addr = mfsp->mfs_baseoff; > uap.len = mfsp->mfs_size; > uap.flags = MS_ASYNC; > > msync(curproc, &uap); > } > } > Index: mkfs.c =================================================================== RCS file: /src/FreeBSD-CVS/ncvs/src/sbin/newfs/mkfs.c,v retrieving revision 1.20 diff -r1.20 mkfs.c 42a43 > #include 181c182,184 < fd = open(filename,O_RDWR|O_TRUNC|O_CREAT,0644); --- > struct stat st; > > fd = open(filename,O_RDWR|O_CREAT,0644); 186,193c189,200 < for(l=0;l< fssize * sectorsize;l += l1) { < l1 = fssize * sectorsize; < if (BUFSIZ < l1) < l1 = BUFSIZ; < if (l1 != write(fd,buf,l1)) { < perror(filename); < exit(12); < } --- > fstat(fd, &st); > if (st.st_size != fssize * sectorsize) { > ftruncate(fd, fssize * sectorsize); > for(l=0;l< fssize * sectorsize;l += l1) { > l1 = fssize * sectorsize; > if (BUFSIZ < l1) > l1 = BUFSIZ; > if (l1 != write(fd,buf,l1)) { > perror(filename); > exit(12); > } > } >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message