From owner-freebsd-bugs Mon Apr 6 21:30:02 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id VAA16096 for freebsd-bugs-outgoing; Mon, 6 Apr 1998 21:30:02 -0700 (PDT) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: (from gnats@localhost) by hub.freebsd.org (8.8.8/8.8.8) id VAA16080; Mon, 6 Apr 1998 21:30:01 -0700 (PDT) (envelope-from gnats) Date: Mon, 6 Apr 1998 21:30:01 -0700 (PDT) Message-Id: <199804070430.VAA16080@hub.freebsd.org> To: freebsd-bugs Cc: From: Matthew Dillon Subject: Re: kern/6212: Two bugs with MFS filesystem fixed, two features added Reply-To: Matthew Dillon Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR kern/6212; it has been noted by GNATS. From: Matthew Dillon To: freebsd-gnats-submit@freebsd.org Cc: Subject: Re: kern/6212: Two bugs with MFS filesystem fixed, two features added Date: Mon, 6 Apr 1998 21:22:21 -0700 (PDT) This is a revised submission to my original submission. Note that the diff included below is relative to the CVS base, *NOT* to my original submission. This submission fixes two bugs with MFS and adds two features that allow MFS to be used properly in a diskless workstation environment. Bug #1 fixed: kernel does not set P_SYSTEM flag for MFS special kernel process, causing paging system to attempt to kill the MFS process if memory runs low. Bug #2 fixed: When using file-backed storage, the dirty pages are never synchronized to the backing store by the kernel update/syncer daemon. The MFS special kernel process must call msync(). The fix causes it to call msync() every 30 seconds. Feature #1 added: MFS does not attempt to zero-out the file before newfs'ing it if the file is already the correct size. This allows MFS to be used with NFS-mounted backing store without eating the network alive. (e.g. my workstation has two 32MB MFS mounts and one 8MB mount. That hurts on a 10BaseT network without this fix). Feature #2 added: The ability to specify file-backed storage and have MFS *NOT* newfs the storage, allowing persistent backing store to survive a reboot. This is critical in a workstation environment because it allows MFS to be used over an NFS-based file backing store in a persistant fashion (i.e. for a small /home so one can use SSH and .Xauthority in a diskless workstation environment). Note that fsck works just fine on the backing store file. Finally, it should be noted that being able to use an NFS-based file for backing store for an MFS filesystem is critical in a diskless workstation environment. It allows the filesystems in question to not eat up memory, especially if the workstation environment has no swap at all. I would also like to submit instructions to the FreeBSD manual to describe how to setup a diskless (floppy boot) workstation environment. It really is quite simple.. a read-only NFS mount for / and /usr, a secure r+w NFS mount for the MFS filesystem images, and three MFS filesytems (two transitory: /var and /var/tmp, and one persistent: /home). It's a fantastic environment, and MFS is extremely stable where as trying to use vnconfig with an NFS-backed file leads to massive system corruption and crashes even under FreeBSD-3.0-current. Since MFS disassociates I/O with a separate kernel process, it can deal with NFS based backing store without screwing up the machine. -Matt Matthew Dillon Engineering, BEST Internet Communications, Inc. [always include a portion of the original email in any response!] Index: mkfs.c =================================================================== RCS file: /src/FreeBSD-CVS/ncvs/src/sbin/newfs/mkfs.c,v retrieving revision 1.21 diff -r1.21 mkfs.c 42a43 > #include 108a110 > extern int skipnewfs; 181c183,185 < fd = open(filename,O_RDWR|O_TRUNC|O_CREAT,0644); --- > struct stat st; > > fd = open(filename,O_RDWR|O_CREAT,0644); 186,191c190,193 < for(l=0;l< fssize * sectorsize;l += l1) { < l1 = fssize * sectorsize; < if (BUFSIZ < l1) < l1 = BUFSIZ; < if (l1 != write(fd,buf,l1)) { < perror(filename); --- > fstat(fd, &st); > if (st.st_size != fssize * sectorsize) { > if (skipnewfs) { > fprintf(stderr, "Filesize does not match filesystem sector count\n"); 193a196,205 > 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); > } > } 218a231,232 > if (skipnewfs == 0) { /* didn't re-indent context so submitted cvs diff would be more readable */ > 701a716,718 > > } /* endif skipnewfs */ > Index: newfs.c =================================================================== RCS file: /src/FreeBSD-CVS/ncvs/src/sbin/newfs/newfs.c,v retrieving revision 1.18 diff -r1.18 newfs.c 195a196 > int skipnewfs; 237c238 < "NF:T:a:b:c:d:e:f:i:m:o:s:" : --- > "NF:U:T:a:b:c:d:e:f:i:m:o:s:" : 255a257,259 > case 'U': > skipnewfs = 1; > /* fall through */ 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; > 471c480,481 < * EINTR/ERESTART. --- > * EINTR/ERESTART. It will return EWOULDBLOCK if the timer > * expired. 482,483c492,495 < } < else if (tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) --- > } else { > int r = tsleep((caddr_t)vp, mfs_pri, "mfsidl", hz * 10); > > if (r && r != EWOULDBLOCK) 484a497,522 > } > > /* > * 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); > } > } > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message