Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Apr 1998 21:30:01 -0700 (PDT)
From:      Matthew Dillon <dillon@backplane.com>
To:        freebsd-bugs
Subject:   Re: kern/6212: Two bugs with MFS filesystem fixed, two features added
Message-ID:  <199804070430.VAA16080@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/6212; it has been noted by GNATS.

From: Matthew Dillon <dillon@backplane.com>
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.
 		     <dillon@backplane.com>
     [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 <sys/stat.h>
 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 <sys/sysproto.h>	/* for msync_args */
 > #include <sys/mman.h>	/* 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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804070430.VAA16080>