Index: trunk/minix/servers/fs/.depend
===================================================================
--- trunk/minix/servers/fs/.depend	(revision 11)
+++ 	(revision )
@@ -1,786 +1,0 @@
-
-cache.o:	/usr/include/ansi.h
-cache.o:	/usr/include/dirent.h
-cache.o:	/usr/include/errno.h
-cache.o:	/usr/include/limits.h
-cache.o:	/usr/include/minix/com.h
-cache.o:	/usr/include/minix/config.h
-cache.o:	/usr/include/minix/const.h
-cache.o:	/usr/include/minix/devio.h
-cache.o:	/usr/include/minix/dmap.h
-cache.o:	/usr/include/minix/ipc.h
-cache.o:	/usr/include/minix/sys_config.h
-cache.o:	/usr/include/minix/syslib.h
-cache.o:	/usr/include/minix/sysutil.h
-cache.o:	/usr/include/minix/type.h
-cache.o:	/usr/include/string.h
-cache.o:	/usr/include/sys/dir.h
-cache.o:	/usr/include/sys/select.h
-cache.o:	/usr/include/sys/time.h
-cache.o:	/usr/include/sys/types.h
-cache.o:	/usr/include/timers.h
-cache.o:	buf.h
-cache.o:	cache.c
-cache.o:	const.h
-cache.o:	file.h
-cache.o:	fproc.h
-cache.o:	fs.h
-cache.o:	glo.h
-cache.o:	proto.h
-cache.o:	super.h
-cache.o:	type.h
-
-cache2.o:	/usr/include/ansi.h
-cache2.o:	/usr/include/dirent.h
-cache2.o:	/usr/include/errno.h
-cache2.o:	/usr/include/limits.h
-cache2.o:	/usr/include/minix/com.h
-cache2.o:	/usr/include/minix/config.h
-cache2.o:	/usr/include/minix/const.h
-cache2.o:	/usr/include/minix/devio.h
-cache2.o:	/usr/include/minix/dmap.h
-cache2.o:	/usr/include/minix/ipc.h
-cache2.o:	/usr/include/minix/sys_config.h
-cache2.o:	/usr/include/minix/syslib.h
-cache2.o:	/usr/include/minix/sysutil.h
-cache2.o:	/usr/include/minix/type.h
-cache2.o:	/usr/include/sys/dir.h
-cache2.o:	/usr/include/sys/types.h
-cache2.o:	/usr/include/timers.h
-cache2.o:	buf.h
-cache2.o:	cache2.c
-cache2.o:	const.h
-cache2.o:	fs.h
-cache2.o:	glo.h
-cache2.o:	proto.h
-cache2.o:	type.h
-
-device.o:	/usr/include/ansi.h
-device.o:	/usr/include/errno.h
-device.o:	/usr/include/fcntl.h
-device.o:	/usr/include/limits.h
-device.o:	/usr/include/minix/callnr.h
-device.o:	/usr/include/minix/com.h
-device.o:	/usr/include/minix/config.h
-device.o:	/usr/include/minix/const.h
-device.o:	/usr/include/minix/devio.h
-device.o:	/usr/include/minix/dmap.h
-device.o:	/usr/include/minix/endpoint.h
-device.o:	/usr/include/minix/ipc.h
-device.o:	/usr/include/minix/sys_config.h
-device.o:	/usr/include/minix/syslib.h
-device.o:	/usr/include/minix/sysutil.h
-device.o:	/usr/include/minix/type.h
-device.o:	/usr/include/string.h
-device.o:	/usr/include/sys/dir.h
-device.o:	/usr/include/sys/select.h
-device.o:	/usr/include/sys/time.h
-device.o:	/usr/include/sys/types.h
-device.o:	/usr/include/timers.h
-device.o:	const.h
-device.o:	device.c
-device.o:	file.h
-device.o:	fproc.h
-device.o:	fs.h
-device.o:	glo.h
-device.o:	inode.h
-device.o:	param.h
-device.o:	proto.h
-device.o:	super.h
-device.o:	type.h
-
-dmap.o:	/usr/include/ansi.h
-dmap.o:	/usr/include/ctype.h
-dmap.o:	/usr/include/errno.h
-dmap.o:	/usr/include/limits.h
-dmap.o:	/usr/include/minix/com.h
-dmap.o:	/usr/include/minix/config.h
-dmap.o:	/usr/include/minix/const.h
-dmap.o:	/usr/include/minix/devio.h
-dmap.o:	/usr/include/minix/dmap.h
-dmap.o:	/usr/include/minix/ipc.h
-dmap.o:	/usr/include/minix/sys_config.h
-dmap.o:	/usr/include/minix/syslib.h
-dmap.o:	/usr/include/minix/sysutil.h
-dmap.o:	/usr/include/minix/type.h
-dmap.o:	/usr/include/stdlib.h
-dmap.o:	/usr/include/string.h
-dmap.o:	/usr/include/sys/dir.h
-dmap.o:	/usr/include/sys/select.h
-dmap.o:	/usr/include/sys/time.h
-dmap.o:	/usr/include/sys/types.h
-dmap.o:	/usr/include/timers.h
-dmap.o:	/usr/include/unistd.h
-dmap.o:	const.h
-dmap.o:	dmap.c
-dmap.o:	fproc.h
-dmap.o:	fs.h
-dmap.o:	glo.h
-dmap.o:	param.h
-dmap.o:	proto.h
-dmap.o:	type.h
-
-filedes.o:	/usr/include/ansi.h
-filedes.o:	/usr/include/errno.h
-filedes.o:	/usr/include/limits.h
-filedes.o:	/usr/include/minix/config.h
-filedes.o:	/usr/include/minix/const.h
-filedes.o:	/usr/include/minix/devio.h
-filedes.o:	/usr/include/minix/dmap.h
-filedes.o:	/usr/include/minix/ipc.h
-filedes.o:	/usr/include/minix/sys_config.h
-filedes.o:	/usr/include/minix/syslib.h
-filedes.o:	/usr/include/minix/sysutil.h
-filedes.o:	/usr/include/minix/type.h
-filedes.o:	/usr/include/string.h
-filedes.o:	/usr/include/sys/dir.h
-filedes.o:	/usr/include/sys/select.h
-filedes.o:	/usr/include/sys/time.h
-filedes.o:	/usr/include/sys/types.h
-filedes.o:	/usr/include/timers.h
-filedes.o:	const.h
-filedes.o:	file.h
-filedes.o:	filedes.c
-filedes.o:	fproc.h
-filedes.o:	fs.h
-filedes.o:	glo.h
-filedes.o:	inode.h
-filedes.o:	proto.h
-filedes.o:	type.h
-
-inode.o:	/usr/include/ansi.h
-inode.o:	/usr/include/dirent.h
-inode.o:	/usr/include/errno.h
-inode.o:	/usr/include/limits.h
-inode.o:	/usr/include/minix/config.h
-inode.o:	/usr/include/minix/const.h
-inode.o:	/usr/include/minix/devio.h
-inode.o:	/usr/include/minix/dmap.h
-inode.o:	/usr/include/minix/ipc.h
-inode.o:	/usr/include/minix/sys_config.h
-inode.o:	/usr/include/minix/syslib.h
-inode.o:	/usr/include/minix/sysutil.h
-inode.o:	/usr/include/minix/type.h
-inode.o:	/usr/include/string.h
-inode.o:	/usr/include/sys/dir.h
-inode.o:	/usr/include/sys/select.h
-inode.o:	/usr/include/sys/time.h
-inode.o:	/usr/include/sys/types.h
-inode.o:	/usr/include/timers.h
-inode.o:	buf.h
-inode.o:	const.h
-inode.o:	file.h
-inode.o:	fproc.h
-inode.o:	fs.h
-inode.o:	glo.h
-inode.o:	inode.c
-inode.o:	inode.h
-inode.o:	proto.h
-inode.o:	super.h
-inode.o:	type.h
-
-link.o:	/usr/include/ansi.h
-link.o:	/usr/include/dirent.h
-link.o:	/usr/include/errno.h
-link.o:	/usr/include/limits.h
-link.o:	/usr/include/minix/callnr.h
-link.o:	/usr/include/minix/com.h
-link.o:	/usr/include/minix/config.h
-link.o:	/usr/include/minix/const.h
-link.o:	/usr/include/minix/devio.h
-link.o:	/usr/include/minix/dmap.h
-link.o:	/usr/include/minix/ipc.h
-link.o:	/usr/include/minix/sys_config.h
-link.o:	/usr/include/minix/syslib.h
-link.o:	/usr/include/minix/sysutil.h
-link.o:	/usr/include/minix/type.h
-link.o:	/usr/include/string.h
-link.o:	/usr/include/sys/dir.h
-link.o:	/usr/include/sys/select.h
-link.o:	/usr/include/sys/stat.h
-link.o:	/usr/include/sys/time.h
-link.o:	/usr/include/sys/types.h
-link.o:	/usr/include/timers.h
-link.o:	buf.h
-link.o:	const.h
-link.o:	file.h
-link.o:	fproc.h
-link.o:	fs.h
-link.o:	glo.h
-link.o:	inode.h
-link.o:	link.c
-link.o:	param.h
-link.o:	proto.h
-link.o:	super.h
-link.o:	type.h
-
-lock.o:	/usr/include/ansi.h
-lock.o:	/usr/include/errno.h
-lock.o:	/usr/include/fcntl.h
-lock.o:	/usr/include/limits.h
-lock.o:	/usr/include/minix/com.h
-lock.o:	/usr/include/minix/config.h
-lock.o:	/usr/include/minix/const.h
-lock.o:	/usr/include/minix/devio.h
-lock.o:	/usr/include/minix/dmap.h
-lock.o:	/usr/include/minix/ipc.h
-lock.o:	/usr/include/minix/sys_config.h
-lock.o:	/usr/include/minix/syslib.h
-lock.o:	/usr/include/minix/sysutil.h
-lock.o:	/usr/include/minix/type.h
-lock.o:	/usr/include/string.h
-lock.o:	/usr/include/sys/dir.h
-lock.o:	/usr/include/sys/select.h
-lock.o:	/usr/include/sys/time.h
-lock.o:	/usr/include/sys/types.h
-lock.o:	/usr/include/timers.h
-lock.o:	/usr/include/unistd.h
-lock.o:	const.h
-lock.o:	file.h
-lock.o:	fproc.h
-lock.o:	fs.h
-lock.o:	glo.h
-lock.o:	inode.h
-lock.o:	lock.c
-lock.o:	lock.h
-lock.o:	param.h
-lock.o:	proto.h
-lock.o:	type.h
-
-main.o:	/usr/include/ansi.h
-main.o:	/usr/include/dirent.h
-main.o:	/usr/include/errno.h
-main.o:	/usr/include/fcntl.h
-main.o:	/usr/include/limits.h
-main.o:	/usr/include/minix/callnr.h
-main.o:	/usr/include/minix/com.h
-main.o:	/usr/include/minix/config.h
-main.o:	/usr/include/minix/const.h
-main.o:	/usr/include/minix/devio.h
-main.o:	/usr/include/minix/dmap.h
-main.o:	/usr/include/minix/endpoint.h
-main.o:	/usr/include/minix/ioctl.h
-main.o:	/usr/include/minix/ipc.h
-main.o:	/usr/include/minix/keymap.h
-main.o:	/usr/include/minix/sys_config.h
-main.o:	/usr/include/minix/syslib.h
-main.o:	/usr/include/minix/sysutil.h
-main.o:	/usr/include/minix/type.h
-main.o:	/usr/include/signal.h
-main.o:	/usr/include/stdio.h
-main.o:	/usr/include/stdlib.h
-main.o:	/usr/include/string.h
-main.o:	/usr/include/sys/dir.h
-main.o:	/usr/include/sys/ioc_memory.h
-main.o:	/usr/include/sys/select.h
-main.o:	/usr/include/sys/svrctl.h
-main.o:	/usr/include/sys/time.h
-main.o:	/usr/include/sys/types.h
-main.o:	/usr/include/timers.h
-main.o:	buf.h
-main.o:	const.h
-main.o:	file.h
-main.o:	fproc.h
-main.o:	fs.h
-main.o:	glo.h
-main.o:	inode.h
-main.o:	main.c
-main.o:	param.h
-main.o:	proto.h
-main.o:	super.h
-main.o:	type.h
-
-misc.o:	/usr/include/ansi.h
-misc.o:	/usr/include/dirent.h
-misc.o:	/usr/include/errno.h
-misc.o:	/usr/include/fcntl.h
-misc.o:	/usr/include/limits.h
-misc.o:	/usr/include/minix/callnr.h
-misc.o:	/usr/include/minix/com.h
-misc.o:	/usr/include/minix/config.h
-misc.o:	/usr/include/minix/const.h
-misc.o:	/usr/include/minix/devio.h
-misc.o:	/usr/include/minix/dmap.h
-misc.o:	/usr/include/minix/endpoint.h
-misc.o:	/usr/include/minix/ioctl.h
-misc.o:	/usr/include/minix/ipc.h
-misc.o:	/usr/include/minix/sys_config.h
-misc.o:	/usr/include/minix/syslib.h
-misc.o:	/usr/include/minix/sysutil.h
-misc.o:	/usr/include/minix/type.h
-misc.o:	/usr/include/string.h
-misc.o:	/usr/include/sys/dir.h
-misc.o:	/usr/include/sys/select.h
-misc.o:	/usr/include/sys/svrctl.h
-misc.o:	/usr/include/sys/time.h
-misc.o:	/usr/include/sys/types.h
-misc.o:	/usr/include/timers.h
-misc.o:	/usr/include/unistd.h
-misc.o:	buf.h
-misc.o:	const.h
-misc.o:	file.h
-misc.o:	fproc.h
-misc.o:	fs.h
-misc.o:	glo.h
-misc.o:	inode.h
-misc.o:	misc.c
-misc.o:	param.h
-misc.o:	proto.h
-misc.o:	super.h
-misc.o:	type.h
-
-mount.o:	/usr/include/ansi.h
-mount.o:	/usr/include/dirent.h
-mount.o:	/usr/include/errno.h
-mount.o:	/usr/include/fcntl.h
-mount.o:	/usr/include/limits.h
-mount.o:	/usr/include/minix/com.h
-mount.o:	/usr/include/minix/config.h
-mount.o:	/usr/include/minix/const.h
-mount.o:	/usr/include/minix/devio.h
-mount.o:	/usr/include/minix/dmap.h
-mount.o:	/usr/include/minix/ipc.h
-mount.o:	/usr/include/minix/sys_config.h
-mount.o:	/usr/include/minix/syslib.h
-mount.o:	/usr/include/minix/sysutil.h
-mount.o:	/usr/include/minix/type.h
-mount.o:	/usr/include/string.h
-mount.o:	/usr/include/sys/dir.h
-mount.o:	/usr/include/sys/select.h
-mount.o:	/usr/include/sys/stat.h
-mount.o:	/usr/include/sys/time.h
-mount.o:	/usr/include/sys/types.h
-mount.o:	/usr/include/timers.h
-mount.o:	buf.h
-mount.o:	const.h
-mount.o:	file.h
-mount.o:	fproc.h
-mount.o:	fs.h
-mount.o:	glo.h
-mount.o:	inode.h
-mount.o:	mount.c
-mount.o:	param.h
-mount.o:	proto.h
-mount.o:	super.h
-mount.o:	type.h
-
-open.o:	/usr/include/ansi.h
-open.o:	/usr/include/dirent.h
-open.o:	/usr/include/errno.h
-open.o:	/usr/include/fcntl.h
-open.o:	/usr/include/limits.h
-open.o:	/usr/include/minix/callnr.h
-open.o:	/usr/include/minix/com.h
-open.o:	/usr/include/minix/config.h
-open.o:	/usr/include/minix/const.h
-open.o:	/usr/include/minix/devio.h
-open.o:	/usr/include/minix/dmap.h
-open.o:	/usr/include/minix/ipc.h
-open.o:	/usr/include/minix/sys_config.h
-open.o:	/usr/include/minix/syslib.h
-open.o:	/usr/include/minix/sysutil.h
-open.o:	/usr/include/minix/type.h
-open.o:	/usr/include/string.h
-open.o:	/usr/include/sys/dir.h
-open.o:	/usr/include/sys/select.h
-open.o:	/usr/include/sys/stat.h
-open.o:	/usr/include/sys/time.h
-open.o:	/usr/include/sys/types.h
-open.o:	/usr/include/timers.h
-open.o:	/usr/include/unistd.h
-open.o:	buf.h
-open.o:	const.h
-open.o:	file.h
-open.o:	fproc.h
-open.o:	fs.h
-open.o:	glo.h
-open.o:	inode.h
-open.o:	lock.h
-open.o:	open.c
-open.o:	param.h
-open.o:	proto.h
-open.o:	super.h
-open.o:	type.h
-
-path.o:	/usr/include/ansi.h
-path.o:	/usr/include/dirent.h
-path.o:	/usr/include/errno.h
-path.o:	/usr/include/limits.h
-path.o:	/usr/include/minix/callnr.h
-path.o:	/usr/include/minix/config.h
-path.o:	/usr/include/minix/const.h
-path.o:	/usr/include/minix/devio.h
-path.o:	/usr/include/minix/dmap.h
-path.o:	/usr/include/minix/ipc.h
-path.o:	/usr/include/minix/sys_config.h
-path.o:	/usr/include/minix/syslib.h
-path.o:	/usr/include/minix/sysutil.h
-path.o:	/usr/include/minix/type.h
-path.o:	/usr/include/string.h
-path.o:	/usr/include/sys/dir.h
-path.o:	/usr/include/sys/select.h
-path.o:	/usr/include/sys/stat.h
-path.o:	/usr/include/sys/time.h
-path.o:	/usr/include/sys/types.h
-path.o:	/usr/include/timers.h
-path.o:	buf.h
-path.o:	const.h
-path.o:	file.h
-path.o:	fproc.h
-path.o:	fs.h
-path.o:	glo.h
-path.o:	inode.h
-path.o:	path.c
-path.o:	proto.h
-path.o:	super.h
-path.o:	type.h
-
-pipe.o:	/usr/include/ansi.h
-pipe.o:	/usr/include/errno.h
-pipe.o:	/usr/include/fcntl.h
-pipe.o:	/usr/include/limits.h
-pipe.o:	/usr/include/minix/callnr.h
-pipe.o:	/usr/include/minix/com.h
-pipe.o:	/usr/include/minix/config.h
-pipe.o:	/usr/include/minix/const.h
-pipe.o:	/usr/include/minix/devio.h
-pipe.o:	/usr/include/minix/dmap.h
-pipe.o:	/usr/include/minix/endpoint.h
-pipe.o:	/usr/include/minix/ipc.h
-pipe.o:	/usr/include/minix/sys_config.h
-pipe.o:	/usr/include/minix/syslib.h
-pipe.o:	/usr/include/minix/sysutil.h
-pipe.o:	/usr/include/minix/type.h
-pipe.o:	/usr/include/signal.h
-pipe.o:	/usr/include/string.h
-pipe.o:	/usr/include/sys/dir.h
-pipe.o:	/usr/include/sys/select.h
-pipe.o:	/usr/include/sys/time.h
-pipe.o:	/usr/include/sys/types.h
-pipe.o:	/usr/include/timers.h
-pipe.o:	const.h
-pipe.o:	file.h
-pipe.o:	fproc.h
-pipe.o:	fs.h
-pipe.o:	glo.h
-pipe.o:	inode.h
-pipe.o:	param.h
-pipe.o:	pipe.c
-pipe.o:	proto.h
-pipe.o:	select.h
-pipe.o:	super.h
-pipe.o:	type.h
-
-protect.o:	/usr/include/ansi.h
-protect.o:	/usr/include/dirent.h
-protect.o:	/usr/include/errno.h
-protect.o:	/usr/include/limits.h
-protect.o:	/usr/include/minix/callnr.h
-protect.o:	/usr/include/minix/config.h
-protect.o:	/usr/include/minix/const.h
-protect.o:	/usr/include/minix/devio.h
-protect.o:	/usr/include/minix/dmap.h
-protect.o:	/usr/include/minix/ipc.h
-protect.o:	/usr/include/minix/sys_config.h
-protect.o:	/usr/include/minix/syslib.h
-protect.o:	/usr/include/minix/sysutil.h
-protect.o:	/usr/include/minix/type.h
-protect.o:	/usr/include/string.h
-protect.o:	/usr/include/sys/dir.h
-protect.o:	/usr/include/sys/select.h
-protect.o:	/usr/include/sys/time.h
-protect.o:	/usr/include/sys/types.h
-protect.o:	/usr/include/timers.h
-protect.o:	/usr/include/unistd.h
-protect.o:	buf.h
-protect.o:	const.h
-protect.o:	file.h
-protect.o:	fproc.h
-protect.o:	fs.h
-protect.o:	glo.h
-protect.o:	inode.h
-protect.o:	param.h
-protect.o:	protect.c
-protect.o:	proto.h
-protect.o:	super.h
-protect.o:	type.h
-
-read.o:	/usr/include/ansi.h
-read.o:	/usr/include/dirent.h
-read.o:	/usr/include/errno.h
-read.o:	/usr/include/fcntl.h
-read.o:	/usr/include/limits.h
-read.o:	/usr/include/minix/com.h
-read.o:	/usr/include/minix/config.h
-read.o:	/usr/include/minix/const.h
-read.o:	/usr/include/minix/devio.h
-read.o:	/usr/include/minix/dmap.h
-read.o:	/usr/include/minix/ipc.h
-read.o:	/usr/include/minix/sys_config.h
-read.o:	/usr/include/minix/syslib.h
-read.o:	/usr/include/minix/sysutil.h
-read.o:	/usr/include/minix/type.h
-read.o:	/usr/include/string.h
-read.o:	/usr/include/sys/dir.h
-read.o:	/usr/include/sys/select.h
-read.o:	/usr/include/sys/time.h
-read.o:	/usr/include/sys/types.h
-read.o:	/usr/include/timers.h
-read.o:	/usr/include/unistd.h
-read.o:	buf.h
-read.o:	const.h
-read.o:	file.h
-read.o:	fproc.h
-read.o:	fs.h
-read.o:	glo.h
-read.o:	inode.h
-read.o:	param.h
-read.o:	proto.h
-read.o:	read.c
-read.o:	super.h
-read.o:	type.h
-
-select.o:	/usr/include/ansi.h
-select.o:	/usr/include/errno.h
-select.o:	/usr/include/limits.h
-select.o:	/usr/include/minix/com.h
-select.o:	/usr/include/minix/config.h
-select.o:	/usr/include/minix/const.h
-select.o:	/usr/include/minix/devio.h
-select.o:	/usr/include/minix/dmap.h
-select.o:	/usr/include/minix/ipc.h
-select.o:	/usr/include/minix/sys_config.h
-select.o:	/usr/include/minix/syslib.h
-select.o:	/usr/include/minix/sysutil.h
-select.o:	/usr/include/minix/type.h
-select.o:	/usr/include/string.h
-select.o:	/usr/include/sys/dir.h
-select.o:	/usr/include/sys/select.h
-select.o:	/usr/include/sys/time.h
-select.o:	/usr/include/sys/types.h
-select.o:	/usr/include/timers.h
-select.o:	const.h
-select.o:	file.h
-select.o:	fs.h
-select.o:	glo.h
-select.o:	inode.h
-select.o:	proto.h
-select.o:	select.c
-select.o:	select.h
-select.o:	type.h
-
-stadir.o:	/usr/include/ansi.h
-stadir.o:	/usr/include/dirent.h
-stadir.o:	/usr/include/errno.h
-stadir.o:	/usr/include/limits.h
-stadir.o:	/usr/include/minix/com.h
-stadir.o:	/usr/include/minix/config.h
-stadir.o:	/usr/include/minix/const.h
-stadir.o:	/usr/include/minix/devio.h
-stadir.o:	/usr/include/minix/dmap.h
-stadir.o:	/usr/include/minix/ipc.h
-stadir.o:	/usr/include/minix/sys_config.h
-stadir.o:	/usr/include/minix/syslib.h
-stadir.o:	/usr/include/minix/sysutil.h
-stadir.o:	/usr/include/minix/type.h
-stadir.o:	/usr/include/string.h
-stadir.o:	/usr/include/sys/dir.h
-stadir.o:	/usr/include/sys/select.h
-stadir.o:	/usr/include/sys/stat.h
-stadir.o:	/usr/include/sys/statfs.h
-stadir.o:	/usr/include/sys/time.h
-stadir.o:	/usr/include/sys/types.h
-stadir.o:	/usr/include/timers.h
-stadir.o:	buf.h
-stadir.o:	const.h
-stadir.o:	file.h
-stadir.o:	fproc.h
-stadir.o:	fs.h
-stadir.o:	glo.h
-stadir.o:	inode.h
-stadir.o:	param.h
-stadir.o:	proto.h
-stadir.o:	stadir.c
-stadir.o:	super.h
-stadir.o:	type.h
-
-super.o:	/usr/include/ansi.h
-super.o:	/usr/include/dirent.h
-super.o:	/usr/include/errno.h
-super.o:	/usr/include/limits.h
-super.o:	/usr/include/minix/com.h
-super.o:	/usr/include/minix/config.h
-super.o:	/usr/include/minix/const.h
-super.o:	/usr/include/minix/devio.h
-super.o:	/usr/include/minix/dmap.h
-super.o:	/usr/include/minix/ipc.h
-super.o:	/usr/include/minix/sys_config.h
-super.o:	/usr/include/minix/syslib.h
-super.o:	/usr/include/minix/sysutil.h
-super.o:	/usr/include/minix/type.h
-super.o:	/usr/include/string.h
-super.o:	/usr/include/sys/dir.h
-super.o:	/usr/include/sys/types.h
-super.o:	/usr/include/timers.h
-super.o:	buf.h
-super.o:	const.h
-super.o:	fs.h
-super.o:	glo.h
-super.o:	inode.h
-super.o:	proto.h
-super.o:	super.c
-super.o:	super.h
-super.o:	type.h
-
-table.o:	/usr/include/ansi.h
-table.o:	/usr/include/dirent.h
-table.o:	/usr/include/errno.h
-table.o:	/usr/include/limits.h
-table.o:	/usr/include/minix/callnr.h
-table.o:	/usr/include/minix/com.h
-table.o:	/usr/include/minix/config.h
-table.o:	/usr/include/minix/const.h
-table.o:	/usr/include/minix/devio.h
-table.o:	/usr/include/minix/dmap.h
-table.o:	/usr/include/minix/ipc.h
-table.o:	/usr/include/minix/sys_config.h
-table.o:	/usr/include/minix/syslib.h
-table.o:	/usr/include/minix/sysutil.h
-table.o:	/usr/include/minix/type.h
-table.o:	/usr/include/string.h
-table.o:	/usr/include/sys/dir.h
-table.o:	/usr/include/sys/select.h
-table.o:	/usr/include/sys/time.h
-table.o:	/usr/include/sys/types.h
-table.o:	/usr/include/timers.h
-table.o:	buf.h
-table.o:	const.h
-table.o:	file.h
-table.o:	fproc.h
-table.o:	fs.h
-table.o:	glo.h
-table.o:	inode.h
-table.o:	lock.h
-table.o:	proto.h
-table.o:	super.h
-table.o:	table.c
-table.o:	type.h
-
-time.o:	/usr/include/ansi.h
-time.o:	/usr/include/errno.h
-time.o:	/usr/include/limits.h
-time.o:	/usr/include/minix/callnr.h
-time.o:	/usr/include/minix/com.h
-time.o:	/usr/include/minix/config.h
-time.o:	/usr/include/minix/const.h
-time.o:	/usr/include/minix/devio.h
-time.o:	/usr/include/minix/dmap.h
-time.o:	/usr/include/minix/ipc.h
-time.o:	/usr/include/minix/sys_config.h
-time.o:	/usr/include/minix/syslib.h
-time.o:	/usr/include/minix/sysutil.h
-time.o:	/usr/include/minix/type.h
-time.o:	/usr/include/string.h
-time.o:	/usr/include/sys/dir.h
-time.o:	/usr/include/sys/select.h
-time.o:	/usr/include/sys/time.h
-time.o:	/usr/include/sys/types.h
-time.o:	/usr/include/timers.h
-time.o:	const.h
-time.o:	file.h
-time.o:	fproc.h
-time.o:	fs.h
-time.o:	glo.h
-time.o:	inode.h
-time.o:	param.h
-time.o:	proto.h
-time.o:	time.c
-time.o:	type.h
-
-timers.o:	/usr/include/ansi.h
-timers.o:	/usr/include/errno.h
-timers.o:	/usr/include/limits.h
-timers.o:	/usr/include/minix/com.h
-timers.o:	/usr/include/minix/config.h
-timers.o:	/usr/include/minix/const.h
-timers.o:	/usr/include/minix/devio.h
-timers.o:	/usr/include/minix/dmap.h
-timers.o:	/usr/include/minix/ipc.h
-timers.o:	/usr/include/minix/sys_config.h
-timers.o:	/usr/include/minix/syslib.h
-timers.o:	/usr/include/minix/sysutil.h
-timers.o:	/usr/include/minix/type.h
-timers.o:	/usr/include/sys/dir.h
-timers.o:	/usr/include/sys/types.h
-timers.o:	/usr/include/timers.h
-timers.o:	const.h
-timers.o:	fs.h
-timers.o:	glo.h
-timers.o:	proto.h
-timers.o:	timers.c
-timers.o:	type.h
-
-utility.o:	/usr/include/ansi.h
-utility.o:	/usr/include/dirent.h
-utility.o:	/usr/include/errno.h
-utility.o:	/usr/include/limits.h
-utility.o:	/usr/include/minix/com.h
-utility.o:	/usr/include/minix/config.h
-utility.o:	/usr/include/minix/const.h
-utility.o:	/usr/include/minix/devio.h
-utility.o:	/usr/include/minix/dmap.h
-utility.o:	/usr/include/minix/endpoint.h
-utility.o:	/usr/include/minix/ipc.h
-utility.o:	/usr/include/minix/sys_config.h
-utility.o:	/usr/include/minix/syslib.h
-utility.o:	/usr/include/minix/sysutil.h
-utility.o:	/usr/include/minix/type.h
-utility.o:	/usr/include/string.h
-utility.o:	/usr/include/sys/dir.h
-utility.o:	/usr/include/sys/select.h
-utility.o:	/usr/include/sys/time.h
-utility.o:	/usr/include/sys/types.h
-utility.o:	/usr/include/timers.h
-utility.o:	/usr/include/unistd.h
-utility.o:	buf.h
-utility.o:	const.h
-utility.o:	file.h
-utility.o:	fproc.h
-utility.o:	fs.h
-utility.o:	glo.h
-utility.o:	inode.h
-utility.o:	param.h
-utility.o:	proto.h
-utility.o:	type.h
-utility.o:	utility.c
-
-write.o:	/usr/include/ansi.h
-write.o:	/usr/include/dirent.h
-write.o:	/usr/include/errno.h
-write.o:	/usr/include/limits.h
-write.o:	/usr/include/minix/config.h
-write.o:	/usr/include/minix/const.h
-write.o:	/usr/include/minix/devio.h
-write.o:	/usr/include/minix/dmap.h
-write.o:	/usr/include/minix/ipc.h
-write.o:	/usr/include/minix/sys_config.h
-write.o:	/usr/include/minix/syslib.h
-write.o:	/usr/include/minix/sysutil.h
-write.o:	/usr/include/minix/type.h
-write.o:	/usr/include/string.h
-write.o:	/usr/include/sys/dir.h
-write.o:	/usr/include/sys/select.h
-write.o:	/usr/include/sys/time.h
-write.o:	/usr/include/sys/types.h
-write.o:	/usr/include/timers.h
-write.o:	buf.h
-write.o:	const.h
-write.o:	file.h
-write.o:	fproc.h
-write.o:	fs.h
-write.o:	glo.h
-write.o:	inode.h
-write.o:	proto.h
-write.o:	super.h
-write.o:	type.h
-write.o:	write.c
Index: trunk/minix/servers/fs/Makefile
===================================================================
--- trunk/minix/servers/fs/Makefile	(revision 11)
+++ 	(revision )
@@ -1,35 +1,0 @@
-# Makefile for File System (FS)
-SERVER = fs
-
-# directories
-u = /usr
-i = $u/include
-s = $i/sys
-h = $i/minix
-
-# programs, flags, etc.
-CC =	exec cc
-CFLAGS = -I$i $(EXTRA_OPTS)
-LDFLAGS = -i
-LIBS = -lsys -lsysutil -ltimers
-
-OBJ =	main.o open.o read.o write.o pipe.o dmap.o \
-	device.o path.o mount.o link.o super.o inode.o \
-	cache.o cache2.o filedes.o stadir.o protect.o time.o \
-	lock.o misc.o utility.o select.o timers.o table.o
-
-# build local binary 
-install all build:	$(SERVER)
-$(SERVER):	$(OBJ)
-	$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
-	install -S 512w $@
-
-# clean up local files
-clean:
-	rm -f $(SERVER) *.o *.bak 
-
-depend: 
-	/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
-
-# Include generated dependencies.
-include .depend
Index: trunk/minix/servers/fs/buf.h
===================================================================
--- trunk/minix/servers/fs/buf.h	(revision 11)
+++ 	(revision )
@@ -1,75 +1,0 @@
-/* Buffer (block) cache.  To acquire a block, a routine calls get_block(),
- * telling which block it wants.  The block is then regarded as "in use"
- * and has its 'b_count' field incremented.  All the blocks that are not
- * in use are chained together in an LRU list, with 'front' pointing
- * to the least recently used block, and 'rear' to the most recently used
- * block.  A reverse chain, using the field b_prev is also maintained.
- * Usage for LRU is measured by the time the put_block() is done.  The second
- * parameter to put_block() can violate the LRU order and put a block on the
- * front of the list, if it will probably not be needed soon.  If a block
- * is modified, the modifying routine must set b_dirt to DIRTY, so the block
- * will eventually be rewritten to the disk.
- */
-
-#include <sys/dir.h>			/* need struct direct */
-#include <dirent.h>
-
-EXTERN struct buf {
-  /* Data portion of the buffer. */
-  union {
-    char b__data[_MAX_BLOCK_SIZE];		     /* ordinary user data */
-/* directory block */
-    struct direct b__dir[NR_DIR_ENTRIES(_MAX_BLOCK_SIZE)];    
-/* V1 indirect block */
-    zone1_t b__v1_ind[V1_INDIRECTS];	     
-/* V2 indirect block */
-    zone_t  b__v2_ind[V2_INDIRECTS(_MAX_BLOCK_SIZE)];	     
-/* V1 inode block */
-    d1_inode b__v1_ino[V1_INODES_PER_BLOCK]; 
-/* V2 inode block */
-    d2_inode b__v2_ino[V2_INODES_PER_BLOCK(_MAX_BLOCK_SIZE)]; 
-/* bit map block */
-    bitchunk_t b__bitmap[FS_BITMAP_CHUNKS(_MAX_BLOCK_SIZE)];  
-  } b;
-
-  /* Header portion of the buffer. */
-  struct buf *b_next;		/* used to link all free bufs in a chain */
-  struct buf *b_prev;		/* used to link all free bufs the other way */
-  struct buf *b_hash;		/* used to link bufs on hash chains */
-  block_t b_blocknr;		/* block number of its (minor) device */
-  dev_t b_dev;			/* major | minor device where block resides */
-  char b_dirt;			/* CLEAN or DIRTY */
-  char b_count;			/* number of users of this buffer */
-} buf[NR_BUFS];
-
-/* A block is free if b_dev == NO_DEV. */
-
-#define NIL_BUF ((struct buf *) 0)	/* indicates absence of a buffer */
-
-/* These defs make it possible to use to bp->b_data instead of bp->b.b__data */
-#define b_data   b.b__data
-#define b_dir    b.b__dir
-#define b_v1_ind b.b__v1_ind
-#define b_v2_ind b.b__v2_ind
-#define b_v1_ino b.b__v1_ino
-#define b_v2_ino b.b__v2_ino
-#define b_bitmap b.b__bitmap
-
-EXTERN struct buf *buf_hash[NR_BUF_HASH];	/* the buffer hash table */
-
-EXTERN struct buf *front;	/* points to least recently used free block */
-EXTERN struct buf *rear;	/* points to most recently used free block */
-EXTERN int bufs_in_use;		/* # bufs currently in use (not on free list)*/
-
-/* When a block is released, the type of usage is passed to put_block(). */
-#define WRITE_IMMED   0100 /* block should be written to disk now */
-#define ONE_SHOT      0200 /* set if block not likely to be needed soon */
-
-#define INODE_BLOCK        0				 /* inode block */
-#define DIRECTORY_BLOCK    1				 /* directory block */
-#define INDIRECT_BLOCK     2				 /* pointer block */
-#define MAP_BLOCK          3				 /* bit map */
-#define FULL_DATA_BLOCK    5		 	 	 /* data, fully used */
-#define PARTIAL_DATA_BLOCK 6 				 /* data, partly used*/
-
-#define HASH_MASK (NR_BUF_HASH - 1)	/* mask for hashing block numbers */
Index: trunk/minix/servers/fs/cache.c
===================================================================
--- trunk/minix/servers/fs/cache.c	(revision 11)
+++ 	(revision )
@@ -1,444 +1,0 @@
-/* The file system maintains a buffer cache to reduce the number of disk
- * accesses needed.  Whenever a read or write to the disk is done, a check is
- * first made to see if the block is in the cache.  This file manages the
- * cache.
- *
- * The entry points into this file are:
- *   get_block:	  request to fetch a block for reading or writing from cache
- *   put_block:	  return a block previously requested with get_block
- *   alloc_zone:  allocate a new zone (to increase the length of a file)
- *   free_zone:	  release a zone (when a file is removed)
- *   invalidate:  remove all the cache blocks on some device
- *
- * Private functions:
- *   rw_block:    read or write a block from the disk itself
- */
-
-#include "fs.h"
-#include <minix/com.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "super.h"
-
-FORWARD _PROTOTYPE( void rm_lru, (struct buf *bp) );
-FORWARD _PROTOTYPE( int rw_block, (struct buf *, int) );
-
-/*===========================================================================*
- *				get_block				     *
- *===========================================================================*/
-PUBLIC struct buf *get_block(dev, block, only_search)
-register dev_t dev;		/* on which device is the block? */
-register block_t block;		/* which block is wanted? */
-int only_search;		/* if NO_READ, don't read, else act normal */
-{
-/* Check to see if the requested block is in the block cache.  If so, return
- * a pointer to it.  If not, evict some other block and fetch it (unless
- * 'only_search' is 1).  All the blocks in the cache that are not in use
- * are linked together in a chain, with 'front' pointing to the least recently
- * used block and 'rear' to the most recently used block.  If 'only_search' is
- * 1, the block being requested will be overwritten in its entirety, so it is
- * only necessary to see if it is in the cache; if it is not, any free buffer
- * will do.  It is not necessary to actually read the block in from disk.
- * If 'only_search' is PREFETCH, the block need not be read from the disk,
- * and the device is not to be marked on the block, so callers can tell if
- * the block returned is valid.
- * In addition to the LRU chain, there is also a hash chain to link together
- * blocks whose block numbers end with the same bit strings, for fast lookup.
- */
-
-  int b;
-  register struct buf *bp, *prev_ptr;
-
-  /* Search the hash chain for (dev, block). Do_read() can use 
-   * get_block(NO_DEV ...) to get an unnamed block to fill with zeros when
-   * someone wants to read from a hole in a file, in which case this search
-   * is skipped
-   */
-  if (dev != NO_DEV) {
-	b = (int) block & HASH_MASK;
-	bp = buf_hash[b];
-	while (bp != NIL_BUF) {
-		if (bp->b_blocknr == block && bp->b_dev == dev) {
-			/* Block needed has been found. */
-			if (bp->b_count == 0) rm_lru(bp);
-			bp->b_count++;	/* record that block is in use */
-
-			return(bp);
-		} else {
-			/* This block is not the one sought. */
-			bp = bp->b_hash; /* move to next block on hash chain */
-		}
-	}
-  }
-
-  /* Desired block is not on available chain.  Take oldest block ('front'). */
-  if ((bp = front) == NIL_BUF) panic(__FILE__,"all buffers in use", NR_BUFS);
-  rm_lru(bp);
-
-  /* Remove the block that was just taken from its hash chain. */
-  b = (int) bp->b_blocknr & HASH_MASK;
-  prev_ptr = buf_hash[b];
-  if (prev_ptr == bp) {
-	buf_hash[b] = bp->b_hash;
-  } else {
-	/* The block just taken is not on the front of its hash chain. */
-	while (prev_ptr->b_hash != NIL_BUF)
-		if (prev_ptr->b_hash == bp) {
-			prev_ptr->b_hash = bp->b_hash;	/* found it */
-			break;
-		} else {
-			prev_ptr = prev_ptr->b_hash;	/* keep looking */
-		}
-  }
-
-  /* If the block taken is dirty, make it clean by writing it to the disk.
-   * Avoid hysteresis by flushing all other dirty blocks for the same device.
-   */
-  if (bp->b_dev != NO_DEV) {
-	if (bp->b_dirt == DIRTY) flushall(bp->b_dev);
-#if ENABLE_CACHE2
-	put_block2(bp);
-#endif
-  }
-
-  /* Fill in block's parameters and add it to the hash chain where it goes. */
-  bp->b_dev = dev;		/* fill in device number */
-  bp->b_blocknr = block;	/* fill in block number */
-  bp->b_count++;		/* record that block is being used */
-  b = (int) bp->b_blocknr & HASH_MASK;
-  bp->b_hash = buf_hash[b];
-  buf_hash[b] = bp;		/* add to hash list */
-
-  /* Go get the requested block unless searching or prefetching. */
-  if (dev != NO_DEV) {
-#if ENABLE_CACHE2
-	if (get_block2(bp, only_search)) /* in 2nd level cache */;
-	else
-#endif
-	if (only_search == PREFETCH) bp->b_dev = NO_DEV;
-	else
-	if (only_search == NORMAL) {
-		rw_block(bp, READING);
-	}
-  }
-  return(bp);			/* return the newly acquired block */
-}
-
-/*===========================================================================*
- *				put_block				     *
- *===========================================================================*/
-PUBLIC void put_block(bp, block_type)
-register struct buf *bp;	/* pointer to the buffer to be released */
-int block_type;			/* INODE_BLOCK, DIRECTORY_BLOCK, or whatever */
-{
-/* Return a block to the list of available blocks.   Depending on 'block_type'
- * it may be put on the front or rear of the LRU chain.  Blocks that are
- * expected to be needed again shortly (e.g., partially full data blocks)
- * go on the rear; blocks that are unlikely to be needed again shortly
- * (e.g., full data blocks) go on the front.  Blocks whose loss can hurt
- * the integrity of the file system (e.g., inode blocks) are written to
- * disk immediately if they are dirty.
- */
-  if (bp == NIL_BUF) return;	/* it is easier to check here than in caller */
-
-  bp->b_count--;		/* there is one use fewer now */
-  if (bp->b_count != 0) return;	/* block is still in use */
-
-  bufs_in_use--;		/* one fewer block buffers in use */
-
-  /* Put this block back on the LRU chain.  If the ONE_SHOT bit is set in
-   * 'block_type', the block is not likely to be needed again shortly, so put
-   * it on the front of the LRU chain where it will be the first one to be
-   * taken when a free buffer is needed later.
-   */
-  if (bp->b_dev == DEV_RAM || (block_type & ONE_SHOT)) {
-	/* Block probably won't be needed quickly. Put it on front of chain.
-  	 * It will be the next block to be evicted from the cache.
-  	 */
-	bp->b_prev = NIL_BUF;
-	bp->b_next = front;
-	if (front == NIL_BUF)
-		rear = bp;	/* LRU chain was empty */
-	else
-		front->b_prev = bp;
-	front = bp;
-  } else {
-	/* Block probably will be needed quickly.  Put it on rear of chain.
-  	 * It will not be evicted from the cache for a long time.
-  	 */
-	bp->b_prev = rear;
-	bp->b_next = NIL_BUF;
-	if (rear == NIL_BUF)
-		front = bp;
-	else
-		rear->b_next = bp;
-	rear = bp;
-  }
-
-  /* Some blocks are so important (e.g., inodes, indirect blocks) that they
-   * should be written to the disk immediately to avoid messing up the file
-   * system in the event of a crash.
-   */
-  if ((block_type & WRITE_IMMED) && bp->b_dirt==DIRTY && bp->b_dev != NO_DEV) {
-		rw_block(bp, WRITING);
-  } 
-}
-
-/*===========================================================================*
- *				alloc_zone				     *
- *===========================================================================*/
-PUBLIC zone_t alloc_zone(dev, z)
-dev_t dev;			/* device where zone wanted */
-zone_t z;			/* try to allocate new zone near this one */
-{
-/* Allocate a new zone on the indicated device and return its number. */
-
-  int major, minor;
-  bit_t b, bit;
-  struct super_block *sp;
-
-  /* Note that the routine alloc_bit() returns 1 for the lowest possible
-   * zone, which corresponds to sp->s_firstdatazone.  To convert a value
-   * between the bit number, 'b', used by alloc_bit() and the zone number, 'z',
-   * stored in the inode, use the formula:
-   *     z = b + sp->s_firstdatazone - 1
-   * Alloc_bit() never returns 0, since this is used for NO_BIT (failure).
-   */
-  sp = get_super(dev);
-
-  /* If z is 0, skip initial part of the map known to be fully in use. */
-  if (z == sp->s_firstdatazone) {
-	bit = sp->s_zsearch;
-  } else {
-	bit = (bit_t) z - (sp->s_firstdatazone - 1);
-  }
-  b = alloc_bit(sp, ZMAP, bit);
-  if (b == NO_BIT) {
-	err_code = ENOSPC;
-	major = (int) (sp->s_dev >> MAJOR) & BYTE;
-	minor = (int) (sp->s_dev >> MINOR) & BYTE;
-	printf("No space on %sdevice %d/%d\n",
-		sp->s_dev == root_dev ? "root " : "", major, minor);
-	return(NO_ZONE);
-  }
-  if (z == sp->s_firstdatazone) sp->s_zsearch = b;	/* for next time */
-  return(sp->s_firstdatazone - 1 + (zone_t) b);
-}
-
-/*===========================================================================*
- *				free_zone				     *
- *===========================================================================*/
-PUBLIC void free_zone(dev, numb)
-dev_t dev;				/* device where zone located */
-zone_t numb;				/* zone to be returned */
-{
-/* Return a zone. */
-
-  register struct super_block *sp;
-  bit_t bit;
-
-  /* Locate the appropriate super_block and return bit. */
-  sp = get_super(dev);
-  if (numb < sp->s_firstdatazone || numb >= sp->s_zones) return;
-  bit = (bit_t) (numb - (sp->s_firstdatazone - 1));
-  free_bit(sp, ZMAP, bit);
-  if (bit < sp->s_zsearch) sp->s_zsearch = bit;
-}
-
-/*===========================================================================*
- *				rw_block				     *
- *===========================================================================*/
-PRIVATE int rw_block(bp, rw_flag)
-register struct buf *bp;	/* buffer pointer */
-int rw_flag;			/* READING or WRITING */
-{
-/* Read or write a disk block. This is the only routine in which actual disk
- * I/O is invoked. If an error occurs, a message is printed here, but the error
- * is not reported to the caller.  If the error occurred while purging a block
- * from the cache, it is not clear what the caller could do about it anyway.
- */
-
-  int r, op;
-  off_t pos;
-  dev_t dev;
-  int block_size;
-
-  block_size = get_block_size(bp->b_dev);
-
-  if ( (dev = bp->b_dev) != NO_DEV) {
-	pos = (off_t) bp->b_blocknr * block_size;
-	op = (rw_flag == READING ? DEV_READ : DEV_WRITE);
-	r = dev_io(op, dev, FS_PROC_NR, bp->b_data, pos, block_size, 0);
-	if (r != block_size) {
-	    if (r >= 0) r = END_OF_FILE;
-	    if (r != END_OF_FILE)
-	      printf("Unrecoverable disk error on device %d/%d, block %ld\n",
-			(dev>>MAJOR)&BYTE, (dev>>MINOR)&BYTE, bp->b_blocknr);
-		bp->b_dev = NO_DEV;	/* invalidate block */
-
-		/* Report read errors to interested parties. */
-		if (rw_flag == READING) rdwt_err = r;
-	}
-  }
-
-  bp->b_dirt = CLEAN;
-
-  return OK;
-}
-
-/*===========================================================================*
- *				invalidate				     *
- *===========================================================================*/
-PUBLIC void invalidate(device)
-dev_t device;			/* device whose blocks are to be purged */
-{
-/* Remove all the blocks belonging to some device from the cache. */
-
-  register struct buf *bp;
-
-  for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++)
-	if (bp->b_dev == device) bp->b_dev = NO_DEV;
-
-#if ENABLE_CACHE2
-  invalidate2(device);
-#endif
-}
-
-/*===========================================================================*
- *				flushall				     *
- *===========================================================================*/
-PUBLIC void flushall(dev)
-dev_t dev;			/* device to flush */
-{
-/* Flush all dirty blocks for one device. */
-
-  register struct buf *bp;
-  static struct buf *dirty[NR_BUFS];	/* static so it isn't on stack */
-  int ndirty;
-
-  for (bp = &buf[0], ndirty = 0; bp < &buf[NR_BUFS]; bp++)
-	if (bp->b_dirt == DIRTY && bp->b_dev == dev) dirty[ndirty++] = bp;
-  rw_scattered(dev, dirty, ndirty, WRITING);
-}
-
-/*===========================================================================*
- *				rw_scattered				     *
- *===========================================================================*/
-PUBLIC void rw_scattered(dev, bufq, bufqsize, rw_flag)
-dev_t dev;			/* major-minor device number */
-struct buf **bufq;		/* pointer to array of buffers */
-int bufqsize;			/* number of buffers */
-int rw_flag;			/* READING or WRITING */
-{
-/* Read or write scattered data from a device. */
-
-  register struct buf *bp;
-  int gap;
-  register int i;
-  register iovec_t *iop;
-  static iovec_t iovec[NR_IOREQS];  /* static so it isn't on stack */
-  int j, r;
-  int block_size;
-
-  block_size = get_block_size(dev);
-
-  /* (Shell) sort buffers on b_blocknr. */
-  gap = 1;
-  do
-	gap = 3 * gap + 1;
-  while (gap <= bufqsize);
-  while (gap != 1) {
-	gap /= 3;
-	for (j = gap; j < bufqsize; j++) {
-		for (i = j - gap;
-		     i >= 0 && bufq[i]->b_blocknr > bufq[i + gap]->b_blocknr;
-		     i -= gap) {
-			bp = bufq[i];
-			bufq[i] = bufq[i + gap];
-			bufq[i + gap] = bp;
-		}
-	}
-  }
-
-  /* Set up I/O vector and do I/O.  The result of dev_io is OK if everything
-   * went fine, otherwise the error code for the first failed transfer.
-   */  
-  while (bufqsize > 0) {
-	for (j = 0, iop = iovec; j < NR_IOREQS && j < bufqsize; j++, iop++) {
-		bp = bufq[j];
-		if (bp->b_blocknr != bufq[0]->b_blocknr + j) break;
-		iop->iov_addr = (vir_bytes) bp->b_data;
-		iop->iov_size = block_size;
-	}
-	r = dev_io(rw_flag == WRITING ? DEV_SCATTER : DEV_GATHER,
-		dev, FS_PROC_NR, iovec,
-		(off_t) bufq[0]->b_blocknr * block_size, j, 0);
-
-	/* Harvest the results.  Dev_io reports the first error it may have
-	 * encountered, but we only care if it's the first block that failed.
-	 */
-	for (i = 0, iop = iovec; i < j; i++, iop++) {
-		bp = bufq[i];
-		if (iop->iov_size != 0) {
-			/* Transfer failed. An error? Do we care? */
-			if (r != OK && i == 0) {
-				printf(
-				"fs: I/O error on device %d/%d, block %lu\n",
-					(dev>>MAJOR)&BYTE, (dev>>MINOR)&BYTE,
-					bp->b_blocknr);
-				bp->b_dev = NO_DEV;	/* invalidate block */
-			}
-			break;
-		}
-		if (rw_flag == READING) {
-			bp->b_dev = dev;	/* validate block */
-			put_block(bp, PARTIAL_DATA_BLOCK);
-		} else {
-			bp->b_dirt = CLEAN;
-		}
-	}
-	bufq += i;
-	bufqsize -= i;
-	if (rw_flag == READING) {
-		/* Don't bother reading more than the device is willing to
-		 * give at this time.  Don't forget to release those extras.
-		 */
-		while (bufqsize > 0) {
-			put_block(*bufq++, PARTIAL_DATA_BLOCK);
-			bufqsize--;
-		}
-	}
-	if (rw_flag == WRITING && i == 0) {
-		/* We're not making progress, this means we might keep
-		 * looping. Buffers remain dirty if un-written. Buffers are
-		 * lost if invalidate()d or LRU-removed while dirty. This
-		 * is better than keeping unwritable blocks around forever..
-		 */
-		break;
-	}
-  }
-}
-
-/*===========================================================================*
- *				rm_lru					     *
- *===========================================================================*/
-PRIVATE void rm_lru(bp)
-struct buf *bp;
-{
-/* Remove a block from its LRU chain. */
-  struct buf *next_ptr, *prev_ptr;
-
-  bufs_in_use++;
-  next_ptr = bp->b_next;	/* successor on LRU chain */
-  prev_ptr = bp->b_prev;	/* predecessor on LRU chain */
-  if (prev_ptr != NIL_BUF)
-	prev_ptr->b_next = next_ptr;
-  else
-	front = next_ptr;	/* this block was at front of chain */
-
-  if (next_ptr != NIL_BUF)
-	next_ptr->b_prev = prev_ptr;
-  else
-	rear = prev_ptr;	/* this block was at rear of chain */
-}
Index: trunk/minix/servers/fs/cache2.c
===================================================================
--- trunk/minix/servers/fs/cache2.c	(revision 11)
+++ 	(revision )
@@ -1,126 +1,0 @@
-/* Second level block cache to supplement the file system cache.  The block
- * cache of a 16-bit Minix system is very small, too small to prevent trashing.
- * A generic 32-bit system also doesn't have a very large cache to allow it
- * to run on systems with little memory.  On a system with lots of memory one
- * can use the RAM disk as a read-only second level cache.  Any blocks pushed
- * out of the primary cache are cached on the RAM disk.  This code manages the
- * second level cache.  The cache is a simple FIFO where old blocks are put
- * into and drop out at the other end.  Must be searched backwards.
- *
- * The entry points into this file are:
- *   init_cache2: initialize the second level cache
- *   get_block2:  get a block from the 2nd level cache
- *   put_block2:  store a block in the 2nd level cache
- *   invalidate2: remove all the cache blocks on some device
- */
-
-#include "fs.h"
-#include <minix/com.h>
-#include "buf.h"
-
-#if ENABLE_CACHE2
-
-#define MAX_BUF2	(256 * sizeof(char *))
-
-PRIVATE struct buf2 {	/* 2nd level cache per block administration */
-  block_t b2_blocknr;		/* block number */
-  dev_t b2_dev;			/* device number */
-  u16_t b2_count;		/* count of in-cache block groups */
-} buf2[MAX_BUF2];
-
-PRIVATE unsigned nr_buf2;		/* actual cache size */
-PRIVATE unsigned buf2_idx;		/* round-robin reuse index */
-
-#define hash2(block)	((unsigned) ((block) & (MAX_BUF2 - 1)))
-
-/*===========================================================================*
- *				init_cache2				     *
- *===========================================================================*/
-PUBLIC void init_cache2(size)
-unsigned long size;
-{
-/* Initialize the second level disk buffer cache of 'size' blocks. */
-
-  nr_buf2 = size > MAX_BUF2 ? MAX_BUF2 : (unsigned) size;
-}
-
-/*===========================================================================*
- *				get_block2				     *
- *===========================================================================*/
-PUBLIC int get_block2(bp, only_search)
-struct buf *bp;			/* buffer to get from the 2nd level cache */
-int only_search;		/* if NO_READ, do nothing, else act normal */
-{
-/* Fill a buffer from the 2nd level cache.  Return true iff block acquired. */
-  unsigned b;
-  struct buf2 *bp2;
-
-  /* If the block wanted is in the RAM disk then our game is over. */
-  if (bp->b_dev == DEV_RAM) nr_buf2 = 0;
-
-  /* Cache enabled?  NO_READ?  Any blocks with the same hash key? */
-  if (nr_buf2 == 0 || only_search == NO_READ
-  			|| buf2[hash2(bp->b_blocknr)].b2_count == 0) return(0);
-
-  /* Search backwards (there may be older versions). */
-  b = buf2_idx;
-  for (;;) {
-	if (b == 0) b = nr_buf2;
-	bp2 = &buf2[--b];
-	if (bp2->b2_blocknr == bp->b_blocknr && bp2->b2_dev == bp->b_dev) break;
-	if (b == buf2_idx) return(0);
-  }
-
-  /* Block is in the cache, get it. */
-  if (dev_io(DEV_READ, DEV_RAM, FS_PROC_NR, bp->b_data,
-			(off_t) b * BLOCK_SIZE, BLOCK_SIZE, 0) == BLOCK_SIZE) {
-	return(1);
-  }
-  return(0);
-}
-
-/*===========================================================================*
- *				put_block2				     *
- *===========================================================================*/
-PUBLIC void put_block2(bp)
-struct buf *bp;			/* buffer to store in the 2nd level cache */
-{
-/* Store a buffer into the 2nd level cache. */
-  unsigned b;
-  struct buf2 *bp2;
-
-  if (nr_buf2 == 0) return;	/* no 2nd level cache */
-
-  b = buf2_idx++;
-  if (buf2_idx == nr_buf2) buf2_idx = 0;
-
-  bp2 = &buf2[b];
-
-  if (dev_io(DEV_WRITE, DEV_RAM, FS_PROC_NR, bp->b_data,
-			(off_t) b * BLOCK_SIZE, BLOCK_SIZE, 0) == BLOCK_SIZE) {
-	if (bp2->b2_dev != NO_DEV) buf2[hash2(bp2->b2_blocknr)].b2_count--;
-	bp2->b2_dev = bp->b_dev;
-	bp2->b2_blocknr = bp->b_blocknr;
-	buf2[hash2(bp2->b2_blocknr)].b2_count++;
-  }
-}
-
-/*===========================================================================*
- *				invalidate2				     *
- *===========================================================================*/
-PUBLIC void invalidate2(device)
-dev_t device;
-{
-/* Invalidate all blocks from a given device in the 2nd level cache. */
-  unsigned b;
-  struct buf2 *bp2;
-
-  for (b = 0; b < nr_buf2; b++) {
-	bp2 = &buf2[b];
-	if (bp2->b2_dev == device) {
-		bp2->b2_dev = NO_DEV;
-		buf2[hash2(bp2->b2_blocknr)].b2_count--;
-	}
-  }
-}
-#endif /* ENABLE_CACHE2 */
Index: trunk/minix/servers/fs/const.h
===================================================================
--- trunk/minix/servers/fs/const.h	(revision 11)
+++ 	(revision )
@@ -1,105 +1,0 @@
-/* Tables sizes */
-#define V1_NR_DZONES       7	/* # direct zone numbers in a V1 inode */
-#define V1_NR_TZONES       9	/* total # zone numbers in a V1 inode */
-#define V2_NR_DZONES       7	/* # direct zone numbers in a V2 inode */
-#define V2_NR_TZONES      10	/* total # zone numbers in a V2 inode */
-
-#define NR_FILPS         256	/* # slots in filp table */
-#define NR_INODES        256	/* # slots in "in core" inode table */
-#define NR_SUPERS         12	/* # slots in super block table */
-#define NR_LOCKS           8	/* # slots in the file locking table */
-
-/* The type of sizeof may be (unsigned) long.  Use the following macro for
- * taking the sizes of small objects so that there are no surprises like
- * (small) long constants being passed to routines expecting an int.
- */
-#define usizeof(t) ((unsigned) sizeof(t))
-
-/* File system types. */
-#define SUPER_MAGIC   0x137F	/* magic number contained in super-block */
-#define SUPER_REV     0x7F13	/* magic # when 68000 disk read on PC or vv */
-#define SUPER_V2      0x2468	/* magic # for V2 file systems */
-#define SUPER_V2_REV  0x6824	/* V2 magic written on PC, read on 68K or vv */
-#define SUPER_V3      0x4d5a	/* magic # for V3 file systems */
-
-#define V1		   1	/* version number of V1 file systems */ 
-#define V2		   2	/* version number of V2 file systems */ 
-#define V3		   3	/* version number of V3 file systems */ 
-
-/* Miscellaneous constants */
-#define SU_UID 	 ((uid_t) 0)	/* super_user's uid_t */
-#define SERVERS_UID ((uid_t) 11) /* who may do FSSIGNON */
-#define SYS_UID  ((uid_t) 0)	/* uid_t for processes MM and INIT */
-#define SYS_GID  ((gid_t) 0)	/* gid_t for processes MM and INIT */
-#define NORMAL	           0	/* forces get_block to do disk read */
-#define NO_READ            1	/* prevents get_block from doing disk read */
-#define PREFETCH           2	/* tells get_block not to read or mark dev */
-
-#define XPIPE   (-NR_TASKS-1)	/* used in fp_task when susp'd on pipe */
-#define XLOCK   (-NR_TASKS-2)	/* used in fp_task when susp'd on lock */
-#define XPOPEN  (-NR_TASKS-3)	/* used in fp_task when susp'd on pipe open */
-#define XSELECT (-NR_TASKS-4)	/* used in fp_task when susp'd on select */
-
-#define NO_BIT   ((bit_t) 0)	/* returned by alloc_bit() to signal failure */
-
-#define DUP_MASK        0100	/* mask to distinguish dup2 from dup */
-
-#define LOOK_UP            0 /* tells search_dir to lookup string */
-#define ENTER              1 /* tells search_dir to make dir entry */
-#define DELETE             2 /* tells search_dir to delete entry */
-#define IS_EMPTY           3 /* tells search_dir to ret. OK or ENOTEMPTY */  
-
-/* write_map() args */
-#define WMAP_FREE	(1 << 0)
-
-#define PATH_TRANSPARENT 000   /* parse_path stops at final object */
-#define PATH_PENULTIMATE 001   /* parse_path stops at last but one name */
-#define PATH_OPAQUE      002   /* parse_path stops at final name */
-#define PATH_NONSYMBOLIC 004   /* parse_path scans final name if symbolic */
-#define PATH_STRIPDOT    010   /* parse_path strips /. from path */
-#define EAT_PATH         PATH_TRANSPARENT
-#define EAT_PATH_OPAQUE  PATH_OPAQUE 
-#define LAST_DIR         PATH_PENULTIMATE
-#define LAST_DIR_NOTDOT  PATH_PENULTIMATE | PATH_STRIPDOT
-#define LAST_DIR_EATSYM  PATH_NONSYMBOLIC
-#define SYMLOOP		16
-
-#define CLEAN              0	/* disk and memory copies identical */
-#define DIRTY              1	/* disk and memory copies differ */
-#define ATIME            002	/* set if atime field needs updating */
-#define CTIME            004	/* set if ctime field needs updating */
-#define MTIME            010	/* set if mtime field needs updating */
-
-#define BYTE_SWAP          0	/* tells conv2/conv4 to swap bytes */
-
-#define END_OF_FILE   (-104)	/* eof detected */
-
-#define ROOT_INODE         1		/* inode number for root directory */
-#define BOOT_BLOCK  ((block_t) 0)	/* block number of boot block */
-#define SUPER_BLOCK_BYTES (1024)	/* bytes offset */
-#define START_BLOCK 	2		/* first block of FS (not counting SB) */
-
-#define DIR_ENTRY_SIZE       usizeof (struct direct)  /* # bytes/dir entry   */
-#define NR_DIR_ENTRIES(b)   ((b)/DIR_ENTRY_SIZE)  /* # dir entries/blk   */
-#define SUPER_SIZE      usizeof (struct super_block)  /* super_block size    */
-#define PIPE_SIZE(b)          (V1_NR_DZONES*(b))  /* pipe size in bytes  */
-
-#define FS_BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk   */
-#define FS_BITCHUNK_BITS		(usizeof(bitchunk_t) * CHAR_BIT)
-#define FS_BITS_PER_BLOCK(b)	(FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
-
-/* Derived sizes pertaining to the V1 file system. */
-#define V1_ZONE_NUM_SIZE           usizeof (zone1_t)  /* # bytes in V1 zone  */
-#define V1_INODE_SIZE             usizeof (d1_inode)  /* bytes in V1 dsk ino */
-
-/* # zones/indir block */
-#define V1_INDIRECTS (_STATIC_BLOCK_SIZE/V1_ZONE_NUM_SIZE)  
-
-/* # V1 dsk inodes/blk */
-#define V1_INODES_PER_BLOCK (_STATIC_BLOCK_SIZE/V1_INODE_SIZE)
-
-/* Derived sizes pertaining to the V2 file system. */
-#define V2_ZONE_NUM_SIZE            usizeof (zone_t)  /* # bytes in V2 zone  */
-#define V2_INODE_SIZE             usizeof (d2_inode)  /* bytes in V2 dsk ino */
-#define V2_INDIRECTS(b)   ((b)/V2_ZONE_NUM_SIZE)  /* # zones/indir block */
-#define V2_INODES_PER_BLOCK(b) ((b)/V2_INODE_SIZE)/* # V2 dsk inodes/blk */
Index: trunk/minix/servers/fs/device.c
===================================================================
--- trunk/minix/servers/fs/device.c	(revision 11)
+++ 	(revision )
@@ -1,630 +1,0 @@
-/* When a needed block is not in the cache, it must be fetched from the disk.
- * Special character files also require I/O.  The routines for these are here.
- *
- * The entry points in this file are:
- *   dev_open:   FS opens a device
- *   dev_close:  FS closes a device
- *   dev_io:	 FS does a read or write on a device
- *   dev_status: FS processes callback request alert
- *   gen_opcl:   generic call to a task to perform an open/close
- *   gen_io:     generic call to a task to perform an I/O operation
- *   no_dev:     open/close processing for devices that don't exist
- *   no_dev_io:  i/o processing for devices that don't exist
- *   tty_opcl:   perform tty-specific processing for open/close
- *   ctty_opcl:  perform controlling-tty-specific processing for open/close
- *   ctty_io:    perform controlling-tty-specific processing for I/O
- *   do_ioctl:	 perform the IOCTL system call
- *   do_setsid:	 perform the SETSID system call (FS side)
- */
-
-#include "fs.h"
-#include <fcntl.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/endpoint.h>
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-#define ELEMENTS(a) (sizeof(a)/sizeof((a)[0]))
-
-extern int dmap_size;
-PRIVATE int dummyproc;
-
-/*===========================================================================*
- *				dev_open				     *
- *===========================================================================*/
-PUBLIC int dev_open(dev, proc, flags)
-dev_t dev;			/* device to open */
-int proc;			/* process to open for */
-int flags;			/* mode bits and flags */
-{
-  int major, r;
-  struct dmap *dp;
-
-  /* Determine the major device number call the device class specific
-   * open/close routine.  (This is the only routine that must check the
-   * device number for being in range.  All others can trust this check.)
-   */
-  major = (dev >> MAJOR) & BYTE;
-  if (major >= NR_DEVICES) major = 0;
-  dp = &dmap[major];
-  if (dp->dmap_driver == NONE) 
-	return ENXIO;
-  r = (*dp->dmap_opcl)(DEV_OPEN, dev, proc, flags);
-  if (r == SUSPEND) panic(__FILE__,"suspend on open from", dp->dmap_driver);
-  return(r);
-}
-
-/*===========================================================================*
- *				dev_close				     *
- *===========================================================================*/
-PUBLIC void dev_close(dev)
-dev_t dev;			/* device to close */
-{
-  /* See if driver is roughly valid. */
-  if (dmap[(dev >> MAJOR)].dmap_driver == NONE) {
-	return;
-  }
-  (void) (*dmap[(dev >> MAJOR) & BYTE].dmap_opcl)(DEV_CLOSE, dev, 0, 0);
-}
-
-/*===========================================================================*
- *				dev_status					*
- *===========================================================================*/
-PUBLIC void dev_status(message *m)
-{
-	message st;
-	int d, get_more = 1;
-
-	for(d = 0; d < NR_DEVICES; d++)
-		if (dmap[d].dmap_driver != NONE &&
-		    dmap[d].dmap_driver == m->m_source)
-			break;
-
-	if (d >= NR_DEVICES)
-		return;
-
-	do {
-		int r;
-		st.m_type = DEV_STATUS;
-		if ((r=sendrec(m->m_source, &st)) != OK) {
-			printf("DEV_STATUS failed to %d: %d\n", m->m_source, r);
-			if (r == EDEADSRCDST) return;
-			if (r == EDSTDIED) return;
-			if (r == ESRCDIED) return;
-			panic(__FILE__,"couldn't sendrec for DEV_STATUS", r);
-		}
-
-		switch(st.m_type) {
-			case DEV_REVIVE:
-				revive(st.REP_ENDPT, st.REP_STATUS);
-				break;
-			case DEV_IO_READY:
-				select_notified(d, st.DEV_MINOR, st.DEV_SEL_OPS);
-				break;
-			default:
-				printf("FS: unrecognized reply %d to DEV_STATUS\n", st.m_type);
-				/* Fall through. */
-			case DEV_NO_STATUS:
-				get_more = 0;
-				break;
-		}
-	} while(get_more);
-
-	return;
-}
-
-/*===========================================================================*
- *				dev_io					     *
- *===========================================================================*/
-PUBLIC int dev_io(op, dev, proc_e, buf, pos, bytes, flags)
-int op;				/* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */
-dev_t dev;			/* major-minor device number */
-int proc_e;			/* in whose address space is buf? */
-void *buf;			/* virtual address of the buffer */
-off_t pos;			/* byte position */
-int bytes;			/* how many bytes to transfer */
-int flags;			/* special flags, like O_NONBLOCK */
-{
-/* Read or write from a device.  The parameter 'dev' tells which one. */
-  struct dmap *dp;
-  message dev_mess;
-
-  /* Determine task dmap. */
-  dp = &dmap[(dev >> MAJOR) & BYTE];
-
-  /* See if driver is roughly valid. */
-  if (dp->dmap_driver == NONE) {
-	printf("FS: dev_io: no driver for dev %x\n", dev);
-	return ENXIO;
-  }
-
-  if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
-	printf("FS: dev_io: old driver for dev %x (%d)\n",
-		dev, dp->dmap_driver);
-	return ENXIO;
-  }
-
-  /* Set up the message passed to task. */
-  dev_mess.m_type   = op;
-  dev_mess.DEVICE   = (dev >> MINOR) & BYTE;
-  dev_mess.POSITION = pos;
-  dev_mess.IO_ENDPT = proc_e;
-  dev_mess.ADDRESS  = buf;
-  dev_mess.COUNT    = bytes;
-  dev_mess.TTY_FLAGS = flags;
-
-  /* Call the task. */
-  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-
-  if(dp->dmap_driver == NONE) {
-  	/* Driver has vanished. */
-	return EIO;
-  }
-
-  /* Task has completed.  See if call completed. */
-  if (dev_mess.REP_STATUS == SUSPEND) {
-	if (flags & O_NONBLOCK) {
-		/* Not supposed to block. */
-		dev_mess.m_type = CANCEL;
-		dev_mess.IO_ENDPT = proc_e;
-		dev_mess.DEVICE = (dev >> MINOR) & BYTE;
-		(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-		if (dev_mess.REP_STATUS == EINTR) dev_mess.REP_STATUS = EAGAIN;
-	} else {
-		/* Suspend user. */
-		suspend(dp->dmap_driver);
-		return(SUSPEND);
-	}
-  }
-  return(dev_mess.REP_STATUS);
-}
-
-/*===========================================================================*
- *				gen_opcl				     *
- *===========================================================================*/
-PUBLIC int gen_opcl(op, dev, proc_e, flags)
-int op;				/* operation, DEV_OPEN or DEV_CLOSE */
-dev_t dev;			/* device to open or close */
-int proc_e;			/* process to open/close for */
-int flags;			/* mode bits and flags */
-{
-/* Called from the dmap struct in table.c on opens & closes of special files.*/
-  struct dmap *dp;
-  message dev_mess;
-
-  /* Determine task dmap. */
-  dp = &dmap[(dev >> MAJOR) & BYTE];
-
-  dev_mess.m_type   = op;
-  dev_mess.DEVICE   = (dev >> MINOR) & BYTE;
-  dev_mess.IO_ENDPT = proc_e;
-  dev_mess.COUNT    = flags;
-
-  if (dp->dmap_driver == NONE) {
-	printf("FS: gen_opcl: no driver for dev %x\n", dev);
-	return ENXIO;
-  }
-  if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
-	printf("FS: gen_opcl: old driver for dev %x (%d)\n",
-		dev, dp->dmap_driver);
-	return ENXIO;
-  }
-
-  /* Call the task. */
-  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-
-  return(dev_mess.REP_STATUS);
-}
-
-/*===========================================================================*
- *				tty_opcl				     *
- *===========================================================================*/
-PUBLIC int tty_opcl(op, dev, proc_e, flags)
-int op;				/* operation, DEV_OPEN or DEV_CLOSE */
-dev_t dev;			/* device to open or close */
-int proc_e;			/* process to open/close for */
-int flags;			/* mode bits and flags */
-{
-/* This procedure is called from the dmap struct on tty open/close. */
- 
-  int r;
-  register struct fproc *rfp;
-
-  /* Add O_NOCTTY to the flags if this process is not a session leader, or
-   * if it already has a controlling tty, or if it is someone elses
-   * controlling tty.
-   */
-  if (!fp->fp_sesldr || fp->fp_tty != 0) {
-	flags |= O_NOCTTY;
-  } else {
-	for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
-		if(rfp->fp_pid == PID_FREE) continue;
-		if (rfp->fp_tty == dev) flags |= O_NOCTTY;
-	}
-  }
-
-  r = gen_opcl(op, dev, proc_e, flags);
-
-  /* Did this call make the tty the controlling tty? */
-  if (r == 1) {
-	fp->fp_tty = dev;
-	r = OK;
-  }
-  return(r);
-}
-
-/*===========================================================================*
- *				ctty_opcl				     *
- *===========================================================================*/
-PUBLIC int ctty_opcl(op, dev, proc_e, flags)
-int op;				/* operation, DEV_OPEN or DEV_CLOSE */
-dev_t dev;			/* device to open or close */
-int proc_e;			/* process to open/close for */
-int flags;			/* mode bits and flags */
-{
-/* This procedure is called from the dmap struct in table.c on opening/closing
- * /dev/tty, the magic device that translates to the controlling tty.
- */
- 
-  return(fp->fp_tty == 0 ? ENXIO : OK);
-}
-
-/*===========================================================================*
- *				do_setsid				     *
- *===========================================================================*/
-PUBLIC int do_setsid()
-{
-/* Perform the FS side of the SETSID call, i.e. get rid of the controlling
- * terminal of a process, and make the process a session leader.
- */
-  register struct fproc *rfp;
-  int slot;
-
-  /* Only MM may do the SETSID call directly. */
-  if (who_e != PM_PROC_NR) return(ENOSYS);
-
-  /* Make the process a session leader with no controlling tty. */
-  okendpt(m_in.endpt1, &slot);
-  rfp = &fproc[slot];
-  rfp->fp_sesldr = TRUE;
-  rfp->fp_tty = 0;
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_ioctl				     *
- *===========================================================================*/
-PUBLIC int do_ioctl()
-{
-/* Perform the ioctl(ls_fd, request, argx) system call (uses m2 fmt). */
-
-  struct filp *f;
-  register struct inode *rip;
-  dev_t dev;
-
-  if ( (f = get_filp(m_in.ls_fd)) == NIL_FILP) return(err_code);
-  rip = f->filp_ino;		/* get inode pointer */
-  if ( (rip->i_mode & I_TYPE) != I_CHAR_SPECIAL
-	&& (rip->i_mode & I_TYPE) != I_BLOCK_SPECIAL) return(ENOTTY);
-  dev = (dev_t) rip->i_zone[0];
-
-#if ENABLE_BINCOMPAT
-  if ((m_in.TTY_REQUEST >> 8) == 't') {
-	/* Obsolete sgtty ioctl, message contains more than is sane. */
-	struct dmap *dp;
-	message dev_mess;
-
-	dp = &dmap[(dev >> MAJOR) & BYTE];
-
-	dev_mess = m;	/* Copy full message with all the weird bits. */
-	dev_mess.m_type   = DEV_IOCTL;
-	dev_mess.PROC_NR  = who_e;
-	dev_mess.TTY_LINE = (dev >> MINOR) & BYTE;	
-
-	/* Call the task. */
-
-  if (dp->dmap_driver == NONE) {
-	printf("FS: do_ioctl: no driver for dev %x\n", dev);
-	return ENXIO;
-  }
-
-  if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
-	printf("FS: do_ioctl: old driver for dev %x (%d)\n",
-		dev, dp->dmap_driver);
-	return ENXIO;
-  }
-
-	(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-
-	m_out.TTY_SPEK = dev_mess.TTY_SPEK;	/* erase and kill */
-	m_out.TTY_FLAGS = dev_mess.TTY_FLAGS;	/* flags */
-	return(dev_mess.REP_STATUS);
-  }
-#endif
-
-  return(dev_io(DEV_IOCTL, dev, who_e, m_in.ADDRESS, 0L, 
-  	m_in.REQUEST, f->filp_flags));
-}
-
-/*===========================================================================*
- *				gen_io					     *
- *===========================================================================*/
-PUBLIC int gen_io(task_nr, mess_ptr)
-int task_nr;			/* which task to call */
-message *mess_ptr;		/* pointer to message for task */
-{
-/* All file system I/O ultimately comes down to I/O on major/minor device
- * pairs.  These lead to calls on the following routines via the dmap table.
- */
-
-  int r, proc_e;
-
-  proc_e = mess_ptr->IO_ENDPT;
-
-#if DEAD_CODE
-  while ((r = sendrec(task_nr, mess_ptr)) == ELOCKED) {
-	/* sendrec() failed to avoid deadlock. The task 'task_nr' is
-	 * trying to send a REVIVE message for an earlier request.
-	 * Handle it and go try again.
-	 */
-	if ((r = receive(task_nr, &local_m)) != OK) {
-		break;
-	}
-
-	/* If we're trying to send a cancel message to a task which has just
-	 * sent a completion reply, ignore the reply and abort the cancel
-	 * request. The caller will do the revive for the process.
-	 */
-	if (mess_ptr->m_type == CANCEL && local_m.REP_ENDPT == proc_e) {
-		return OK;
-	}
-
-	/* Otherwise it should be a REVIVE. */
-	if (local_m.m_type != REVIVE) {
-		printf(
-		"fs: strange device reply from %d, type = %d, proc = %d (1)\n",
-			local_m.m_source,
-			local_m.m_type, local_m.REP_ENDPT);
-		continue;
-	}
-
-	revive(local_m.REP_ENDPT, local_m.REP_STATUS);
-  }
-#endif
-
-  /* The message received may be a reply to this call, or a REVIVE for some
-   * other process.
-   */
-  r = sendrec(task_nr, mess_ptr);
-  for(;;) {
-	if (r != OK) {
-		if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
-			printf("fs: dead driver %d\n", task_nr);
-			dmap_unmap_by_endpt(task_nr);
-			return r;
-		}
-		if (r == ELOCKED) {
-			printf("fs: ELOCKED talking to %d\n", task_nr);
-			return r;
-		}
-		panic(__FILE__,"call_task: can't send/receive", r);
-	}
-
-  	/* Did the process we did the sendrec() for get a result? */
-  	if (mess_ptr->REP_ENDPT == proc_e) {
-  		break;
-	} else if (mess_ptr->m_type == REVIVE) {
-		/* Otherwise it should be a REVIVE. */
-		revive(mess_ptr->REP_ENDPT, mess_ptr->REP_STATUS);
-	} else {
-		printf(
-		"fs: strange device reply from %d, type = %d, proc = %d (2) ignored\n",
-			mess_ptr->m_source,
-			mess_ptr->m_type, mess_ptr->REP_ENDPT);
-	}
-	r = receive(task_nr, mess_ptr);
-  }
-
-  return OK;
-}
-
-/*===========================================================================*
- *				ctty_io					     *
- *===========================================================================*/
-PUBLIC int ctty_io(task_nr, mess_ptr)
-int task_nr;			/* not used - for compatibility with dmap_t */
-message *mess_ptr;		/* pointer to message for task */
-{
-/* This routine is only called for one device, namely /dev/tty.  Its job
- * is to change the message to use the controlling terminal, instead of the
- * major/minor pair for /dev/tty itself.
- */
-
-  struct dmap *dp;
-
-  if (fp->fp_tty == 0) {
-	/* No controlling tty present anymore, return an I/O error. */
-	mess_ptr->REP_STATUS = EIO;
-  } else {
-	/* Substitute the controlling terminal device. */
-	dp = &dmap[(fp->fp_tty >> MAJOR) & BYTE];
-	mess_ptr->DEVICE = (fp->fp_tty >> MINOR) & BYTE;
-
-  if (dp->dmap_driver == NONE) {
-	printf("FS: ctty_io: no driver for dev\n");
-	return EIO;
-  }
-
-	if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
-		printf("FS: ctty_io: old driver %d\n",
-			dp->dmap_driver);
-		return EIO;
-	}
-
-	(*dp->dmap_io)(dp->dmap_driver, mess_ptr);
-  }
-  return OK;
-}
-
-/*===========================================================================*
- *				no_dev					     *
- *===========================================================================*/
-PUBLIC int no_dev(op, dev, proc, flags)
-int op;				/* operation, DEV_OPEN or DEV_CLOSE */
-dev_t dev;			/* device to open or close */
-int proc;			/* process to open/close for */
-int flags;			/* mode bits and flags */
-{
-/* Called when opening a nonexistent device. */
-  return(ENODEV);
-}
-
-/*===========================================================================*
- *				no_dev_io				     *
- *===========================================================================*/
-PUBLIC int no_dev_io(int proc, message *m)
-{
-/* Called when doing i/o on a nonexistent device. */
-  printf("FS: I/O on unmapped device number\n");
-  return EIO;
-}
-
-/*===========================================================================*
- *				clone_opcl				     *
- *===========================================================================*/
-PUBLIC int clone_opcl(op, dev, proc_e, flags)
-int op;				/* operation, DEV_OPEN or DEV_CLOSE */
-dev_t dev;			/* device to open or close */
-int proc_e;			/* process to open/close for */
-int flags;			/* mode bits and flags */
-{
-/* Some devices need special processing upon open.  Such a device is "cloned",
- * i.e. on a succesful open it is replaced by a new device with a new unique
- * minor device number.  This new device number identifies a new object (such
- * as a new network connection) that has been allocated within a task.
- */
-  struct dmap *dp;
-  int r, minor;
-  message dev_mess;
-
-  /* Determine task dmap. */
-  dp = &dmap[(dev >> MAJOR) & BYTE];
-  minor = (dev >> MINOR) & BYTE;
-
-  dev_mess.m_type   = op;
-  dev_mess.DEVICE   = minor;
-  dev_mess.IO_ENDPT = proc_e;
-  dev_mess.COUNT    = flags;
-
-
-  if (dp->dmap_driver == NONE) {
-	printf("FS: clone_opcl: no driver for dev %x\n", dev);
-	return ENXIO;
-  }
-
-  if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
-  	printf("FS: clone_opcl: old driver for dev %x (%d)\n",
-  		dev, dp->dmap_driver);
-  	return ENXIO;
-  }
-
-  /* Call the task. */
-  r= (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-  if (r != OK)
-	return r;
-
-  if (op == DEV_OPEN && dev_mess.REP_STATUS >= 0) {
-	if (dev_mess.REP_STATUS != minor) {
-		/* A new minor device number has been returned.  Create a
-		 * temporary device file to hold it.
-		 */
-		struct inode *ip;
-
-		/* Device number of the new device. */
-		dev = (dev & ~(BYTE << MINOR)) | (dev_mess.REP_STATUS << MINOR);
-
-		ip = alloc_inode(root_dev, ALL_MODES | I_CHAR_SPECIAL);
-		if (ip == NIL_INODE) {
-			/* Oops, that didn't work.  Undo open. */
-			(void) clone_opcl(DEV_CLOSE, dev, proc_e, 0);
-			return(err_code);
-		}
-		ip->i_zone[0] = dev;
-
-		put_inode(fp->fp_filp[m_in.fd]->filp_ino);
-		fp->fp_filp[m_in.fd]->filp_ino = ip;
-	}
-	dev_mess.REP_STATUS = OK;
-  }
-  return(dev_mess.REP_STATUS);
-}
-
-/*===========================================================================*
- *				dev_up					     *
- *===========================================================================*/
-PUBLIC void dev_up(int maj)
-{
-	/* A new device driver has been mapped in. This function
-	 * checks if any filesystems are mounted on it, and if so,
-	 * dev_open()s them so the filesystem can be reused.
-	 */
-	struct super_block *sb;
-	struct filp *fp;
-	int r;
-
-	/* Open a device once for every filp that's opened on it,
-	 * and once for every filesystem mounted from it.
-	 */
-
-	for(sb = super_block; sb < &super_block[NR_SUPERS]; sb++) {
-		int minor;
-		if(sb->s_dev == NO_DEV)
-			continue;
-		if(((sb->s_dev >> MAJOR) & BYTE) != maj)
-			continue;
-		minor = ((sb->s_dev >> MINOR) & BYTE);
-		printf("FS: remounting dev %d/%d\n", maj, minor);
-		if((r = dev_open(sb->s_dev, FS_PROC_NR,
-		   sb->s_rd_only ? R_BIT : (R_BIT|W_BIT))) != OK) {
-			printf("FS: mounted dev %d/%d re-open failed: %d.\n",
-				maj, minor, r);
-		}
-	}
-
-	for(fp = filp; fp < &filp[NR_FILPS]; fp++) {
-		struct inode *in;
-		int minor;
-
-		if(fp->filp_count < 1 || !(in=fp->filp_ino)) continue;
-		if(((in->i_zone[0] >> MAJOR) & BYTE) != maj) continue;
-		if(!(in->i_mode & (I_BLOCK_SPECIAL|I_CHAR_SPECIAL))) continue;
-		
-		minor = ((in->i_zone[0] >> MINOR) & BYTE);
-
-		printf("FS: reopening special %d/%d..\n", maj, minor);
-
-		if((r = dev_open(in->i_zone[0], FS_PROC_NR,
-		   in->i_mode & (R_BIT|W_BIT))) != OK) {
-			int n;
-			/* This function will set the fp_filp[]s of processes
-			 * holding that fp to NULL, but _not_ clear
-			 * fp_filp_inuse, so that fd can't be recycled until
-			 * it's close()d.
-			 */
-			n = inval_filp(fp);
-			if(n != fp->filp_count)
-				printf("FS: warning: invalidate/count "
-				 "discrepancy (%d, %d)\n", n, fp->filp_count);
-			fp->filp_count = 0;
-			printf("FS: file on dev %d/%d re-open failed: %d; "
-				"invalidated %d fd's.\n", maj, minor, r, n);
-		}
-	}
-
-	return;
-}
-
Index: trunk/minix/servers/fs/dmap.c
===================================================================
--- trunk/minix/servers/fs/dmap.c	(revision 11)
+++ 	(revision )
@@ -1,250 +1,0 @@
-/* This file contains the table with device <-> driver mappings. It also
- * contains some routines to dynamically add and/ or remove device drivers
- * or change mappings.  
- */
-
-#include "fs.h"
-#include "fproc.h"
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <minix/com.h>
-#include "param.h"
-
-/* Some devices may or may not be there in the next table. */
-#define DT(enable, opcl, io, driver, flags) \
-  { (enable?(opcl):no_dev), (enable?(io):0), \
-  	(enable?(driver):0), (flags) },
-#define NC(x) (NR_CTRLRS >= (x))
-
-/* The order of the entries here determines the mapping between major device
- * numbers and tasks.  The first entry (major device 0) is not used.  The
- * next entry is major device 1, etc.  Character and block devices can be
- * intermixed at random.  The ordering determines the device numbers in /dev/.
- * Note that FS knows the device number of /dev/ram/ to load the RAM disk.
- * Also note that the major device numbers used in /dev/ are NOT the same as 
- * the process numbers of the device drivers. 
- */
-/*
-  Driver enabled     Open/Cls  I/O     Driver #     Flags Device  File
-  --------------     --------  ------  -----------  ----- ------  ----       
- */
-struct dmap dmap[NR_DEVICES];				/* actual map */ 
-PRIVATE struct dmap init_dmap[] = {
-  DT(1, no_dev,   0,       0,       	0) 	  	/* 0 = not used   */
-  DT(1, gen_opcl, gen_io,  MEM_PROC_NR, 0)	        /* 1 = /dev/mem   */
-  DT(0, no_dev,   0,       0,           DMAP_MUTABLE)	/* 2 = /dev/fd0   */
-  DT(0, no_dev,   0,       0,           DMAP_MUTABLE)	/* 3 = /dev/c0    */
-  DT(1, tty_opcl, gen_io,  TTY_PROC_NR, 0)    	  	/* 4 = /dev/tty00 */
-  DT(1, ctty_opcl,ctty_io, TTY_PROC_NR, 0)     	   	/* 5 = /dev/tty   */
-  DT(0, no_dev,   0,       NONE,	DMAP_MUTABLE)	/* 6 = /dev/lp    */
-
-#if (MACHINE == IBM_PC)
-  DT(1, no_dev,   0,       0,   	DMAP_MUTABLE)   /* 7 = /dev/ip    */
-  DT(0, no_dev,   0,       NONE,        DMAP_MUTABLE)   /* 8 = /dev/c1    */
-  DT(0, 0,        0,       0,   	DMAP_MUTABLE)   /* 9 = not used   */
-  DT(0, no_dev,   0,       0,           DMAP_MUTABLE)   /*10 = /dev/c2    */
-  DT(0, 0,        0,       0,   	DMAP_MUTABLE)   /*11 = not used   */
-  DT(0, no_dev,   0,       NONE,     	DMAP_MUTABLE)   /*12 = /dev/c3    */
-  DT(0, no_dev,   0,       NONE,	DMAP_MUTABLE)   /*13 = /dev/audio */
-  DT(0, no_dev,   0,       NONE,	DMAP_MUTABLE)   /*14 = /dev/mixer */
-  DT(1, gen_opcl, gen_io,  LOG_PROC_NR, 0)  	        /*15 = /dev/klog  */
-  DT(0, no_dev,   0,       NONE,	DMAP_MUTABLE)   /*16 = /dev/random*/
-  DT(0, no_dev,   0,       NONE,	DMAP_MUTABLE)   /*17 = /dev/cmos  */
-#endif /* IBM_PC */
-};
-
-/*===========================================================================*
- *				do_devctl		 		     *
- *===========================================================================*/
-PUBLIC int do_devctl()
-{
-  int result, proc_nr_e, proc_nr_n;
-
-  switch(m_in.ctl_req) {
-  case DEV_MAP:
-      /* Check process number of new driver. */
-      proc_nr_e= m_in.driver_nr;
-      if (isokendpt(proc_nr_e, &proc_nr_n) != OK)
-	return(EINVAL);
-
-      /* Try to update device mapping. */
-      result = map_driver(m_in.dev_nr, proc_nr_e, m_in.dev_style);
-      if (result == OK)
-      {
-	/* If a driver has completed its exec(), it can be announced to be
-	 * up.
-	 */
-	if(fproc[proc_nr_n].fp_execced) {
-		dev_up(m_in.dev_nr);
-	} else {
-		dmap[m_in.dev_nr].dmap_flags |= DMAP_BABY;
-	}
-      }
-      break;
-  case DEV_UNMAP:
-      result = map_driver(m_in.dev_nr, NONE, 0);
-      break;
-  default:
-      result = EINVAL;
-  }
-  return(result);
-}
-
-/*===========================================================================*
- *				map_driver		 		     *
- *===========================================================================*/
-PUBLIC int map_driver(major, proc_nr_e, style)
-int major;			/* major number of the device */
-int proc_nr_e;			/* process number of the driver */
-int style;			/* style of the device */
-{
-/* Set a new device driver mapping in the dmap table. Given that correct 
- * arguments are given, this only works if the entry is mutable and the 
- * current driver is not busy.  If the proc_nr is set to NONE, we're supposed
- * to unmap it.
- *
- * Normal error codes are returned so that this function can be used from
- * a system call that tries to dynamically install a new driver.
- */
-  struct dmap *dp;
-  int proc_nr_n;
-
-  /* Get pointer to device entry in the dmap table. */
-  if (major < 0 || major >= NR_DEVICES) return(ENODEV);
-  dp = &dmap[major];		
-
-  /* Check if we're supposed to unmap it. If so, do it even
-   * if busy or unmutable, as unmap is called when driver has
-   * exited.
-   */
- if(proc_nr_e == NONE) {
-	dp->dmap_opcl = no_dev;
-	dp->dmap_io = no_dev_io;
-	dp->dmap_driver = NONE;
-	dp->dmap_flags = DMAP_MUTABLE;	/* When gone, not busy or reserved. */
-	return(OK);
-  }
-	
-  /* See if updating the entry is allowed. */
-  if (! (dp->dmap_flags & DMAP_MUTABLE))  return(EPERM);
-  if (dp->dmap_flags & DMAP_BUSY)  return(EBUSY);
-
-  /* Check process number of new driver. */
-  if (isokendpt(proc_nr_e, &proc_nr_n) != OK)
-	return(EINVAL);
-
-  /* Try to update the entry. */
-  switch (style) {
-  case STYLE_DEV:	dp->dmap_opcl = gen_opcl;	break;
-  case STYLE_TTY:	dp->dmap_opcl = tty_opcl;	break;
-  case STYLE_CLONE:	dp->dmap_opcl = clone_opcl;	break;
-  default:		return(EINVAL);
-  }
-  dp->dmap_io = gen_io;
-  dp->dmap_driver = proc_nr_e;
-
-  return(OK); 
-}
-
-/*===========================================================================*
- *				dmap_unmap_by_endpt	 		     *
- *===========================================================================*/
-PUBLIC void dmap_unmap_by_endpt(int proc_nr_e)
-{
-	int i, r;
-	for (i=0; i<NR_DEVICES; i++)
-	  if(dmap[i].dmap_driver && dmap[i].dmap_driver == proc_nr_e)
-	    if((r=map_driver(i, NONE, 0)) != OK)
-		printf("FS: unmap of p %d / d %d failed: %d\n", proc_nr_e,i,r);
-
-	return;
-
-}
-
-/*===========================================================================*
- *				build_dmap		 		     *
- *===========================================================================*/
-PUBLIC void build_dmap()
-{
-/* Initialize the table with all device <-> driver mappings. Then, map  
- * the boot driver to a controller and update the dmap table to that
- * selection. The boot driver and the controller it handles are set at 
- * the boot monitor.  
- */
-  int i;
-  struct dmap *dp;
-
-  /* Build table with device <-> driver mappings. */
-  for (i=0; i<NR_DEVICES; i++) {
-      dp = &dmap[i];		
-      if (i < sizeof(init_dmap)/sizeof(struct dmap) && 
-              init_dmap[i].dmap_opcl != no_dev) {	/* a preset driver */
-          dp->dmap_opcl = init_dmap[i].dmap_opcl;
-          dp->dmap_io = init_dmap[i].dmap_io;
-          dp->dmap_driver = init_dmap[i].dmap_driver;
-          dp->dmap_flags = init_dmap[i].dmap_flags;
-      } else {						/* no default */
-          dp->dmap_opcl = no_dev;
-          dp->dmap_io = no_dev_io;
-          dp->dmap_driver = NONE;
-          dp->dmap_flags = DMAP_MUTABLE;
-      }
-  }
-
-#if 0
-  /* Get settings of 'controller' and 'driver' at the boot monitor. */
-  if ((s = env_get_param("label", driver, sizeof(driver))) != OK) 
-      panic(__FILE__,"couldn't get boot monitor parameter 'driver'", s);
-  if ((s = env_get_param("controller", controller, sizeof(controller))) != OK) 
-      panic(__FILE__,"couldn't get boot monitor parameter 'controller'", s);
-
-  /* Determine major number to map driver onto. */
-  if (controller[0] == 'f' && controller[1] == 'd') {
-      major = FLOPPY_MAJOR;
-  } 
-  else if (controller[0] == 'c' && isdigit(controller[1])) {
-      if ((nr = (unsigned) atoi(&controller[1])) > NR_CTRLRS)
-          panic(__FILE__,"monitor 'controller' maximum 'c#' is", NR_CTRLRS);
-      major = CTRLR(nr);
-  } 
-  else {
-      panic(__FILE__,"monitor 'controller' syntax is 'c#' of 'fd'", NO_NUM); 
-  }
-  
-  /* Now try to set the actual mapping and report to the user. */
-  if ((s=map_driver(major, DRVR_PROC_NR, STYLE_DEV)) != OK)
-      panic(__FILE__,"map_driver failed",s);
-  printf("Boot medium driver: %s driver mapped onto controller %s.\n",
-      driver, controller);
-#endif
-}
-
-/*===========================================================================*
- *				dmap_driver_match	 		     *
- *===========================================================================*/ 
-PUBLIC int dmap_driver_match(int proc, int major)
-{
-	if (major < 0 || major >= NR_DEVICES) return(0);
-	if(dmap[major].dmap_driver != NONE && dmap[major].dmap_driver == proc)
-		return 1;
-	return 0;
-}
-
-/*===========================================================================*
- *				dmap_endpt_up		 		     *
- *===========================================================================*/ 
-PUBLIC void dmap_endpt_up(int proc_e)
-{
-	int i;
-	for (i=0; i<NR_DEVICES; i++) {
-		if(dmap[i].dmap_driver != NONE
-			&& dmap[i].dmap_driver == proc_e
-			&& (dmap[i].dmap_flags & DMAP_BABY)) {
-			dmap[i].dmap_flags &= ~DMAP_BABY;
-			dev_up(i);
-		}
-	}
-	return;
-}
Index: trunk/minix/servers/fs/file.h
===================================================================
--- trunk/minix/servers/fs/file.h	(revision 11)
+++ 	(revision )
@@ -1,24 +1,0 @@
-/* This is the filp table.  It is an intermediary between file descriptors and
- * inodes.  A slot is free if filp_count == 0.
- */
-
-EXTERN struct filp {
-  mode_t filp_mode;		/* RW bits, telling how file is opened */
-  int filp_flags;		/* flags from open and fcntl */
-  int filp_count;		/* how many file descriptors share this slot?*/
-  struct inode *filp_ino;	/* pointer to the inode */
-  off_t filp_pos;		/* file position */
-
-  /* the following fields are for select() and are owned by the generic
-   * select() code (i.e., fd-type-specific select() code can't touch these).
-   */
-  int filp_selectors;		/* select()ing processes blocking on this fd */
-  int filp_select_ops;		/* interested in these SEL_* operations */
-
-  /* following are for fd-type-specific select() */
-  int filp_pipe_select_ops;
-} filp[NR_FILPS];
-
-#define FILP_CLOSED	0	/* filp_mode: associated device closed */
-
-#define NIL_FILP (struct filp *) 0	/* indicates absence of a filp slot */
Index: trunk/minix/servers/fs/filedes.c
===================================================================
--- trunk/minix/servers/fs/filedes.c	(revision 11)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/* This file contains the procedures that manipulate file descriptors.
- *
- * The entry points into this file are
- *   get_fd:	 look for free file descriptor and free filp slots
- *   get_filp:	 look up the filp entry for a given file descriptor
- *   find_filp:	 find a filp slot that points to a given inode
- *   inval_filp: invalidate a filp and associated fd's, only let close()
- *               happen on it
- */
-
-#include <sys/select.h>
-
-#include "fs.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-
-/*===========================================================================*
- *				get_fd					     *
- *===========================================================================*/
-PUBLIC int get_fd(int start, mode_t bits, int *k, struct filp **fpt)
-{
-/* Look for a free file descriptor and a free filp slot.  Fill in the mode word
- * in the latter, but don't claim either one yet, since the open() or creat()
- * may yet fail.
- */
-
-  register struct filp *f;
-  register int i;
-
-  *k = -1;			/* we need a way to tell if file desc found */
-
-  /* Search the fproc fp_filp table for a free file descriptor. */
-  for (i = start; i < OPEN_MAX; i++) {
-	if (fp->fp_filp[i] == NIL_FILP && !FD_ISSET(i, &fp->fp_filp_inuse)) {
-		/* A file descriptor has been located. */
-		*k = i;
-		break;
-	}
-  }
-
-  /* Check to see if a file descriptor has been found. */
-  if (*k < 0) return(EMFILE);	/* this is why we initialized k to -1 */
-
-  /* Now that a file descriptor has been found, look for a free filp slot. */
-  for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
-	if (f->filp_count == 0) {
-		f->filp_mode = bits;
-		f->filp_pos = 0L;
-		f->filp_selectors = 0;
-		f->filp_select_ops = 0;
-		f->filp_pipe_select_ops = 0;
-		f->filp_flags = 0;
-		*fpt = f;
-		return(OK);
-	}
-  }
-
-  /* If control passes here, the filp table must be full.  Report that back. */
-  return(ENFILE);
-}
-
-/*===========================================================================*
- *				get_filp				     *
- *===========================================================================*/
-PUBLIC struct filp *get_filp(fild)
-int fild;			/* file descriptor */
-{
-/* See if 'fild' refers to a valid file descr.  If so, return its filp ptr. */
-
-  err_code = EBADF;
-  if (fild < 0 || fild >= OPEN_MAX ) return(NIL_FILP);
-  return(fp->fp_filp[fild]);	/* may also be NIL_FILP */
-}
-
-/*===========================================================================*
- *				find_filp				     *
- *===========================================================================*/
-PUBLIC struct filp *find_filp(register struct inode *rip, mode_t bits)
-{
-/* Find a filp slot that refers to the inode 'rip' in a way as described
- * by the mode bit 'bits'. Used for determining whether somebody is still
- * interested in either end of a pipe.  Also used when opening a FIFO to
- * find partners to share a filp field with (to shared the file position).
- * Like 'get_fd' it performs its job by linear search through the filp table.
- */
-
-  register struct filp *f;
-
-  for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
-	if (f->filp_count != 0 && f->filp_ino == rip && (f->filp_mode & bits)){
-		return(f);
-	}
-  }
-
-  /* If control passes here, the filp wasn't there.  Report that back. */
-  return(NIL_FILP);
-}
-
-/*===========================================================================*
- *				inval_filp				     *
- *===========================================================================*/
-PUBLIC int inval_filp(struct filp *fp)
-{
-	int f, fd, n = 0;
-	for(f = 0; f < NR_PROCS; f++) {
-		if(fproc[f].fp_pid == PID_FREE) continue;
-		for(fd = 0; fd < OPEN_MAX; fd++) {
-			if(fproc[f].fp_filp[fd] && fproc[f].fp_filp[fd] == fp) {
-				fproc[f].fp_filp[fd] = NIL_FILP;
-				n++;
-			}
-		}
-	}
-
-	return n;
-}
Index: trunk/minix/servers/fs/fproc.h
===================================================================
--- trunk/minix/servers/fs/fproc.h	(revision 11)
+++ 	(revision )
@@ -1,41 +1,0 @@
-#include <sys/select.h>
-
-/* This is the per-process information.  A slot is reserved for each potential
- * process. Thus NR_PROCS must be the same as in the kernel. It is not 
- * possible or even necessary to tell when a slot is free here.
- */
-EXTERN struct fproc {
-  mode_t fp_umask;		/* mask set by umask system call */
-  struct inode *fp_workdir;	/* pointer to working directory's inode */
-  struct inode *fp_rootdir;	/* pointer to current root dir (see chroot) */
-  struct filp *fp_filp[OPEN_MAX];/* the file descriptor table */
-  fd_set fp_filp_inuse;		/* which fd's are in use? */
-  uid_t fp_realuid;		/* real user id */
-  uid_t fp_effuid;		/* effective user id */
-  gid_t fp_realgid;		/* real group id */
-  gid_t fp_effgid;		/* effective group id */
-  dev_t fp_tty;			/* major/minor of controlling tty */
-  int fp_fd;			/* place to save fd if rd/wr can't finish */
-  char *fp_buffer;		/* place to save buffer if rd/wr can't finish*/
-  int  fp_nbytes;		/* place to save bytes if rd/wr can't finish */
-  int  fp_cum_io_partial;	/* partial byte count if rd/wr can't finish */
-  char fp_suspended;		/* set to indicate process hanging */
-  char fp_revived;		/* set to indicate process being revived */
-  int fp_task;			/* which task is proc suspended on */
-  char fp_sesldr;		/* true if proc is a session leader */
-  char fp_execced;		/* true if proc has exec()ced after fork */
-  pid_t fp_pid;			/* process id */
-  long fp_cloexec;		/* bit map for POSIX Table 6-2 FD_CLOEXEC */
-  int fp_endpoint;		/* kernel endpoint number of this process */
-} fproc[NR_PROCS];
-
-/* Field values. */
-#define NOT_SUSPENDED      0	/* process is not suspended on pipe or task */
-#define SUSPENDED          1	/* process is suspended on pipe or task */
-#define NOT_REVIVING       0	/* process is not being revived */
-#define REVIVING           1	/* process is being revived from suspension */
-#define PID_FREE	   0	/* process slot free */
-
-/* Check is process number is acceptable - includes system processes. */
-#define isokprocnr(n)	((unsigned)((n)+NR_TASKS) < NR_PROCS + NR_TASKS)
-
Index: trunk/minix/servers/fs/fs.h
===================================================================
--- trunk/minix/servers/fs/fs.h	(revision 11)
+++ 	(revision )
@@ -1,27 +1,0 @@
-/* This is the master header for fs.  It includes some other files
- * and defines the principal constants.
- */
-#define _POSIX_SOURCE      1	/* tell headers to include POSIX stuff */
-#define _MINIX             1	/* tell headers to include MINIX stuff */
-#define _SYSTEM            1	/* tell headers that this is the kernel */
-
-#define VERBOSE		   0    /* show messages during initialization? */
-
-/* The following are so basic, all the *.c files get them automatically. */
-#include <minix/config.h>	/* MUST be first */
-#include <ansi.h>		/* MUST be second */
-#include <sys/types.h>
-#include <minix/const.h>
-#include <minix/type.h>
-#include <minix/dmap.h>
-
-#include <limits.h>
-#include <errno.h>
-
-#include <minix/syslib.h>
-#include <minix/sysutil.h>
-
-#include "const.h"
-#include "type.h"
-#include "proto.h"
-#include "glo.h"
Index: trunk/minix/servers/fs/glo.h
===================================================================
--- trunk/minix/servers/fs/glo.h	(revision 11)
+++ 	(revision )
@@ -1,32 +1,0 @@
-/* EXTERN should be extern except for the table file */
-#ifdef _TABLE
-#undef EXTERN
-#define EXTERN
-#endif
-
-/* File System global variables */
-EXTERN struct fproc *fp;	/* pointer to caller's fproc struct */
-EXTERN int super_user;		/* 1 if caller is super_user, else 0 */
-EXTERN int susp_count;		/* number of procs suspended on pipe */
-EXTERN int nr_locks;		/* number of locks currently in place */
-EXTERN int reviving;		/* number of pipe processes to be revived */
-EXTERN off_t rdahedpos;		/* position to read ahead */
-EXTERN struct inode *rdahed_inode;	/* pointer to inode to read ahead */
-EXTERN Dev_t root_dev;		/* device number of the root device */
-EXTERN time_t boottime;		/* time in seconds at system boot */
-
-/* The parameters of the call are kept here. */
-EXTERN message m_in;		/* the input message itself */
-EXTERN message m_out;		/* the output message used for reply */
-EXTERN int who_p, who_e;	/* caller's proc number, endpoint */
-EXTERN int call_nr;		/* system call number */
-EXTERN char user_path[PATH_MAX];/* storage for user path name */
-
-/* The following variables are used for returning results to the caller. */
-EXTERN int err_code;		/* temporary storage for error number */
-EXTERN int rdwt_err;		/* status of last disk i/o request */
-
-/* Data initialized elsewhere. */
-extern _PROTOTYPE (int (*call_vec[]), (void) ); /* sys call table */
-extern char dot1[2];   /* dot1 (&dot1[0]) and dot2 (&dot2[0]) have a special */
-extern char dot2[3];   /* meaning to search_dir: no access permission check. */
Index: trunk/minix/servers/fs/inode.c
===================================================================
--- trunk/minix/servers/fs/inode.c	(revision 11)
+++ 	(revision )
@@ -1,366 +1,0 @@
-/* This file manages the inode table.  There are procedures to allocate and
- * deallocate inodes, acquire, erase, and release them, and read and write
- * them from the disk.
- *
- * The entry points into this file are
- *   get_inode:	   search inode table for a given inode; if not there,
- *                 read it
- *   put_inode:	   indicate that an inode is no longer needed in memory
- *   alloc_inode:  allocate a new, unused inode
- *   wipe_inode:   erase some fields of a newly allocated inode
- *   free_inode:   mark an inode as available for a new file
- *   update_times: update atime, ctime, and mtime
- *   rw_inode:	   read a disk block and extract an inode, or corresp. write
- *   old_icopy:	   copy to/from in-core inode struct and disk inode (V1.x)
- *   new_icopy:	   copy to/from in-core inode struct and disk inode (V2.x)
- *   dup_inode:	   indicate that someone else is using an inode table entry
- */
-
-#include "fs.h"
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "super.h"
-
-FORWARD _PROTOTYPE( void old_icopy, (struct inode *rip, d1_inode *dip,
-						int direction, int norm));
-FORWARD _PROTOTYPE( void new_icopy, (struct inode *rip, d2_inode *dip,
-						int direction, int norm));
-
-/*===========================================================================*
- *				get_inode				     *
- *===========================================================================*/
-PUBLIC struct inode *get_inode(dev, numb)
-dev_t dev;			/* device on which inode resides */
-int numb;			/* inode number (ANSI: may not be unshort) */
-{
-/* Find a slot in the inode table, load the specified inode into it, and
- * return a pointer to the slot.  If 'dev' == NO_DEV, just return a free slot.
- */
-
-  register struct inode *rip, *xp;
-
-  /* Search the inode table both for (dev, numb) and a free slot. */
-  xp = NIL_INODE;
-  for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++) {
-	if (rip->i_count > 0) { /* only check used slots for (dev, numb) */
-		if (rip->i_dev == dev && rip->i_num == numb) {
-			/* This is the inode that we are looking for. */
-			rip->i_count++;
-			return(rip);	/* (dev, numb) found */
-		}
-	} else {
-		xp = rip;	/* remember this free slot for later */
-	}
-  }
-
-  /* Inode we want is not currently in use.  Did we find a free slot? */
-  if (xp == NIL_INODE) {	/* inode table completely full */
-	err_code = ENFILE;
-	return(NIL_INODE);
-  }
-
-  /* A free inode slot has been located.  Load the inode into it. */
-  xp->i_dev = dev;
-  xp->i_num = numb;
-  xp->i_count = 1;
-  if (dev != NO_DEV) rw_inode(xp, READING);	/* get inode from disk */
-  xp->i_update = 0;		/* all the times are initially up-to-date */
-
-  return(xp);
-}
-
-/*===========================================================================*
- *				put_inode				     *
- *===========================================================================*/
-PUBLIC void put_inode(rip)
-register struct inode *rip;	/* pointer to inode to be released */
-{
-/* The caller is no longer using this inode.  If no one else is using it either
- * write it back to the disk immediately.  If it has no links, truncate it and
- * return it to the pool of available inodes.
- */
-
-  if (rip == NIL_INODE) return;	/* checking here is easier than in caller */
-  if (--rip->i_count == 0) {	/* i_count == 0 means no one is using it now */
-	if (rip->i_nlinks == 0) {
-		/* i_nlinks == 0 means free the inode. */
-		truncate_inode(rip, 0);	/* return all the disk blocks */
-		rip->i_mode = I_NOT_ALLOC;	/* clear I_TYPE field */
-		rip->i_dirt = DIRTY;
-		free_inode(rip->i_dev, rip->i_num);
-	} else {
-		if (rip->i_pipe == I_PIPE) truncate_inode(rip, 0);
-	}
-	rip->i_pipe = NO_PIPE;  /* should always be cleared */
-	if (rip->i_dirt == DIRTY) rw_inode(rip, WRITING);
-  }
-}
-
-/*===========================================================================*
- *				alloc_inode				     *
- *===========================================================================*/
-PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
-{
-/* Allocate a free inode on 'dev', and return a pointer to it. */
-
-  register struct inode *rip;
-  register struct super_block *sp;
-  int major, minor, inumb;
-  bit_t b;
-
-  sp = get_super(dev);	/* get pointer to super_block */
-  if (sp->s_rd_only) {	/* can't allocate an inode on a read only device. */
-	err_code = EROFS;
-	return(NIL_INODE);
-  }
-
-  /* Acquire an inode from the bit map. */
-  b = alloc_bit(sp, IMAP, sp->s_isearch);
-  if (b == NO_BIT) {
-	err_code = ENFILE;
-	major = (int) (sp->s_dev >> MAJOR) & BYTE;
-	minor = (int) (sp->s_dev >> MINOR) & BYTE;
-	printf("Out of i-nodes on %sdevice %d/%d\n",
-		sp->s_dev == root_dev ? "root " : "", major, minor);
-	return(NIL_INODE);
-  }
-  sp->s_isearch = b;		/* next time start here */
-  inumb = (int) b;		/* be careful not to pass unshort as param */
-
-  /* Try to acquire a slot in the inode table. */
-  if ((rip = get_inode(NO_DEV, inumb)) == NIL_INODE) {
-	/* No inode table slots available.  Free the inode just allocated. */
-	free_bit(sp, IMAP, b);
-  } else {
-	/* An inode slot is available. Put the inode just allocated into it. */
-	rip->i_mode = bits;		/* set up RWX bits */
-	rip->i_nlinks = 0;		/* initial no links */
-	rip->i_uid = fp->fp_effuid;	/* file's uid is owner's */
-	rip->i_gid = fp->fp_effgid;	/* ditto group id */
-	rip->i_dev = dev;		/* mark which device it is on */
-	rip->i_ndzones = sp->s_ndzones;	/* number of direct zones */
-	rip->i_nindirs = sp->s_nindirs;	/* number of indirect zones per blk*/
-	rip->i_sp = sp;			/* pointer to super block */
-
-	/* Fields not cleared already are cleared in wipe_inode().  They have
-	 * been put there because truncate() needs to clear the same fields if
-	 * the file happens to be open while being truncated.  It saves space
-	 * not to repeat the code twice.
-	 */
-	wipe_inode(rip);
-  }
-
-  return(rip);
-}
-
-/*===========================================================================*
- *				wipe_inode				     *
- *===========================================================================*/
-PUBLIC void wipe_inode(rip)
-register struct inode *rip;	/* the inode to be erased */
-{
-/* Erase some fields in the inode.  This function is called from alloc_inode()
- * when a new inode is to be allocated, and from truncate(), when an existing
- * inode is to be truncated.
- */
-
-  register int i;
-
-  rip->i_size = 0;
-  rip->i_update = ATIME | CTIME | MTIME;	/* update all times later */
-  rip->i_dirt = DIRTY;
-  for (i = 0; i < V2_NR_TZONES; i++) rip->i_zone[i] = NO_ZONE;
-}
-
-/*===========================================================================*
- *				free_inode				     *
- *===========================================================================*/
-PUBLIC void free_inode(dev, inumb)
-dev_t dev;			/* on which device is the inode */
-ino_t inumb;			/* number of inode to be freed */
-{
-/* Return an inode to the pool of unallocated inodes. */
-
-  register struct super_block *sp;
-  bit_t b;
-
-  /* Locate the appropriate super_block. */
-  sp = get_super(dev);
-  if (inumb <= 0 || inumb > sp->s_ninodes) return;
-  b = inumb;
-  free_bit(sp, IMAP, b);
-  if (b < sp->s_isearch) sp->s_isearch = b;
-}
-
-/*===========================================================================*
- *				update_times				     *
- *===========================================================================*/
-PUBLIC void update_times(rip)
-register struct inode *rip;	/* pointer to inode to be read/written */
-{
-/* Various system calls are required by the standard to update atime, ctime,
- * or mtime.  Since updating a time requires sending a message to the clock
- * task--an expensive business--the times are marked for update by setting
- * bits in i_update.  When a stat, fstat, or sync is done, or an inode is 
- * released, update_times() may be called to actually fill in the times.
- */
-
-  time_t cur_time;
-  struct super_block *sp;
-
-  sp = rip->i_sp;		/* get pointer to super block. */
-  if (sp->s_rd_only) return;	/* no updates for read-only file systems */
-
-  cur_time = clock_time();
-  if (rip->i_update & ATIME) rip->i_atime = cur_time;
-  if (rip->i_update & CTIME) rip->i_ctime = cur_time;
-  if (rip->i_update & MTIME) rip->i_mtime = cur_time;
-  rip->i_update = 0;		/* they are all up-to-date now */
-}
-
-/*===========================================================================*
- *				rw_inode				     *
- *===========================================================================*/
-PUBLIC void rw_inode(rip, rw_flag)
-register struct inode *rip;	/* pointer to inode to be read/written */
-int rw_flag;			/* READING or WRITING */
-{
-/* An entry in the inode table is to be copied to or from the disk. */
-
-  register struct buf *bp;
-  register struct super_block *sp;
-  d1_inode *dip;
-  d2_inode *dip2;
-  block_t b, offset;
-
-  /* Get the block where the inode resides. */
-  sp = get_super(rip->i_dev);	/* get pointer to super block */
-  rip->i_sp = sp;		/* inode must contain super block pointer */
-  offset = sp->s_imap_blocks + sp->s_zmap_blocks + 2;
-  b = (block_t) (rip->i_num - 1)/sp->s_inodes_per_block + offset;
-  bp = get_block(rip->i_dev, b, NORMAL);
-  dip  = bp->b_v1_ino + (rip->i_num - 1) % V1_INODES_PER_BLOCK;
-  dip2 = bp->b_v2_ino + (rip->i_num - 1) %
-  	 V2_INODES_PER_BLOCK(sp->s_block_size);
-
-  /* Do the read or write. */
-  if (rw_flag == WRITING) {
-	if (rip->i_update) update_times(rip);	/* times need updating */
-	if (sp->s_rd_only == FALSE) bp->b_dirt = DIRTY;
-  }
-
-  /* Copy the inode from the disk block to the in-core table or vice versa.
-   * If the fourth parameter below is FALSE, the bytes are swapped.
-   */
-  if (sp->s_version == V1)
-	old_icopy(rip, dip,  rw_flag, sp->s_native);
-  else
-	new_icopy(rip, dip2, rw_flag, sp->s_native);
-  
-  put_block(bp, INODE_BLOCK);
-  rip->i_dirt = CLEAN;
-}
-
-/*===========================================================================*
- *				old_icopy				     *
- *===========================================================================*/
-PRIVATE void old_icopy(rip, dip, direction, norm)
-register struct inode *rip;	/* pointer to the in-core inode struct */
-register d1_inode *dip;		/* pointer to the d1_inode inode struct */
-int direction;			/* READING (from disk) or WRITING (to disk) */
-int norm;			/* TRUE = do not swap bytes; FALSE = swap */
-
-{
-/* The V1.x IBM disk, the V1.x 68000 disk, and the V2 disk (same for IBM and
- * 68000) all have different inode layouts.  When an inode is read or written
- * this routine handles the conversions so that the information in the inode
- * table is independent of the disk structure from which the inode came.
- * The old_icopy routine copies to and from V1 disks.
- */
-
-  int i;
-
-  if (direction == READING) {
-	/* Copy V1.x inode to the in-core table, swapping bytes if need be. */
-	rip->i_mode    = conv2(norm, (int) dip->d1_mode);
-	rip->i_uid     = conv2(norm, (int) dip->d1_uid );
-	rip->i_size    = conv4(norm,       dip->d1_size);
-	rip->i_mtime   = conv4(norm,       dip->d1_mtime);
-	rip->i_atime   = rip->i_mtime;
-	rip->i_ctime   = rip->i_mtime;
-	rip->i_nlinks  = dip->d1_nlinks;		/* 1 char */
-	rip->i_gid     = dip->d1_gid;			/* 1 char */
-	rip->i_ndzones = V1_NR_DZONES;
-	rip->i_nindirs = V1_INDIRECTS;
-	for (i = 0; i < V1_NR_TZONES; i++)
-		rip->i_zone[i] = conv2(norm, (int) dip->d1_zone[i]);
-  } else {
-	/* Copying V1.x inode to disk from the in-core table. */
-	dip->d1_mode   = conv2(norm, (int) rip->i_mode);
-	dip->d1_uid    = conv2(norm, (int) rip->i_uid );
-	dip->d1_size   = conv4(norm,       rip->i_size);
-	dip->d1_mtime  = conv4(norm,       rip->i_mtime);
-	dip->d1_nlinks = rip->i_nlinks;			/* 1 char */
-	dip->d1_gid    = rip->i_gid;			/* 1 char */
-	for (i = 0; i < V1_NR_TZONES; i++)
-		dip->d1_zone[i] = conv2(norm, (int) rip->i_zone[i]);
-  }
-}
-
-/*===========================================================================*
- *				new_icopy				     *
- *===========================================================================*/
-PRIVATE void new_icopy(rip, dip, direction, norm)
-register struct inode *rip;	/* pointer to the in-core inode struct */
-register d2_inode *dip;	/* pointer to the d2_inode struct */
-int direction;			/* READING (from disk) or WRITING (to disk) */
-int norm;			/* TRUE = do not swap bytes; FALSE = swap */
-
-{
-/* Same as old_icopy, but to/from V2 disk layout. */
-
-  int i;
-
-  if (direction == READING) {
-	/* Copy V2.x inode to the in-core table, swapping bytes if need be. */
-	rip->i_mode    = conv2(norm,dip->d2_mode);
-	rip->i_uid     = conv2(norm,dip->d2_uid);
-	rip->i_nlinks  = conv2(norm,dip->d2_nlinks);
-	rip->i_gid     = conv2(norm,dip->d2_gid);
-	rip->i_size    = conv4(norm,dip->d2_size);
-	rip->i_atime   = conv4(norm,dip->d2_atime);
-	rip->i_ctime   = conv4(norm,dip->d2_ctime);
-	rip->i_mtime   = conv4(norm,dip->d2_mtime);
-	rip->i_ndzones = V2_NR_DZONES;
-	rip->i_nindirs = V2_INDIRECTS(rip->i_sp->s_block_size);
-	for (i = 0; i < V2_NR_TZONES; i++)
-		rip->i_zone[i] = conv4(norm, (long) dip->d2_zone[i]);
-  } else {
-	/* Copying V2.x inode to disk from the in-core table. */
-	dip->d2_mode   = conv2(norm,rip->i_mode);
-	dip->d2_uid    = conv2(norm,rip->i_uid);
-	dip->d2_nlinks = conv2(norm,rip->i_nlinks);
-	dip->d2_gid    = conv2(norm,rip->i_gid);
-	dip->d2_size   = conv4(norm,rip->i_size);
-	dip->d2_atime  = conv4(norm,rip->i_atime);
-	dip->d2_ctime  = conv4(norm,rip->i_ctime);
-	dip->d2_mtime  = conv4(norm,rip->i_mtime);
-	for (i = 0; i < V2_NR_TZONES; i++)
-		dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);
-  }
-}
-
-/*===========================================================================*
- *				dup_inode				     *
- *===========================================================================*/
-PUBLIC void dup_inode(ip)
-struct inode *ip;		/* The inode to be duplicated. */
-{
-/* This routine is a simplified form of get_inode() for the case where
- * the inode pointer is already known.
- */
-
-  ip->i_count++;
-}
Index: trunk/minix/servers/fs/inode.h
===================================================================
--- trunk/minix/servers/fs/inode.h	(revision 11)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/* Inode table.  This table holds inodes that are currently in use.  In some
- * cases they have been opened by an open() or creat() system call, in other
- * cases the file system itself needs the inode for one reason or another,
- * such as to search a directory for a path name.
- * The first part of the struct holds fields that are present on the
- * disk; the second part holds fields not present on the disk.
- * The disk inode part is also declared in "type.h" as 'd1_inode' for V1
- * file systems and 'd2_inode' for V2 file systems.
- */
-
-EXTERN struct inode {
-  mode_t i_mode;		/* file type, protection, etc. */
-  nlink_t i_nlinks;		/* how many links to this file */
-  uid_t i_uid;			/* user id of the file's owner */
-  gid_t i_gid;			/* group number */
-  off_t i_size;			/* current file size in bytes */
-  time_t i_atime;		/* time of last access (V2 only) */
-  time_t i_mtime;		/* when was file data last changed */
-  time_t i_ctime;		/* when was inode itself changed (V2 only)*/
-  zone_t i_zone[V2_NR_TZONES]; /* zone numbers for direct, ind, and dbl ind */
-  
-  /* The following items are not present on the disk. */
-  dev_t i_dev;			/* which device is the inode on */
-  ino_t i_num;			/* inode number on its (minor) device */
-  int i_count;			/* # times inode used; 0 means slot is free */
-  int i_ndzones;		/* # direct zones (Vx_NR_DZONES) */
-  int i_nindirs;		/* # indirect zones per indirect block */
-  struct super_block *i_sp;	/* pointer to super block for inode's device */
-  char i_dirt;			/* CLEAN or DIRTY */
-  char i_pipe;			/* set to I_PIPE if pipe */
-  char i_mount;			/* this bit is set if file mounted on */
-  char i_seek;			/* set on LSEEK, cleared on READ/WRITE */
-  char i_update;		/* the ATIME, CTIME, and MTIME bits are here */
-} inode[NR_INODES];
-
-#define NIL_INODE (struct inode *) 0	/* indicates absence of inode slot */
-
-/* Field values.  Note that CLEAN and DIRTY are defined in "const.h" */
-#define NO_PIPE            0	/* i_pipe is NO_PIPE if inode is not a pipe */
-#define I_PIPE             1	/* i_pipe is I_PIPE if inode is a pipe */
-#define NO_MOUNT           0	/* i_mount is NO_MOUNT if file not mounted on*/
-#define I_MOUNT            1	/* i_mount is I_MOUNT if file mounted on */
-#define NO_SEEK            0	/* i_seek = NO_SEEK if last op was not SEEK */
-#define ISEEK              1	/* i_seek = ISEEK if last op was SEEK */
Index: trunk/minix/servers/fs/link.c
===================================================================
--- trunk/minix/servers/fs/link.c	(revision 11)
+++ 	(revision )
@@ -1,616 +1,0 @@
-/* This file handles the LINK and UNLINK system calls.  It also deals with
- * deallocating the storage used by a file when the last UNLINK is done to a
- * file and the blocks must be returned to the free block pool.
- *
- * The entry points into this file are
- *   do_link:         perform the LINK system call
- *   do_unlink:	      perform the UNLINK and RMDIR system calls
- *   do_rename:	      perform the RENAME system call
- *   do_truncate:     perform the TRUNCATE system call
- *   do_ftruncate:    perform the FTRUNCATE system call
- *   truncate_inode:  release the blocks associated with an inode up to a size
- *   freesp_inode:    release a range of blocks without setting the size
- */
-
-#include "fs.h"
-#include <sys/stat.h>
-#include <string.h>
-#include <minix/com.h>
-#include <minix/callnr.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-#define SAME 1000
-
-FORWARD _PROTOTYPE( int remove_dir, (struct inode *rldirp, struct inode *rip,
-			char dir_name[NAME_MAX])			);
-FORWARD _PROTOTYPE( int unlink_file, (struct inode *dirp, struct inode *rip,
-			char file_name[NAME_MAX])			);
-FORWARD _PROTOTYPE( off_t nextblock, (off_t pos, int zonesize)		);
-FORWARD _PROTOTYPE( void zeroblock_half, (struct inode *i, off_t p, int l));
-FORWARD _PROTOTYPE( void zeroblock_range, (struct inode *i, off_t p, off_t h));
-
-/* Args to zeroblock_half() */
-#define FIRST_HALF	0
-#define LAST_HALF	1
-
-/*===========================================================================*
- *				do_link					     *
- *===========================================================================*/
-PUBLIC int do_link()
-{
-/* Perform the link(name1, name2) system call. */
-
-  struct inode *ip, *rip;
-  register int r;
-  char string[NAME_MAX];
-  struct inode *new_ip;
-
-  /* See if 'name' (file to be linked) exists. */
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-
-  /* Check to see if the file has maximum number of links already. */
-  r = OK;
-  if (rip->i_nlinks >= (rip->i_sp->s_version == V1 ? CHAR_MAX : SHRT_MAX))
-	r = EMLINK;
-
-  /* Only super_user may link to directories. */
-  if (r == OK)
-	if ( (rip->i_mode & I_TYPE) == I_DIRECTORY && !super_user) r = EPERM;
-
-  /* If error with 'name', return the inode. */
-  if (r != OK) {
-	put_inode(rip);
-	return(r);
-  }
-
-  /* Does the final directory of 'name2' exist? */
-  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
-	put_inode(rip);
-	return(err_code);
-  }
-  if ( (ip = last_dir(user_path, string)) == NIL_INODE) r = err_code;
-
-  /* If 'name2' exists in full (even if no space) set 'r' to error. */
-  if (r == OK) {
-	if ( (new_ip = advance(&ip, string)) == NIL_INODE) {
-		r = err_code;
-		if (r == ENOENT) r = OK;
-	} else {
-		put_inode(new_ip);
-		r = EEXIST;
-	}
-  }
-
-  /* Check for links across devices. */
-  if (r == OK)
-	if (rip->i_dev != ip->i_dev) r = EXDEV;
-
-  /* Try to link. */
-  if (r == OK)
-	r = search_dir(ip, string, &rip->i_num, ENTER);
-
-  /* If success, register the linking. */
-  if (r == OK) {
-	rip->i_nlinks++;
-	rip->i_update |= CTIME;
-	rip->i_dirt = DIRTY;
-  }
-
-  /* Done.  Release both inodes. */
-  put_inode(rip);
-  put_inode(ip);
-  return(r);
-}
-
-/*===========================================================================*
- *				do_unlink				     *
- *===========================================================================*/
-PUBLIC int do_unlink()
-{
-/* Perform the unlink(name) or rmdir(name) system call. The code for these two
- * is almost the same.  They differ only in some condition testing.  Unlink()
- * may be used by the superuser to do dangerous things; rmdir() may not.
- */
-
-  register struct inode *rip;
-  struct inode *rldirp;
-  int r;
-  char string[NAME_MAX];
-
-  /* Get the last directory in the path. */
-  if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
-  if ( (rldirp = last_dir(user_path, string)) == NIL_INODE)
-	return(err_code);
-
-  /* The last directory exists.  Does the file also exist? */
-  r = OK;
-  if ( (rip = advance(&rldirp, string)) == NIL_INODE) r = err_code;
-
-  /* If error, return inode. */
-  if (r != OK) {
-	put_inode(rldirp);
-	return(r);
-  }
-
-  /* Do not remove a mount point. */
-  if (rip->i_num == ROOT_INODE) {
-	put_inode(rldirp);
-	put_inode(rip);
-	return(EBUSY);
-  }
-
-  /* Now test if the call is allowed, separately for unlink() and rmdir(). */
-  if (call_nr == UNLINK) {
-	/* Only the su may unlink directories, but the su can unlink any dir.*/
-	if ( (rip->i_mode & I_TYPE) == I_DIRECTORY && !super_user) r = EPERM;
-
-	/* Don't unlink a file if it is the root of a mounted file system. */
-	if (rip->i_num == ROOT_INODE) r = EBUSY;
-
-	/* Actually try to unlink the file; fails if parent is mode 0 etc. */
-	if (r == OK) r = unlink_file(rldirp, rip, string);
-
-  } else {
-	r = remove_dir(rldirp, rip, string); /* call is RMDIR */
-  }
-
-  /* If unlink was possible, it has been done, otherwise it has not. */
-  put_inode(rip);
-  put_inode(rldirp);
-  return(r);
-}
-
-/*===========================================================================*
- *				do_rename				     *
- *===========================================================================*/
-PUBLIC int do_rename()
-{
-/* Perform the rename(name1, name2) system call. */
-
-  struct inode *old_dirp, *old_ip;	/* ptrs to old dir, file inodes */
-  struct inode *new_dirp, *new_ip;	/* ptrs to new dir, file inodes */
-  struct inode *new_superdirp, *next_new_superdirp;
-  int r = OK;				/* error flag; initially no error */
-  int odir, ndir;			/* TRUE iff {old|new} file is dir */
-  int same_pdir;			/* TRUE iff parent dirs are the same */
-  char old_name[NAME_MAX], new_name[NAME_MAX];
-  ino_t numb;
-  int r1;
-  
-  /* See if 'name1' (existing file) exists.  Get dir and file inodes. */
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  if ( (old_dirp = last_dir(user_path, old_name))==NIL_INODE) return(err_code);
-
-  if ( (old_ip = advance(&old_dirp, old_name)) == NIL_INODE) r = err_code;
-
-  /* See if 'name2' (new name) exists.  Get dir and file inodes. */
-  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) r = err_code;
-  if ( (new_dirp = last_dir(user_path, new_name)) == NIL_INODE) r = err_code;
-  new_ip = advance(&new_dirp, new_name);	/* not required to exist */
-
-  if (old_ip != NIL_INODE)
-	odir = ((old_ip->i_mode & I_TYPE) == I_DIRECTORY);  /* TRUE iff dir */
-
-  /* If it is ok, check for a variety of possible errors. */
-  if (r == OK) {
-	same_pdir = (old_dirp == new_dirp);
-
-	/* The old inode must not be a superdirectory of the new last dir. */
-	if (odir && !same_pdir) {
-		dup_inode(new_superdirp = new_dirp);
-		while (TRUE) {		/* may hang in a file system loop */
-			if (new_superdirp == old_ip) {
-				r = EINVAL;
-				break;
-			}
-			next_new_superdirp = advance(&new_superdirp, dot2);
-			put_inode(new_superdirp);
-			if (next_new_superdirp == new_superdirp)
-				break;	/* back at system root directory */
-			new_superdirp = next_new_superdirp;
-			if (new_superdirp == NIL_INODE) {
-				/* Missing ".." entry.  Assume the worst. */
-				r = EINVAL;
-				break;
-			}
-		} 	
-		put_inode(new_superdirp);
-	}	
-
-	/* The old or new name must not be . or .. */
-	if (strcmp(old_name, ".")==0 || strcmp(old_name, "..")==0 ||
-	    strcmp(new_name, ".")==0 || strcmp(new_name, "..")==0) r = EINVAL;
-
-	/* Both parent directories must be on the same device. */
-	if (old_dirp->i_dev != new_dirp->i_dev) r = EXDEV;
-
-	/* Parent dirs must be writable, searchable and on a writable device */
-	if ((r1 = forbidden(old_dirp, W_BIT | X_BIT)) != OK ||
-	    (r1 = forbidden(new_dirp, W_BIT | X_BIT)) != OK) r = r1;
-
-	/* Some tests apply only if the new path exists. */
-	if (new_ip == NIL_INODE) {
-		/* don't rename a file with a file system mounted on it. */
-		if (old_ip->i_dev != old_dirp->i_dev) r = EXDEV;
-		if (odir && new_dirp->i_nlinks >=
-		    (new_dirp->i_sp->s_version == V1 ? CHAR_MAX : SHRT_MAX) &&
-		    !same_pdir && r == OK) r = EMLINK;
-	} else {
-		if (old_ip == new_ip) r = SAME; /* old=new */
-
-		/* has the old file or new file a file system mounted on it? */
-		if (old_ip->i_dev != new_ip->i_dev) r = EXDEV;
-
-		ndir = ((new_ip->i_mode & I_TYPE) == I_DIRECTORY); /* dir ? */
-		if (odir == TRUE && ndir == FALSE) r = ENOTDIR;
-		if (odir == FALSE && ndir == TRUE) r = EISDIR;
-	}
-  }
-
-  /* If a process has another root directory than the system root, we might
-   * "accidently" be moving it's working directory to a place where it's
-   * root directory isn't a super directory of it anymore. This can make
-   * the function chroot useless. If chroot will be used often we should
-   * probably check for it here.
-   */
-
-  /* The rename will probably work. Only two things can go wrong now:
-   * 1. being unable to remove the new file. (when new file already exists)
-   * 2. being unable to make the new directory entry. (new file doesn't exists)
-   *     [directory has to grow by one block and cannot because the disk
-   *      is completely full].
-   */
-  if (r == OK) {
-	if (new_ip != NIL_INODE) {
-		  /* There is already an entry for 'new'. Try to remove it. */
-		if (odir) 
-			r = remove_dir(new_dirp, new_ip, new_name);
-		else 
-			r = unlink_file(new_dirp, new_ip, new_name);
-	}
-	/* if r is OK, the rename will succeed, while there is now an
-	 * unused entry in the new parent directory.
-	 */
-  }
-
-  if (r == OK) {
-	/* If the new name will be in the same parent directory as the old one,
-	 * first remove the old name to free an entry for the new name,
-	 * otherwise first try to create the new name entry to make sure
-	 * the rename will succeed.
-	 */
-	numb = old_ip->i_num;		/* inode number of old file */
-
-  	if (same_pdir) {
-		r = search_dir(old_dirp, old_name, (ino_t *) 0, DELETE);
-						/* shouldn't go wrong. */
-		if (r==OK) (void) search_dir(old_dirp, new_name, &numb, ENTER);
-	} else {
-		r = search_dir(new_dirp, new_name, &numb, ENTER);
-		if (r == OK)
-		    (void) search_dir(old_dirp, old_name, (ino_t *) 0, DELETE);
-	}
-  }
-  /* If r is OK, the ctime and mtime of old_dirp and new_dirp have been marked
-   * for update in search_dir.
-   */
-
-  if (r == OK && odir && !same_pdir) {
-	/* Update the .. entry in the directory (still points to old_dirp). */
-	numb = new_dirp->i_num;
-	(void) unlink_file(old_ip, NIL_INODE, dot2);
-	if (search_dir(old_ip, dot2, &numb, ENTER) == OK) {
-		/* New link created. */
-		new_dirp->i_nlinks++;
-		new_dirp->i_dirt = DIRTY;
-	}
-  }
-	
-  /* Release the inodes. */
-  put_inode(old_dirp);
-  put_inode(old_ip);
-  put_inode(new_dirp);
-  put_inode(new_ip);
-  return(r == SAME ? OK : r);
-}
-
-/*===========================================================================*
- *				do_truncate				     *
- *===========================================================================*/
-PUBLIC int do_truncate()
-{
-/* truncate_inode() does the actual work of do_truncate() and do_ftruncate().
- * do_truncate() and do_ftruncate() have to get hold of the inode, either
- * by name or fd, do checks on it, and call truncate_inode() to do the
- * work.
- */
-	int r;
-	struct inode *rip;	/* pointer to inode to be truncated */
-
-	if (fetch_name(m_in.m2_p1, m_in.m2_i1, M1) != OK)
-		return err_code;
-	if( (rip = eat_path(user_path)) == NIL_INODE)
-		return err_code;
-	if ( (rip->i_mode & I_TYPE) != I_REGULAR)
-		r = EINVAL;
-	else
-		r = truncate_inode(rip, m_in.m2_l1); 
-	put_inode(rip);
-
-	return r;
-}
-
-/*===========================================================================*
- *				do_ftruncate				     *
- *===========================================================================*/
-PUBLIC int do_ftruncate()
-{
-/* As with do_truncate(), truncate_inode() does the actual work. */
-	struct filp *rfilp;
-	if ( (rfilp = get_filp(m_in.m2_i1)) == NIL_FILP)
-		return err_code;
-	if ( (rfilp->filp_ino->i_mode & I_TYPE) != I_REGULAR)
-		return EINVAL;
-	return truncate_inode(rfilp->filp_ino, m_in.m2_l1);
-}
-
-/*===========================================================================*
- *				truncate_inode				     *
- *===========================================================================*/
-PUBLIC int truncate_inode(rip, newsize)
-register struct inode *rip;	/* pointer to inode to be truncated */
-off_t newsize;			/* inode must become this size */
-{
-/* Set inode to a certain size, freeing any zones no longer referenced
- * and updating the size in the inode. If the inode is extended, the
- * extra space is a hole that reads as zeroes.
- *
- * Nothing special has to happen to file pointers if inode is opened in
- * O_APPEND mode, as this is different per fd and is checked when 
- * writing is done.
- */
-  zone_t zone_size;
-  int scale, file_type, waspipe;
-  dev_t dev;
-
-  file_type = rip->i_mode & I_TYPE;	/* check to see if file is special */
-  if (file_type == I_CHAR_SPECIAL || file_type == I_BLOCK_SPECIAL)
-	return EINVAL;
-  if(newsize > rip->i_sp->s_max_size)	/* don't let inode grow too big */
-	return EFBIG;
-
-  dev = rip->i_dev;		/* device on which inode resides */
-  scale = rip->i_sp->s_log_zone_size;
-  zone_size = (zone_t) rip->i_sp->s_block_size << scale;
-
-  /* Pipes can shrink, so adjust size to make sure all zones are removed. */
-  waspipe = rip->i_pipe == I_PIPE;	/* TRUE if this was a pipe */
-  if (waspipe) {
-	if(newsize != 0)
-		return EINVAL;	/* Only truncate pipes to 0. */
-	rip->i_size = PIPE_SIZE(rip->i_sp->s_block_size);
-  }
-
-  /* Free the actual space if relevant. */
-  if(newsize < rip->i_size)
-	  freesp_inode(rip, newsize, rip->i_size);
-
-  /* Next correct the inode size. */
-  if(!waspipe) rip->i_size = newsize;
-  else wipe_inode(rip);	/* Pipes can only be truncated to 0. */
-  rip->i_dirt = DIRTY;
-
-  return OK;
-}
-
-/*===========================================================================*
- *				freesp_inode				     *
- *===========================================================================*/
-PUBLIC int freesp_inode(rip, start, end)
-register struct inode *rip;	/* pointer to inode to be partly freed */
-off_t start, end;		/* range of bytes to free (end uninclusive) */
-{
-/* Cut an arbitrary hole in an inode. The caller is responsible for checking
- * the reasonableness of the inode type of rip. The reason is this is that
- * this function can be called for different reasons, for which different
- * sets of inode types are reasonable. Adjusting the final size of the inode
- * is to be done by the caller too, if wished.
- *
- * Consumers of this function currently are truncate_inode() (used to
- * free indirect and data blocks for any type of inode, but also to
- * implement the ftruncate() and truncate() system calls) and the F_FREESP
- * fcntl().
- */
-	off_t p, e;
-	int zone_size, dev;
-
-	if(end > rip->i_size)		/* freeing beyond end makes no sense */
-		end = rip->i_size;
-	if(end <= start)		/* end is uninclusive, so start<end */
-		return EINVAL;
-        zone_size = rip->i_sp->s_block_size << rip->i_sp->s_log_zone_size;
-	dev = rip->i_dev;             /* device on which inode resides */
-
-	/* If freeing doesn't cross a zone boundary, then we may only zero
-	 * a range of the block.
-	 */
-	if(start/zone_size == (end-1)/zone_size) {
-		zeroblock_range(rip, start, end-start);
-	} else { 
-		/* First zero unused part of partly used blocks. */
-		if(start%zone_size)
-			zeroblock_half(rip, start, LAST_HALF);
-		if(end%zone_size && end < rip->i_size)
-			zeroblock_half(rip, end, FIRST_HALF);
-	}
-
-	/* Now completely free the completely unused blocks.
-	 * write_map() will free unused (double) indirect
-	 * blocks too. Converting the range to zone numbers avoids
-	 * overflow on p when doing e.g. 'p += zone_size'.
-	 */
-	e = end/zone_size;
-	if(end == rip->i_size && (end % zone_size)) e++;
-	for(p = nextblock(start, zone_size)/zone_size; p < e; p ++)
-		write_map(rip, p*zone_size, NO_ZONE, WMAP_FREE);
-
-	return OK;
-}
-
-/*===========================================================================*
- *				nextblock				     *
- *===========================================================================*/
-PRIVATE off_t nextblock(pos, zone_size)
-off_t pos;
-int zone_size;
-{
-/* Return the first position in the next block after position 'pos'
- * (unless this is the first position in the current block).
- * This can be done in one expression, but that can overflow pos.
- */
-	off_t p;
-	p = (pos/zone_size)*zone_size;
-	if((pos % zone_size)) p += zone_size;	/* Round up. */
-	return p;
-}
-
-/*===========================================================================*
- *				zeroblock_half				     *
- *===========================================================================*/
-PRIVATE void zeroblock_half(rip, pos, half)
-struct inode *rip;
-off_t pos;
-int half;
-{
-/* Zero the upper or lower 'half' of a block that holds position 'pos'.
- * half can be FIRST_HALF or LAST_HALF.
- *
- * FIRST_HALF: 0..pos-1 will be zeroed
- * LAST_HALF:  pos..blocksize-1 will be zeroed
- */
-	int offset, len;
-
-	 /* Offset of zeroing boundary. */
-	 offset = pos % rip->i_sp->s_block_size;
-
-	 if(half == LAST_HALF)  {
-	   	len = rip->i_sp->s_block_size - offset;
-	 } else {
-		len = offset;
-		pos -= offset;
-		offset = 0;
-	 }
-
-	zeroblock_range(rip, pos, len);
-}
-
-/*===========================================================================*
- *				zeroblock_range				     *
- *===========================================================================*/
-PRIVATE void zeroblock_range(rip, pos, len)
-struct inode *rip;
-off_t pos;
-off_t len;
-{
-/* Zero a range in a block.
- * This function is used to zero a segment of a block, either 
- * FIRST_HALF of LAST_HALF.
- * 
- */
-	block_t b;
-	struct buf *bp;
-	off_t offset;
-
-	if(!len) return; /* no zeroing to be done. */
-	if( (b = read_map(rip, pos)) == NO_BLOCK) return;
-	if( (bp = get_block(rip->i_dev, b, NORMAL)) == NIL_BUF)
-	   panic(__FILE__, "zeroblock_range: no block", NO_NUM);
-	offset = pos % rip->i_sp->s_block_size;
-	if(offset + len > rip->i_sp->s_block_size)
-	   panic(__FILE__, "zeroblock_range: len too long", len);
-	memset(bp->b_data + offset, 0, len);
-	bp->b_dirt = DIRTY;
-	put_block(bp, FULL_DATA_BLOCK);
-}
-
-/*===========================================================================*
- *				remove_dir				     *
- *===========================================================================*/
-PRIVATE int remove_dir(rldirp, rip, dir_name)
-struct inode *rldirp;		 	/* parent directory */
-struct inode *rip;			/* directory to be removed */
-char dir_name[NAME_MAX];		/* name of directory to be removed */
-{
-  /* A directory file has to be removed. Five conditions have to met:
-   * 	- The file must be a directory
-   *	- The directory must be empty (except for . and ..)
-   *	- The final component of the path must not be . or ..
-   *	- The directory must not be the root of a mounted file system
-   *	- The directory must not be anybody's root/working directory
-   */
-
-  int r;
-  register struct fproc *rfp;
-
-  /* search_dir checks that rip is a directory too. */
-  if ((r = search_dir(rip, "", (ino_t *) 0, IS_EMPTY)) != OK) return r;
-
-  if (strcmp(dir_name, ".") == 0 || strcmp(dir_name, "..") == 0)return(EINVAL);
-  if (rip->i_num == ROOT_INODE) return(EBUSY); /* can't remove 'root' */
-  
-  for (rfp = &fproc[INIT_PROC_NR + 1]; rfp < &fproc[NR_PROCS]; rfp++)
-	if (rfp->fp_pid != PID_FREE &&
-	     (rfp->fp_workdir == rip || rfp->fp_rootdir == rip))
-		return(EBUSY); /* can't remove anybody's working dir */
-
-  /* Actually try to unlink the file; fails if parent is mode 0 etc. */
-  if ((r = unlink_file(rldirp, rip, dir_name)) != OK) return r;
-
-  /* Unlink . and .. from the dir. The super user can link and unlink any dir,
-   * so don't make too many assumptions about them.
-   */
-  (void) unlink_file(rip, NIL_INODE, dot1);
-  (void) unlink_file(rip, NIL_INODE, dot2);
-  return(OK);
-}
-
-/*===========================================================================*
- *				unlink_file				     *
- *===========================================================================*/
-PRIVATE int unlink_file(dirp, rip, file_name)
-struct inode *dirp;		/* parent directory of file */
-struct inode *rip;		/* inode of file, may be NIL_INODE too. */
-char file_name[NAME_MAX];	/* name of file to be removed */
-{
-/* Unlink 'file_name'; rip must be the inode of 'file_name' or NIL_INODE. */
-
-  ino_t numb;			/* inode number */
-  int	r;
-
-  /* If rip is not NIL_INODE, it is used to get faster access to the inode. */
-  if (rip == NIL_INODE) {
-  	/* Search for file in directory and try to get its inode. */
-	err_code = search_dir(dirp, file_name, &numb, LOOK_UP);
-	if (err_code == OK) rip = get_inode(dirp->i_dev, (int) numb);
-	if (err_code != OK || rip == NIL_INODE) return(err_code);
-  } else {
-	dup_inode(rip);		/* inode will be returned with put_inode */
-  }
-
-  r = search_dir(dirp, file_name, (ino_t *) 0, DELETE);
-
-  if (r == OK) {
-	rip->i_nlinks--;	/* entry deleted from parent's dir */
-	rip->i_update |= CTIME;
-	rip->i_dirt = DIRTY;
-  }
-
-  put_inode(rip);
-  return(r);
-}
Index: trunk/minix/servers/fs/lock.c
===================================================================
--- trunk/minix/servers/fs/lock.c	(revision 11)
+++ 	(revision )
@@ -1,186 +1,0 @@
-/* This file handles advisory file locking as required by POSIX.
- *
- * The entry points into this file are
- *   lock_op:	perform locking operations for FCNTL system call
- *   lock_revive: revive processes when a lock is released
- */
-
-#include "fs.h"
-#include <minix/com.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "lock.h"
-#include "param.h"
-
-/*===========================================================================*
- *				lock_op					     *
- *===========================================================================*/
-PUBLIC int lock_op(f, req)
-struct filp *f;
-int req;			/* either F_SETLK or F_SETLKW */
-{
-/* Perform the advisory locking required by POSIX. */
-
-  int r, ltype, i, conflict = 0, unlocking = 0;
-  mode_t mo;
-  off_t first, last;
-  struct flock flock;
-  vir_bytes user_flock;
-  struct file_lock *flp, *flp2, *empty;
-
-  /* Fetch the flock structure from user space. */
-  user_flock = (vir_bytes) m_in.name1;
-  r = sys_datacopy(who_e, (vir_bytes) user_flock,
-	FS_PROC_NR, (vir_bytes) &flock, (phys_bytes) sizeof(flock));
-  if (r != OK) return(EINVAL);
-
-  /* Make some error checks. */
-  ltype = flock.l_type;
-  mo = f->filp_mode;
-  if (ltype != F_UNLCK && ltype != F_RDLCK && ltype != F_WRLCK) return(EINVAL);
-  if (req == F_GETLK && ltype == F_UNLCK) return(EINVAL);
-  if ( (f->filp_ino->i_mode & I_TYPE) != I_REGULAR) return(EINVAL);
-  if (req != F_GETLK && ltype == F_RDLCK && (mo & R_BIT) == 0) return(EBADF);
-  if (req != F_GETLK && ltype == F_WRLCK && (mo & W_BIT) == 0) return(EBADF);
-
-  /* Compute the first and last bytes in the lock region. */
-  switch (flock.l_whence) {
-	case SEEK_SET:	first = 0; break;
-	case SEEK_CUR:	first = f->filp_pos; break;
-	case SEEK_END:	first = f->filp_ino->i_size; break;
-	default:	return(EINVAL);
-  }
-  /* Check for overflow. */
-  if (((long)flock.l_start > 0) && ((first + flock.l_start) < first))
-	return(EINVAL);
-  if (((long)flock.l_start < 0) && ((first + flock.l_start) > first))
-	return(EINVAL);
-  first = first + flock.l_start;
-  last = first + flock.l_len - 1;
-  if (flock.l_len == 0) last = MAX_FILE_POS;
-  if (last < first) return(EINVAL);
-
-  /* Check if this region conflicts with any existing lock. */
-  empty = (struct file_lock *) 0;
-  for (flp = &file_lock[0]; flp < & file_lock[NR_LOCKS]; flp++) {
-	if (flp->lock_type == 0) {
-		if (empty == (struct file_lock *) 0) empty = flp;
-		continue;	/* 0 means unused slot */
-	}
-	if (flp->lock_inode != f->filp_ino) continue;	/* different file */
-	if (last < flp->lock_first) continue;	/* new one is in front */
-	if (first > flp->lock_last) continue;	/* new one is afterwards */
-	if (ltype == F_RDLCK && flp->lock_type == F_RDLCK) continue;
-	if (ltype != F_UNLCK && flp->lock_pid == fp->fp_pid) continue;
-  
-	/* There might be a conflict.  Process it. */
-	conflict = 1;
-	if (req == F_GETLK) break;
-
-	/* If we are trying to set a lock, it just failed. */
-	if (ltype == F_RDLCK || ltype == F_WRLCK) {
-		if (req == F_SETLK) {
-			/* For F_SETLK, just report back failure. */
-			return(EAGAIN);
-		} else {
-			/* For F_SETLKW, suspend the process. */
-			suspend(XLOCK);
-			return(SUSPEND);
-		}
-	}
-
-	/* We are clearing a lock and we found something that overlaps. */
-	unlocking = 1;
-	if (first <= flp->lock_first && last >= flp->lock_last) {
-		flp->lock_type = 0;	/* mark slot as unused */
-		nr_locks--;		/* number of locks is now 1 less */
-		continue;
-	}
-
-	/* Part of a locked region has been unlocked. */
-	if (first <= flp->lock_first) {
-		flp->lock_first = last + 1;
-		continue;
-	}
-
-	if (last >= flp->lock_last) {
-		flp->lock_last = first - 1;
-		continue;
-	}
-	
-	/* Bad luck. A lock has been split in two by unlocking the middle. */
-	if (nr_locks == NR_LOCKS) return(ENOLCK);
-	for (i = 0; i < NR_LOCKS; i++)
-		if (file_lock[i].lock_type == 0) break;
-	flp2 = &file_lock[i];
-	flp2->lock_type = flp->lock_type;
-	flp2->lock_pid = flp->lock_pid;
-	flp2->lock_inode = flp->lock_inode;
-	flp2->lock_first = last + 1;
-	flp2->lock_last = flp->lock_last;
-	flp->lock_last = first - 1;
-	nr_locks++;
-  }
-  if (unlocking) lock_revive();
-
-  if (req == F_GETLK) {
-	if (conflict) {
-		/* GETLK and conflict. Report on the conflicting lock. */
-		flock.l_type = flp->lock_type;
-		flock.l_whence = SEEK_SET;
-		flock.l_start = flp->lock_first;
-		flock.l_len = flp->lock_last - flp->lock_first + 1;
-		flock.l_pid = flp->lock_pid;
-
-	} else {
-		/* It is GETLK and there is no conflict. */
-		flock.l_type = F_UNLCK;
-	}
-
-	/* Copy the flock structure back to the caller. */
-	r = sys_datacopy(FS_PROC_NR, (vir_bytes) &flock,
-		who_e, (vir_bytes) user_flock, (phys_bytes) sizeof(flock));
-	return(r);
-  }
-
-  if (ltype == F_UNLCK) return(OK);	/* unlocked a region with no locks */
-
-  /* There is no conflict.  If space exists, store new lock in the table. */
-  if (empty == (struct file_lock *) 0) return(ENOLCK);	/* table full */
-  empty->lock_type = ltype;
-  empty->lock_pid = fp->fp_pid;
-  empty->lock_inode = f->filp_ino;
-  empty->lock_first = first;
-  empty->lock_last = last;
-  nr_locks++;
-  return(OK);
-}
-
-/*===========================================================================*
- *				lock_revive				     *
- *===========================================================================*/
-PUBLIC void lock_revive()
-{
-/* Go find all the processes that are waiting for any kind of lock and 
- * revive them all.  The ones that are still blocked will block again when 
- * they run.  The others will complete.  This strategy is a space-time 
- * tradeoff.  Figuring out exactly which ones to unblock now would take 
- * extra code, and the only thing it would win would be some performance in 
- * extremely rare circumstances (namely, that somebody actually used 
- * locking).
- */
-
-  int task;
-  struct fproc *fptr;
-
-  for (fptr = &fproc[INIT_PROC_NR + 1]; fptr < &fproc[NR_PROCS]; fptr++){
-	if(fptr->fp_pid == PID_FREE) continue;
-	task = -fptr->fp_task;
-	if (fptr->fp_suspended == SUSPENDED && task == XLOCK) {
-		revive(fptr->fp_endpoint, 0);
-	}
-  }
-}
Index: trunk/minix/servers/fs/lock.h
===================================================================
--- trunk/minix/servers/fs/lock.h	(revision 11)
+++ 	(revision )
@@ -1,10 +1,0 @@
-/* This is the file locking table.  Like the filp table, it points to the
- * inode table, however, in this case to achieve advisory locking.
- */
-EXTERN struct file_lock {
-  short lock_type;		/* F_RDLOCK or F_WRLOCK; 0 means unused slot */
-  pid_t lock_pid;		/* pid of the process holding the lock */
-  struct inode *lock_inode;	/* pointer to the inode locked */
-  off_t lock_first;		/* offset of first byte locked */
-  off_t lock_last;		/* offset of last byte locked */
-} file_lock[NR_LOCKS];
Index: trunk/minix/servers/fs/main.c
===================================================================
--- trunk/minix/servers/fs/main.c	(revision 11)
+++ 	(revision )
@@ -1,293 +1,0 @@
-/* This file contains the main program of the File System.  It consists of
- * a loop that gets messages requesting work, carries out the work, and sends
- * replies.
- *
- * The entry points into this file are:
- *   main:	main program of the File System
- *   reply:	send a reply to a process after the requested work is done
- *
- */
-
-struct super_block;		/* proto.h needs to know this */
-
-#include "fs.h"
-#include <fcntl.h>
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <sys/ioc_memory.h>
-#include <sys/svrctl.h>
-#include <sys/select.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/keymap.h>
-#include <minix/const.h>
-#include <minix/endpoint.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-FORWARD _PROTOTYPE( void fs_init, (void)				);
-FORWARD _PROTOTYPE( void get_work, (void)				);
-FORWARD _PROTOTYPE( void init_root, (void)				);
-
-/*===========================================================================*
- *				main					     *
- *===========================================================================*/
-PUBLIC int main()
-{
-/* This is the main program of the file system.  The main loop consists of
- * three major activities: getting new work, processing the work, and sending
- * the reply.  This loop never terminates as long as the file system runs.
- */
-  int error;
-
-  fs_init();
-
-
-  /* This is the main loop that gets work, processes it, and sends replies. */
-  while (TRUE) {
-	get_work();		/* sets who and call_nr */
-	fp = &fproc[who_p];	/* pointer to proc table struct */
-	super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE);   /* su? */
-
- 	/* Check for special control messages first. */
-	if (call_nr == PROC_EVENT) {
-		/* Assume FS got signal. Synchronize, but don't exit. */
-		do_sync();
-        } else if (call_nr == SYN_ALARM) {
-        	/* Alarm timer expired. Used only for select(). Check it. */
-        	fs_expire_timers(m_in.NOTIFY_TIMESTAMP);
-        } else if ((call_nr & NOTIFY_MESSAGE)) {
-        	/* Device notifies us of an event. */
-        	dev_status(&m_in);
-        } else {
-		/* Call the internal function that does the work. */
-		if (call_nr < 0 || call_nr >= NCALLS) { 
-			error = ENOSYS;
-		/* Not supposed to happen. */
-			printf("FS, warning illegal %d system call by %d\n", call_nr, who_e);
-		} else if (fp->fp_pid == PID_FREE) {
-			error = ENOSYS;
-			printf("FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n",
-				 who_e, call_nr, m_in.endpt1);
-		} else {
-			error = (*call_vec[call_nr])();
-		}
-
-		/* Copy the results back to the user and send reply. */
-		if (error != SUSPEND) { reply(who_e, error); }
-		if (rdahed_inode != NIL_INODE) {
-			read_ahead(); /* do block read ahead */
-		}
-	}
-  }
-  return(OK);				/* shouldn't come here */
-}
-
-/*===========================================================================*
- *				get_work				     *
- *===========================================================================*/
-PRIVATE void get_work()
-{  
-  /* Normally wait for new input.  However, if 'reviving' is
-   * nonzero, a suspended process must be awakened.
-   */
-  register struct fproc *rp;
-
-  if (reviving != 0) {
-	/* Revive a suspended process. */
-	for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) 
-		if (rp->fp_pid != PID_FREE && rp->fp_revived == REVIVING) {
-			who_p = (int)(rp - fproc);
-			who_e = rp->fp_endpoint;
-			call_nr = rp->fp_fd & BYTE;
-			m_in.fd = (rp->fp_fd >>8) & BYTE;
-			m_in.buffer = rp->fp_buffer;
-			m_in.nbytes = rp->fp_nbytes;
-			rp->fp_suspended = NOT_SUSPENDED; /*no longer hanging*/
-			rp->fp_revived = NOT_REVIVING;
-			reviving--;
-			return;
-		}
-	panic(__FILE__,"get_work couldn't revive anyone", NO_NUM);
-  }
-
-  for(;;) {
-    /* Normal case.  No one to revive. */
-    if (receive(ANY, &m_in) != OK)
-	panic(__FILE__,"fs receive error", NO_NUM);
-    who_e = m_in.m_source;
-    who_p = _ENDPOINT_P(who_e);
-    if(who_p < -NR_TASKS || who_p >= NR_PROCS)
-     	panic(__FILE__,"receive process out of range", who_p);
-    if(who_p >= 0 && fproc[who_p].fp_endpoint == NONE) {
-    	printf("FS: ignoring request from %d, endpointless slot %d (%d)\n",
-		m_in.m_source, who_p, m_in.m_type);
-	continue;
-    }
-    if(who_p >= 0 && fproc[who_p].fp_endpoint != who_e) {
-    	printf("FS: receive endpoint inconsistent (%d, %d, %d).\n",
-		who_e, fproc[who_p].fp_endpoint, who_e);
-	panic(__FILE__, "FS: inconsistent endpoint ", NO_NUM);
-	continue;
-    }
-    call_nr = m_in.m_type;
-    return;
-  }
-}
-
-/*===========================================================================*
- *				buf_pool				     *
- *===========================================================================*/
-PRIVATE void buf_pool(void)
-{
-/* Initialize the buffer pool. */
-
-  register struct buf *bp;
-
-  bufs_in_use = 0;
-  front = &buf[0];
-  rear = &buf[NR_BUFS - 1];
-
-  for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) {
-	bp->b_blocknr = NO_BLOCK;
-	bp->b_dev = NO_DEV;
-	bp->b_next = bp + 1;
-	bp->b_prev = bp - 1;
-  }
-  buf[0].b_prev = NIL_BUF;
-  buf[NR_BUFS - 1].b_next = NIL_BUF;
-
-  for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) bp->b_hash = bp->b_next;
-  buf_hash[0] = front;
-
-}
-
-/*===========================================================================*
- *				reply					     *
- *===========================================================================*/
-PUBLIC void reply(whom, result)
-int whom;			/* process to reply to */
-int result;			/* result of the call (usually OK or error #) */
-{
-/* Send a reply to a user process.  If the send fails, just ignore it. */
-  int s;
-  m_out.reply_type = result;
-  s = send(whom, &m_out);
-  if (s != OK) printf("FS: couldn't send reply %d to %d: %d\n",
-	result, whom, s);
-}
-
-/*===========================================================================*
- *				fs_init					     *
- *===========================================================================*/
-PRIVATE void fs_init()
-{
-/* Initialize global variables, tables, etc. */
-  register struct inode *rip;
-  register struct fproc *rfp;
-  message mess;
-  int s;
-
-  /* Initialize the process table with help of the process manager messages. 
-   * Expect one message for each system process with its slot number and pid. 
-   * When no more processes follow, the magic process number NONE is sent. 
-   * Then, stop and synchronize with the PM.
-   */
-  do {
-  	if (OK != (s=receive(PM_PROC_NR, &mess)))
-  		panic(__FILE__,"FS couldn't receive from PM", s);
-  	if (NONE == mess.PR_ENDPT) break; 
-
-	rfp = &fproc[mess.PR_SLOT];
-	rfp->fp_pid = mess.PR_PID;
-	rfp->fp_endpoint = mess.PR_ENDPT;
-	rfp->fp_realuid = (uid_t) SYS_UID;
-	rfp->fp_effuid = (uid_t) SYS_UID;
-	rfp->fp_realgid = (gid_t) SYS_GID;
-	rfp->fp_effgid = (gid_t) SYS_GID;
-	rfp->fp_umask = ~0;
-   
-  } while (TRUE);			/* continue until process NONE */
-  mess.m_type = OK;			/* tell PM that we succeeded */
-  s=send(PM_PROC_NR, &mess);		/* send synchronization message */
-
-  /* All process table entries have been set. Continue with FS initialization.
-   * Certain relations must hold for the file system to work at all. Some 
-   * extra block_size requirements are checked at super-block-read-in time.
-   */
-  if (OPEN_MAX > 127) panic(__FILE__,"OPEN_MAX > 127", NO_NUM);
-  if (NR_BUFS < 6) panic(__FILE__,"NR_BUFS < 6", NO_NUM);
-  if (V1_INODE_SIZE != 32) panic(__FILE__,"V1 inode size != 32", NO_NUM);
-  if (V2_INODE_SIZE != 64) panic(__FILE__,"V2 inode size != 64", NO_NUM);
-  if (OPEN_MAX > 8 * sizeof(long))
-  	 panic(__FILE__,"Too few bits in fp_cloexec", NO_NUM);
-
-  /* The following initializations are needed to let dev_opcl succeed .*/
-  fp = (struct fproc *) NULL;
-  who_e = who_p = FS_PROC_NR;
-
-  buf_pool();			/* initialize buffer pool */
-  build_dmap();			/* build device table and map boot driver */
-  init_root();			/* init root device and load super block */
-  init_select();		/* init select() structures */
-
-  /* The root device can now be accessed; set process directories. */
-  for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
-	FD_ZERO(&(rfp->fp_filp_inuse));
-  	if (rfp->fp_pid != PID_FREE) {
-		rip = get_inode(root_dev, ROOT_INODE);
-		dup_inode(rip);
-		rfp->fp_rootdir = rip;
-		rfp->fp_workdir = rip;
-  	} else  rfp->fp_endpoint = NONE;
-  }
-}
-
-/*===========================================================================*
- *				init_root				     *
- *===========================================================================*/
-PRIVATE void init_root()
-{
-  int bad;
-  register struct super_block *sp;
-  register struct inode *rip = NIL_INODE;
-  int s;
-
-  /* Open the root device. */
-  root_dev = DEV_IMGRD;
-  if ((s=dev_open(root_dev, FS_PROC_NR, R_BIT|W_BIT)) != OK)
-	panic(__FILE__,"Cannot open root device", s);
-
-#if ENABLE_CACHE2
-  /* The RAM disk is a second level block cache while not otherwise used. */
-  init_cache2(ram_size);
-#endif
-
-  /* Initialize the super_block table. */
-  for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++)
-  	sp->s_dev = NO_DEV;
-
-  /* Read in super_block for the root file system. */
-  sp = &super_block[0];
-  sp->s_dev = root_dev;
-
-  /* Check super_block for consistency. */
-  bad = (read_super(sp) != OK);
-  if (!bad) {
-	rip = get_inode(root_dev, ROOT_INODE);	/* inode for root dir */
-	if ( (rip->i_mode & I_TYPE) != I_DIRECTORY || rip->i_nlinks < 3) bad++;
-  }
-  if (bad) panic(__FILE__,"Invalid root file system", NO_NUM);
-
-  sp->s_imount = rip;
-  dup_inode(rip);
-  sp->s_isup = rip;
-  sp->s_rd_only = 0;
-  return;
-}
Index: trunk/minix/servers/fs/misc.c
===================================================================
--- trunk/minix/servers/fs/misc.c	(revision 11)
+++ 	(revision )
@@ -1,590 +1,0 @@
-/* This file contains a collection of miscellaneous procedures.  Some of them
- * perform simple system calls.  Some others do a little part of system calls
- * that are mostly performed by the Memory Manager.
- *
- * The entry points into this file are
- *   do_dup:	  perform the DUP system call
- *   do_fcntl:	  perform the FCNTL system call
- *   do_sync:	  perform the SYNC system call
- *   do_fsync:	  perform the FSYNC system call
- *   do_reboot:	  sync disks and prepare for shutdown
- *   do_fork:	  adjust the tables after MM has performed a FORK system call
- *   do_exec:	  handle files with FD_CLOEXEC on after MM has done an EXEC
- *   do_exit:	  a process has exited; note that in the tables
- *   do_set:	  set uid or gid for some process
- *   do_revive:	  revive a process that was waiting for something (e.g. TTY)
- *   do_svrctl:	  file system control
- *   do_getsysinfo:	request copy of FS data structure
- */
-
-#include "fs.h"
-#include <fcntl.h>
-#include <unistd.h>	/* cc runs out of memory with unistd.h :-( */
-#include <minix/callnr.h>
-#include <minix/endpoint.h>
-#include <minix/com.h>
-#include <sys/svrctl.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-FORWARD _PROTOTYPE( int free_proc, (struct fproc *freed, int flags));
-
-#define FP_EXITING	1
-
-/*===========================================================================*
- *				do_getsysinfo				     *
- *===========================================================================*/
-PUBLIC int do_getsysinfo()
-{
-  struct fproc *proc_addr;
-  vir_bytes src_addr, dst_addr;
-  size_t len;
-  int s;
-
-  switch(m_in.info_what) {
-  case SI_PROC_ADDR:
-  	proc_addr = &fproc[0];
-  	src_addr = (vir_bytes) &proc_addr;
-  	len = sizeof(struct fproc *);
-  	break; 
-  case SI_PROC_TAB:
-  	src_addr = (vir_bytes) fproc;
-  	len = sizeof(struct fproc) * NR_PROCS;
-  	break; 
-  case SI_DMAP_TAB:
-  	src_addr = (vir_bytes) dmap;
-  	len = sizeof(struct dmap) * NR_DEVICES;
-  	break; 
-  default:
-  	return(EINVAL);
-  }
-
-  dst_addr = (vir_bytes) m_in.info_where;
-  if (OK != (s=sys_datacopy(SELF, src_addr, who_e, dst_addr, len)))
-  	return(s);
-  return(OK);
-
-}
-
-/*===========================================================================*
- *				do_dup					     *
- *===========================================================================*/
-PUBLIC int do_dup()
-{
-/* Perform the dup(fd) or dup2(fd,fd2) system call. These system calls are
- * obsolete.  In fact, it is not even possible to invoke them using the
- * current library because the library routines call fcntl().  They are
- * provided to permit old binary programs to continue to run.
- */
-
-  register int rfd;
-  register struct filp *f;
-  struct filp *dummy;
-  int r;
-
-  /* Is the file descriptor valid? */
-  rfd = m_in.fd & ~DUP_MASK;		/* kill off dup2 bit, if on */
-  if ((f = get_filp(rfd)) == NIL_FILP) return(err_code);
-
-  /* Distinguish between dup and dup2. */
-  if (m_in.fd == rfd) {			/* bit not on */
-	/* dup(fd) */
-	if ( (r = get_fd(0, 0, &m_in.fd2, &dummy)) != OK) return(r);
-  } else {
-	/* dup2(fd, fd2) */
-	if (m_in.fd2 < 0 || m_in.fd2 >= OPEN_MAX) return(EBADF);
-	if (rfd == m_in.fd2) return(m_in.fd2);	/* ignore the call: dup2(x, x) */
-	m_in.fd = m_in.fd2;		/* prepare to close fd2 */
-	(void) do_close();	/* cannot fail */
-  }
-
-  /* Success. Set up new file descriptors. */
-  f->filp_count++;
-  fp->fp_filp[m_in.fd2] = f;
-  FD_SET(m_in.fd2, &fp->fp_filp_inuse);
-  return(m_in.fd2);
-}
-
-/*===========================================================================*
- *				do_fcntl				     *
- *===========================================================================*/
-PUBLIC int do_fcntl()
-{
-/* Perform the fcntl(fd, request, ...) system call. */
-
-  register struct filp *f;
-  int new_fd, r, fl;
-  long cloexec_mask;		/* bit map for the FD_CLOEXEC flag */
-  long clo_value;		/* FD_CLOEXEC flag in proper position */
-  struct filp *dummy;
-
-  /* Is the file descriptor valid? */
-  if ((f = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
-
-  switch (m_in.request) {
-     case F_DUPFD:
-	/* This replaces the old dup() system call. */
-	if (m_in.addr < 0 || m_in.addr >= OPEN_MAX) return(EINVAL);
-	if ((r = get_fd(m_in.addr, 0, &new_fd, &dummy)) != OK) return(r);
-	f->filp_count++;
-	fp->fp_filp[new_fd] = f;
-	return(new_fd);
-
-     case F_GETFD:
-	/* Get close-on-exec flag (FD_CLOEXEC in POSIX Table 6-2). */
-	return( ((fp->fp_cloexec >> m_in.fd) & 01) ? FD_CLOEXEC : 0);
-
-     case F_SETFD:
-	/* Set close-on-exec flag (FD_CLOEXEC in POSIX Table 6-2). */
-	cloexec_mask = 1L << m_in.fd;	/* singleton set position ok */
-	clo_value = (m_in.addr & FD_CLOEXEC ? cloexec_mask : 0L);
-	fp->fp_cloexec = (fp->fp_cloexec & ~cloexec_mask) | clo_value;
-	return(OK);
-
-     case F_GETFL:
-	/* Get file status flags (O_NONBLOCK and O_APPEND). */
-	fl = f->filp_flags & (O_NONBLOCK | O_APPEND | O_ACCMODE);
-	return(fl);	
-
-     case F_SETFL:
-	/* Set file status flags (O_NONBLOCK and O_APPEND). */
-	fl = O_NONBLOCK | O_APPEND;
-	f->filp_flags = (f->filp_flags & ~fl) | (m_in.addr & fl);
-	return(OK);
-
-     case F_GETLK:
-     case F_SETLK:
-     case F_SETLKW:
-	/* Set or clear a file lock. */
-	r = lock_op(f, m_in.request);
-	return(r);
-
-     case F_FREESP:
-     {
-	/* Free a section of a file. Preparation is done here,
-	 * actual freeing in freesp_inode().
-	 */
-	off_t start, end;
-	struct flock flock_arg;
-	signed long offset;
-
-	/* Check if it's a regular file. */
-	if((f->filp_ino->i_mode & I_TYPE) != I_REGULAR) {
-		return EINVAL;
-	}
-
-	/* Copy flock data from userspace. */
-	if((r = sys_datacopy(who_e, (vir_bytes) m_in.name1, 
-	  SELF, (vir_bytes) &flock_arg,
-	  (phys_bytes) sizeof(flock_arg))) != OK)
-		return r;
-
-	/* Convert starting offset to signed. */
-	offset = (signed long) flock_arg.l_start;
-
-	/* Figure out starting position base. */
-	switch(flock_arg.l_whence) {
-		case SEEK_SET: start = 0; if(offset < 0) return EINVAL; break;
-		case SEEK_CUR: start = f->filp_pos; break;
-		case SEEK_END: start = f->filp_ino->i_size; break;
-		default: return EINVAL;
-	}
-
-	/* Check for overflow or underflow. */
-	if(offset > 0 && start + offset < start) { return EINVAL; }
-	if(offset < 0 && start + offset > start) { return EINVAL; }
-	start += offset;
-	if(flock_arg.l_len > 0) {
-		end = start + flock_arg.l_len;
-		if(end <= start) {
-			return EINVAL;
-		}
-		r = freesp_inode(f->filp_ino, start, end);
-	} else {
-		r = truncate_inode(f->filp_ino, start);
-	}
-	return r;
-     }
-
-     default:
-	return(EINVAL);
-  }
-}
-
-/*===========================================================================*
- *				do_sync					     *
- *===========================================================================*/
-PUBLIC int do_sync()
-{
-/* Perform the sync() system call.  Flush all the tables. 
- * The order in which the various tables are flushed is critical.  The
- * blocks must be flushed last, since rw_inode() leaves its results in
- * the block cache.
- */
-  register struct inode *rip;
-  register struct buf *bp;
-
-  /* Write all the dirty inodes to the disk. */
-  for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++)
-	if (rip->i_count > 0 && rip->i_dirt == DIRTY) rw_inode(rip, WRITING);
-
-  /* Write all the dirty blocks to the disk, one drive at a time. */
-  for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++)
-	if (bp->b_dev != NO_DEV && bp->b_dirt == DIRTY) flushall(bp->b_dev);
-
-  return(OK);		/* sync() can't fail */
-}
-
-/*===========================================================================*
- *				do_fsync				     *
- *===========================================================================*/
-PUBLIC int do_fsync()
-{
-/* Perform the fsync() system call. For now, don't be unnecessarily smart. */
-
-  do_sync();
-
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_reboot				     *
- *===========================================================================*/
-PUBLIC int do_reboot()
-{
-  /* Perform the FS side of the reboot call. */
-  int i;
-  struct super_block *sp;
-  struct inode dummy;
-
-  /* Only PM may make this call directly. */
-  if (who_e != PM_PROC_NR) return(EGENERIC);
-
-  /* Do exit processing for all leftover processes and servers,
-   * but don't actually exit them (if they were really gone, PM
-   * will tell us about it).
-   */
-  for (i = 0; i < NR_PROCS; i++)
-	if((m_in.endpt1 = fproc[i].fp_endpoint) != NONE)
-		free_proc(&fproc[i], 0);
-
-  /* The root file system is mounted onto itself, which keeps it from being
-   * unmounted.  Pull an inode out of thin air and put the root on it.
-   */
-  put_inode(super_block[0].s_imount);
-  super_block[0].s_imount= &dummy;
-  dummy.i_count = 2;			/* expect one "put" */
-
-  /* Unmount all filesystems.  File systems are mounted on other file systems,
-   * so you have to pull off the loose bits repeatedly to get it all undone.
-   */
-  for (i= 0; i < NR_SUPERS; i++) {
-	/* Unmount at least one. */
-	for (sp= &super_block[0]; sp < &super_block[NR_SUPERS]; sp++) {
-		if (sp->s_dev != NO_DEV) (void) unmount(sp->s_dev);
-	}
-  }
-
-  /* Sync any unwritten buffers. */
-  do_sync();
-
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_fork					     *
- *===========================================================================*/
-PUBLIC int do_fork()
-{
-/* Perform those aspects of the fork() system call that relate to files.
- * In particular, let the child inherit its parent's file descriptors.
- * The parent and child parameters tell who forked off whom. The file
- * system uses the same slot numbers as the kernel.  Only MM makes this call.
- */
-
-  register struct fproc *cp;
-  int i, parentno, childno;
-
-  /* Only PM may make this call directly. */
-  if (who_e != PM_PROC_NR) return(EGENERIC);
-
-  /* Check up-to-dateness of fproc. */
-  okendpt(m_in.parent_endpt, &parentno);
-
-  /* PM gives child endpoint, which implies process slot information.
-   * Don't call isokendpt, because that will verify if the endpoint
-   * number is correct in fproc, which it won't be.
-   */
-  childno = _ENDPOINT_P(m_in.child_endpt);
-  if(childno < 0 || childno >= NR_PROCS)
-	panic(__FILE__, "FS: bogus child for forking", m_in.child_endpt);
-  if(fproc[childno].fp_pid != PID_FREE)
-	panic(__FILE__, "FS: forking on top of in-use child", childno);
-
-  /* Copy the parent's fproc struct to the child. */
-  fproc[childno] = fproc[parentno];
-
-  /* Increase the counters in the 'filp' table. */
-  cp = &fproc[childno];
-  for (i = 0; i < OPEN_MAX; i++)
-	if (cp->fp_filp[i] != NIL_FILP) cp->fp_filp[i]->filp_count++;
-
-  /* Fill in new process and endpoint id. */
-  cp->fp_pid = m_in.pid;
-  cp->fp_endpoint = m_in.child_endpt;
-
-  /* A child is not a process leader. */
-  cp->fp_sesldr = 0;
-
-  /* This child has not exec()ced yet. */
-  cp->fp_execced = 0;
-#if 0
-printf("do_fork: child %d, slot %d\n", m_in.child_endpt, cp-fproc);
-#endif
-
-  /* Record the fact that both root and working dir have another user. */
-  dup_inode(cp->fp_rootdir);
-  dup_inode(cp->fp_workdir);
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_exec					     *
- *===========================================================================*/
-PUBLIC int do_exec()
-{
-/* Files can be marked with the FD_CLOEXEC bit (in fp->fp_cloexec).  When
- * MM does an EXEC, it calls FS to allow FS to find these files and close them.
- */
-
-  int i, proc;
-  long bitmap;
-
-  /* Only PM may make this call directly. */
-  if (who_e != PM_PROC_NR) return(EGENERIC);
-
-  /* The array of FD_CLOEXEC bits is in the fp_cloexec bit map. */
-  okendpt(m_in.endpt1, &proc);
-  fp = &fproc[proc];		/* get_filp() needs 'fp' */
-  bitmap = fp->fp_cloexec;
-  if (bitmap) {
-    /* Check the file desriptors one by one for presence of FD_CLOEXEC. */
-    for (i = 0; i < OPEN_MAX; i++) {
-	  m_in.fd = i;
-	  if ( (bitmap >> i) & 01) (void) do_close();
-    }
-  }
-
-  /* This child has now exec()ced. */
-  fp->fp_execced = 1;
-
-  /* Reply to caller (PM) directly. */
-  reply(who_e, OK);
-
-  /* Check if this is a driver that can now be useful. */
-  dmap_endpt_up(fp->fp_endpoint);
-
-  /* Suppress reply to caller (caller already replied to). */
-  return SUSPEND;
-}
-
-/*===========================================================================*
- *				free_proc				     *
- *===========================================================================*/
-PRIVATE int free_proc(struct fproc *exiter, int flags)
-{
-  int i, task;
-  register struct fproc *rfp;
-  register struct filp *rfilp;
-  register struct inode *rip;
-  dev_t dev;
-
-  fp = exiter;		/* get_filp() needs 'fp' */
-
-  if (fp->fp_suspended == SUSPENDED) {
-	task = -fp->fp_task;
-	if (task == XPIPE || task == XPOPEN) susp_count--;
-	m_in.ENDPT = fp->fp_endpoint;
-	(void) do_unpause();	/* this always succeeds for MM */
-	fp->fp_suspended = NOT_SUSPENDED;
-  }
-
-  /* Loop on file descriptors, closing any that are open. */
-  for (i = 0; i < OPEN_MAX; i++) {
-	m_in.fd = i;
-	(void) do_close();
-  }
-
-  /* Release root and working directories. */
-  put_inode(fp->fp_rootdir);
-  put_inode(fp->fp_workdir);
-  fp->fp_rootdir = NIL_INODE;
-  fp->fp_workdir = NIL_INODE;
-
-  /* Check if any process is SUSPENDed on this driver.
-   * If a driver exits, unmap its entries in the dmap table.
-   * (unmapping has to be done after the first step, because the
-   * dmap table is used in the first step.)
-   */
-  unsuspend_by_endpt(fp->fp_endpoint);
-
-  /* The rest of these actions is only done when processes actually
-   * exit.
-   */
-  if(!(flags & FP_EXITING))
-	return OK;
-
-  dmap_unmap_by_endpt(fp->fp_endpoint);
-  /* Invalidate endpoint number for error and sanity checks. */
-  fp->fp_endpoint = NONE;
-
-  /* If a session leader exits and it has a controlling tty, then revoke 
-   * access to its controlling tty from all other processes using it.
-   */
-  if (fp->fp_sesldr && fp->fp_tty != 0) {
-
-      dev = fp->fp_tty;
-
-      for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
-	  if(rfp->fp_pid == PID_FREE) continue;
-          if (rfp->fp_tty == dev) rfp->fp_tty = 0;
-
-          for (i = 0; i < OPEN_MAX; i++) {
-		if ((rfilp = rfp->fp_filp[i]) == NIL_FILP) continue;
-		if (rfilp->filp_mode == FILP_CLOSED) continue;
-		rip = rfilp->filp_ino;
-		if ((rip->i_mode & I_TYPE) != I_CHAR_SPECIAL) continue;
-		if ((dev_t) rip->i_zone[0] != dev) continue;
-		dev_close(dev);
-		rfilp->filp_mode = FILP_CLOSED;
-          }
-      }
-  }
-
-  /* Exit done. Mark slot as free. */
-  fp->fp_pid = PID_FREE;
-  return(OK);
-
-}
-
-/*===========================================================================*
- *				do_exit					     *
- *===========================================================================*/
-PUBLIC int do_exit()
-{
-  int exitee_p, exitee_e;
-/* Perform the file system portion of the exit(status) system call. */
-
-  /* Only PM may do the EXIT call directly. */
-  if (who_e != PM_PROC_NR) return(EGENERIC);
-
-  /* Nevertheless, pretend that the call came from the user. */
-  exitee_e = m_in.endpt1;
-  okendpt(exitee_e, &exitee_p);
-  return free_proc(&fproc[exitee_p], FP_EXITING);
-}
-
-/*===========================================================================*
- *				do_set					     *
- *===========================================================================*/
-PUBLIC int do_set()
-{
-/* Set uid_t or gid_t field. */
-
-  register struct fproc *tfp;
-  int proc;
-
-  /* Only PM may make this call directly. */
-  if (who_e != PM_PROC_NR) return(EGENERIC);
-
-  okendpt(m_in.endpt1, &proc);
-  tfp = &fproc[proc];
-  if (call_nr == SETUID) {
-	tfp->fp_realuid = (uid_t) m_in.real_user_id;
-	tfp->fp_effuid =  (uid_t) m_in.eff_user_id;
-  }
-  if (call_nr == SETGID) {
-	tfp->fp_effgid =  (gid_t) m_in.eff_grp_id;
-	tfp->fp_realgid = (gid_t) m_in.real_grp_id;
-  }
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_revive				     *
- *===========================================================================*/
-PUBLIC int do_revive()
-{
-/* A driver, typically TTY, has now gotten the characters that were needed for 
- * a previous read.  The process did not get a reply when it made the call.
- * Instead it was suspended.  Now we can send the reply to wake it up.  This
- * business has to be done carefully, since the incoming message is from
- * a driver (to which no reply can be sent), and the reply must go to a process
- * that blocked earlier.  The reply to the caller is inhibited by returning the
- * 'SUSPEND' pseudo error, and the reply to the blocked process is done
- * explicitly in revive().
- */
-  revive(m_in.REP_ENDPT, m_in.REP_STATUS);
-  return(SUSPEND);		/* don't reply to the TTY task */
-}
-
-/*===========================================================================*
- *				do_svrctl				     *
- *===========================================================================*/
-PUBLIC int do_svrctl()
-{
-  switch (m_in.svrctl_req) {
-  case FSSIGNON: {
-	/* A server in user space calls in to manage a device. */
-	struct fssignon device;
-	int r, major, proc_nr_n;
-
-	if (fp->fp_effuid != SU_UID && fp->fp_effuid != SERVERS_UID)
-		return(EPERM);
-
-	/* Try to copy request structure to FS. */
-	if ((r = sys_datacopy(who_e, (vir_bytes) m_in.svrctl_argp,
-		FS_PROC_NR, (vir_bytes) &device,
-		(phys_bytes) sizeof(device))) != OK) 
-	    return(r);
-
-	if (isokendpt(who_e, &proc_nr_n) != OK)
-		return(EINVAL);
-
-	/* Try to update device mapping. */
-	major = (device.dev >> MAJOR) & BYTE;
-	r=map_driver(major, who_e, device.style);
-	if (r == OK)
-	{
-		/* If a driver has completed its exec(), it can be announced
-		 * to be up.
-		*/
-		if(fproc[proc_nr_n].fp_execced) {
-			dev_up(major);
-		} else {
-			dmap[major].dmap_flags |= DMAP_BABY;
-		}
-	}
-
-	return(r);
-  }
-  case FSDEVUNMAP: {
-	struct fsdevunmap fdu;
-	int r, major;
-	/* Try to copy request structure to FS. */
-	if ((r = sys_datacopy(who_e, (vir_bytes) m_in.svrctl_argp,
-		FS_PROC_NR, (vir_bytes) &fdu,
-		(phys_bytes) sizeof(fdu))) != OK) 
-	    return(r);
-	major = (fdu.dev >> MAJOR) & BYTE;
-	r=map_driver(major, NONE, 0);
-	return(r);
-  }
-  default:
-	return(EINVAL);
-  }
-}
Index: trunk/minix/servers/fs/mount.c
===================================================================
--- trunk/minix/servers/fs/mount.c	(revision 11)
+++ 	(revision )
@@ -1,353 +1,0 @@
-/* This file performs the MOUNT and UMOUNT system calls.
- *
- * The entry points into this file are
- *   do_mount:	perform the MOUNT system call
- *   do_umount:	perform the UMOUNT system call
- */
-
-#include "fs.h"
-#include <fcntl.h>
-#include <string.h>
-#include <minix/com.h>
-#include <sys/stat.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-/* Allow the root to be replaced before the first 'real' mount. */
-PRIVATE int allow_newroot= 1;
-
-FORWARD _PROTOTYPE( dev_t name_to_dev, (char *path)			);
-
-/*===========================================================================*
- *				do_mount				     *
- *===========================================================================*/
-PUBLIC int do_mount()
-{
-/* Perform the mount(name, mfile, rd_only) system call. */
-
-  register struct inode *rip, *root_ip;
-  struct super_block *xp, *sp;
-  dev_t dev;
-  mode_t bits;
-  int rdir, mdir;		/* TRUE iff {root|mount} file is dir */
-  int i, r, found;
-  struct fproc *tfp;
-
-  /* Only the super-user may do MOUNT. */
-  if (!super_user) return(EPERM);
-
-  /* If 'name' is not for a block special file, return error. */
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  if ( (dev = name_to_dev(user_path)) == NO_DEV) return(err_code);
-
-  /* Scan super block table to see if dev already mounted & find a free slot.*/
-  sp = NIL_SUPER;
-  found = FALSE;
-  for (xp = &super_block[0]; xp < &super_block[NR_SUPERS]; xp++) {
-	if (xp->s_dev == dev)
-	{
-		/* is it mounted already? */
-		found = TRUE;
-		sp= xp;
-		break;
-	}
-	if (xp->s_dev == NO_DEV) sp = xp;	/* record free slot */
-  }
-  if (found)
-  {
-	printf(
-"do_mount: s_imount = 0x%x (%x, %d), s_isup = 0x%x (%x, %d), fp_rootdir = 0x%x\n",
-		xp->s_imount, xp->s_imount->i_dev, xp->s_imount->i_num,
-		xp->s_isup, xp->s_isup->i_dev, xp->s_isup->i_num,
-		fproc[FS_PROC_NR].fp_rootdir);
-	/* It is possible that we have an old root lying around that 
-	 * needs to be remounted.
-	 */
-	if (xp->s_imount != xp->s_isup ||
-		xp->s_isup == fproc[FS_PROC_NR].fp_rootdir)
-	{
-		/* Normally, s_imount refers to the mount point. For a root
-		 * filesystem, s_imount is equal to the root inode. We assume
-		 * that the root of FS is always the real root. If the two
-		 * inodes are different or if the root of FS is equal two the
-		 * root of the filesystem we found, we found a filesystem that
-		 * is in use.
-		 */
-		return(EBUSY);	/* already mounted */
-	}
-
-	if (root_dev == xp->s_dev)
-	{
-		panic("fs", "inconsistency remounting old root",
-			NO_NUM);
-	}
-
-	/* Now get the inode of the file to be mounted on. */
-	if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
-		return(err_code);
-	}
-
-	if ( (rip = eat_path(user_path)) == NIL_INODE) {
-		return(err_code);
-	}
-
-	r = OK;
-
-	/* It may not be special. */
-	bits = rip->i_mode & I_TYPE;
-	if (bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL)
-		r = ENOTDIR;
-
-	/* Get the root inode of the mounted file system. */
-	root_ip= sp->s_isup;
-
-	/* File types of 'rip' and 'root_ip' may not conflict. */
-	if (r == OK) {
-		mdir = ((rip->i_mode & I_TYPE) == I_DIRECTORY); 
-						/* TRUE iff dir */
-		rdir = ((root_ip->i_mode & I_TYPE) == I_DIRECTORY);
-		if (!mdir && rdir) r = EISDIR;
-	}
-
-	/* If error, return the mount point. */
-	if (r != OK) {
-		put_inode(rip);
-		return(r);
-	}
-
-	/* Nothing else can go wrong.  Perform the mount. */
-	rip->i_mount = I_MOUNT;	/* this bit says the inode is
-				 * mounted on
-				 */
-	put_inode(sp->s_imount);
-	sp->s_imount = rip;
-	sp->s_rd_only = m_in.rd_only;
-	allow_newroot= 0;		/* The root is now fixed */
-	return(OK);
-  }
-  if (sp == NIL_SUPER) return(ENFILE);	/* no super block available */
-
-  /* Open the device the file system lives on. */
-  if (dev_open(dev, who_e, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK) 
-  	return(EINVAL);
-
-  /* Make the cache forget about blocks it has open on the filesystem */
-  (void) do_sync();
-  invalidate(dev);
-
-  /* Fill in the super block. */
-  sp->s_dev = dev;		/* read_super() needs to know which dev */
-  r = read_super(sp);
-
-  /* Is it recognized as a Minix filesystem? */
-  if (r != OK) {
-	dev_close(dev);
-	sp->s_dev = NO_DEV;
-	return(r);
-  }
-
-  /* Now get the inode of the file to be mounted on. */
-  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
-	dev_close(dev);
-	sp->s_dev = NO_DEV;
-	return(err_code);
-  }
-
-  if (strcmp(user_path, "/") == 0 && allow_newroot)
-  {
-	printf("Replacing root\n");
-
-	/* Get the root inode of the mounted file system. */
-	if ( (root_ip = get_inode(dev, ROOT_INODE)) == NIL_INODE) r = err_code;
-	if (root_ip != NIL_INODE && root_ip->i_mode == 0) {
-		r = EINVAL;
-	}
-
-	/* If error, return the super block and both inodes; release the
-	 * maps.
-	 */
-	if (r != OK) {
-		put_inode(root_ip);
-		(void) do_sync();
-		invalidate(dev);
-		dev_close(dev);
-		sp->s_dev = NO_DEV;
-		return(r);
-	}
-
-	/* Nothing else can go wrong.  Perform the mount. */
-	sp->s_imount = root_ip;
-	dup_inode(root_ip);
-	sp->s_isup = root_ip;
-	sp->s_rd_only = m_in.rd_only;
-	root_dev= dev;
-
-	/* Replace all root and working directories */
-	for (i= 0, tfp= fproc; i<NR_PROCS; i++, tfp++)
-	{
-		if (tfp->fp_pid == PID_FREE)
-			continue;
-		if (tfp->fp_rootdir == NULL)
-			panic("fs", "do_mount: null rootdir", i);
-		put_inode(tfp->fp_rootdir);
-		dup_inode(root_ip);
-		tfp->fp_rootdir= root_ip;
-
-		if (tfp->fp_workdir == NULL)
-			panic("fs", "do_mount: null workdir", i);
-		put_inode(tfp->fp_workdir);
-		dup_inode(root_ip);
-		tfp->fp_workdir= root_ip;
-	}
-
-	/* Leave the old filesystem lying around. */
-	return(OK);
-  }
-
-  if ( (rip = eat_path(user_path)) == NIL_INODE) {
-	dev_close(dev);
-	sp->s_dev = NO_DEV;
-	return(err_code);
-  }
-
-  /* It may not be busy. */
-  r = OK;
-  if (rip->i_count > 1) r = EBUSY;
-
-  /* It may not be special. */
-  bits = rip->i_mode & I_TYPE;
-  if (bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL) r = ENOTDIR;
-
-  /* Get the root inode of the mounted file system. */
-  root_ip = NIL_INODE;		/* if 'r' not OK, make sure this is defined */
-  if (r == OK) {
-	if ( (root_ip = get_inode(dev, ROOT_INODE)) == NIL_INODE) r = err_code;
-  }
-  if (root_ip != NIL_INODE && root_ip->i_mode == 0) {
-  	r = EINVAL;
-  }
-
-  /* File types of 'rip' and 'root_ip' may not conflict. */
-  if (r == OK) {
-	mdir = ((rip->i_mode & I_TYPE) == I_DIRECTORY);  /* TRUE iff dir */
-	rdir = ((root_ip->i_mode & I_TYPE) == I_DIRECTORY);
-	if (!mdir && rdir) r = EISDIR;
-  }
-
-  /* If error, return the super block and both inodes; release the maps. */
-  if (r != OK) {
-	put_inode(rip);
-	put_inode(root_ip);
-	(void) do_sync();
-	invalidate(dev);
-	dev_close(dev);
-	sp->s_dev = NO_DEV;
-	return(r);
-  }
-
-  /* Nothing else can go wrong.  Perform the mount. */
-  rip->i_mount = I_MOUNT;	/* this bit says the inode is mounted on */
-  sp->s_imount = rip;
-  sp->s_isup = root_ip;
-  sp->s_rd_only = m_in.rd_only;
-  allow_newroot= 0;		/* The root is now fixed */
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_umount				     *
- *===========================================================================*/
-PUBLIC int do_umount()
-{
-/* Perform the umount(name) system call. */
-  dev_t dev;
-
-  /* Only the super-user may do UMOUNT. */
-  if (!super_user) return(EPERM);
-
-  /* If 'name' is not for a block special file, return error. */
-  if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
-  if ( (dev = name_to_dev(user_path)) == NO_DEV) return(err_code);
-
-  return(unmount(dev));
-}
-
-/*===========================================================================*
- *				unmount					     *
- *===========================================================================*/
-PUBLIC int unmount(dev)
-Dev_t dev;
-{
-/* Unmount a file system by device number. */
-  register struct inode *rip;
-  struct super_block *sp, *sp1;
-  int count;
-
-  /* See if the mounted device is busy.  Only 1 inode using it should be
-   * open -- the root inode -- and that inode only 1 time.
-   */
-  count = 0;
-  for (rip = &inode[0]; rip< &inode[NR_INODES]; rip++)
-	if (rip->i_count > 0 && rip->i_dev == dev) count += rip->i_count;
-  if (count > 1) return(EBUSY);	/* can't umount a busy file system */
-
-  /* Find the super block. */
-  sp = NIL_SUPER;
-  for (sp1 = &super_block[0]; sp1 < &super_block[NR_SUPERS]; sp1++) {
-	if (sp1->s_dev == dev) {
-		sp = sp1;
-		break;
-	}
-  }
-
-  /* Sync the disk, and invalidate cache. */
-  (void) do_sync();		/* force any cached blocks out of memory */
-  invalidate(dev);		/* invalidate cache entries for this dev */
-  if (sp == NIL_SUPER) {
-  	return(EINVAL);
-  }
-
-  /* Close the device the file system lives on. */
-  dev_close(dev);
-
-  /* Finish off the unmount. */
-  sp->s_imount->i_mount = NO_MOUNT;	/* inode returns to normal */
-  put_inode(sp->s_imount);	/* release the inode mounted on */
-  put_inode(sp->s_isup);	/* release the root inode of the mounted fs */
-  sp->s_imount = NIL_INODE;
-  sp->s_dev = NO_DEV;
-  return(OK);
-}
-
-/*===========================================================================*
- *				name_to_dev				     *
- *===========================================================================*/
-PRIVATE dev_t name_to_dev(path)
-char *path;			/* pointer to path name */
-{
-/* Convert the block special file 'path' to a device number.  If 'path'
- * is not a block special file, return error code in 'err_code'.
- */
-
-  register struct inode *rip;
-  register dev_t dev;
-
-  /* If 'path' can't be opened, give up immediately. */
-  if ( (rip = eat_path(path)) == NIL_INODE) return(NO_DEV);
-
-  /* If 'path' is not a block special file, return error. */
-  if ( (rip->i_mode & I_TYPE) != I_BLOCK_SPECIAL) {
-	err_code = ENOTBLK;
-	put_inode(rip);
-	return(NO_DEV);
-  }
-
-  /* Extract the device number. */
-  dev = (dev_t) rip->i_zone[0];
-  put_inode(rip);
-  return(dev);
-}
Index: trunk/minix/servers/fs/open.c
===================================================================
--- trunk/minix/servers/fs/open.c	(revision 11)
+++ 	(revision )
@@ -1,563 +1,0 @@
-/* This file contains the procedures for creating, opening, closing, and
- * seeking on files.
- *
- * The entry points into this file are
- *   do_creat:	perform the CREAT system call
- *   do_open:	perform the OPEN system call
- *   do_mknod:	perform the MKNOD system call
- *   do_mkdir:	perform the MKDIR system call
- *   do_close:	perform the CLOSE system call
- *   do_lseek:  perform the LSEEK system call
- */
-
-#include "fs.h"
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "lock.h"
-#include "param.h"
-#include "super.h"
-
-#define offset m2_l1
-
-PRIVATE char mode_map[] = {R_BIT, W_BIT, R_BIT|W_BIT, 0};
-
-FORWARD _PROTOTYPE( int common_open, (int oflags, mode_t omode)		);
-FORWARD _PROTOTYPE( int pipe_open, (struct inode *rip,mode_t bits,int oflags));
-FORWARD _PROTOTYPE( struct inode *new_node, (struct inode **ldirp, 
-	char *path, mode_t bits, zone_t z0, int opaque, char *string));
-
-/*===========================================================================*
- *				do_creat				     *
- *===========================================================================*/
-PUBLIC int do_creat()
-{
-/* Perform the creat(name, mode) system call. */
-  int r;
-
-  if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
-  r = common_open(O_WRONLY | O_CREAT | O_TRUNC, (mode_t) m_in.mode);
-  return(r);
-}
-
-/*===========================================================================*
- *				do_open					     *
- *===========================================================================*/
-PUBLIC int do_open()
-{
-/* Perform the open(name, flags,...) system call. */
-
-  int create_mode = 0;		/* is really mode_t but this gives problems */
-  int r;
-
-  /* If O_CREAT is set, open has three parameters, otherwise two. */
-  if (m_in.mode & O_CREAT) {
-	create_mode = m_in.c_mode;	
-	r = fetch_name(m_in.c_name, m_in.name1_length, M1);
-  } else {
-	r = fetch_name(m_in.name, m_in.name_length, M3);
-  }
-
-  if (r != OK) return(err_code); /* name was bad */
-  r = common_open(m_in.mode, create_mode);
-  return(r);
-}
-
-/*===========================================================================*
- *				common_open				     *
- *===========================================================================*/
-PRIVATE int common_open(register int oflags, mode_t omode)
-{
-/* Common code from do_creat and do_open. */
-
-  struct inode *rip, *ldirp;
-  int r, b, exist = TRUE;
-  dev_t dev;
-  mode_t bits;
-  off_t pos;
-  struct filp *fil_ptr, *filp2;
-
-  /* Remap the bottom two bits of oflags. */
-  bits = (mode_t) mode_map[oflags & O_ACCMODE];
-
-  /* See if file descriptor and filp slots are available. */
-  if ( (r = get_fd(0, bits, &m_in.fd, &fil_ptr)) != OK) return(r);
-
-  /* If O_CREATE is set, try to make the file. */ 
-  if (oflags & O_CREAT) {
-  	/* Create a new inode by calling new_node(). */
-        omode = I_REGULAR | (omode & ALL_MODES & fp->fp_umask);
-    	rip = new_node(&ldirp, user_path, omode, NO_ZONE, oflags&O_EXCL, NULL);
-    	r = err_code;
-        put_inode(ldirp);
-    	if (r == OK) exist = FALSE;      /* we just created the file */
-	else if (r != EEXIST) return(r); /* other error */
-	else exist = !(oflags & O_EXCL); /* file exists, if the O_EXCL 
-					    flag is set this is an error */
-  } else {
-	 /* Scan path name. */
-    	if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-  }
-
-  /* Claim the file descriptor and filp slot and fill them in. */
-  fp->fp_filp[m_in.fd] = fil_ptr;
-  FD_SET(m_in.fd, &fp->fp_filp_inuse);
-  fil_ptr->filp_count = 1;
-  fil_ptr->filp_ino = rip;
-  fil_ptr->filp_flags = oflags;
-
-  /* Only do the normal open code if we didn't just create the file. */
-  if (exist) {
-  	/* Check protections. */
-  	if ((r = forbidden(rip, bits)) == OK) {
-  		/* Opening reg. files directories and special files differ. */
-	  	switch (rip->i_mode & I_TYPE) {
-    		   case I_REGULAR: 
-			/* Truncate regular file if O_TRUNC. */
-			if (oflags & O_TRUNC) {
-				if ((r = forbidden(rip, W_BIT)) !=OK) break;
-				truncate_inode(rip, 0);
-				wipe_inode(rip);
-				/* Send the inode from the inode cache to the
-				 * block cache, so it gets written on the next
-				 * cache flush.
-				 */
-				rw_inode(rip, WRITING);
-			}
-			break;
- 
-	    	   case I_DIRECTORY: 
-			/* Directories may be read but not written. */
-			r = (bits & W_BIT ? EISDIR : OK);
-			break;
-
-	     	   case I_CHAR_SPECIAL:
-     		   case I_BLOCK_SPECIAL:
-			/* Invoke the driver for special processing. */
-			dev = (dev_t) rip->i_zone[0];
-			r = dev_open(dev, who_e, bits | (oflags & ~O_ACCMODE));
-			break;
-
-		   case I_NAMED_PIPE:
-			oflags |= O_APPEND;	/* force append mode */
-			fil_ptr->filp_flags = oflags;
-			r = pipe_open(rip, bits, oflags);
-			if (r != ENXIO) {
-				/* See if someone else is doing a rd or wt on
-				 * the FIFO.  If so, use its filp entry so the
-				 * file position will be automatically shared.
-				 */
-				b = (bits & R_BIT ? R_BIT : W_BIT);
-				fil_ptr->filp_count = 0; /* don't find self */
-				if ((filp2 = find_filp(rip, b)) != NIL_FILP) {
-					/* Co-reader or writer found. Use it.*/
-					fp->fp_filp[m_in.fd] = filp2;
-					filp2->filp_count++;
-					filp2->filp_ino = rip;
-					filp2->filp_flags = oflags;
-
-					/* i_count was incremented incorrectly
-					 * by eatpath above, not knowing that
-					 * we were going to use an existing
-					 * filp entry.  Correct this error.
-					 */
-					rip->i_count--;
-				} else {
-					/* Nobody else found.  Restore filp. */
-					fil_ptr->filp_count = 1;
-					if (b == R_BIT)
-					     pos = rip->i_zone[V2_NR_DZONES+0];
-					else
-					     pos = rip->i_zone[V2_NR_DZONES+1];
-					fil_ptr->filp_pos = pos;
-				}
-			}
-			break;
- 		}
-  	}
-  }
-
-  /* If error, release inode. */
-  if (r != OK) {
-	if (r == SUSPEND) return(r);		/* Oops, just suspended */
-	fp->fp_filp[m_in.fd] = NIL_FILP;
-  	FD_CLR(m_in.fd, &fp->fp_filp_inuse);
-	fil_ptr->filp_count= 0;
-	put_inode(rip);
-	return(r);
-  }
-  
-  return(m_in.fd);
-}
-
-/*===========================================================================*
- *				new_node				     *
- *===========================================================================*/
-PRIVATE struct inode *new_node(struct inode **ldirp,
-	char *path, mode_t bits, zone_t z0, int opaque, char *parsed)
-{
-/* New_node() is called by common_open(), do_mknod(), and do_mkdir().  
- * In all cases it allocates a new inode, makes a directory entry for it on 
- * the path 'path', and initializes it.  It returns a pointer to the inode if 
- * it can do this; otherwise it returns NIL_INODE.  It always sets 'err_code'
- * to an appropriate value (OK or an error code).
- * 
- * The parsed path rest is returned in 'parsed' if parsed is nonzero. It
- * has to hold at least NAME_MAX bytes.
- */
-
-  register struct inode *rip;
-  register int r;
-  char string[NAME_MAX];
-
-  *ldirp = parse_path(path, string, opaque ? LAST_DIR : LAST_DIR_EATSYM);       
-  if (*ldirp == NIL_INODE) return(NIL_INODE);
-
-  /* The final directory is accessible. Get final component of the path. */
-  rip = advance(ldirp, string);
-
-  if (S_ISDIR(bits) && 
-      (*ldirp)->i_nlinks >= ((*ldirp)->i_sp->s_version == V1 ?
-      CHAR_MAX : SHRT_MAX)) {
-        /* New entry is a directory, alas we can't give it a ".." */
-        put_inode(rip);
-        err_code = EMLINK;
-        return(NIL_INODE);
-  }
-
-  if ( rip == NIL_INODE && err_code == ENOENT) {
-	/* Last path component does not exist.  Make new directory entry. */
-	if ( (rip = alloc_inode((*ldirp)->i_dev, bits)) == NIL_INODE) {
-		/* Can't creat new inode: out of inodes. */
-		return(NIL_INODE);
-	}
-
-	/* Force inode to the disk before making directory entry to make
-	 * the system more robust in the face of a crash: an inode with
-	 * no directory entry is much better than the opposite.
-	 */
-	rip->i_nlinks++;
-	rip->i_zone[0] = z0;		/* major/minor device numbers */
-	rw_inode(rip, WRITING);		/* force inode to disk now */
-
-	/* New inode acquired.  Try to make directory entry. */
-	if ((r = search_dir(*ldirp, string, &rip->i_num,ENTER)) != OK) {
-		rip->i_nlinks--;	/* pity, have to free disk inode */
-		rip->i_dirt = DIRTY;	/* dirty inodes are written out */
-		put_inode(rip);	/* this call frees the inode */
-		err_code = r;
-		return(NIL_INODE);
-	}
-
-  } else {
-	/* Either last component exists, or there is some problem. */
-	if (rip != NIL_INODE)
-		r = EEXIST;
-	else
-		r = err_code;
-  }
-
-  if(parsed) { /* Give the caller the parsed string if requested. */
-	strncpy(parsed, string, NAME_MAX-1);
-	parsed[NAME_MAX-1] = '\0';
-  }
-
-  /* The caller has to return the directory inode (*ldirp).  */
-  err_code = r;
-  return(rip);
-}
-
-/*===========================================================================*
- *				pipe_open				     *
- *===========================================================================*/
-PRIVATE int pipe_open(register struct inode *rip, register mode_t bits,
-	register int oflags)
-{
-/*  This function is called from common_open. It checks if
- *  there is at least one reader/writer pair for the pipe, if not
- *  it suspends the caller, otherwise it revives all other blocked
- *  processes hanging on the pipe.
- */
-
-  rip->i_pipe = I_PIPE; 
-
-  if((bits & (R_BIT|W_BIT)) == (R_BIT|W_BIT)) {
-	printf("pipe opened RW.\n");
-	return ENXIO;
-  }
-
-  if (find_filp(rip, bits & W_BIT ? R_BIT : W_BIT) == NIL_FILP) { 
-	if (oflags & O_NONBLOCK) {
-		if (bits & W_BIT) return(ENXIO);
-	} else {
-		suspend(XPOPEN);	/* suspend caller */
-		return(SUSPEND);
-	}
-  } else if (susp_count > 0) {/* revive blocked processes */
-	release(rip, OPEN, susp_count);
-	release(rip, CREAT, susp_count);
-  }
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_mknod				     *
- *===========================================================================*/
-PUBLIC int do_mknod()
-{
-/* Perform the mknod(name, mode, addr) system call. */
-
-  register mode_t bits, mode_bits;
-  struct inode *ip, *ldirp;
-
-  /* Only the super_user may make nodes other than fifos. */
-  mode_bits = (mode_t) m_in.mk_mode;		/* mode of the inode */
-  if (!super_user && ((mode_bits & I_TYPE) != I_NAMED_PIPE)) return(EPERM);
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  bits = (mode_bits & I_TYPE) | (mode_bits & ALL_MODES & fp->fp_umask);
-  ip = new_node(&ldirp, user_path, bits, (zone_t) m_in.mk_z0, TRUE, NULL);
-  put_inode(ip);
-  put_inode(ldirp);
-  return(err_code);
-}
-
-/*===========================================================================*
- *				do_mkdir				     *
- *===========================================================================*/
-PUBLIC int do_mkdir()
-{
-/* Perform the mkdir(name, mode) system call. */
-
-  int r1, r2;			/* status codes */
-  ino_t dot, dotdot;		/* inode numbers for . and .. */
-  mode_t bits;			/* mode bits for the new inode */
-  char string[NAME_MAX];	/* last component of the new dir's path name */
-  struct inode *rip, *ldirp;
-
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-
-  /* Next make the inode. If that fails, return error code. */
-  bits = I_DIRECTORY | (m_in.mode & RWX_MODES & fp->fp_umask);
-  rip = new_node(&ldirp, user_path, bits, (zone_t) 0, TRUE, string);
-  if (rip == NIL_INODE || err_code == EEXIST) {
-	put_inode(rip);		/* can't make dir: it already exists */
-	put_inode(ldirp);
-	return(err_code);
-  }
-
-  /* Get the inode numbers for . and .. to enter in the directory. */
-  dotdot = ldirp->i_num;	/* parent's inode number */
-  dot = rip->i_num;		/* inode number of the new dir itself */
-
-  /* Now make dir entries for . and .. unless the disk is completely full. */
-  /* Use dot1 and dot2, so the mode of the directory isn't important. */
-  rip->i_mode = bits;	/* set mode */
-  r1 = search_dir(rip, dot1, &dot, ENTER);	/* enter . in the new dir */
-  r2 = search_dir(rip, dot2, &dotdot, ENTER);	/* enter .. in the new dir */
-
-  /* If both . and .. were successfully entered, increment the link counts. */
-  if (r1 == OK && r2 == OK) {
-	/* Normal case.  It was possible to enter . and .. in the new dir. */
-	rip->i_nlinks++;	/* this accounts for . */
-	ldirp->i_nlinks++;	/* this accounts for .. */
-	ldirp->i_dirt = DIRTY;	/* mark parent's inode as dirty */
-  } else {
-	/* It was not possible to enter . or .. probably disk was full -
-	 * links counts haven't been touched.
-	 */
-	if(search_dir(ldirp, string, (ino_t *) 0, DELETE) != OK)
-		panic(__FILE__, "Dir disappeared ", rip->i_num);
-	rip->i_nlinks--;	/* undo the increment done in new_node() */
-  }
-  rip->i_dirt = DIRTY;		/* either way, i_nlinks has changed */
-
-  put_inode(ldirp);		/* return the inode of the parent dir */
-  put_inode(rip);		/* return the inode of the newly made dir */
-  return(err_code);		/* new_node() always sets 'err_code' */
-}
-
-/*===========================================================================*
- *				do_close				     *
- *===========================================================================*/
-PUBLIC int do_close()
-{
-/* Perform the close(fd) system call. */
-
-  register struct filp *rfilp;
-  register struct inode *rip;
-  struct file_lock *flp;
-  int rw, mode_word, lock_count;
-  dev_t dev;
-
-  /* First locate the inode that belongs to the file descriptor. */
-  if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
-  rip = rfilp->filp_ino;	/* 'rip' points to the inode */
-
-  if (rfilp->filp_count - 1 == 0 && rfilp->filp_mode != FILP_CLOSED) {
-	/* Check to see if the file is special. */
-	mode_word = rip->i_mode & I_TYPE;
-	if (mode_word == I_CHAR_SPECIAL || mode_word == I_BLOCK_SPECIAL) {
-		dev = (dev_t) rip->i_zone[0];
-		if (mode_word == I_BLOCK_SPECIAL)  {
-			/* Invalidate cache entries unless special is mounted
-			 * or ROOT
-			 */
-			if (!mounted(rip)) {
-			        (void) do_sync();	/* purge cache */
-				invalidate(dev);
-			}    
-		}
-		/* Do any special processing on device close. */
-		dev_close(dev);
-	}
-  }
-
-  /* If the inode being closed is a pipe, release everyone hanging on it. */
-  if (rip->i_pipe == I_PIPE) {
-	rw = (rfilp->filp_mode & R_BIT ? WRITE : READ);
-	release(rip, rw, NR_PROCS);
-  }
-
-  /* If a write has been done, the inode is already marked as DIRTY. */
-  if (--rfilp->filp_count == 0) {
-	if (rip->i_pipe == I_PIPE && rip->i_count > 1) {
-		/* Save the file position in the i-node in case needed later.
-		 * The read and write positions are saved separately.  The
-		 * last 3 zones in the i-node are not used for (named) pipes.
-		 */
-		if (rfilp->filp_mode == R_BIT)
-			rip->i_zone[V2_NR_DZONES+0] = (zone_t) rfilp->filp_pos;
-		else
-			rip->i_zone[V2_NR_DZONES+1] = (zone_t) rfilp->filp_pos;
-	}
-	put_inode(rip);
-  }
-
-  fp->fp_cloexec &= ~(1L << m_in.fd);	/* turn off close-on-exec bit */
-  fp->fp_filp[m_in.fd] = NIL_FILP;
-  FD_CLR(m_in.fd, &fp->fp_filp_inuse);
-
-  /* Check to see if the file is locked.  If so, release all locks. */
-  if (nr_locks == 0) return(OK);
-  lock_count = nr_locks;	/* save count of locks */
-  for (flp = &file_lock[0]; flp < &file_lock[NR_LOCKS]; flp++) {
-	if (flp->lock_type == 0) continue;	/* slot not in use */
-	if (flp->lock_inode == rip && flp->lock_pid == fp->fp_pid) {
-		flp->lock_type = 0;
-		nr_locks--;
-	}
-  }
-  if (nr_locks < lock_count) lock_revive();	/* lock released */
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_lseek				     *
- *===========================================================================*/
-PUBLIC int do_lseek()
-{
-/* Perform the lseek(ls_fd, offset, whence) system call. */
-
-  register struct filp *rfilp;
-  register off_t pos;
-
-  /* Check to see if the file descriptor is valid. */
-  if ( (rfilp = get_filp(m_in.ls_fd)) == NIL_FILP) return(err_code);
-
-  /* No lseek on pipes. */
-  if (rfilp->filp_ino->i_pipe == I_PIPE) return(ESPIPE);
-
-  /* The value of 'whence' determines the start position to use. */
-  switch(m_in.whence) {
-	case SEEK_SET: pos = 0;	break;
-	case SEEK_CUR: pos = rfilp->filp_pos;	break;
-	case SEEK_END: pos = rfilp->filp_ino->i_size;	break;
-	default: return(EINVAL);
-  }
-
-  /* Check for overflow. */
-  if (((long)m_in.offset > 0) && ((long)(pos + m_in.offset) < (long)pos)) 
-  	return(EINVAL);
-  if (((long)m_in.offset < 0) && ((long)(pos + m_in.offset) > (long)pos)) 
-  	return(EINVAL);
-  pos = pos + m_in.offset;
-
-  if (pos != rfilp->filp_pos)
-	rfilp->filp_ino->i_seek = ISEEK;	/* inhibit read ahead */
-  rfilp->filp_pos = pos;
-  m_out.reply_l1 = pos;		/* insert the long into the output message */
-  return(OK);
-}
-
-/*===========================================================================*
- *                             do_slink					     *
- *===========================================================================*/
-PUBLIC int do_slink()
-{
-/* Perform the symlink(name1, name2) system call. */
-
-  register int r;              /* error code */
-  char string[NAME_MAX];       /* last component of the new dir's path name */
-  struct inode *sip;           /* inode containing symbolic link */
-  struct buf *bp;              /* disk buffer for link */
-  struct inode *ldirp;         /* directory containing link */
-
-  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK)
-       return(err_code);
-
-  if (m_in.name1_length <= 1 || m_in.name1_length >= _MIN_BLOCK_SIZE)
-       return(ENAMETOOLONG);
-
-  /* Create the inode for the symlink. */
-  sip = new_node(&ldirp, user_path, (mode_t) (I_SYMBOLIC_LINK | RWX_MODES),
-                 (zone_t) 0, TRUE, string);
-
-  /* Allocate a disk block for the contents of the symlink.
-   * Copy contents of symlink (the name pointed to) into first disk block.
-   */
-  if ((r = err_code) == OK) {
-       r = (bp = new_block(sip, (off_t) 0)) == NIL_BUF
-           ? err_code
-           : sys_vircopy(who_e, D, (vir_bytes) m_in.name1,
-                       SELF, D, (vir_bytes) bp->b_data,
-		       (vir_bytes) m_in.name1_length-1);
-
-	if(r == OK) {
-		bp->b_data[_MIN_BLOCK_SIZE-1] = '\0';
-		sip->i_size = strlen(bp->b_data);
-		if(sip->i_size != m_in.name1_length-1) {
-			/* This can happen if the user provides a buffer
-			 * with a \0 in it. This can cause a lot of trouble
-			 * when the symlink is used later. We could just use
-			 * the strlen() value, but we want to let the user
-			 * know he did something wrong. ENAMETOOLONG doesn't
-			 * exactly describe the error, but there is no
-			 * ENAMETOOWRONG.
-			 */
-			r = ENAMETOOLONG;
-		}
-	}
-  
-       put_block(bp, DIRECTORY_BLOCK); 	/* put_block() accepts NIL_BUF. */
-  
-       if (r != OK) {
-               sip->i_nlinks = 0;
-               if (search_dir(ldirp, string, (ino_t *) 0, DELETE) != OK)
-                       panic(__FILE__, "Symbolic link vanished", NO_NUM);
-       } 
-  }
-
-  /* put_inode() accepts NIL_INODE as a noop, so the below are safe. */
-  put_inode(sip);
-  put_inode(ldirp);
-
-  return(r);
-}
-
Index: trunk/minix/servers/fs/param.h
===================================================================
--- trunk/minix/servers/fs/param.h	(revision 11)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/* The following names are synonyms for the variables in the input message. */
-#define acc_time      m2_l1
-#define addr	      m1_i3
-#define buffer	      m1_p1
-#define child_endpt      m1_i2
-#define co_mode	      m1_i1
-#define eff_grp_id    m1_i3
-#define eff_user_id   m1_i3
-#define erki          m1_p1
-#define fd	      m1_i1
-#define fd2	      m1_i2
-#define ioflags       m1_i3
-#define group	      m1_i3
-#define real_grp_id   m1_i2
-#define ls_fd	      m2_i1
-#define mk_mode	      m1_i2
-#define mk_z0	      m1_i3
-#define mode	      m3_i2
-#define c_mode        m1_i3
-#define c_name        m1_p1
-#define name	      m3_p1
-#define name1	      m1_p1
-#define name2	      m1_p2
-#define	name_length   m3_i1
-#define name1_length  m1_i1
-#define name2_length  m1_i2
-#define nbytes        m1_i2
-#define owner	      m1_i2
-#define parent_endpt      m1_i1
-#define pathname      m3_ca1
-#define pid	      m1_i3
-#define ENDPT	      m1_i1
-#define ctl_req       m4_l1
-#define driver_nr     m4_l2
-#define dev_nr	      m4_l3
-#define dev_style     m4_l4
-#define rd_only	      m1_i3
-#define real_user_id  m1_i2
-#define request       m1_i2
-#define sig	      m1_i2
-#define endpt1	      m1_i1
-#define tp	      m2_l1
-#define utime_actime  m2_l1
-#define utime_modtime m2_l2
-#define utime_file    m2_p1
-#define utime_length  m2_i1
-#define utime_strlen  m2_i2
-#define whence	      m2_i2
-#define svrctl_req    m2_i1
-#define svrctl_argp   m2_p1
-#define pm_stime      m1_i1
-#define info_what     m1_i1
-#define info_where    m1_p1
-
-/* The following names are synonyms for the variables in the output message. */
-#define reply_type    m_type
-#define reply_l1      m2_l1
-#define reply_i1      m1_i1
-#define reply_i2      m1_i2
-#define reply_t1      m4_l1
-#define reply_t2      m4_l2
-#define reply_t3      m4_l3
-#define reply_t4      m4_l4
-#define reply_t5      m4_l5
Index: trunk/minix/servers/fs/path.c
===================================================================
--- trunk/minix/servers/fs/path.c	(revision 11)
+++ 	(revision )
@@ -1,486 +1,0 @@
-/* This file contains the procedures that look up path names in the directory
- * system and determine the inode number that goes with a given path name.
- *
- *  The entry points into this file are
- *   eat_path:	 the 'main' routine of the path-to-inode conversion mechanism
- *   last_dir:	 find the final directory on a given path
- *   advance:	 parse one component of a path name
- *   search_dir: search a directory for a string and return its inode number
- *
- */
-
-#include "fs.h"
-#include <string.h>
-#include <minix/callnr.h>
-#include <sys/stat.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "super.h"
-
-PUBLIC char dot1[2] = ".";	/* used for search_dir to bypass the access */
-PUBLIC char dot2[3] = "..";	/* permissions for . and ..		    */
-
-FORWARD _PROTOTYPE( char *get_name, (char *old_name, char string [NAME_MAX]) );
-
-FORWARD _PROTOTYPE( struct inode *ltraverse, (struct inode *rip,
-                       char *path, char *suffix, struct inode *ldip)   );
-
-/*===========================================================================*
- *                             parse_path				     *
- *===========================================================================*/
-PUBLIC struct inode *parse_path(path, string, action)
-char *path;                    /* the path name to be parsed */
-char string[NAME_MAX];         /* the final component is returned here */
-int action;                    /* action on last part of path */
-{
-/* This is the actual code for last_dir and eat_path. Return the inode of
- * the last directory and the name of object within that directory, or the
- * inode of the last object (an empty name will be returned). Names are
- * returned in string. If string is null the name is discarded. The action
- * code determines how "last" is defined. If an error occurs, NIL_INODE
- * will be returned with an error code in err_code.
- */
-
-  struct inode *rip, *dir_ip;
-  char *new_name;
-  int symloop;
-  char lstring[NAME_MAX];
-
-  /* Is the path absolute or relative?  Initialize 'rip' accordingly. */
-  rip = (*path == '/' ? fp->fp_rootdir : fp->fp_workdir);
-
-  /* If dir has been removed or path is empty, return ENOENT. */
-  if (rip->i_nlinks == 0 || *path == '\0') {
-	err_code = ENOENT;
-	return(NIL_INODE);
-  }
-
-  dup_inode(rip);		/* inode will be returned with put_inode */
-
-  symloop = 0;                 /* symbolic link traversal count */
-  if (string == (char *) 0) string = lstring;
-
-  /* Scan the path component by component. */
-  while (TRUE) {
-	/* Extract one component. */
-	if ( (new_name = get_name(path, string)) == (char*) 0) {
-		put_inode(rip);	/* bad path in user space */
-		return(NIL_INODE);
-	}
-	if (*new_name == '\0' && (action & PATH_PENULTIMATE)) {
-		if ( (rip->i_mode & I_TYPE) == I_DIRECTORY) {
-			return(rip);	/* normal exit */
-		} else {
-			/* last file of path prefix is not a directory */
-			put_inode(rip);
-			err_code = ENOTDIR;			
-			return(NIL_INODE);
-		}
-        }
-
-	/* There is more path.  Keep parsing. */
-	dir_ip = rip;
-	rip = advance(&dir_ip, string);
-
-       if (rip == NIL_INODE) {
-               if (*new_name == '\0' && (action & PATH_NONSYMBOLIC) != 0)
-                       return(dir_ip);
-               else {
-                       put_inode(dir_ip);
-                       return(NIL_INODE);
-               }
-       }
-
-       /* The call to advance() succeeded.  Fetch next component. */
-       if (S_ISLNK(rip->i_mode)) {
-               if (*new_name != '\0' || (action & PATH_OPAQUE) == 0) {
-                       if (*new_name != '\0') new_name--;
-                       rip = ltraverse(rip, path, new_name, dir_ip);
-                       put_inode(dir_ip);
-                       if (++symloop > SYMLOOP) {
-                               err_code = ELOOP;
-                               put_inode(rip);
-                               rip = NIL_INODE;
-                       }
-                       if (rip == NIL_INODE) return(NIL_INODE);
-                       continue;
-               }
-       } else if (*new_name != '\0') {
-               put_inode(dir_ip);
-               path = new_name;
-               continue;
-	}
-      
-       /* Either last name reached or symbolic link is opaque */
-       if ((action & PATH_NONSYMBOLIC) != 0) {
-               put_inode(rip);
-               return(dir_ip);
-       } else {
-               put_inode(dir_ip);
-               return(rip);
-       }
-  }
-}
-
-/*===========================================================================*
- *                             eat_path					     *
- *===========================================================================*/
-PUBLIC struct inode *eat_path(path)
-char *path;                    /* the path name to be parsed */
-{
- /* Parse the path 'path' and put its inode in the inode table. If not possible,
-  * return NIL_INODE as function value and an error code in 'err_code'.
-  */
-  
-  return parse_path(path, (char *) 0, EAT_PATH);
-}
-
-/*===========================================================================*
- *                             last_dir					     *
- *===========================================================================*/
-PUBLIC struct inode *last_dir(path, string)
-char *path;                    /* the path name to be parsed */
-char string[NAME_MAX];         /* the final component is returned here */
-{
-/* Given a path, 'path', located in the fs address space, parse it as
- * far as the last directory, fetch the inode for the last directory into
- * the inode table, and return a pointer to the inode.  In
- * addition, return the final component of the path in 'string'.
- * If the last directory can't be opened, return NIL_INODE and
- * the reason for failure in 'err_code'.
- */
-  
-  return parse_path(path, string, LAST_DIR);
-}
-
-/*===========================================================================*
- *                             ltraverse				     *
- *===========================================================================*/
-PRIVATE struct inode *ltraverse(rip, path, suffix, ldip)
-register struct inode *rip;    /* symbolic link */
-char *path;                    /* path containing link */
-char *suffix;                  /* suffix following link within path */
-register struct inode *ldip;   /* directory containing link */
-{
-/* Traverse a symbolic link. Copy the link text from the inode and insert
- * the text into the path. Return the inode of base directory and the
- * ammended path. The symbolic link inode is always freed. The inode
- * returned is already duplicated. NIL_INODE is returned on error.
- */
-  
-  block_t b;                   /* block containing link text */
-  struct inode *bip;           /* inode of base directory */
-  struct buf *bp;              /* buffer containing link text */
-  size_t sl;                   /* length of link */
-  size_t tl;                   /* length of suffix */
-  char *sp;                    /* start of link text */
-
-  bip = NIL_INODE;
-  bp  = NIL_BUF;
-
-  if ((b = read_map(rip, (off_t) 0)) != NO_BLOCK) {
-       bp = get_block(rip->i_dev, b, NORMAL);
-       sl = rip->i_size;
-       sp = bp->b_data;
-
-       /* Insert symbolic text into path name. */
-       tl = strlen(suffix);
-       if (sl > 0 && sl + tl <= PATH_MAX-1) {
-               memmove(path+sl, suffix, tl);
-               memmove(path, sp, sl);
-               path[sl+tl] = 0;
-               dup_inode(bip = path[0] == '/' ? fp->fp_rootdir : ldip);
-       }
-  }
-  
-  put_block(bp, DIRECTORY_BLOCK);
-  put_inode(rip);
-  if (bip == NIL_INODE)
-  {
-       err_code = ENOENT;
-  }
-  return (bip);
-}
-
-/*===========================================================================*
- *				get_name				     *
- *===========================================================================*/
-PRIVATE char *get_name(old_name, string)
-char *old_name;			/* path name to parse */
-char string[NAME_MAX];		/* component extracted from 'old_name' */
-{
-/* Given a pointer to a path name in fs space, 'old_name', copy the next
- * component to 'string' and pad with zeros.  A pointer to that part of
- * the name as yet unparsed is returned.  Roughly speaking,
- * 'get_name' = 'old_name' - 'string'.
- *
- * This routine follows the standard convention that /usr/ast, /usr//ast,
- * //usr///ast and /usr/ast/ are all equivalent.
- */
-
-  register int c;
-  register char *np, *rnp;
-
-  np = string;			/* 'np' points to current position */
-  rnp = old_name;		/* 'rnp' points to unparsed string */
-  while ( (c = *rnp) == '/') rnp++;	/* skip leading slashes */
-
-  /* Copy the unparsed path, 'old_name', to the array, 'string'. */
-  while ( rnp < &old_name[PATH_MAX]  &&  c != '/'   &&  c != '\0') {
-	if (np < &string[NAME_MAX]) *np++ = c;
-	c = *++rnp;		/* advance to next character */
-  }
-
-  /* To make /usr/ast/ equivalent to /usr/ast, skip trailing slashes. */
-  while (c == '/' && rnp < &old_name[PATH_MAX]) c = *++rnp;
-
-  if (np < &string[NAME_MAX]) *np = '\0';	/* Terminate string */
-
-  if (rnp >= &old_name[PATH_MAX]) {
-	err_code = ENAMETOOLONG;
-	return((char *) 0);
-  }
-  return(rnp);
-}
-
-/*===========================================================================*
- *				advance					     *
- *===========================================================================*/
-PUBLIC struct inode *advance(pdirp, string)
-struct inode **pdirp;		/* inode for directory to be searched */
-char string[NAME_MAX];		/* component name to look for */
-{
-/* Given a directory and a component of a path, look up the component in
- * the directory, find the inode, open it, and return a pointer to its inode
- * slot.  If it can't be done, return NIL_INODE.
- */
-
-  register struct inode *rip, *dirp;
-  register struct super_block *sp;
-  int r, inumb;
-  dev_t mnt_dev;
-  ino_t numb;
-
-  dirp = *pdirp;
-
-  /* If 'string' is empty, yield same inode straight away. */
-  if (string[0] == '\0') { return(get_inode(dirp->i_dev, (int) dirp->i_num)); }
-
-  /* Check for NIL_INODE. */
-  if (dirp == NIL_INODE) { return(NIL_INODE); }
-
-  /* If 'string' is not present in the directory, signal error. */
-  if ( (r = search_dir(dirp, string, &numb, LOOK_UP)) != OK) {
-	err_code = r;
-	return(NIL_INODE);
-  }
-
-  /* Don't go beyond the current root directory, unless the string is dot2. */
-  if (dirp == fp->fp_rootdir && strcmp(string, "..") == 0 && string != dot2)
-		return(get_inode(dirp->i_dev, (int) dirp->i_num));
-
-  /* The component has been found in the directory.  Get inode. */
-  if ( (rip = get_inode(dirp->i_dev, (int) numb)) == NIL_INODE)  {
-	return(NIL_INODE);
-	}
-
-  /* The following test is for "mountpoint/.." where mountpoint is a
-   * mountpoint. ".." will refer to the root of the mounted filesystem,
-   * but has to become a reference to the parent of the 'mountpoint'
-   * directory.
-   *
-   * This case is recognized by the looked up name pointing to a
-   * root inode, and the directory in which it is held being a
-   * root inode, _and_ the name[1] being '.'. (This is a test for '..'
-   * and excludes '.'.)
-   */
-  if (rip->i_num == ROOT_INODE)
-	if (dirp->i_num == ROOT_INODE) {
-	    if (string[1] == '.') {
-		sp= rip->i_sp;
-		if (sp->s_imount != sp->s_isup)
-		{
-			/* Release the root inode.  Replace by the
-			 * inode mounted on. Update parent.
-			 */
-			put_inode(rip);
-			put_inode(dirp);
-			mnt_dev = sp->s_imount->i_dev;
-			inumb = (int) sp->s_imount->i_num;
-			dirp = *pdirp = get_inode(mnt_dev, inumb);
-			rip = advance(pdirp, string);
-		}
-	    }
-	}
-  if (rip == NIL_INODE) return(NIL_INODE);
-
-  /* See if the inode is mounted on.  If so, switch to root directory of the
-   * mounted file system.  The super_block provides the linkage between the
-   * inode mounted on and the root directory of the mounted file system.
-   */
-  while (rip != NIL_INODE && rip->i_mount == I_MOUNT) {
-	/* The inode is indeed mounted on. */
-	for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++) {
-		if (sp->s_imount == rip) {
-			/* Release the inode mounted on.  Replace by the
-			 * inode of the root inode of the mounted device.
-			 */
-			put_inode(rip);
-			rip = get_inode(sp->s_dev, ROOT_INODE);
-			break;
-		}
-	}
-  }
-  return(rip);		/* return pointer to inode's component */
-}
-
-/*===========================================================================*
- *				search_dir				     *
- *===========================================================================*/
-PUBLIC int search_dir(ldir_ptr, string, numb, flag)
-register struct inode *ldir_ptr; /* ptr to inode for dir to search */
-char string[NAME_MAX];		 /* component to search for */
-ino_t *numb;			 /* pointer to inode number */
-int flag;			 /* LOOK_UP, ENTER, DELETE or IS_EMPTY */
-{
-/* This function searches the directory whose inode is pointed to by 'ldip':
- * if (flag == ENTER)  enter 'string' in the directory with inode # '*numb';
- * if (flag == DELETE) delete 'string' from the directory;
- * if (flag == LOOK_UP) search for 'string' and return inode # in 'numb';
- * if (flag == IS_EMPTY) return OK if only . and .. in dir else ENOTEMPTY;
- *
- *    if 'string' is dot1 or dot2, no access permissions are checked.
- */
-
-  register struct direct *dp = NULL;
-  register struct buf *bp = NULL;
-  int i, r, e_hit, t, match;
-  mode_t bits;
-  off_t pos;
-  unsigned new_slots, old_slots;
-  block_t b;
-  struct super_block *sp;
-  int extended = 0;
-
-  /* If 'ldir_ptr' is not a pointer to a dir inode, error. */
-  if ( (ldir_ptr->i_mode & I_TYPE) != I_DIRECTORY)  {
-	return(ENOTDIR);
-   }
-
-  r = OK;
-
-  if (flag != IS_EMPTY) {
-	bits = (flag == LOOK_UP ? X_BIT : W_BIT | X_BIT);
-
-	if (string == dot1 || string == dot2) {
-		if (flag != LOOK_UP) r = read_only(ldir_ptr);
-				     /* only a writable device is required. */
-        }
-	else r = forbidden(ldir_ptr, bits); /* check access permissions */
-  }
-  if (r != OK) return(r);
-  
-  /* Step through the directory one block at a time. */
-  old_slots = (unsigned) (ldir_ptr->i_size/DIR_ENTRY_SIZE);
-  new_slots = 0;
-  e_hit = FALSE;
-  match = 0;			/* set when a string match occurs */
-
-  for (pos = 0; pos < ldir_ptr->i_size; pos += ldir_ptr->i_sp->s_block_size) {
-	b = read_map(ldir_ptr, pos);	/* get block number */
-
-	/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
-	bp = get_block(ldir_ptr->i_dev, b, NORMAL);	/* get a dir block */
-
-	if (bp == NO_BLOCK)
-		panic(__FILE__,"get_block returned NO_BLOCK", NO_NUM);
-
-	/* Search a directory block. */
-	for (dp = &bp->b_dir[0];
-		dp < &bp->b_dir[NR_DIR_ENTRIES(ldir_ptr->i_sp->s_block_size)];
-		dp++) {
-		if (++new_slots > old_slots) { /* not found, but room left */
-			if (flag == ENTER) e_hit = TRUE;
-			break;
-		}
-
-		/* Match occurs if string found. */
-		if (flag != ENTER && dp->d_ino != 0) {
-			if (flag == IS_EMPTY) {
-				/* If this test succeeds, dir is not empty. */
-				if (strcmp(dp->d_name, "." ) != 0 &&
-				    strcmp(dp->d_name, "..") != 0) match = 1;
-			} else {
-				if (strncmp(dp->d_name, string, NAME_MAX) == 0) {
-					match = 1;
-				}
-			}
-		}
-
-		if (match) {
-			/* LOOK_UP or DELETE found what it wanted. */
-			r = OK;
-			if (flag == IS_EMPTY) r = ENOTEMPTY;
-			else if (flag == DELETE) {
-				/* Save d_ino for recovery. */
-				t = NAME_MAX - sizeof(ino_t);
-				*((ino_t *) &dp->d_name[t]) = dp->d_ino;
-				dp->d_ino = 0;	/* erase entry */
-				bp->b_dirt = DIRTY;
-				ldir_ptr->i_update |= CTIME | MTIME;
-				ldir_ptr->i_dirt = DIRTY;
-			} else {
-				sp = ldir_ptr->i_sp;	/* 'flag' is LOOK_UP */
-				*numb = conv4(sp->s_native, (int) dp->d_ino);
-			}
-			put_block(bp, DIRECTORY_BLOCK);
-			return(r);
-		}
-
-		/* Check for free slot for the benefit of ENTER. */
-		if (flag == ENTER && dp->d_ino == 0) {
-			e_hit = TRUE;	/* we found a free slot */
-			break;
-		}
-	}
-
-	/* The whole block has been searched or ENTER has a free slot. */
-	if (e_hit) break;	/* e_hit set if ENTER can be performed now */
-	put_block(bp, DIRECTORY_BLOCK);	/* otherwise, continue searching dir */
-  }
-
-  /* The whole directory has now been searched. */
-  if (flag != ENTER) {
-  	return(flag == IS_EMPTY ? OK : ENOENT);
-  }
-
-  /* This call is for ENTER.  If no free slot has been found so far, try to
-   * extend directory.
-   */
-  if (e_hit == FALSE) { /* directory is full and no room left in last block */
-	new_slots++;		/* increase directory size by 1 entry */
-	if (new_slots == 0) return(EFBIG); /* dir size limited by slot count */
-	if ( (bp = new_block(ldir_ptr, ldir_ptr->i_size)) == NIL_BUF)
-		return(err_code);
-	dp = &bp->b_dir[0];
-	extended = 1;
-  }
-
-  /* 'bp' now points to a directory block with space. 'dp' points to slot. */
-  (void) memset(dp->d_name, 0, (size_t) NAME_MAX); /* clear entry */
-  for (i = 0; string[i] && i < NAME_MAX; i++) dp->d_name[i] = string[i];
-  sp = ldir_ptr->i_sp; 
-  dp->d_ino = conv4(sp->s_native, (int) *numb);
-  bp->b_dirt = DIRTY;
-  put_block(bp, DIRECTORY_BLOCK);
-  ldir_ptr->i_update |= CTIME | MTIME;	/* mark mtime for update later */
-  ldir_ptr->i_dirt = DIRTY;
-  if (new_slots > old_slots) {
-	ldir_ptr->i_size = (off_t) new_slots * DIR_ENTRY_SIZE;
-	/* Send the change to disk if the directory is extended. */
-	if (extended) rw_inode(ldir_ptr, WRITING);
-  }
-  return(OK);
-}
Index: trunk/minix/servers/fs/pipe.c
===================================================================
--- trunk/minix/servers/fs/pipe.c	(revision 11)
+++ 	(revision )
@@ -1,426 +1,0 @@
-/* This file deals with the suspension and revival of processes.  A process can
- * be suspended because it wants to read or write from a pipe and can't, or
- * because it wants to read or write from a special file and can't.  When a
- * process can't continue it is suspended, and revived later when it is able
- * to continue.
- *
- * The entry points into this file are
- *   do_pipe:	  perform the PIPE system call
- *   pipe_check:  check to see that a read or write on a pipe is feasible now
- *   suspend:	  suspend a process that cannot do a requested read or write
- *   release:	  check to see if a suspended process can be released and do
- *                it
- *   revive:	  mark a suspended process as able to run again
- *   unsuspend_by_endpt: revive all processes blocking on a given process
- *   do_unpause:  a signal has been sent to a process; see if it suspended
- */
-
-#include "fs.h"
-#include <fcntl.h>
-#include <signal.h>
-#include <minix/callnr.h>
-#include <minix/endpoint.h>
-#include <minix/com.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-#include "select.h"
-
-/*===========================================================================*
- *				do_pipe					     *
- *===========================================================================*/
-PUBLIC int do_pipe()
-{
-/* Perform the pipe(fil_des) system call. */
-
-  register struct fproc *rfp;
-  register struct inode *rip;
-  int r;
-  struct filp *fil_ptr0, *fil_ptr1;
-  int fil_des[2];		/* reply goes here */
-
-  /* Acquire two file descriptors. */
-  rfp = fp;
-  if ( (r = get_fd(0, R_BIT, &fil_des[0], &fil_ptr0)) != OK) return(r);
-  rfp->fp_filp[fil_des[0]] = fil_ptr0;
-  FD_SET(fil_des[0], &rfp->fp_filp_inuse);
-  fil_ptr0->filp_count = 1;
-  if ( (r = get_fd(0, W_BIT, &fil_des[1], &fil_ptr1)) != OK) {
-	rfp->fp_filp[fil_des[0]] = NIL_FILP;
-  	FD_CLR(fil_des[0], &rfp->fp_filp_inuse);
-	fil_ptr0->filp_count = 0;
-	return(r);
-  }
-  rfp->fp_filp[fil_des[1]] = fil_ptr1;
-  FD_SET(fil_des[1], &rfp->fp_filp_inuse);
-  fil_ptr1->filp_count = 1;
-
-  /* Make the inode on the pipe device. */
-  if ( (rip = alloc_inode(root_dev, I_REGULAR) ) == NIL_INODE) {
-	rfp->fp_filp[fil_des[0]] = NIL_FILP;
-  	FD_CLR(fil_des[0], &rfp->fp_filp_inuse);
-	fil_ptr0->filp_count = 0;
-	rfp->fp_filp[fil_des[1]] = NIL_FILP;
-  	FD_CLR(fil_des[1], &rfp->fp_filp_inuse);
-	fil_ptr1->filp_count = 0;
-	return(err_code);
-  }
-
-  if (read_only(rip) != OK) 
-  	panic(__FILE__,"pipe device is read only", NO_NUM);
- 
-  rip->i_pipe = I_PIPE;
-  rip->i_mode &= ~I_REGULAR;
-  rip->i_mode |= I_NAMED_PIPE;	/* pipes and FIFOs have this bit set */
-  fil_ptr0->filp_ino = rip;
-  fil_ptr0->filp_flags = O_RDONLY;
-  dup_inode(rip);		/* for double usage */
-  fil_ptr1->filp_ino = rip;
-  fil_ptr1->filp_flags = O_WRONLY;
-  rw_inode(rip, WRITING);	/* mark inode as allocated */
-  m_out.reply_i1 = fil_des[0];
-  m_out.reply_i2 = fil_des[1];
-  rip->i_update = ATIME | CTIME | MTIME;
-  return(OK);
-}
-
-/*===========================================================================*
- *				pipe_check				     *
- *===========================================================================*/
-PUBLIC int pipe_check(rip, rw_flag, oflags, bytes, position, canwrite, notouch)
-register struct inode *rip;	/* the inode of the pipe */
-int rw_flag;			/* READING or WRITING */
-int oflags;			/* flags set by open or fcntl */
-register int bytes;		/* bytes to be read or written (all chunks) */
-register off_t position;	/* current file position */
-int *canwrite;			/* return: number of bytes we can write */
-int notouch;			/* check only */
-{
-/* Pipes are a little different.  If a process reads from an empty pipe for
- * which a writer still exists, suspend the reader.  If the pipe is empty
- * and there is no writer, return 0 bytes.  If a process is writing to a
- * pipe and no one is reading from it, give a broken pipe error.
- */
-
-  /* If reading, check for empty pipe. */
-  if (rw_flag == READING) {
-	if (position >= rip->i_size) {
-		/* Process is reading from an empty pipe. */
-		int r = 0;
-		if (find_filp(rip, W_BIT) != NIL_FILP) {
-			/* Writer exists */
-			if (oflags & O_NONBLOCK) {
-				r = EAGAIN;
-			} else {
-				if (!notouch)
-					suspend(XPIPE);	/* block reader */
-				r = SUSPEND;
-			}
-			/* If need be, activate sleeping writers. */
-			if (susp_count > 0 && !notouch)
-				release(rip, WRITE, susp_count);
-		}
-		return(r);
-	}
-  } else {
-	/* Process is writing to a pipe. */
-	if (find_filp(rip, R_BIT) == NIL_FILP) {
-		/* Tell kernel to generate a SIGPIPE signal. */
-		if (!notouch) {
-			sys_kill(fp->fp_endpoint, SIGPIPE);
-		}
-		return(EPIPE);
-	}
-
-	if (position + bytes > PIPE_SIZE(rip->i_sp->s_block_size)) {
-		if ((oflags & O_NONBLOCK)
-		 && bytes < PIPE_SIZE(rip->i_sp->s_block_size))
-			return(EAGAIN);
-		else if ((oflags & O_NONBLOCK)
-		&& bytes > PIPE_SIZE(rip->i_sp->s_block_size)) {
-		if ( (*canwrite = (PIPE_SIZE(rip->i_sp->s_block_size) 
-			- position)) > 0)  {
-				/* Do a partial write. Need to wakeup reader */
-				if (!notouch)
-					release(rip, READ, susp_count);
-				return(1);
-			} else {
-				return(EAGAIN);
-			}
-		     }
-		if (bytes > PIPE_SIZE(rip->i_sp->s_block_size)) {
-			if ((*canwrite = PIPE_SIZE(rip->i_sp->s_block_size) 
-				- position) > 0) {
-				/* Do a partial write. Need to wakeup reader
-				 * since we'll suspend ourself in read_write()
-				 */
-				if (!notouch)
-					release(rip, READ, susp_count);
-				return(1);
-			}
-		}
-		if (!notouch)
-			suspend(XPIPE);	/* stop writer -- pipe full */
-		return(SUSPEND);
-	}
-
-	/* Writing to an empty pipe.  Search for suspended reader. */
-	if (position == 0 && !notouch)
-		release(rip, READ, susp_count);
-  }
-
-  *canwrite = 0;
-  return(1);
-}
-
-/*===========================================================================*
- *				suspend					     *
- *===========================================================================*/
-PUBLIC void suspend(task)
-int task;			/* who is proc waiting for? (PIPE = pipe) */
-{
-/* Take measures to suspend the processing of the present system call.
- * Store the parameters to be used upon resuming in the process table.
- * (Actually they are not used when a process is waiting for an I/O device,
- * but they are needed for pipes, and it is not worth making the distinction.)
- * The SUSPEND pseudo error should be returned after calling suspend().
- */
-
-  if (task == XPIPE || task == XPOPEN) susp_count++;/* #procs susp'ed on pipe*/
-  fp->fp_suspended = SUSPENDED;
-  fp->fp_fd = m_in.fd << 8 | call_nr;
-  if(task == NONE)
-	panic(__FILE__,"suspend on NONE",NO_NUM);
-  fp->fp_task = -task;
-  if (task == XLOCK) {
-	fp->fp_buffer = (char *) m_in.name1;	/* third arg to fcntl() */
-	fp->fp_nbytes = m_in.request;		/* second arg to fcntl() */
-  } else {
-	fp->fp_buffer = m_in.buffer;		/* for reads and writes */
-	fp->fp_nbytes = m_in.nbytes;
-  }
-}
-
-/*===========================================================================*
- *				unsuspend_by_endpt			     *
- *===========================================================================*/
-PUBLIC void unsuspend_by_endpt(int proc_e)
-{
-  struct fproc *rp;
-  int client = 0;
-
-  /* Revive processes waiting for drivers (SUSPENDed) that have
-   * disappeared with return code EAGAIN.
-   */
-  for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++, client++)
-	if(rp->fp_pid != PID_FREE &&
-	   rp->fp_suspended == SUSPENDED && rp->fp_task == -proc_e) {
-		revive(rp->fp_endpoint, EAGAIN);
-	}
-
-  /* Revive processes waiting in drivers on select()s
-   * with EAGAIN too.
-   */
-  select_unsuspend_by_endpt(proc_e);
-
-  return;
-}
-
-
-/*===========================================================================*
- *				release					     *
- *===========================================================================*/
-PUBLIC void release(ip, call_nr, count)
-register struct inode *ip;	/* inode of pipe */
-int call_nr;			/* READ, WRITE, OPEN or CREAT */
-int count;			/* max number of processes to release */
-{
-/* Check to see if any process is hanging on the pipe whose inode is in 'ip'.
- * If one is, and it was trying to perform the call indicated by 'call_nr',
- * release it.
- */
-
-  register struct fproc *rp;
-  struct filp *f;
-
-  /* Trying to perform the call also includes SELECTing on it with that
-   * operation.
-   */
-  if (call_nr == READ || call_nr == WRITE) {
-  	  int op;
-  	  if (call_nr == READ)
-  	  	op = SEL_RD;
-  	  else
-  	  	op = SEL_WR;
-	  for(f = &filp[0]; f < &filp[NR_FILPS]; f++) {
-  		if (f->filp_count < 1 || !(f->filp_pipe_select_ops & op) ||
-  		   f->filp_ino != ip)
-  			continue;
-  		 select_callback(f, op);
-		f->filp_pipe_select_ops &= ~op;
-  	}
-  }
-
-  /* Search the proc table. */
-  for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) {
-	if (rp->fp_pid != PID_FREE && rp->fp_suspended == SUSPENDED &&
-			rp->fp_revived == NOT_REVIVING &&
-			(rp->fp_fd & BYTE) == call_nr &&
-			rp->fp_filp[rp->fp_fd>>8]->filp_ino == ip) {
-		revive(rp->fp_endpoint, 0);
-		susp_count--;	/* keep track of who is suspended */
-		if (--count == 0) return;
-	}
-  }
-}
-
-/*===========================================================================*
- *				revive					     *
- *===========================================================================*/
-PUBLIC void revive(proc_nr_e, returned)
-int proc_nr_e;			/* process to revive */
-int returned;			/* if hanging on task, how many bytes read */
-{
-/* Revive a previously blocked process. When a process hangs on tty, this
- * is the way it is eventually released.
- */
-
-  register struct fproc *rfp;
-  register int task;
-  int proc_nr;
-
-  if(isokendpt(proc_nr_e, &proc_nr) != OK)
-	return;
-
-  rfp = &fproc[proc_nr];
-  if (rfp->fp_suspended == NOT_SUSPENDED || rfp->fp_revived == REVIVING)return;
-
-  /* The 'reviving' flag only applies to pipes.  Processes waiting for TTY get
-   * a message right away.  The revival process is different for TTY and pipes.
-   * For select and TTY revival, the work is already done, for pipes it is not:
-   *  the proc must be restarted so it can try again.
-   */
-  task = -rfp->fp_task;
-  if (task == XPIPE || task == XLOCK) {
-	/* Revive a process suspended on a pipe or lock. */
-	rfp->fp_revived = REVIVING;
-	reviving++;		/* process was waiting on pipe or lock */
-  } else {
-	rfp->fp_suspended = NOT_SUSPENDED;
-	if (task == XPOPEN) /* process blocked in open or create */
-		reply(proc_nr_e, rfp->fp_fd>>8);
-	else if (task == XSELECT) {
-		reply(proc_nr_e, returned);
-	} else {
-		/* Revive a process suspended on TTY or other device. */
-		rfp->fp_nbytes = returned;	/*pretend it wants only what there is*/
-		reply(proc_nr_e, returned);	/* unblock the process */
-	}
-  }
-}
-
-/*===========================================================================*
- *				do_unpause				     *
- *===========================================================================*/
-PUBLIC int do_unpause()
-{
-/* A signal has been sent to a user who is paused on the file system.
- * Abort the system call with the EINTR error message.
- */
-
-  register struct fproc *rfp;
-  int proc_nr_e, proc_nr_p, task, fild;
-  struct filp *f;
-  dev_t dev;
-  message mess;
-
-  if (who_e != PM_PROC_NR) return(EPERM);
-  proc_nr_e = m_in.ENDPT;
-  okendpt(proc_nr_e, &proc_nr_p);
-  rfp = &fproc[proc_nr_p];
-  if (rfp->fp_suspended == NOT_SUSPENDED) return(OK);
-  task = -rfp->fp_task;
-
-  switch (task) {
-	case XPIPE:		/* process trying to read or write a pipe */
-		break;
-
-	case XLOCK:		/* process trying to set a lock with FCNTL */
-		break;
-
-	case XSELECT:		/* process blocking on select() */
-		select_forget(proc_nr_e);
-		break;
-
-	case XPOPEN:		/* process trying to open a fifo */
-		break;
-
-	default:		/* process trying to do device I/O (e.g. tty)*/
-		fild = (rfp->fp_fd >> 8) & BYTE;/* extract file descriptor */
-		if (fild < 0 || fild >= OPEN_MAX)
-			panic(__FILE__,"unpause err 2",NO_NUM);
-		f = rfp->fp_filp[fild];
-		dev = (dev_t) f->filp_ino->i_zone[0];	/* device hung on */
-		mess.TTY_LINE = (dev >> MINOR) & BYTE;
-		mess.IO_ENDPT = proc_nr_e;
-
-		/* Tell kernel R or W. Mode is from current call, not open. */
-		mess.COUNT = (rfp->fp_fd & BYTE) == READ ? R_BIT : W_BIT;
-		mess.m_type = CANCEL;
-		fp = rfp;	/* hack - ctty_io uses fp */
-		(*dmap[(dev >> MAJOR) & BYTE].dmap_io)(task, &mess);
-  }
-
-  rfp->fp_suspended = NOT_SUSPENDED;
-  reply(proc_nr_e, EINTR);	/* signal interrupted call */
-  return(OK);
-}
-
-/*===========================================================================*
- *				select_request_pipe			     *
- *===========================================================================*/
-PUBLIC int select_request_pipe(struct filp *f, int *ops, int block)
-{
-	int orig_ops, r = 0, err, canwrite;
-	orig_ops = *ops;
-	if ((*ops & (SEL_RD|SEL_ERR))) {
-		if ((err = pipe_check(f->filp_ino, READING, 0,
-			1, f->filp_pos, &canwrite, 1)) != SUSPEND && err > 0)
-			r |= SEL_RD;
-		if (err < 0 && err != SUSPEND)
-			r |= SEL_ERR;
-	}
-	if ((*ops & (SEL_WR|SEL_ERR))) {
-		if ((err = pipe_check(f->filp_ino, WRITING, 0,
-			1, f->filp_pos, &canwrite, 1)) != SUSPEND &&
-			err > 0 && canwrite > 0)
-			r |= SEL_WR;
-		if (err < 0 && err != SUSPEND)
-			r |= SEL_ERR;
-	}
-
-	/* Some options we collected might not be requested. */
-	*ops = r & orig_ops;
-
-	if (!*ops && block) {
-		f->filp_pipe_select_ops |= orig_ops;
-	}
-
-	return SEL_OK;
-}
-
-/*===========================================================================*
- *				select_match_pipe			     *
- *===========================================================================*/
-PUBLIC int select_match_pipe(struct filp *f)
-{
-	/* recognize either pipe or named pipe (FIFO) */
-	if (f && f->filp_ino && (f->filp_ino->i_mode & I_NAMED_PIPE))
-		return 1;
-	return 0;
-}
-
Index: trunk/minix/servers/fs/protect.c
===================================================================
--- trunk/minix/servers/fs/protect.c	(revision 11)
+++ 	(revision )
@@ -1,211 +1,0 @@
-/* This file deals with protection in the file system.  It contains the code
- * for four system calls that relate to protection.
- *
- * The entry points into this file are
- *   do_chmod:	perform the CHMOD system call
- *   do_chown:	perform the CHOWN system call
- *   do_umask:	perform the UMASK system call
- *   do_access:	perform the ACCESS system call
- *   forbidden:	check to see if a given access is allowed on a given inode
- */
-
-#include "fs.h"
-#include <unistd.h>
-#include <minix/callnr.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-/*===========================================================================*
- *				do_chmod				     *
- *===========================================================================*/
-PUBLIC int do_chmod()
-{
-/* Perform the chmod(name, mode) system call. */
-
-  register struct inode *rip;
-  register int r;
-
-  /* Temporarily open the file. */
-  if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
-  if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-
-  /* Only the owner or the super_user may change the mode of a file.
-   * No one may change the mode of a file on a read-only file system.
-   */
-  if (rip->i_uid != fp->fp_effuid && !super_user)
-	r = EPERM;
-  else
-	r = read_only(rip);
-
-  /* If error, return inode. */
-  if (r != OK)	{
-	put_inode(rip);
-	return(r);
-  }
-
-  /* Now make the change. Clear setgid bit if file is not in caller's grp */
-  rip->i_mode = (rip->i_mode & ~ALL_MODES) | (m_in.mode & ALL_MODES);
-  if (!super_user && rip->i_gid != fp->fp_effgid)rip->i_mode &= ~I_SET_GID_BIT;
-  rip->i_update |= CTIME;
-  rip->i_dirt = DIRTY;
-
-  put_inode(rip);
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_chown				     *
- *===========================================================================*/
-PUBLIC int do_chown()
-{
-/* Perform the chown(name, owner, group) system call. */
-
-  register struct inode *rip;
-  register int r;
-
-  /* Temporarily open the file. */
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-
-  /* Not permitted to change the owner of a file on a read-only file sys. */
-  r = read_only(rip);
-  if (r == OK) {
-	/* FS is R/W.  Whether call is allowed depends on ownership, etc. */
-	if (super_user) {
-		/* The super user can do anything. */
-		rip->i_uid = m_in.owner;	/* others later */
-	} else {
-		/* Regular users can only change groups of their own files. */
-		if (rip->i_uid != fp->fp_effuid) r = EPERM;
-		if (rip->i_uid != m_in.owner) r = EPERM;  /* no giving away */
-		if (fp->fp_effgid != m_in.group) r = EPERM;
-	}
-  }
-  if (r == OK) {
-	rip->i_gid = m_in.group;
-	rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT);
-	rip->i_update |= CTIME;
-	rip->i_dirt = DIRTY;
-  }
-
-  put_inode(rip);
-  return(r);
-}
-
-/*===========================================================================*
- *				do_umask				     *
- *===========================================================================*/
-PUBLIC int do_umask()
-{
-/* Perform the umask(co_mode) system call. */
-  register mode_t r;
-
-  r = ~fp->fp_umask;		/* set 'r' to complement of old mask */
-  fp->fp_umask = ~(m_in.co_mode & RWX_MODES);
-  return(r);			/* return complement of old mask */
-}
-
-/*===========================================================================*
- *				do_access				     *
- *===========================================================================*/
-PUBLIC int do_access()
-{
-/* Perform the access(name, mode) system call. */
-
-  struct inode *rip;
-  register int r;
-
-  /* First check to see if the mode is correct. */
-  if ( (m_in.mode & ~(R_OK | W_OK | X_OK)) != 0 && m_in.mode != F_OK)
-	return(EINVAL);
-
-  /* Temporarily open the file whose access is to be checked. */
-  if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
-  if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-
-  /* Now check the permissions. */
-  r = forbidden(rip, (mode_t) m_in.mode);
-  put_inode(rip);
-  return(r);
-}
-
-/*===========================================================================*
- *				forbidden				     *
- *===========================================================================*/
-PUBLIC int forbidden(register struct inode *rip, mode_t access_desired)
-{
-/* Given a pointer to an inode, 'rip', and the access desired, determine
- * if the access is allowed, and if not why not.  The routine looks up the
- * caller's uid in the 'fproc' table.  If access is allowed, OK is returned
- * if it is forbidden, EACCES is returned.
- */
-
-  register struct inode *old_rip = rip;
-  register struct super_block *sp;
-  register mode_t bits, perm_bits;
-  int r, shift, test_uid, test_gid, type;
-
-  if (rip->i_mount == I_MOUNT)	/* The inode is mounted on. */
-	for (sp = &super_block[1]; sp < &super_block[NR_SUPERS]; sp++)
-		if (sp->s_imount == rip) {
-			rip = get_inode(sp->s_dev, ROOT_INODE);
-			break;
-		} /* if */
-
-  /* Isolate the relevant rwx bits from the mode. */
-  bits = rip->i_mode;
-  test_uid = (call_nr == ACCESS ? fp->fp_realuid : fp->fp_effuid);
-  test_gid = (call_nr == ACCESS ? fp->fp_realgid : fp->fp_effgid);
-  if (test_uid == SU_UID) {
-	/* Grant read and write permission.  Grant search permission for
-	 * directories.  Grant execute permission (for non-directories) if
-	 * and only if one of the 'X' bits is set.
-	 */
-	if ( (bits & I_TYPE) == I_DIRECTORY ||
-	     bits & ((X_BIT << 6) | (X_BIT << 3) | X_BIT))
-		perm_bits = R_BIT | W_BIT | X_BIT;
-	else
-		perm_bits = R_BIT | W_BIT;
-  } else {
-	if (test_uid == rip->i_uid) shift = 6;		/* owner */
-	else if (test_gid == rip->i_gid ) shift = 3;	/* group */
-	else shift = 0;					/* other */
-	perm_bits = (bits >> shift) & (R_BIT | W_BIT | X_BIT);
-  }
-
-  /* If access desired is not a subset of what is allowed, it is refused. */
-  r = OK;
-  if ((perm_bits | access_desired) != perm_bits) r = EACCES;
-
-  /* Check to see if someone is trying to write on a file system that is
-   * mounted read-only.
-   */
-  type = rip->i_mode & I_TYPE;
-  if (r == OK)
-	if (access_desired & W_BIT)
-	 	r = read_only(rip);
-
-  if (rip != old_rip) put_inode(rip);
-
-  return(r);
-}
-
-/*===========================================================================*
- *				read_only				     *
- *===========================================================================*/
-PUBLIC int read_only(ip)
-struct inode *ip;		/* ptr to inode whose file sys is to be cked */
-{
-/* Check to see if the file system on which the inode 'ip' resides is mounted
- * read only.  If so, return EROFS, else return OK.
- */
-
-  register struct super_block *sp;
-
-  sp = ip->i_sp;
-  return(sp->s_rd_only ? EROFS : OK);
-}
Index: trunk/minix/servers/fs/proto.h
===================================================================
--- trunk/minix/servers/fs/proto.h	(revision 11)
+++ 	(revision )
@@ -1,216 +1,0 @@
-/* Function prototypes. */
-
-#include "timers.h"
-
-/* Structs used in prototypes must be declared as such first. */
-struct buf;
-struct filp;		
-struct inode;
-struct super_block;
-
-/* cache.c */
-_PROTOTYPE( zone_t alloc_zone, (Dev_t dev, zone_t z)			);
-_PROTOTYPE( void flushall, (Dev_t dev)					);
-_PROTOTYPE( void free_zone, (Dev_t dev, zone_t numb)			);
-_PROTOTYPE( struct buf *get_block, (Dev_t dev, block_t block,int only_search));
-_PROTOTYPE( void invalidate, (Dev_t device)				);
-_PROTOTYPE( void put_block, (struct buf *bp, int block_type)		);
-_PROTOTYPE( void rw_scattered, (Dev_t dev,
-			struct buf **bufq, int bufqsize, int rw_flag)	);
-
-#if ENABLE_CACHE2
-/* cache2.c */
-_PROTOTYPE( void init_cache2, (unsigned long size)			);
-_PROTOTYPE( int get_block2, (struct buf *bp, int only_search)		);
-_PROTOTYPE( void put_block2, (struct buf *bp)				);
-_PROTOTYPE( void invalidate2, (Dev_t device)				);
-#endif
-
-/* device.c */
-_PROTOTYPE( int dev_open, (Dev_t dev, int proc, int flags)		);
-_PROTOTYPE( void dev_close, (Dev_t dev)					);
-_PROTOTYPE( int dev_io, (int op, Dev_t dev, int proc, void *buf,
-			off_t pos, int bytes, int flags)		);
-_PROTOTYPE( int gen_opcl, (int op, Dev_t dev, int proc, int flags)	);
-_PROTOTYPE( int gen_io, (int task_nr, message *mess_ptr)		);
-_PROTOTYPE( int no_dev, (int op, Dev_t dev, int proc, int flags)	);
-_PROTOTYPE( int no_dev_io, (int, message *)				);
-_PROTOTYPE( int tty_opcl, (int op, Dev_t dev, int proc, int flags)	);
-_PROTOTYPE( int ctty_opcl, (int op, Dev_t dev, int proc, int flags)	);
-_PROTOTYPE( int clone_opcl, (int op, Dev_t dev, int proc, int flags)	);
-_PROTOTYPE( int ctty_io, (int task_nr, message *mess_ptr)		);
-_PROTOTYPE( int do_ioctl, (void)					);
-_PROTOTYPE( int do_setsid, (void)					);
-_PROTOTYPE( void dev_status, (message *)				);
-_PROTOTYPE( void dev_up, (int major)					);
-
-/* dmp.c */
-_PROTOTYPE( int do_fkey_pressed, (void)					);
-
-/* dmap.c */
-_PROTOTYPE( int do_devctl, (void)					);
-_PROTOTYPE( void build_dmap, (void)					);
-_PROTOTYPE( int map_driver, (int major, int proc_nr, int dev_style)	);
-_PROTOTYPE( int dmap_driver_match, (int proc, int major)		);
-_PROTOTYPE( void dmap_unmap_by_endpt, (int proc_nr)			);
-_PROTOTYPE( void dmap_endpt_up, (int proc_nr)				);
-
-/* filedes.c */
-_PROTOTYPE( struct filp *find_filp, (struct inode *rip, mode_t bits)	);
-_PROTOTYPE( int get_fd, (int start, mode_t bits, int *k, struct filp **fpt) );
-_PROTOTYPE( struct filp *get_filp, (int fild)				);
-_PROTOTYPE( int inval_filp, (struct filp *)				);
-
-/* inode.c */
-_PROTOTYPE( struct inode *alloc_inode, (dev_t dev, mode_t bits)		);
-_PROTOTYPE( void dup_inode, (struct inode *ip)				);
-_PROTOTYPE( void free_inode, (Dev_t dev, Ino_t numb)			);
-_PROTOTYPE( struct inode *get_inode, (Dev_t dev, int numb)		);
-_PROTOTYPE( void put_inode, (struct inode *rip)				);
-_PROTOTYPE( void update_times, (struct inode *rip)			);
-_PROTOTYPE( void rw_inode, (struct inode *rip, int rw_flag)		);
-_PROTOTYPE( void wipe_inode, (struct inode *rip)			);
-
-/* link.c */
-_PROTOTYPE( int do_link, (void)						);
-_PROTOTYPE( int do_unlink, (void)					);
-_PROTOTYPE( int do_rename, (void)					);
-_PROTOTYPE( int do_truncate, (void)					);
-_PROTOTYPE( int do_ftruncate, (void)					);
-_PROTOTYPE( int truncate_inode, (struct inode *rip, off_t len)		);
-_PROTOTYPE( int freesp_inode, (struct inode *rip, off_t st, off_t end)	);
-
-/* lock.c */
-_PROTOTYPE( int lock_op, (struct filp *f, int req)			);
-_PROTOTYPE( void lock_revive, (void)					);
-
-/* main.c */
-_PROTOTYPE( int main, (void)						);
-_PROTOTYPE( void reply, (int whom, int result)				);
-
-/* misc.c */
-_PROTOTYPE( int do_dup, (void)						);
-_PROTOTYPE( int do_exit, (void)						);
-_PROTOTYPE( int do_fcntl, (void)					);
-_PROTOTYPE( int do_fork, (void)						);
-_PROTOTYPE( int do_exec, (void)						);
-_PROTOTYPE( int do_revive, (void)					);
-_PROTOTYPE( int do_set, (void)						);
-_PROTOTYPE( int do_sync, (void)						);
-_PROTOTYPE( int do_fsync, (void)					);
-_PROTOTYPE( int do_reboot, (void)					);
-_PROTOTYPE( int do_svrctl, (void)					);
-_PROTOTYPE( int do_getsysinfo, (void)					);
-
-/* mount.c */
-_PROTOTYPE( int do_mount, (void)					);
-_PROTOTYPE( int do_umount, (void)					);
-_PROTOTYPE( int unmount, (Dev_t dev)					);
-
-/* open.c */
-_PROTOTYPE( int do_close, (void)					);
-_PROTOTYPE( int do_creat, (void)					);
-_PROTOTYPE( int do_lseek, (void)					);
-_PROTOTYPE( int do_mknod, (void)					);
-_PROTOTYPE( int do_mkdir, (void)					);
-_PROTOTYPE( int do_open, (void)						);
-_PROTOTYPE( int do_slink, (void)                                       );
-
-/* path.c */
-_PROTOTYPE( struct inode *advance,(struct inode **dirp, char string[NAME_MAX]));
-_PROTOTYPE( int search_dir, (struct inode *ldir_ptr,
-			char string [NAME_MAX], ino_t *numb, int flag)	);
-_PROTOTYPE( struct inode *eat_path, (char *path)			);
-_PROTOTYPE( struct inode *last_dir, (char *path, char string [NAME_MAX]));
-_PROTOTYPE( struct inode *parse_path, (char *path, char string[NAME_MAX], 
-                                                       int action)     );
-
-/* pipe.c */
-_PROTOTYPE( int do_pipe, (void)						);
-_PROTOTYPE( int do_unpause, (void)					);
-_PROTOTYPE( int pipe_check, (struct inode *rip, int rw_flag,
-			int oflags, int bytes, off_t position, int *canwrite, int notouch));
-_PROTOTYPE( void release, (struct inode *ip, int call_nr, int count)	);
-_PROTOTYPE( void revive, (int proc_nr, int bytes)			);
-_PROTOTYPE( void suspend, (int task)					);
-_PROTOTYPE( int select_request_pipe, (struct filp *f, int *ops, int bl)	);
-_PROTOTYPE( int select_cancel_pipe, (struct filp *f)			);
-_PROTOTYPE( int select_match_pipe, (struct filp *f)			);
-_PROTOTYPE( void unsuspend_by_endpt, (int)				);
-
-/* protect.c */
-_PROTOTYPE( int do_access, (void)					);
-_PROTOTYPE( int do_chmod, (void)					);
-_PROTOTYPE( int do_chown, (void)					);
-_PROTOTYPE( int do_umask, (void)					);
-_PROTOTYPE( int forbidden, (struct inode *rip, mode_t access_desired)	);
-_PROTOTYPE( int read_only, (struct inode *ip)				);
-
-/* read.c */
-_PROTOTYPE( int do_read, (void)						);
-_PROTOTYPE( struct buf *rahead, (struct inode *rip, block_t baseblock,
-			off_t position, unsigned bytes_ahead)		);
-_PROTOTYPE( void read_ahead, (void)					);
-_PROTOTYPE( block_t read_map, (struct inode *rip, off_t pos)		);
-_PROTOTYPE( int read_write, (int rw_flag)				);
-_PROTOTYPE( zone_t rd_indir, (struct buf *bp, int index)		);
-
-/* stadir.c */
-_PROTOTYPE( int do_chdir, (void)					);
-_PROTOTYPE( int do_fchdir, (void)					);
-_PROTOTYPE( int do_chroot, (void)					);
-_PROTOTYPE( int do_fstat, (void)					);
-_PROTOTYPE( int do_stat, (void)						);
-_PROTOTYPE( int do_fstatfs, (void)					);
-_PROTOTYPE( int do_rdlink, (void)                                      );
-_PROTOTYPE( int do_lstat, (void)                                       );
-
-/* super.c */
-_PROTOTYPE( bit_t alloc_bit, (struct super_block *sp, int map, bit_t origin));
-_PROTOTYPE( void free_bit, (struct super_block *sp, int map,
-						bit_t bit_returned)	);
-_PROTOTYPE( struct super_block *get_super, (Dev_t dev)			);
-_PROTOTYPE( int mounted, (struct inode *rip)				);
-_PROTOTYPE( int read_super, (struct super_block *sp)			);
-_PROTOTYPE( int get_block_size, (dev_t dev)				);
-
-/* time.c */
-_PROTOTYPE( int do_stime, (void)					);
-_PROTOTYPE( int do_utime, (void)					);
-
-/* utility.c */
-_PROTOTYPE( time_t clock_time, (void)					);
-_PROTOTYPE( unsigned conv2, (int norm, int w)				);
-_PROTOTYPE( long conv4, (int norm, long x)				);
-_PROTOTYPE( int fetch_name, (char *path, int len, int flag)		);
-_PROTOTYPE( int no_sys, (void)						);
-_PROTOTYPE( int isokendpt_f, (char *f, int l, int e, int *p, int ft));
-_PROTOTYPE( void panic, (char *who, char *mess, int num)		);
-
-#define okendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 1)
-#define isokendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 0)
-
-/* write.c */
-_PROTOTYPE( void clear_zone, (struct inode *rip, off_t pos, int flag)	);
-_PROTOTYPE( int do_write, (void)					);
-_PROTOTYPE( struct buf *new_block, (struct inode *rip, off_t position)	);
-_PROTOTYPE( void zero_block, (struct buf *bp)				);
-_PROTOTYPE( int write_map, (struct inode *, off_t, zone_t, int)		);
-
-/* select.c */
-_PROTOTYPE( int do_select, (void)					);
-_PROTOTYPE( int select_callback, (struct filp *, int ops)		);
-_PROTOTYPE( void select_forget, (int fproc)				);
-_PROTOTYPE( void select_timeout_check, (timer_t *)			);
-_PROTOTYPE( void init_select, (void)					);
-_PROTOTYPE( void select_unsuspend_by_endpt, (int proc)			);
-_PROTOTYPE( int select_notified, (int major, int minor, int ops)	);
-
-/* timers.c */
-_PROTOTYPE( void fs_set_timer, (timer_t *tp, int delta, tmr_func_t watchdog, int arg));
-_PROTOTYPE( void fs_expire_timers, (clock_t now)			);
-_PROTOTYPE( void fs_cancel_timer, (timer_t *tp)				);
-_PROTOTYPE( void fs_init_timer, (timer_t *tp)				);
-
-/* cdprobe.c */
-_PROTOTYPE( int cdprobe, (void)						);
Index: trunk/minix/servers/fs/read.c
===================================================================
--- trunk/minix/servers/fs/read.c	(revision 11)
+++ 	(revision )
@@ -1,560 +1,0 @@
-/* This file contains the heart of the mechanism used to read (and write)
- * files.  Read and write requests are split up into chunks that do not cross
- * block boundaries.  Each chunk is then processed in turn.  Reads on special
- * files are also detected and handled.
- *
- * The entry points into this file are
- *   do_read:	 perform the READ system call by calling read_write
- *   read_write: actually do the work of READ and WRITE
- *   read_map:	 given an inode and file position, look up its zone number
- *   rd_indir:	 read an entry in an indirect block 
- *   read_ahead: manage the block read ahead business
- */
-
-#include "fs.h"
-#include <fcntl.h>
-#include <unistd.h>
-#include <minix/com.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-FORWARD _PROTOTYPE( int rw_chunk, (struct inode *rip, off_t position,
-	unsigned off, int chunk, unsigned left, int rw_flag,
-	char *buff, int seg, int usr, int block_size, int *completed));
-
-/*===========================================================================*
- *				do_read					     *
- *===========================================================================*/
-PUBLIC int do_read()
-{
-  return(read_write(READING));
-}
-
-/*===========================================================================*
- *				read_write				     *
- *===========================================================================*/
-PUBLIC int read_write(rw_flag)
-int rw_flag;			/* READING or WRITING */
-{
-/* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
-
-  register struct inode *rip;
-  register struct filp *f;
-  off_t bytes_left, f_size, position;
-  unsigned int off, cum_io;
-  int op, oflags, r, chunk, usr, seg, block_spec, char_spec;
-  int regular, partial_pipe = 0, partial_cnt = 0;
-  mode_t mode_word;
-  struct filp *wf;
-  int block_size;
-  int completed, r2 = OK;
-  phys_bytes p;
-
-  /* PM loads segments by putting funny things in other bits of the
-   * message, indicated by a high bit in fd.
-   */
-  if (who_e == PM_PROC_NR && (m_in.fd & _PM_SEG_FLAG)) {
-	seg = (int) m_in.m1_p2;
-	usr = (int) m_in.m1_p3;
-	m_in.fd &= ~(_PM_SEG_FLAG);	/* get rid of flag bit */
-  } else {
-	usr = who_e;		/* normal case */
-	seg = D;
-  }
-
-  /* If the file descriptor is valid, get the inode, size and mode. */
-  if (m_in.nbytes < 0) return(EINVAL);
-  if ((f = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
-  if (((f->filp_mode) & (rw_flag == READING ? R_BIT : W_BIT)) == 0) {
-	return(f->filp_mode == FILP_CLOSED ? EIO : EBADF);
-  }
-  if (m_in.nbytes == 0)
-  	 return(0);	/* so char special files need not check for 0*/
-
-  /* check if user process has the memory it needs.
-   * if not, copying will fail later.
-   * do this after 0-check above because umap doesn't want to map 0 bytes.
-   */
-  if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK) {
-	printf("FS: read_write: umap failed for process %d\n", usr);
-	return r;
-  }
-  position = f->filp_pos;
-  oflags = f->filp_flags;
-  rip = f->filp_ino;
-  f_size = rip->i_size;
-  r = OK;
-  if (rip->i_pipe == I_PIPE) {
-	/* fp->fp_cum_io_partial is only nonzero when doing partial writes */
-	cum_io = fp->fp_cum_io_partial; 
-  } else {
-	cum_io = 0;
-  }
-  op = (rw_flag == READING ? DEV_READ : DEV_WRITE);
-  mode_word = rip->i_mode & I_TYPE;
-  regular = mode_word == I_REGULAR || mode_word == I_NAMED_PIPE;
-
-  if ((char_spec = (mode_word == I_CHAR_SPECIAL ? 1 : 0))) {
-  	if (rip->i_zone[0] == NO_DEV)
-  		panic(__FILE__,"read_write tries to read from "
-  			"character device NO_DEV", NO_NUM);
-  	block_size = get_block_size(rip->i_zone[0]);
-  }
-  if ((block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0))) {
-  	f_size = ULONG_MAX;
-  	if (rip->i_zone[0] == NO_DEV)
-  		panic(__FILE__,"read_write tries to read from "
-  		" block device NO_DEV", NO_NUM);
-  	block_size = get_block_size(rip->i_zone[0]);
-  }
-
-  if (!char_spec && !block_spec)
-  	block_size = rip->i_sp->s_block_size;
-
-  rdwt_err = OK;		/* set to EIO if disk error occurs */
-
-  /* Check for character special files. */
-  if (char_spec) {
-  	dev_t dev;
-	dev = (dev_t) rip->i_zone[0];
-	r = dev_io(op, dev, usr, m_in.buffer, position, m_in.nbytes, oflags);
-	if (r >= 0) {
-		cum_io = r;
-		position += r;
-		r = OK;
-	}
-  } else {
-	if (rw_flag == WRITING && block_spec == 0) {
-		/* Check in advance to see if file will grow too big. */
-		if (position > rip->i_sp->s_max_size - m_in.nbytes) 
-			return(EFBIG);
-
-		/* Check for O_APPEND flag. */
-		if (oflags & O_APPEND) position = f_size;
-
-		/* Clear the zone containing present EOF if hole about
-		 * to be created.  This is necessary because all unwritten
-		 * blocks prior to the EOF must read as zeros.
-		 */
-		if (position > f_size) clear_zone(rip, f_size, 0);
-	}
-
-	/* Pipes are a little different.  Check. */
-	if (rip->i_pipe == I_PIPE) {
-	       r = pipe_check(rip, rw_flag, oflags,
-	       		m_in.nbytes, position, &partial_cnt, 0);
-	       if (r <= 0) return(r);
-	}
-
-	if (partial_cnt > 0) partial_pipe = 1;
-
-	/* Split the transfer into chunks that don't span two blocks. */
-	while (m_in.nbytes != 0) {
-
-		off = (unsigned int) (position % block_size);/* offset in blk*/
-		if (partial_pipe) {  /* pipes only */
-			chunk = MIN(partial_cnt, block_size - off);
-		} else
-			chunk = MIN(m_in.nbytes, block_size - off);
-		if (chunk < 0) chunk = block_size - off;
-
-		if (rw_flag == READING) {
-			bytes_left = f_size - position;
-			if (position >= f_size) break;	/* we are beyond EOF */
-			if (chunk > bytes_left) chunk = (int) bytes_left;
-		}
-
-		/* Read or write 'chunk' bytes. */
-		r = rw_chunk(rip, position, off, chunk, (unsigned) m_in.nbytes,
-			     rw_flag, m_in.buffer, seg, usr, block_size, &completed);
-
-		if (r != OK) break;	/* EOF reached */
-		if (rdwt_err < 0) break;
-
-		/* Update counters and pointers. */
-		m_in.buffer += chunk;	/* user buffer address */
-		m_in.nbytes -= chunk;	/* bytes yet to be read */
-		cum_io += chunk;	/* bytes read so far */
-		position += chunk;	/* position within the file */
-
-		if (partial_pipe) {
-			partial_cnt -= chunk;
-			if (partial_cnt <= 0)  break;
-		}
-	}
-  }
-
-  /* On write, update file size and access time. */
-  if (rw_flag == WRITING) {
-	if (regular || mode_word == I_DIRECTORY) {
-		if (position > f_size) rip->i_size = position;
-	}
-  } else {
-	if (rip->i_pipe == I_PIPE) {
-		if ( position >= rip->i_size) {
-			/* Reset pipe pointers. */
-			rip->i_size = 0;	/* no data left */
-			position = 0;		/* reset reader(s) */
-			wf = find_filp(rip, W_BIT);
-			if (wf != NIL_FILP) wf->filp_pos = 0;
-		}
-	}
-  }
-  f->filp_pos = position;
-
-  /* Check to see if read-ahead is called for, and if so, set it up. */
-  if (rw_flag == READING && rip->i_seek == NO_SEEK && position % block_size== 0
-		&& (regular || mode_word == I_DIRECTORY)) {
-	rdahed_inode = rip;
-	rdahedpos = position;
-  }
-  rip->i_seek = NO_SEEK;
-
-  if (rdwt_err != OK) r = rdwt_err;	/* check for disk error */
-  if (rdwt_err == END_OF_FILE) r = OK;
-
-  /* if user-space copying failed, read/write failed. */
-  if (r == OK && r2 != OK) {
-	r = r2;
-  }
-  if (r == OK) {
-	if (rw_flag == READING) rip->i_update |= ATIME;
-	if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
-	rip->i_dirt = DIRTY;		/* inode is thus now dirty */
-	if (partial_pipe) {
-		partial_pipe = 0;
-			/* partial write on pipe with */
-		/* O_NONBLOCK, return write count */
-		if (!(oflags & O_NONBLOCK)) {
-			fp->fp_cum_io_partial = cum_io;
-			suspend(XPIPE);   /* partial write on pipe with */
-			return(SUSPEND);  /* nbyte > PIPE_SIZE - non-atomic */
-		}
-	}
-	fp->fp_cum_io_partial = 0;
-	return(cum_io);
-  }
-  return(r);
-}
-
-/*===========================================================================*
- *				rw_chunk				     *
- *===========================================================================*/
-PRIVATE int rw_chunk(rip, position, off, chunk, left, rw_flag, buff,
- seg, usr, block_size, completed)
-register struct inode *rip;	/* pointer to inode for file to be rd/wr */
-off_t position;			/* position within file to read or write */
-unsigned off;			/* off within the current block */
-int chunk;			/* number of bytes to read or write */
-unsigned left;			/* max number of bytes wanted after position */
-int rw_flag;			/* READING or WRITING */
-char *buff;			/* virtual address of the user buffer */
-int seg;			/* T or D segment in user space */
-int usr;			/* which user process */
-int block_size;			/* block size of FS operating on */
-int *completed;			/* number of bytes copied */
-{
-/* Read or write (part of) a block. */
-
-  register struct buf *bp;
-  register int r = OK;
-  int n, block_spec;
-  block_t b;
-  dev_t dev;
-
-  *completed = 0;
-
-  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
-  if (block_spec) {
-	b = position/block_size;
-	dev = (dev_t) rip->i_zone[0];
-  } else {
-	b = read_map(rip, position);
-	dev = rip->i_dev;
-  }
-
-  if (!block_spec && b == NO_BLOCK) {
-	if (rw_flag == READING) {
-		/* Reading from a nonexistent block.  Must read as all zeros.*/
-		bp = get_block(NO_DEV, NO_BLOCK, NORMAL);    /* get a buffer */
-		zero_block(bp);
-	} else {
-		/* Writing to a nonexistent block. Create and enter in inode.*/
-		if ((bp= new_block(rip, position)) == NIL_BUF)return(err_code);
-	}
-  } else if (rw_flag == READING) {
-	/* Read and read ahead if convenient. */
-	bp = rahead(rip, b, position, left);
-  } else {
-	/* Normally an existing block to be partially overwritten is first read
-	 * in.  However, a full block need not be read in.  If it is already in
-	 * the cache, acquire it, otherwise just acquire a free buffer.
-	 */
-	n = (chunk == block_size ? NO_READ : NORMAL);
-	if (!block_spec && off == 0 && position >= rip->i_size) n = NO_READ;
-	bp = get_block(dev, b, n);
-  }
-
-  /* In all cases, bp now points to a valid buffer. */
-  if (bp == NIL_BUF) {
-  	panic(__FILE__,"bp not valid in rw_chunk, this can't happen", NO_NUM);
-  }
-  if (rw_flag == WRITING && chunk != block_size && !block_spec &&
-					position >= rip->i_size && off == 0) {
-	zero_block(bp);
-  }
-
-  if (rw_flag == READING) {
-	/* Copy a chunk from the block buffer to user space. */
-	r = sys_vircopy(FS_PROC_NR, D, (phys_bytes) (bp->b_data+off),
-			usr, seg, (phys_bytes) buff,
-			(phys_bytes) chunk);
-  } else {
-	/* Copy a chunk from user space to the block buffer. */
-	r = sys_vircopy(usr, seg, (phys_bytes) buff,
-			FS_PROC_NR, D, (phys_bytes) (bp->b_data+off),
-			(phys_bytes) chunk);
-	bp->b_dirt = DIRTY;
-  }
-  n = (off + chunk == block_size ? FULL_DATA_BLOCK : PARTIAL_DATA_BLOCK);
-  put_block(bp, n);
-
-  return(r);
-}
-
-
-/*===========================================================================*
- *				read_map				     *
- *===========================================================================*/
-PUBLIC block_t read_map(rip, position)
-register struct inode *rip;	/* ptr to inode to map from */
-off_t position;			/* position in file whose blk wanted */
-{
-/* Given an inode and a position within the corresponding file, locate the
- * block (not zone) number in which that position is to be found and return it.
- */
-
-  register struct buf *bp;
-  register zone_t z;
-  int scale, boff, dzones, nr_indirects, index, zind, ex;
-  block_t b;
-  long excess, zone, block_pos;
-  
-  scale = rip->i_sp->s_log_zone_size;	/* for block-zone conversion */
-  block_pos = position/rip->i_sp->s_block_size;	/* relative blk # in file */
-  zone = block_pos >> scale;	/* position's zone */
-  boff = (int) (block_pos - (zone << scale) ); /* relative blk # within zone */
-  dzones = rip->i_ndzones;
-  nr_indirects = rip->i_nindirs;
-
-  /* Is 'position' to be found in the inode itself? */
-  if (zone < dzones) {
-	zind = (int) zone;	/* index should be an int */
-	z = rip->i_zone[zind];
-	if (z == NO_ZONE) return(NO_BLOCK);
-	b = ((block_t) z << scale) + boff;
-	return(b);
-  }
-
-  /* It is not in the inode, so it must be single or double indirect. */
-  excess = zone - dzones;	/* first Vx_NR_DZONES don't count */
-
-  if (excess < nr_indirects) {
-	/* 'position' can be located via the single indirect block. */
-	z = rip->i_zone[dzones];
-  } else {
-	/* 'position' can be located via the double indirect block. */
-	if ( (z = rip->i_zone[dzones+1]) == NO_ZONE) return(NO_BLOCK);
-	excess -= nr_indirects;			/* single indir doesn't count*/
-	b = (block_t) z << scale;
-	bp = get_block(rip->i_dev, b, NORMAL);	/* get double indirect block */
-	index = (int) (excess/nr_indirects);
-	z = rd_indir(bp, index);		/* z= zone for single*/
-	put_block(bp, INDIRECT_BLOCK);		/* release double ind block */
-	excess = excess % nr_indirects;		/* index into single ind blk */
-  }
-
-  /* 'z' is zone num for single indirect block; 'excess' is index into it. */
-  if (z == NO_ZONE) return(NO_BLOCK);
-  b = (block_t) z << scale;			/* b is blk # for single ind */
-  bp = get_block(rip->i_dev, b, NORMAL);	/* get single indirect block */
-  ex = (int) excess;				/* need an integer */
-  z = rd_indir(bp, ex);				/* get block pointed to */
-  put_block(bp, INDIRECT_BLOCK);		/* release single indir blk */
-  if (z == NO_ZONE) return(NO_BLOCK);
-  b = ((block_t) z << scale) + boff;
-  return(b);
-}
-
-/*===========================================================================*
- *				rd_indir				     *
- *===========================================================================*/
-PUBLIC zone_t rd_indir(bp, index)
-struct buf *bp;			/* pointer to indirect block */
-int index;			/* index into *bp */
-{
-/* Given a pointer to an indirect block, read one entry.  The reason for
- * making a separate routine out of this is that there are four cases:
- * V1 (IBM and 68000), and V2 (IBM and 68000).
- */
-
-  struct super_block *sp;
-  zone_t zone;			/* V2 zones are longs (shorts in V1) */
-
-  if(bp == NIL_BUF)
-	panic(__FILE__, "rd_indir() on NIL_BUF", NO_NUM);
-
-  sp = get_super(bp->b_dev);	/* need super block to find file sys type */
-
-  /* read a zone from an indirect block */
-  if (sp->s_version == V1)
-	zone = (zone_t) conv2(sp->s_native, (int)  bp->b_v1_ind[index]);
-  else
-	zone = (zone_t) conv4(sp->s_native, (long) bp->b_v2_ind[index]);
-
-  if (zone != NO_ZONE &&
-		(zone < (zone_t) sp->s_firstdatazone || zone >= sp->s_zones)) {
-	printf("Illegal zone number %ld in indirect block, index %d\n",
-	       (long) zone, index);
-	panic(__FILE__,"check file system", NO_NUM);
-  }
-  return(zone);
-}
-
-/*===========================================================================*
- *				read_ahead				     *
- *===========================================================================*/
-PUBLIC void read_ahead()
-{
-/* Read a block into the cache before it is needed. */
-  int block_size;
-  register struct inode *rip;
-  struct buf *bp;
-  block_t b;
-
-  rip = rdahed_inode;		/* pointer to inode to read ahead from */
-  block_size = get_block_size(rip->i_dev);
-  rdahed_inode = NIL_INODE;	/* turn off read ahead */
-  if ( (b = read_map(rip, rdahedpos)) == NO_BLOCK) return;	/* at EOF */
-  bp = rahead(rip, b, rdahedpos, block_size);
-  put_block(bp, PARTIAL_DATA_BLOCK);
-}
-
-/*===========================================================================*
- *				rahead					     *
- *===========================================================================*/
-PUBLIC struct buf *rahead(rip, baseblock, position, bytes_ahead)
-register struct inode *rip;	/* pointer to inode for file to be read */
-block_t baseblock;		/* block at current position */
-off_t position;			/* position within file */
-unsigned bytes_ahead;		/* bytes beyond position for immediate use */
-{
-/* Fetch a block from the cache or the device.  If a physical read is
- * required, prefetch as many more blocks as convenient into the cache.
- * This usually covers bytes_ahead and is at least BLOCKS_MINIMUM.
- * The device driver may decide it knows better and stop reading at a
- * cylinder boundary (or after an error).  Rw_scattered() puts an optional
- * flag on all reads to allow this.
- */
-  int block_size;
-/* Minimum number of blocks to prefetch. */
-# define BLOCKS_MINIMUM		(NR_BUFS < 50 ? 18 : 32)
-  int block_spec, scale, read_q_size;
-  unsigned int blocks_ahead, fragment;
-  block_t block, blocks_left;
-  off_t ind1_pos;
-  dev_t dev;
-  struct buf *bp;
-  static struct buf *read_q[NR_BUFS];
-
-  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
-  if (block_spec) {
-	dev = (dev_t) rip->i_zone[0];
-  } else {
-	dev = rip->i_dev;
-  }
-  block_size = get_block_size(dev);
-
-  block = baseblock;
-  bp = get_block(dev, block, PREFETCH);
-  if (bp->b_dev != NO_DEV) return(bp);
-
-  /* The best guess for the number of blocks to prefetch:  A lot.
-   * It is impossible to tell what the device looks like, so we don't even
-   * try to guess the geometry, but leave it to the driver.
-   *
-   * The floppy driver can read a full track with no rotational delay, and it
-   * avoids reading partial tracks if it can, so handing it enough buffers to
-   * read two tracks is perfect.  (Two, because some diskette types have
-   * an odd number of sectors per track, so a block may span tracks.)
-   *
-   * The disk drivers don't try to be smart.  With todays disks it is
-   * impossible to tell what the real geometry looks like, so it is best to
-   * read as much as you can.  With luck the caching on the drive allows
-   * for a little time to start the next read.
-   *
-   * The current solution below is a bit of a hack, it just reads blocks from
-   * the current file position hoping that more of the file can be found.  A
-   * better solution must look at the already available zone pointers and
-   * indirect blocks (but don't call read_map!).
-   */
-
-  fragment = position % block_size;
-  position -= fragment;
-  bytes_ahead += fragment;
-
-  blocks_ahead = (bytes_ahead + block_size - 1) / block_size;
-
-  if (block_spec && rip->i_size == 0) {
-	blocks_left = NR_IOREQS;
-  } else {
-	blocks_left = (rip->i_size - position + block_size - 1) / block_size;
-
-	/* Go for the first indirect block if we are in its neighborhood. */
-	if (!block_spec) {
-		scale = rip->i_sp->s_log_zone_size;
-		ind1_pos = (off_t) rip->i_ndzones * (block_size << scale);
-		if (position <= ind1_pos && rip->i_size > ind1_pos) {
-			blocks_ahead++;
-			blocks_left++;
-		}
-	}
-  }
-
-  /* No more than the maximum request. */
-  if (blocks_ahead > NR_IOREQS) blocks_ahead = NR_IOREQS;
-
-  /* Read at least the minimum number of blocks, but not after a seek. */
-  if (blocks_ahead < BLOCKS_MINIMUM && rip->i_seek == NO_SEEK)
-	blocks_ahead = BLOCKS_MINIMUM;
-
-  /* Can't go past end of file. */
-  if (blocks_ahead > blocks_left) blocks_ahead = blocks_left;
-
-  read_q_size = 0;
-
-  /* Acquire block buffers. */
-  for (;;) {
-	read_q[read_q_size++] = bp;
-
-	if (--blocks_ahead == 0) break;
-
-	/* Don't trash the cache, leave 4 free. */
-	if (bufs_in_use >= NR_BUFS - 4) break;
-
-	block++;
-
-	bp = get_block(dev, block, PREFETCH);
-	if (bp->b_dev != NO_DEV) {
-		/* Oops, block already in the cache, get out. */
-		put_block(bp, FULL_DATA_BLOCK);
-		break;
-	}
-  }
-  rw_scattered(dev, read_q, read_q_size, READING);
-  return(get_block(dev, baseblock, NORMAL));
-}
Index: trunk/minix/servers/fs/select.c
===================================================================
--- trunk/minix/servers/fs/select.c	(revision 11)
+++ 	(revision )
@@ -1,702 +1,0 @@
-/* Implement entry point to select system call.
- *
- * The entry points into this file are
- *   do_select:	       perform the SELECT system call
- *   select_callback:  notify select system of possible fd operation 
- *   select_notified:  low-level entry for device notifying select
- *   select_unsuspend_by_endpt: cancel a blocking select on exiting driver
- * 
- * Changes:
- *   6 june 2005  Created (Ben Gras)
- */
-
-#define DEBUG_SELECT 0
-
-#include "fs.h"
-#include "select.h"
-#include "file.h"
-#include "inode.h"
-
-#include <sys/time.h>
-#include <sys/select.h>
-#include <minix/com.h>
-#include <string.h>
-
-/* max. number of simultaneously pending select() calls */
-#define MAXSELECTS 25
-
-PRIVATE struct selectentry {
-	struct fproc *requestor;	/* slot is free iff this is NULL */
-	int req_endpt;
-	fd_set readfds, writefds, errorfds;
-	fd_set ready_readfds, ready_writefds, ready_errorfds;
-	fd_set *vir_readfds, *vir_writefds, *vir_errorfds;
-	struct filp *filps[FD_SETSIZE];
-	int type[FD_SETSIZE];
-	int nfds, nreadyfds;
-	clock_t expiry;
-	timer_t timer;	/* if expiry > 0 */
-} selecttab[MAXSELECTS];
-
-#define SELFD_FILE	0
-#define SELFD_PIPE	1
-#define SELFD_TTY	2
-#define SELFD_INET	3
-#define SELFD_LOG	4
-#define SEL_FDS		5
-
-FORWARD _PROTOTYPE(int select_reevaluate, (struct filp *fp));
-
-FORWARD _PROTOTYPE(int select_request_file,
-	 (struct filp *f, int *ops, int block));
-FORWARD _PROTOTYPE(int select_match_file, (struct filp *f));
-
-FORWARD _PROTOTYPE(int select_request_general,
-	 (struct filp *f, int *ops, int block));
-FORWARD _PROTOTYPE(int select_major_match,
-	(int match_major, struct filp *file));
-
-FORWARD _PROTOTYPE(void select_cancel_all, (struct selectentry *e));
-FORWARD _PROTOTYPE(void select_wakeup, (struct selectentry *e, int r));
-FORWARD _PROTOTYPE(void select_return, (struct selectentry *, int));
-
-/* The Open Group:
- * "The pselect() and select() functions shall support
- * regular files, terminal and pseudo-terminal devices,
- * STREAMS-based files, FIFOs, pipes, and sockets."
- */
-
-PRIVATE struct fdtype {
-	int (*select_request)(struct filp *, int *ops, int block);	
-	int (*select_match)(struct filp *);
-	int select_major;
-} fdtypes[SEL_FDS] = {
-		/* SELFD_FILE */
-	{ select_request_file, select_match_file, 0 },
-		/* SELFD_TTY (also PTY) */
-	{ select_request_general, NULL, TTY_MAJOR },
-		/* SELFD_INET */
-	{ select_request_general, NULL, INET_MAJOR },
-		/* SELFD_PIPE (pipe(2) pipes and FS FIFOs) */
-	{ select_request_pipe, select_match_pipe, 0 },
-		/* SELFD_LOG (/dev/klog) */
-	{ select_request_general, NULL, LOG_MAJOR },
-};
-
-/* Open Group:
- * "File descriptors associated with regular files shall always select true
- * for ready to read, ready to write, and error conditions."
- */
-
-/*===========================================================================*
- *				select_request_file			     *
- *===========================================================================*/
-PRIVATE int select_request_file(struct filp *f, int *ops, int block)
-{
-	/* output *ops is input *ops */
-	return SEL_OK;
-}
-
-/*===========================================================================*
- *				select_match_file			     *
- *===========================================================================*/
-PRIVATE int select_match_file(struct filp *file)
-{
-	if (file && file->filp_ino && (file->filp_ino->i_mode & I_REGULAR))
-		return 1;
-	return 0;
-}
-
-/*===========================================================================*
- *				select_request_general			     *
- *===========================================================================*/
-PRIVATE int select_request_general(struct filp *f, int *ops, int block)
-{
-	int rops = *ops;
-	if (block) rops |= SEL_NOTIFY;
-	*ops = dev_io(DEV_SELECT, f->filp_ino->i_zone[0], rops, NULL, 0, 0, 0);
-	if (*ops < 0)
-		return SEL_ERR;
-	return SEL_OK;
-}
-
-/*===========================================================================*
- *				select_major_match			     *
- *===========================================================================*/
-PRIVATE int select_major_match(int match_major, struct filp *file)
-{
-	int major;
-	if (!(file && file->filp_ino &&
-		(file->filp_ino->i_mode & I_TYPE) == I_CHAR_SPECIAL))
-		return 0;
-	major = (file->filp_ino->i_zone[0] >> MAJOR) & BYTE;
-	if (major == match_major)
-		return 1;
-	return 0;
-}
-
-/*===========================================================================*
- *				tab2ops					     *
- *===========================================================================*/
-PRIVATE int tab2ops(int fd, struct selectentry *e)
-{
-	return (FD_ISSET(fd, &e->readfds) ? SEL_RD : 0) |
-		(FD_ISSET(fd, &e->writefds) ? SEL_WR : 0) |
-		(FD_ISSET(fd, &e->errorfds) ? SEL_ERR : 0);
-}
-
-/*===========================================================================*
- *				ops2tab					     *
- *===========================================================================*/
-PRIVATE void ops2tab(int ops, int fd, struct selectentry *e)
-{
-	if ((ops & SEL_RD) && e->vir_readfds && FD_ISSET(fd, &e->readfds)
-	        && !FD_ISSET(fd, &e->ready_readfds)) {
-		FD_SET(fd, &e->ready_readfds);
-		e->nreadyfds++;
-	}
-	if ((ops & SEL_WR) && e->vir_writefds && FD_ISSET(fd, &e->writefds) 
-		&& !FD_ISSET(fd, &e->ready_writefds)) {
-		FD_SET(fd, &e->ready_writefds);
-		e->nreadyfds++;
-	}
-	if ((ops & SEL_ERR) && e->vir_errorfds && FD_ISSET(fd, &e->errorfds)
-		&& !FD_ISSET(fd, &e->ready_errorfds)) {
-		FD_SET(fd, &e->ready_errorfds);
-		e->nreadyfds++;
-	}
-
-	return;
-}
-
-/*===========================================================================*
- *				copy_fdsets				     *
- *===========================================================================*/
-PRIVATE void copy_fdsets(struct selectentry *e)
-{
-	if (e->vir_readfds)
-		sys_vircopy(SELF, D, (vir_bytes) &e->ready_readfds,
-		e->req_endpt, D, (vir_bytes) e->vir_readfds, sizeof(fd_set));
-	if (e->vir_writefds)
-		sys_vircopy(SELF, D, (vir_bytes) &e->ready_writefds,
-		e->req_endpt, D, (vir_bytes) e->vir_writefds, sizeof(fd_set));
-	if (e->vir_errorfds)
-		sys_vircopy(SELF, D, (vir_bytes) &e->ready_errorfds,
-		e->req_endpt, D, (vir_bytes) e->vir_errorfds, sizeof(fd_set));
-
-	return;
-}
-
-/*===========================================================================*
- *				do_select				      *
- *===========================================================================*/
-PUBLIC int do_select(void)
-{
-	int r, nfds, is_timeout = 1, nonzero_timeout = 0,
-		fd, s, block = 0;
-	struct timeval timeout;
-	nfds = m_in.SEL_NFDS;
-
-	if (nfds < 0 || nfds > FD_SETSIZE)
-		return EINVAL;
-
-	for(s = 0; s < MAXSELECTS; s++)
-		if (!selecttab[s].requestor)
-			break;
-
-	if (s >= MAXSELECTS)
-		return ENOSPC;
-
-	selecttab[s].req_endpt = who_e;
-	selecttab[s].nfds = 0;
-	selecttab[s].nreadyfds = 0;
-	memset(selecttab[s].filps, 0, sizeof(selecttab[s].filps));
-
-	/* defaults */
-	FD_ZERO(&selecttab[s].readfds);
-	FD_ZERO(&selecttab[s].writefds);
-	FD_ZERO(&selecttab[s].errorfds);
-	FD_ZERO(&selecttab[s].ready_readfds);
-	FD_ZERO(&selecttab[s].ready_writefds);
-	FD_ZERO(&selecttab[s].ready_errorfds);
-
-	selecttab[s].vir_readfds = (fd_set *) m_in.SEL_READFDS;
-	selecttab[s].vir_writefds = (fd_set *) m_in.SEL_WRITEFDS;
-	selecttab[s].vir_errorfds = (fd_set *) m_in.SEL_ERRORFDS;
-
-	/* copy args */
-	if (selecttab[s].vir_readfds
-	 && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_READFDS,
-		SELF, D, (vir_bytes) &selecttab[s].readfds, sizeof(fd_set))) != OK)
-		return r;
-
-	if (selecttab[s].vir_writefds
-	 && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_WRITEFDS,
-		SELF, D, (vir_bytes) &selecttab[s].writefds, sizeof(fd_set))) != OK)
-		return r;
-
-	if (selecttab[s].vir_errorfds
-	 && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_ERRORFDS,
-		SELF, D, (vir_bytes) &selecttab[s].errorfds, sizeof(fd_set))) != OK)
-		return r;
-
-	if (!m_in.SEL_TIMEOUT)
-		is_timeout = nonzero_timeout = 0;
-	else
-		if ((r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_TIMEOUT,
-			SELF, D, (vir_bytes) &timeout, sizeof(timeout))) != OK)
-			return r;
-
-	/* No nonsense in the timeval please. */
-	if (is_timeout && (timeout.tv_sec < 0 || timeout.tv_usec < 0))
-		return EINVAL;
-
-	/* if is_timeout if 0, we block forever. otherwise, if nonzero_timeout
-	 * is 0, we do a poll (don't block). otherwise, we block up to the
-	 * specified time interval.
-	 */
-	if (is_timeout && (timeout.tv_sec > 0 || timeout.tv_usec > 0))
-		nonzero_timeout = 1;
-
-	if (nonzero_timeout || !is_timeout)
-		block = 1;
-	else
-		block = 0; /* timeout set as (0,0) - this effects a poll */
-
-	/* no timeout set (yet) */
-	selecttab[s].expiry = 0;
-
-	for(fd = 0; fd < nfds; fd++) {
-		int orig_ops, ops, t, type = -1, r;
-		struct filp *filp;
-	
-		if (!(orig_ops = ops = tab2ops(fd, &selecttab[s])))
-			continue;
-		if (!(filp = selecttab[s].filps[fd] = get_filp(fd))) {
-			select_cancel_all(&selecttab[s]);
-			return EBADF;
-		}
-
-		for(t = 0; t < SEL_FDS; t++) {
-			if (fdtypes[t].select_match) {
-			   if (fdtypes[t].select_match(filp)) {
-#if DEBUG_SELECT
-				printf("select: fd %d is type %d ", fd, t);
-#endif
-				if (type != -1)
-					printf("select: double match\n");
-				type = t;
-			  }
-	 		} else if (select_major_match(fdtypes[t].select_major, filp)) {
-				type = t;
-			}
-		}
-
-		/* Open Group:
-		 * "The pselect() and select() functions shall support
-		 * regular files, terminal and pseudo-terminal devices,
-		 * STREAMS-based files, FIFOs, pipes, and sockets. The
-		 * behavior of pselect() and select() on file descriptors
-		 * that refer to other types of file is unspecified."
-		 *
-		 * If all types are implemented, then this is another
-		 * type of file and we get to do whatever we want.
-		 */
-		if (type == -1)
-		{
-#if DEBUG_SELECT
-			printf("do_select: bad type\n");
-#endif
-			return EBADF;
-		}
-
-		selecttab[s].type[fd] = type;
-
-		if ((selecttab[s].filps[fd]->filp_select_ops & ops) != ops) {
-			int wantops;
-			/* Request the select on this fd.  */
-#if DEBUG_SELECT
-			printf("%p requesting ops %d -> ",
-				selecttab[s].filps[fd],
-				selecttab[s].filps[fd]->filp_select_ops);
-#endif
-			wantops = (selecttab[s].filps[fd]->filp_select_ops |= ops);
-#if DEBUG_SELECT
-			printf("%d\n", selecttab[s].filps[fd]->filp_select_ops);
-#endif
-			if ((r = fdtypes[type].select_request(filp,
-				&wantops, block)) != SEL_OK) {
-				/* error or bogus return code.. backpaddle */
-				select_cancel_all(&selecttab[s]);
-				printf("select: select_request returned error\n");
-				return EINVAL;
-			}
-			if (wantops) {
-				if (wantops & ops) {
-					/* operations that were just requested
-					 * are ready to go right away
-					 */
-					ops2tab(wantops, fd, &selecttab[s]);
-				}
-				/* if there are any other select()s blocking
-				 * on these operations of this fp, they can
-				 * be awoken too
-				 */
-				select_callback(filp, ops);
-			}
-#if DEBUG_SELECT
-			printf("select request ok; ops returned %d\n", wantops);
-#endif
-		} else {
-#if DEBUG_SELECT
-			printf("select already happening on that filp\n");
-#endif
-		}
-
-		selecttab[s].nfds = fd+1;
-		selecttab[s].filps[fd]->filp_selectors++;
-
-#if DEBUG_SELECT
-		printf("[fd %d ops: %d] ", fd, ops);
-#endif
-	}
-
-	if (selecttab[s].nreadyfds > 0 || !block) {
-		/* fd's were found that were ready to go right away, and/or
-		 * we were instructed not to block at all. Must return
-		 * immediately.
-		 */
-		copy_fdsets(&selecttab[s]);
-		select_cancel_all(&selecttab[s]);
-		selecttab[s].requestor = NULL;
-
-		/* Open Group:
-		 * "Upon successful completion, the pselect() and select()
-		 * functions shall return the total number of bits
-		 * set in the bit masks."
-		 */
-#if DEBUG_SELECT
-		printf("returning\n");
-#endif
-
-		return selecttab[s].nreadyfds;
-	}
-#if DEBUG_SELECT
-		printf("not returning (%d, %d)\n", selecttab[s].nreadyfds, block);
-#endif
- 
-	/* Convert timeval to ticks and set the timer. If it fails, undo
-	 * all, return error.
-	 */
-	if (is_timeout) {
-		int ticks;
-		/* Open Group:
-		 * "If the requested timeout interval requires a finer
-		 * granularity than the implementation supports, the
-		 * actual timeout interval shall be rounded up to the next
-		 * supported value."
-		 */
-#define USECPERSEC 1000000
-		while(timeout.tv_usec >= USECPERSEC) {
-			/* this is to avoid overflow with *HZ below */
-			timeout.tv_usec -= USECPERSEC;
-			timeout.tv_sec++;
-		}
-		ticks = timeout.tv_sec * HZ +
-			(timeout.tv_usec * HZ + USECPERSEC-1) / USECPERSEC;
-		selecttab[s].expiry = ticks;
-		fs_set_timer(&selecttab[s].timer, ticks, select_timeout_check, s);
-#if DEBUG_SELECT
-		printf("%d: blocking %d ticks\n", s, ticks);
-#endif
-	}
-
-	/* if we're blocking, the table entry is now valid. */
-	selecttab[s].requestor = fp;
-
-	/* process now blocked */
-	suspend(XSELECT);
-	return SUSPEND;
-}
-
-/*===========================================================================*
- *				select_cancel_all			     *
- *===========================================================================*/
-PRIVATE void select_cancel_all(struct selectentry *e)
-{
-	int fd;
-
-	for(fd = 0; fd < e->nfds; fd++) {
-		struct filp *fp;
-		fp = e->filps[fd];
-		if (!fp) {
-#if DEBUG_SELECT
-			printf("[ fd %d/%d NULL ] ", fd, e->nfds);
-#endif
-			continue;
-		}
-		if (fp->filp_selectors < 1) {
-#if DEBUG_SELECT
-			printf("select: %d selectors?!\n", fp->filp_selectors);
-#endif
-			continue;
-		}
-		fp->filp_selectors--;
-		e->filps[fd] = NULL;
-		select_reevaluate(fp);
-	}
-
-	if (e->expiry > 0) {
-#if DEBUG_SELECT
-		printf("cancelling timer %d\n", e - selecttab);
-#endif
-		fs_cancel_timer(&e->timer); 
-		e->expiry = 0;
-	}
-
-	return;
-}
-
-/*===========================================================================*
- *				select_wakeup				     *
- *===========================================================================*/
-PRIVATE void select_wakeup(struct selectentry *e, int r)
-{
-	revive(e->req_endpt, r);
-}
-
-/*===========================================================================*
- *				select_reevaluate			     *
- *===========================================================================*/
-PRIVATE int select_reevaluate(struct filp *fp)
-{
-	int s, remain_ops = 0, fd, type = -1;
-
-	if (!fp) {
-		printf("fs: select: reevalute NULL fp\n");
-		return 0;
-	}
-
-	for(s = 0; s < MAXSELECTS; s++) {
-		if (!selecttab[s].requestor)
-			continue;
-		for(fd = 0; fd < selecttab[s].nfds; fd++)
-			if (fp == selecttab[s].filps[fd]) {
-				remain_ops |= tab2ops(fd, &selecttab[s]);
-				type = selecttab[s].type[fd];
-			}
-	}
-
-	/* If there are any select()s open that want any operations on
-	 * this fd that haven't been satisfied by this callback, then we're
-	 * still in the market for it.
-	 */
-	fp->filp_select_ops = remain_ops;
-#if DEBUG_SELECT
-	printf("remaining operations on fp are %d\n", fp->filp_select_ops);
-#endif
-
-	return remain_ops;
-}
-
-/*===========================================================================*
- *				select_return				     *
- *===========================================================================*/
-PRIVATE void select_return(struct selectentry *s, int r)
-{
-	select_cancel_all(s);
-	copy_fdsets(s);
-	select_wakeup(s, r ? r : s->nreadyfds);
-	s->requestor = NULL;
-}
-
-/*===========================================================================*
- *				select_callback			             *
- *===========================================================================*/
-PUBLIC int select_callback(struct filp *fp, int ops)
-{
-	int s, fd, want_ops, type;
-
-	/* We are being notified that file pointer fp is available for
-	 * operations 'ops'. We must re-register the select for
-	 * operations that we are still interested in, if any.
-	 */
-
-	want_ops = 0;
-	type = -1;
-	for(s = 0; s < MAXSELECTS; s++) {
-		int wakehim = 0;
-		if (!selecttab[s].requestor)
-			continue;
-		for(fd = 0; fd < selecttab[s].nfds; fd++) {
-			if (!selecttab[s].filps[fd])
-				continue;
-			if (selecttab[s].filps[fd] == fp) {
-				int this_want_ops;
-				this_want_ops = tab2ops(fd, &selecttab[s]);
-				want_ops |= this_want_ops;
-				if (this_want_ops & ops) {
-					/* this select() has been satisfied. */
-					ops2tab(ops, fd, &selecttab[s]);
-					wakehim = 1;
-				}
-				type = selecttab[s].type[fd];
-			}
-		}
-		if (wakehim)
-			select_return(&selecttab[s], 0);
-	}
-
-	return 0;
-}
-
-/*===========================================================================*
- *				select_notified			             *
- *===========================================================================*/
-PUBLIC int select_notified(int major, int minor, int selected_ops)
-{
-	int s, f, t;
-
-#if DEBUG_SELECT
-	printf("select callback: %d, %d: %d\n", major, minor, selected_ops);
-#endif
-
-	for(t = 0; t < SEL_FDS; t++)
-		if (!fdtypes[t].select_match && fdtypes[t].select_major == major)
-		    	break;
-
-	if (t >= SEL_FDS) {
-#if DEBUG_SELECT
-		printf("select callback: no fdtype found for device %d\n", major);
-#endif
-		return OK;
-	}
-
-	/* We have a select callback from major device no.
-	 * d, which corresponds to our select type t.
-	 */
-
-	for(s = 0; s < MAXSELECTS; s++) {
-		int s_minor, ops;
-		if (!selecttab[s].requestor)
-			continue;
-		for(f = 0; f < selecttab[s].nfds; f++) {
-			if (!selecttab[s].filps[f] ||
-			   !select_major_match(major, selecttab[s].filps[f]))
-			   	continue;
-			ops = tab2ops(f, &selecttab[s]);
-			s_minor =
-			(selecttab[s].filps[f]->filp_ino->i_zone[0] >> MINOR)
-				& BYTE;
-			if ((s_minor == minor) &&
-				(selected_ops & ops)) {
-				select_callback(selecttab[s].filps[f], (selected_ops & ops));
-			}
-		}
-	}
-
-	return OK;
-}
-
-/*===========================================================================*
- *				init_select  				     *
- *===========================================================================*/
-PUBLIC void init_select(void)
-{
-	int s;
-
-	for(s = 0; s < MAXSELECTS; s++)
-		fs_init_timer(&selecttab[s].timer);
-}
-
-/*===========================================================================*
- *				select_forget			             *
- *===========================================================================*/
-PUBLIC void select_forget(int proc_e)
-{
-	/* something has happened (e.g. signal delivered that interrupts
-	 * select()). totally forget about the select().
-	 */
-	int s;
-
-	for(s = 0; s < MAXSELECTS; s++) {
-		if (selecttab[s].requestor &&
-			selecttab[s].req_endpt == proc_e) {
-			break;
-		}
-
-	}
-
-	if (s >= MAXSELECTS) {
-#if DEBUG_SELECT
-		printf("select: cancelled select() not found");
-#endif
-		return;
-	}
-
-	select_cancel_all(&selecttab[s]);
-	selecttab[s].requestor = NULL;
-
-	return;
-}
-
-/*===========================================================================*
- *				select_timeout_check	  	     	     *
- *===========================================================================*/
-PUBLIC void select_timeout_check(timer_t *timer)
-{
-	int s;
-
-	s = tmr_arg(timer)->ta_int;
-
-	if (s < 0 || s >= MAXSELECTS) {
-#if DEBUG_SELECT
-		printf("select: bogus slot arg to watchdog %d\n", s);
-#endif
-		return;
-	}
-
-	if (!selecttab[s].requestor) {
-#if DEBUG_SELECT
-		printf("select: no requestor in watchdog\n");
-#endif
-		return;
-	}
-
-	if (selecttab[s].expiry <= 0) {
-#if DEBUG_SELECT
-		printf("select: strange expiry value in watchdog\n", s);
-#endif
-		return;
-	}
-
-	selecttab[s].expiry = 0;
-	select_return(&selecttab[s], 0);
-
-	return;
-}
-
-/*===========================================================================*
- *				select_unsuspend_by_endpt  	     	     *
- *===========================================================================*/
-PUBLIC void select_unsuspend_by_endpt(int proc_e)
-{
-	int fd, s;
-
-	for(s = 0; s < MAXSELECTS; s++) {
-	  if (!selecttab[s].requestor)
-		  continue;
-	  for(fd = 0; fd < selecttab[s].nfds; fd++) {
-	    int maj;
-	    if (!selecttab[s].filps[fd] || !selecttab[s].filps[fd]->filp_ino)
-		continue;
-	    maj = (selecttab[s].filps[fd]->filp_ino->i_zone[0] >> MAJOR)&BYTE;
-	    if(dmap_driver_match(proc_e, maj)) {
-			select_return(&selecttab[s], EAGAIN);
-	    }
-	  }
-	}
-
-	return;
-}
-
Index: trunk/minix/servers/fs/select.h
===================================================================
--- trunk/minix/servers/fs/select.h	(revision 11)
+++ 	(revision )
@@ -1,9 +1,0 @@
-#ifndef _FS_SELECT_H
-#define _FS_SELECT_H 1
-
-/* return codes for select_request_* and select_cancel_* */
-#define SEL_OK		0	/* ready */
-#define SEL_ERROR	1	/* failed */
-
-#endif
-
Index: trunk/minix/servers/fs/stadir.c
===================================================================
--- trunk/minix/servers/fs/stadir.c	(revision 11)
+++ 	(revision )
@@ -1,303 +1,0 @@
-/* This file contains the code for performing four system calls relating to
- * status and directories.
- *
- * The entry points into this file are
- *   do_chdir:	perform the CHDIR system call
- *   do_chroot:	perform the CHROOT system call
- *   do_stat:	perform the STAT system call
- *   do_fstat:	perform the FSTAT system call
- *   do_fstatfs: perform the FSTATFS system call
- *   do_lstat:  perform the LSTAT system call
- *   do_rdlink: perform the RDLNK system call
- */
-
-#include "fs.h"
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <minix/com.h>
-#include <string.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-#include "super.h"
-
-FORWARD _PROTOTYPE( int change, (struct inode **iip, char *name_ptr, int len));
-FORWARD _PROTOTYPE( int change_into, (struct inode **iip, struct inode *ip));
-FORWARD _PROTOTYPE( int stat_inode, (struct inode *rip, struct filp *fil_ptr,
-			char *user_addr)				);
-
-/*===========================================================================*
- *				do_fchdir				     *
- *===========================================================================*/
-PUBLIC int do_fchdir()
-{
-	/* Change directory on already-opened fd. */
-	struct filp *rfilp;
-
-	/* Is the file descriptor valid? */
-	if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
-	dup_inode(rfilp->filp_ino);
-	return change_into(&fp->fp_workdir, rfilp->filp_ino);
-}
-
-/*===========================================================================*
- *				do_chdir				     *
- *===========================================================================*/
-PUBLIC int do_chdir()
-{
-/* Change directory.  This function is  also called by MM to simulate a chdir
- * in order to do EXEC, etc.  It also changes the root directory, the uids and
- * gids, and the umask. 
- */
-
-  int r;
-  register struct fproc *rfp;
-
-  if (who_e == PM_PROC_NR) {
-	int slot;
-	if(isokendpt(m_in.endpt1, &slot) != OK)
-		return EINVAL;
-	rfp = &fproc[slot];
-	put_inode(fp->fp_rootdir);
-	dup_inode(fp->fp_rootdir = rfp->fp_rootdir);
-	put_inode(fp->fp_workdir);
-	dup_inode(fp->fp_workdir = rfp->fp_workdir);
-
-	/* MM uses access() to check permissions.  To make this work, pretend
-	 * that the user's real ids are the same as the user's effective ids.
-	 * FS calls other than access() do not use the real ids, so are not
-	 * affected.
-	 */
-	fp->fp_realuid =
-	fp->fp_effuid = rfp->fp_effuid;
-	fp->fp_realgid =
-	fp->fp_effgid = rfp->fp_effgid;
-	fp->fp_umask = rfp->fp_umask;
-	return(OK);
-  }
-
-  /* Perform the chdir(name) system call. */
-  r = change(&fp->fp_workdir, m_in.name, m_in.name_length);
-  return(r);
-}
-
-/*===========================================================================*
- *				do_chroot				     *
- *===========================================================================*/
-PUBLIC int do_chroot()
-{
-/* Perform the chroot(name) system call. */
-
-  register int r;
-
-  if (!super_user) return(EPERM);	/* only su may chroot() */
-  r = change(&fp->fp_rootdir, m_in.name, m_in.name_length);
-  return(r);
-}
-
-/*===========================================================================*
- *				change					     *
- *===========================================================================*/
-PRIVATE int change(iip, name_ptr, len)
-struct inode **iip;		/* pointer to the inode pointer for the dir */
-char *name_ptr;			/* pointer to the directory name to change to */
-int len;			/* length of the directory name string */
-{
-/* Do the actual work for chdir() and chroot(). */
-  struct inode *rip;
-
-  /* Try to open the new directory. */
-  if (fetch_name(name_ptr, len, M3) != OK) return(err_code);
-  if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-  return change_into(iip, rip);
-}
-
-/*===========================================================================*
- *				change_into				     *
- *===========================================================================*/
-PRIVATE int change_into(iip, rip)
-struct inode **iip;		/* pointer to the inode pointer for the dir */
-struct inode *rip;		/* this is what the inode has to become */
-{
-  register int r;
-
-  /* It must be a directory and also be searchable. */
-  if ( (rip->i_mode & I_TYPE) != I_DIRECTORY)
-	r = ENOTDIR;
-  else
-	r = forbidden(rip, X_BIT);	/* check if dir is searchable */
-
-  /* If error, return inode. */
-  if (r != OK) {
-	put_inode(rip);
-	return(r);
-  }
-
-  /* Everything is OK.  Make the change. */
-  put_inode(*iip);		/* release the old directory */
-  *iip = rip;			/* acquire the new one */
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_stat					     *
- *===========================================================================*/
-PUBLIC int do_stat()
-{
-/* Perform the stat(name, buf) system call. */
-
-  register struct inode *rip;
-  register int r;
-
-  /* Both stat() and fstat() use the same routine to do the real work.  That
-   * routine expects an inode, so acquire it temporarily.
-   */
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-  r = stat_inode(rip, NIL_FILP, m_in.name2);	/* actually do the work.*/
-  put_inode(rip);		/* release the inode */
-  return(r);
-}
-
-/*===========================================================================*
- *				do_fstat				     *
- *===========================================================================*/
-PUBLIC int do_fstat()
-{
-/* Perform the fstat(fd, buf) system call. */
-
-  register struct filp *rfilp;
-
-  /* Is the file descriptor valid? */
-  if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
-
-  return(stat_inode(rfilp->filp_ino, rfilp, m_in.buffer));
-}
-
-/*===========================================================================*
- *				stat_inode				     *
- *===========================================================================*/
-PRIVATE int stat_inode(rip, fil_ptr, user_addr)
-register struct inode *rip;	/* pointer to inode to stat */
-struct filp *fil_ptr;		/* filp pointer, supplied by 'fstat' */
-char *user_addr;		/* user space address where stat buf goes */
-{
-/* Common code for stat and fstat system calls. */
-
-  struct stat statbuf;
-  mode_t mo;
-  int r, s;
-
-  /* Update the atime, ctime, and mtime fields in the inode, if need be. */
-  if (rip->i_update) update_times(rip);
-
-  /* Fill in the statbuf struct. */
-  mo = rip->i_mode & I_TYPE;
-
-  /* true iff special */
-  s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
-
-  statbuf.st_dev = rip->i_dev;
-  statbuf.st_ino = rip->i_num;
-  statbuf.st_mode = rip->i_mode;
-  statbuf.st_nlink = rip->i_nlinks;
-  statbuf.st_uid = rip->i_uid;
-  statbuf.st_gid = rip->i_gid;
-  statbuf.st_rdev = (dev_t) (s ? rip->i_zone[0] : NO_DEV);
-  statbuf.st_size = rip->i_size;
-
-  if (rip->i_pipe == I_PIPE) {
-	statbuf.st_mode &= ~I_REGULAR;	/* wipe out I_REGULAR bit for pipes */
-	if (fil_ptr != NIL_FILP && fil_ptr->filp_mode & R_BIT) 
-		statbuf.st_size -= fil_ptr->filp_pos;
-  }
-
-  statbuf.st_atime = rip->i_atime;
-  statbuf.st_mtime = rip->i_mtime;
-  statbuf.st_ctime = rip->i_ctime;
-
-  /* Copy the struct to user space. */
-  r = sys_datacopy(FS_PROC_NR, (vir_bytes) &statbuf,
-  		who_e, (vir_bytes) user_addr, (phys_bytes) sizeof(statbuf));
-  return(r);
-}
-
-/*===========================================================================*
- *				do_fstatfs				     *
- *===========================================================================*/
-PUBLIC int do_fstatfs()
-{
-  /* Perform the fstatfs(fd, buf) system call. */
-  struct statfs st;
-  register struct filp *rfilp;
-  int r;
-
-  /* Is the file descriptor valid? */
-  if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
-
-  st.f_bsize = rfilp->filp_ino->i_sp->s_block_size;
-
-  r = sys_datacopy(FS_PROC_NR, (vir_bytes) &st,
-  		who_e, (vir_bytes) m_in.buffer, (phys_bytes) sizeof(st));
-
-   return(r);
-}
-
-/*===========================================================================*
- *                             do_lstat                                     *
- *===========================================================================*/
-PUBLIC int do_lstat()
-{
-/* Perform the lstat(name, buf) system call. */
-
-  register int r;              /* return value */
-  register struct inode *rip;  /* target inode */
-
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  if ((rip = parse_path(user_path, (char *) 0, EAT_PATH_OPAQUE)) == NIL_INODE)
-       return(err_code);
-  r = stat_inode(rip, NIL_FILP, m_in.name2);
-  put_inode(rip);
-  return(r);
-}
-
-/*===========================================================================*
- *                             do_rdlink                                    *
- *===========================================================================*/
-PUBLIC int do_rdlink()
-{
-/* Perform the readlink(name, buf) system call. */
-
-  register int r;              /* return value */
-  block_t b;                   /* block containing link text */
-  struct buf *bp;              /* buffer containing link text */
-  register struct inode *rip;  /* target inode */
-  int copylen;
-  copylen = m_in.m1_i2;
-  if(copylen < 0) return EINVAL;
-
-  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-  if ((rip = parse_path(user_path, (char *) 0, EAT_PATH_OPAQUE)) == NIL_INODE)
-       return(err_code);
-
-  r = EACCES;
-  if (S_ISLNK(rip->i_mode) && (b = read_map(rip, (off_t) 0)) != NO_BLOCK) {
-       if (m_in.name2_length <= 0) r = EINVAL;
-       else if (m_in.name2_length < rip->i_size) r = ERANGE;
-       else {
-	       if(rip->i_size < copylen) copylen = rip->i_size;
-               bp = get_block(rip->i_dev, b, NORMAL);
-               r = sys_vircopy(SELF, D, (vir_bytes) bp->b_data,
-		who_e, D, (vir_bytes) m_in.name2, (vir_bytes) copylen);
-
-               if (r == OK) r = copylen;
-               put_block(bp, DIRECTORY_BLOCK);
-       }
-  }
-
-  put_inode(rip);
-  return(r);
-}
-
Index: trunk/minix/servers/fs/super.c
===================================================================
--- trunk/minix/servers/fs/super.c	(revision 11)
+++ 	(revision )
@@ -1,319 +1,0 @@
-/* This file manages the super block table and the related data structures,
- * namely, the bit maps that keep track of which zones and which inodes are
- * allocated and which are free.  When a new inode or zone is needed, the
- * appropriate bit map is searched for a free entry.
- *
- * The entry points into this file are
- *   alloc_bit:       somebody wants to allocate a zone or inode; find one
- *   free_bit:        indicate that a zone or inode is available for allocation
- *   get_super:       search the 'superblock' table for a device
- *   mounted:         tells if file inode is on mounted (or ROOT) file system
- *   read_super:      read a superblock
- */
-
-#include "fs.h"
-#include <string.h>
-#include <minix/com.h>
-#include "buf.h"
-#include "inode.h"
-#include "super.h"
-#include "const.h"
-
-/*===========================================================================*
- *				alloc_bit				     *
- *===========================================================================*/
-PUBLIC bit_t alloc_bit(sp, map, origin)
-struct super_block *sp;		/* the filesystem to allocate from */
-int map;			/* IMAP (inode map) or ZMAP (zone map) */
-bit_t origin;			/* number of bit to start searching at */
-{
-/* Allocate a bit from a bit map and return its bit number. */
-
-  block_t start_block;		/* first bit block */
-  bit_t map_bits;		/* how many bits are there in the bit map? */
-  unsigned bit_blocks;		/* how many blocks are there in the bit map? */
-  unsigned block, word, bcount;
-  struct buf *bp;
-  bitchunk_t *wptr, *wlim, k;
-  bit_t i, b;
-
-  if (sp->s_rd_only)
-	panic(__FILE__,"can't allocate bit on read-only filesys.", NO_NUM);
-
-  if (map == IMAP) {
-	start_block = START_BLOCK;
-	map_bits = sp->s_ninodes + 1;
-	bit_blocks = sp->s_imap_blocks;
-  } else {
-	start_block = START_BLOCK + sp->s_imap_blocks;
-	map_bits = sp->s_zones - (sp->s_firstdatazone - 1);
-	bit_blocks = sp->s_zmap_blocks;
-  }
-
-  /* Figure out where to start the bit search (depends on 'origin'). */
-  if (origin >= map_bits) origin = 0;	/* for robustness */
-
-  /* Locate the starting place. */
-  block = origin / FS_BITS_PER_BLOCK(sp->s_block_size);
-  word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
-
-  /* Iterate over all blocks plus one, because we start in the middle. */
-  bcount = bit_blocks + 1;
-  do {
-	bp = get_block(sp->s_dev, start_block + block, NORMAL);
-	wlim = &bp->b_bitmap[FS_BITMAP_CHUNKS(sp->s_block_size)];
-
-	/* Iterate over the words in block. */
-	for (wptr = &bp->b_bitmap[word]; wptr < wlim; wptr++) {
-
-		/* Does this word contain a free bit? */
-		if (*wptr == (bitchunk_t) ~0) continue;
-
-		/* Find and allocate the free bit. */
-		k = conv2(sp->s_native, (int) *wptr);
-		for (i = 0; (k & (1 << i)) != 0; ++i) {}
-
-		/* Bit number from the start of the bit map. */
-		b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size))
-		    + (wptr - &bp->b_bitmap[0]) * FS_BITCHUNK_BITS
-		    + i;
-
-		/* Don't allocate bits beyond the end of the map. */
-		if (b >= map_bits) break;
-
-		/* Allocate and return bit number. */
-		k |= 1 << i;
-		*wptr = conv2(sp->s_native, (int) k);
-		bp->b_dirt = DIRTY;
-		put_block(bp, MAP_BLOCK);
-		return(b);
-	}
-	put_block(bp, MAP_BLOCK);
-	if (++block >= bit_blocks) block = 0;	/* last block, wrap around */
-	word = 0;
-  } while (--bcount > 0);
-  return(NO_BIT);		/* no bit could be allocated */
-}
-
-/*===========================================================================*
- *				free_bit				     *
- *===========================================================================*/
-PUBLIC void free_bit(sp, map, bit_returned)
-struct super_block *sp;		/* the filesystem to operate on */
-int map;			/* IMAP (inode map) or ZMAP (zone map) */
-bit_t bit_returned;		/* number of bit to insert into the map */
-{
-/* Return a zone or inode by turning off its bitmap bit. */
-
-  unsigned block, word, bit;
-  struct buf *bp;
-  bitchunk_t k, mask;
-  block_t start_block;
-
-  if (sp->s_rd_only)
-	panic(__FILE__,"can't free bit on read-only filesys.", NO_NUM);
-
-  if (map == IMAP) {
-	start_block = START_BLOCK;
-  } else {
-	start_block = START_BLOCK + sp->s_imap_blocks;
-  }
-  block = bit_returned / FS_BITS_PER_BLOCK(sp->s_block_size);
-  word = (bit_returned % FS_BITS_PER_BLOCK(sp->s_block_size))
-  	 / FS_BITCHUNK_BITS;
-
-  bit = bit_returned % FS_BITCHUNK_BITS;
-  mask = 1 << bit;
-
-  bp = get_block(sp->s_dev, start_block + block, NORMAL);
-
-  k = conv2(sp->s_native, (int) bp->b_bitmap[word]);
-  if (!(k & mask)) {
-	panic(__FILE__,map == IMAP ? "tried to free unused inode" :
-	      "tried to free unused block", bit_returned);
-  }
-
-  k &= ~mask;
-  bp->b_bitmap[word] = conv2(sp->s_native, (int) k);
-  bp->b_dirt = DIRTY;
-
-  put_block(bp, MAP_BLOCK);
-}
-
-/*===========================================================================*
- *				get_super				     *
- *===========================================================================*/
-PUBLIC struct super_block *get_super(dev)
-dev_t dev;			/* device number whose super_block is sought */
-{
-/* Search the superblock table for this device.  It is supposed to be there. */
-
-  register struct super_block *sp;
-
-  if (dev == NO_DEV)
-  	panic(__FILE__,"request for super_block of NO_DEV", NO_NUM);
-
-  for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++)
-	if (sp->s_dev == dev) return(sp);
-
-  /* Search failed.  Something wrong. */
-  panic(__FILE__,"can't find superblock for device (in decimal)", (int) dev);
-
-  return(NIL_SUPER);		/* to keep the compiler and lint quiet */
-}
-
-/*===========================================================================*
- *				get_block_size				     *
- *===========================================================================*/
-PUBLIC int get_block_size(dev_t dev)
-{
-/* Search the superblock table for this device. */
-
-  register struct super_block *sp;
-
-  if (dev == NO_DEV)
-  	panic(__FILE__,"request for block size of NO_DEV", NO_NUM);
-
-  for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++) {
-	if (sp->s_dev == dev) {
-		return(sp->s_block_size);
-	}
-  }
-
-  /* no mounted filesystem? use this block size then. */
-  return _MIN_BLOCK_SIZE;
-}
-
-/*===========================================================================*
- *				mounted					     *
- *===========================================================================*/
-PUBLIC int mounted(rip)
-register struct inode *rip;	/* pointer to inode */
-{
-/* Report on whether the given inode is on a mounted (or ROOT) file system. */
-
-  register struct super_block *sp;
-  register dev_t dev;
-
-  dev = (dev_t) rip->i_zone[0];
-  if (dev == root_dev) return(TRUE);	/* inode is on root file system */
-
-  for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++)
-	if (sp->s_dev == dev) return(TRUE);
-
-  return(FALSE);
-}
-
-/*===========================================================================*
- *				read_super				     *
- *===========================================================================*/
-PUBLIC int read_super(sp)
-register struct super_block *sp; /* pointer to a superblock */
-{
-/* Read a superblock. */
-  dev_t dev;
-  int magic;
-  int version, native, r;
-  static char sbbuf[_MIN_BLOCK_SIZE];
-
-  dev = sp->s_dev;		/* save device (will be overwritten by copy) */
-  if (dev == NO_DEV)
-  	panic(__FILE__,"request for super_block of NO_DEV", NO_NUM);
-  r = dev_io(DEV_READ, dev, FS_PROC_NR,
-  	sbbuf, SUPER_BLOCK_BYTES, _MIN_BLOCK_SIZE, 0);
-  if (r != _MIN_BLOCK_SIZE) {
-  	return EINVAL;
-  }
-  memcpy(sp, sbbuf, sizeof(*sp));
-  sp->s_dev = NO_DEV;		/* restore later */
-  magic = sp->s_magic;		/* determines file system type */
-
-  /* Get file system version and type. */
-  if (magic == SUPER_MAGIC || magic == conv2(BYTE_SWAP, SUPER_MAGIC)) {
-	version = V1;
-	native  = (magic == SUPER_MAGIC);
-  } else if (magic == SUPER_V2 || magic == conv2(BYTE_SWAP, SUPER_V2)) {
-	version = V2;
-	native  = (magic == SUPER_V2);
-  } else if (magic == SUPER_V3) {
-	version = V3;
-  	native = 1;
-  } else {
-	return(EINVAL);
-  }
-
-  /* If the super block has the wrong byte order, swap the fields; the magic
-   * number doesn't need conversion. */
-  sp->s_ninodes =       conv4(native, sp->s_ninodes);
-  sp->s_nzones =        conv2(native, (int) sp->s_nzones);
-  sp->s_imap_blocks =   conv2(native, (int) sp->s_imap_blocks);
-  sp->s_zmap_blocks =   conv2(native, (int) sp->s_zmap_blocks);
-  sp->s_firstdatazone = conv2(native, (int) sp->s_firstdatazone);
-  sp->s_log_zone_size = conv2(native, (int) sp->s_log_zone_size);
-  sp->s_max_size =      conv4(native, sp->s_max_size);
-  sp->s_zones =         conv4(native, sp->s_zones);
-
-  /* In V1, the device size was kept in a short, s_nzones, which limited
-   * devices to 32K zones.  For V2, it was decided to keep the size as a
-   * long.  However, just changing s_nzones to a long would not work, since
-   * then the position of s_magic in the super block would not be the same
-   * in V1 and V2 file systems, and there would be no way to tell whether
-   * a newly mounted file system was V1 or V2.  The solution was to introduce
-   * a new variable, s_zones, and copy the size there.
-   *
-   * Calculate some other numbers that depend on the version here too, to
-   * hide some of the differences.
-   */
-  if (version == V1) {
-  	sp->s_block_size = _STATIC_BLOCK_SIZE;
-	sp->s_zones = sp->s_nzones;	/* only V1 needs this copy */
-	sp->s_inodes_per_block = V1_INODES_PER_BLOCK;
-	sp->s_ndzones = V1_NR_DZONES;
-	sp->s_nindirs = V1_INDIRECTS;
-  } else {
-  	if (version == V2)
-  		sp->s_block_size = _STATIC_BLOCK_SIZE;
-  	if (sp->s_block_size < _MIN_BLOCK_SIZE)
-  		return EINVAL;
-	sp->s_inodes_per_block = V2_INODES_PER_BLOCK(sp->s_block_size);
-	sp->s_ndzones = V2_NR_DZONES;
-	sp->s_nindirs = V2_INDIRECTS(sp->s_block_size);
-  }
-
-  if (sp->s_block_size < _MIN_BLOCK_SIZE) {
-  	return EINVAL;
-  }
-  if (sp->s_block_size > _MAX_BLOCK_SIZE) {
-  	printf("Filesystem block size is %d kB; maximum filesystem\n"
- 	"block size is %d kB. This limit can be increased by recompiling.\n",
-  	sp->s_block_size/1024, _MAX_BLOCK_SIZE/1024);
-  	return EINVAL;
-  }
-  if ((sp->s_block_size % 512) != 0) {
-  	return EINVAL;
-  }
-  if (SUPER_SIZE > sp->s_block_size) {
-  	return EINVAL;
-  }
-  if ((sp->s_block_size % V2_INODE_SIZE) != 0 ||
-     (sp->s_block_size % V1_INODE_SIZE) != 0) {
-  	return EINVAL;
-  }
-
-  sp->s_isearch = 0;		/* inode searches initially start at 0 */
-  sp->s_zsearch = 0;		/* zone searches initially start at 0 */
-  sp->s_version = version;
-  sp->s_native  = native;
-
-  /* Make a few basic checks to see if super block looks reasonable. */
-  if (sp->s_imap_blocks < 1 || sp->s_zmap_blocks < 1
-				|| sp->s_ninodes < 1 || sp->s_zones < 1
-				|| (unsigned) sp->s_log_zone_size > 4) {
-  	printf("not enough imap or zone map blocks, \n");
-  	printf("or not enough inodes, or not enough zones, "
-  		"or zone size too large\n");
-	return(EINVAL);
-  }
-  sp->s_dev = dev;		/* restore device number */
-  return(OK);
-}
Index: trunk/minix/servers/fs/super.h
===================================================================
--- trunk/minix/servers/fs/super.h	(revision 11)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/* Super block table.  The root file system and every mounted file system
- * has an entry here.  The entry holds information about the sizes of the bit
- * maps and inodes.  The s_ninodes field gives the number of inodes available
- * for files and directories, including the root directory.  Inode 0 is 
- * on the disk, but not used.  Thus s_ninodes = 4 means that 5 bits will be
- * used in the bit map, bit 0, which is always 1 and not used, and bits 1-4
- * for files and directories.  The disk layout is:
- *
- *    Item        # blocks
- *    boot block      1
- *    super block     1    (offset 1kB)
- *    inode map     s_imap_blocks
- *    zone map      s_zmap_blocks
- *    inodes        (s_ninodes + 'inodes per block' - 1)/'inodes per block'
- *    unused        whatever is needed to fill out the current zone
- *    data zones    (s_zones - s_firstdatazone) << s_log_zone_size
- *
- * A super_block slot is free if s_dev == NO_DEV. 
- */
-
-EXTERN struct super_block {
-  ino_t s_ninodes;		/* # usable inodes on the minor device */
-  zone1_t  s_nzones;		/* total device size, including bit maps etc */
-  short s_imap_blocks;		/* # of blocks used by inode bit map */
-  short s_zmap_blocks;		/* # of blocks used by zone bit map */
-  zone1_t s_firstdatazone;	/* number of first data zone */
-  short s_log_zone_size;	/* log2 of blocks/zone */
-  short s_pad;			/* try to avoid compiler-dependent padding */
-  off_t s_max_size;		/* maximum file size on this device */
-  zone_t s_zones;		/* number of zones (replaces s_nzones in V2) */
-  short s_magic;		/* magic number to recognize super-blocks */
-
-  /* The following items are valid on disk only for V3 and above */
-
-  /* The block size in bytes. Minimum MIN_BLOCK SIZE. SECTOR_SIZE
-   * multiple. If V1 or V2 filesystem, this should be
-   * initialised to STATIC_BLOCK_SIZE. Maximum MAX_BLOCK_SIZE.
-   */
-  short s_pad2;			/* try to avoid compiler-dependent padding */
-  unsigned short s_block_size;	/* block size in bytes. */
-  char s_disk_version;		/* filesystem format sub-version */
-
-  /* The following items are only used when the super_block is in memory. */
-  struct inode *s_isup;		/* inode for root dir of mounted file sys */
-  struct inode *s_imount;	/* inode mounted on */
-  unsigned s_inodes_per_block;	/* precalculated from magic number */
-  dev_t s_dev;			/* whose super block is this? */
-  int s_rd_only;		/* set to 1 iff file sys mounted read only */
-  int s_native;			/* set to 1 iff not byte swapped file system */
-  int s_version;		/* file system version, zero means bad magic */
-  int s_ndzones;		/* # direct zones in an inode */
-  int s_nindirs;		/* # indirect zones per indirect block */
-  bit_t s_isearch;		/* inodes below this bit number are in use */
-  bit_t s_zsearch;		/* all zones below this bit number are in use*/
-} super_block[NR_SUPERS];
-
-#define NIL_SUPER (struct super_block *) 0
-#define IMAP		0	/* operating on the inode bit map */
-#define ZMAP		1	/* operating on the zone bit map */
Index: trunk/minix/servers/fs/table.c
===================================================================
--- trunk/minix/servers/fs/table.c	(revision 11)
+++ 	(revision )
@@ -1,119 +1,0 @@
-/* This file contains the table used to map system call numbers onto the
- * routines that perform them.
- */
-
-#define _TABLE
-
-#include "fs.h"
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "lock.h"
-#include "super.h"
-
-PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
-	no_sys,		/*  0 = unused	*/
-	do_exit,	/*  1 = exit	*/
-	do_fork,	/*  2 = fork	*/
-	do_read,	/*  3 = read	*/
-	do_write,	/*  4 = write	*/
-	do_open,	/*  5 = open	*/
-	do_close,	/*  6 = close	*/
-	no_sys,		/*  7 = wait	*/
-	do_creat,	/*  8 = creat	*/
-	do_link,	/*  9 = link	*/
-	do_unlink,	/* 10 = unlink	*/
-	no_sys,		/* 11 = waitpid	*/
-	do_chdir,	/* 12 = chdir	*/
-	no_sys,		/* 13 = time	*/
-	do_mknod,	/* 14 = mknod	*/
-	do_chmod,	/* 15 = chmod	*/
-	do_chown,	/* 16 = chown	*/
-	no_sys,		/* 17 = break	*/
-	do_stat,	/* 18 = stat	*/
-	do_lseek,	/* 19 = lseek	*/
-	no_sys,		/* 20 = getpid	*/
-	do_mount,	/* 21 = mount	*/
-	do_umount,	/* 22 = umount	*/
-	do_set,		/* 23 = setuid	*/
-	no_sys,		/* 24 = getuid	*/
-	do_stime,	/* 25 = stime	*/
-	no_sys,		/* 26 = ptrace	*/
-	no_sys,		/* 27 = alarm	*/
-	do_fstat,	/* 28 = fstat	*/
-	no_sys,		/* 29 = pause	*/
-	do_utime,	/* 30 = utime	*/
-	no_sys,		/* 31 = (stty)	*/
-	no_sys,		/* 32 = (gtty)	*/
-	do_access,	/* 33 = access	*/
-	no_sys,		/* 34 = (nice)	*/
-	no_sys,		/* 35 = (ftime)	*/
-	do_sync,	/* 36 = sync	*/
-	no_sys,		/* 37 = kill	*/
-	do_rename,	/* 38 = rename	*/
-	do_mkdir,	/* 39 = mkdir	*/
-	do_unlink,	/* 40 = rmdir	*/
-	do_dup,		/* 41 = dup	*/
-	do_pipe,	/* 42 = pipe	*/
-	no_sys,		/* 43 = times	*/
-	no_sys,		/* 44 = (prof)	*/
-	do_slink,	/* 45 = symlink	*/
-	do_set,		/* 46 = setgid	*/
-	no_sys,		/* 47 = getgid	*/
-	no_sys,		/* 48 = (signal)*/
-	do_rdlink,	/* 49 = readlink*/
-	do_lstat,	/* 50 = lstat	*/
-	no_sys,		/* 51 = (acct)	*/
-	no_sys,		/* 52 = (phys)	*/
-	no_sys,		/* 53 = (lock)	*/
-	do_ioctl,	/* 54 = ioctl	*/
-	do_fcntl,	/* 55 = fcntl	*/
-	no_sys,		/* 56 = (mpx)	*/
-	no_sys,		/* 57 = unused	*/
-	no_sys,		/* 58 = unused	*/
-	do_exec,	/* 59 = execve	*/
-	do_umask,	/* 60 = umask	*/
-	do_chroot,	/* 61 = chroot	*/
-	do_setsid,	/* 62 = setsid	*/
-	no_sys,		/* 63 = getpgrp	*/
-
-	no_sys,		/* 64 = KSIG: signals originating in the kernel	*/
-	do_unpause,	/* 65 = UNPAUSE	*/
-	no_sys, 	/* 66 = unused  */
-	do_revive,	/* 67 = REVIVE	*/
-	no_sys,		/* 68 = TASK_REPLY	*/
-	no_sys,		/* 69 = unused */
-	no_sys,		/* 70 = unused */
-	no_sys,		/* 71 = si */
-	no_sys,		/* 72 = sigsuspend */
-	no_sys,		/* 73 = sigpending */
-	no_sys,		/* 74 = sigprocmask */
-	no_sys,		/* 75 = sigreturn */
-	do_reboot,	/* 76 = reboot */
-	do_svrctl,	/* 77 = svrctl */
-
-	no_sys,		/* 78 = unused */
-	do_getsysinfo,  /* 79 = getsysinfo */
-	no_sys,		/* 80 = unused */
-	do_devctl,	/* 81 = devctl */
-	do_fstatfs,	/* 82 = fstatfs */
-	no_sys,		/* 83 = memalloc */
-	no_sys,		/* 84 = memfree */
-	do_select,	/* 85 = select */
-	do_fchdir,	/* 86 = fchdir */
-	do_fsync,	/* 87 = fsync */
-	no_sys,		/* 88 = getpriority */
-	no_sys,		/* 89 = setpriority */
-	no_sys,		/* 90 = gettimeofday */
-	no_sys,		/* 91 = seteuid */
-	no_sys,		/* 92 = setegid */
-	do_truncate,	/* 93 = truncate */
-	do_ftruncate,	/* 94 = truncate */
-	no_sys,		/* 95 = foo */
-};
-/* This should not fail with "array size is negative": */
-extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
-
Index: trunk/minix/servers/fs/time.c
===================================================================
--- trunk/minix/servers/fs/time.c	(revision 11)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/* This file takes care of those system calls that deal with time.
- *
- * The entry points into this file are
- *   do_utime:		perform the UTIME system call
- *   do_stime:		PM informs FS about STIME system call
- */
-
-#include "fs.h"
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-
-/*===========================================================================*
- *				do_utime				     *
- *===========================================================================*/
-PUBLIC int do_utime()
-{
-/* Perform the utime(name, timep) system call. */
-
-  register struct inode *rip;
-  register int len, r;
-
-  /* Adjust for case of 'timep' being NULL;
-   * utime_strlen then holds the actual size: strlen(name)+1.
-   */
-  len = m_in.utime_length;
-  if (len == 0) len = m_in.utime_strlen;
-
-  /* Temporarily open the file. */
-  if (fetch_name(m_in.utime_file, len, M1) != OK) return(err_code);
-  if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
-
-  /* Only the owner of a file or the super_user can change its time. */
-  r = OK;
-  if (rip->i_uid != fp->fp_effuid && !super_user) r = EPERM;
-  if (m_in.utime_length == 0 && r != OK) r = forbidden(rip, W_BIT);
-  if (read_only(rip) != OK) r = EROFS;	/* not even su can touch if R/O */
-  if (r == OK) {
-	if (m_in.utime_length == 0) {
-		rip->i_atime = clock_time();
-		rip->i_mtime = rip->i_atime;
-	} else {
-		rip->i_atime = m_in.utime_actime;
-		rip->i_mtime = m_in.utime_modtime;
-	}
-	rip->i_update = CTIME;	/* discard any stale ATIME and MTIME flags */
-	rip->i_dirt = DIRTY;
-  }
-
-  put_inode(rip);
-  return(r);
-}
-
-/*===========================================================================*
- *				do_stime				     *
- *===========================================================================*/
-PUBLIC int do_stime()
-{
-/* Perform the stime(tp) system call. */
-  boottime = (long) m_in.pm_stime; 
-  return(OK);
-}
-
Index: trunk/minix/servers/fs/timers.c
===================================================================
--- trunk/minix/servers/fs/timers.c	(revision 11)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/* FS timers library
- */
-
-#include "fs.h"
-
-#include <timers.h>
-#include <minix/syslib.h>
-#include <minix/com.h>
-
-PRIVATE timer_t *fs_timers = NULL;
-
-PUBLIC void fs_set_timer(timer_t *tp, int ticks, tmr_func_t watchdog, int arg)
-{
-	int r;
-	clock_t now, old_head = 0, new_head;
-
-	if ((r = getuptime(&now)) != OK)
-		panic(__FILE__, "FS couldn't get uptime from system task.", NO_NUM);
-
-	tmr_arg(tp)->ta_int = arg;
-
-	old_head = tmrs_settimer(&fs_timers, tp, now+ticks, watchdog, &new_head);
-
-	/* reschedule our synchronous alarm if necessary */
-	if (!old_head || old_head > new_head) {
-		if (sys_setalarm(new_head, 1) != OK)
-			panic(__FILE__, "FS set timer "
-			"couldn't set synchronous alarm.", NO_NUM);
-	}
-
-	return;
-}
-
-PUBLIC void fs_expire_timers(clock_t now)
-{
-	clock_t new_head;
-	tmrs_exptimers(&fs_timers, now, &new_head);
-	if (new_head > 0) {
-		if (sys_setalarm(new_head, 1) != OK)
-			panic(__FILE__, "FS expire timer couldn't set "
-				"synchronous alarm.", NO_NUM);
-	}
-}
-
-PUBLIC void fs_init_timer(timer_t *tp)
-{
-	tmr_inittimer(tp);
-}
-
-PUBLIC void fs_cancel_timer(timer_t *tp)
-{
-	clock_t new_head, old_head;
-	old_head = tmrs_clrtimer(&fs_timers, tp, &new_head);
-
-	/* if the earliest timer has been removed, we have to set
-	 * the synalarm to the next timer, or cancel the synalarm
-	 * altogether if th last time has been cancelled (new_head
-	 * will be 0 then).
-	 */
-	if (old_head < new_head || !new_head) {
-		if (sys_setalarm(new_head, 1) != OK)
-			panic(__FILE__,
-			"FS expire timer couldn't set synchronous alarm.",
-				 NO_NUM);
-	}
-}
Index: trunk/minix/servers/fs/type.h
===================================================================
--- trunk/minix/servers/fs/type.h	(revision 11)
+++ 	(revision )
@@ -1,23 +1,0 @@
-/* Declaration of the V1 inode as it is on the disk (not in core). */
-typedef struct {		/* V1.x disk inode */
-  mode_t d1_mode;		/* file type, protection, etc. */
-  uid_t d1_uid;			/* user id of the file's owner */
-  off_t d1_size;		/* current file size in bytes */
-  time_t d1_mtime;		/* when was file data last changed */
-  u8_t d1_gid;			/* group number */
-  u8_t d1_nlinks;		/* how many links to this file */
-  u16_t d1_zone[V1_NR_TZONES];	/* block nums for direct, ind, and dbl ind */
-} d1_inode;
-
-/* Declaration of the V2 inode as it is on the disk (not in core). */
-typedef struct {		/* V2.x disk inode */
-  mode_t d2_mode;		/* file type, protection, etc. */
-  u16_t d2_nlinks;		/* how many links to this file. HACK! */
-  uid_t d2_uid;			/* user id of the file's owner. */
-  u16_t d2_gid;			/* group number HACK! */
-  off_t d2_size;		/* current file size in bytes */
-  time_t d2_atime;		/* when was file data last accessed */
-  time_t d2_mtime;		/* when was file data last changed */
-  time_t d2_ctime;		/* when was inode data last changed */
-  zone_t d2_zone[V2_NR_TZONES];	/* block nums for direct, ind, and dbl ind */
-} d2_inode;
Index: trunk/minix/servers/fs/utility.c
===================================================================
--- trunk/minix/servers/fs/utility.c	(revision 11)
+++ 	(revision )
@@ -1,165 +1,0 @@
-/* This file contains a few general purpose utility routines.
- *
- * The entry points into this file are
- *   clock_time:  ask the clock task for the real time
- *   copy:	  copy a block of data
- *   fetch_name:  go get a path name from user space
- *   no_sys:      reject a system call that FS does not handle
- *   panic:       something awful has occurred;  MINIX cannot continue
- *   conv2:	  do byte swapping on a 16-bit int
- *   conv4:	  do byte swapping on a 32-bit long
- */
-
-#include "fs.h"
-#include <minix/com.h>
-#include <minix/endpoint.h>
-#include <unistd.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "param.h"
-
-PRIVATE int panicking;		/* inhibits recursive panics during sync */
-
-/*===========================================================================*
- *				clock_time				     *
- *===========================================================================*/
-PUBLIC time_t clock_time()
-{
-/* This routine returns the time in seconds since 1.1.1970.  MINIX is an
- * astrophysically naive system that assumes the earth rotates at a constant
- * rate and that such things as leap seconds do not exist.
- */
-
-  register int k;
-  clock_t uptime;
-
-  if ( (k=getuptime(&uptime)) != OK) panic(__FILE__,"clock_time err", k);
-  return( (time_t) (boottime + (uptime/HZ)));
-}
-
-/*===========================================================================*
- *				fetch_name				     *
- *===========================================================================*/
-PUBLIC int fetch_name(path, len, flag)
-char *path;			/* pointer to the path in user space */
-int len;			/* path length, including 0 byte */
-int flag;			/* M3 means path may be in message */
-{
-/* Go get path and put it in 'user_path'.
- * If 'flag' = M3 and 'len' <= M3_STRING, the path is present in 'message'.
- * If it is not, go copy it from user space.
- */
-  register char *rpu, *rpm;
-  int r;
-
-  /* Check name length for validity. */
-  if (len <= 0) {
-	err_code = EINVAL;
-	return(EGENERIC);
-  }
-
-  if (len > PATH_MAX) {
-	err_code = ENAMETOOLONG;
-	return(EGENERIC);
-  }
-
-  if (flag == M3 && len <= M3_STRING) {
-	/* Just copy the path from the message to 'user_path'. */
-	rpu = &user_path[0];
-	rpm = m_in.pathname;		/* contained in input message */
-	do { *rpu++ = *rpm++; } while (--len);
-	r = OK;
-  } else {
-	/* String is not contained in the message.  Get it from user space. */
-	r = sys_datacopy(who_e, (vir_bytes) path,
-		FS_PROC_NR, (vir_bytes) user_path, (phys_bytes) len);
-  }
-  return(r);
-}
-
-/*===========================================================================*
- *				no_sys					     *
- *===========================================================================*/
-PUBLIC int no_sys()
-{
-/* Somebody has used an illegal system call number */
-  return(EINVAL);
-}
-
-/*===========================================================================*
- *				panic					     *
- *===========================================================================*/
-PUBLIC void panic(who, mess, num)
-char *who;			/* who caused the panic */
-char *mess;			/* panic message string */
-int num;			/* number to go with it */
-{
-/* Something awful has happened.  Panics are caused when an internal
- * inconsistency is detected, e.g., a programming error or illegal value of a
- * defined constant.
- */
-  if (panicking) return;	/* do not panic during a sync */
-  panicking = TRUE;		/* prevent another panic during the sync */
-
-  printf("FS panic (%s): %s ", who, mess);
-  if (num != NO_NUM) printf("%d",num); 
-  (void) do_sync();		/* flush everything to the disk */
-  sys_exit(SELF);
-}
-
-/*===========================================================================*
- *				conv2					     *
- *===========================================================================*/
-PUBLIC unsigned conv2(norm, w)
-int norm;			/* TRUE if no swap, FALSE for byte swap */
-int w;				/* promotion of 16-bit word to be swapped */
-{
-/* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
-  if (norm) return( (unsigned) w & 0xFFFF);
-  return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
-}
-
-/*===========================================================================*
- *				conv4					     *
- *===========================================================================*/
-PUBLIC long conv4(norm, x)
-int norm;			/* TRUE if no swap, FALSE for byte swap */
-long x;				/* 32-bit long to be byte swapped */
-{
-/* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
-  unsigned lo, hi;
-  long l;
-  
-  if (norm) return(x);			/* byte order was already ok */
-  lo = conv2(FALSE, (int) x & 0xFFFF);	/* low-order half, byte swapped */
-  hi = conv2(FALSE, (int) (x>>16) & 0xFFFF);	/* high-order half, swapped */
-  l = ( (long) lo <<16) | hi;
-  return(l);
-}
-
-/*===========================================================================*
- *				isokendpt_f				     *
- *===========================================================================*/
-PUBLIC int isokendpt_f(char *file, int line, int endpoint, int *proc, int fatal)
-{
-	int failed = 0;
-	*proc = _ENDPOINT_P(endpoint);
-	if(*proc < 0 || *proc >= NR_PROCS) {
-		printf("FS:%s:%d: proc (%d) from endpoint (%d) out of range\n",
-			file, line, *proc, endpoint);
-		failed = 1;
-	} else if(fproc[*proc].fp_endpoint != endpoint) {
-		printf("FS:%s:%d: proc (%d) from endpoint (%d) doesn't match "
-			"known endpoint (%d)\n",
-			file, line, *proc, endpoint, fproc[*proc].fp_endpoint);
-		failed = 1;
-	}
-
-	if(failed && fatal)
-		panic(__FILE__, "isokendpt_f failed", NO_NUM);
-
-	return failed ? EDEADSRCDST : OK;
-}
-
Index: trunk/minix/servers/fs/write.c
===================================================================
--- trunk/minix/servers/fs/write.c	(revision 11)
+++ 	(revision )
@@ -1,338 +1,0 @@
-/* This file is the counterpart of "read.c".  It contains the code for writing
- * insofar as this is not contained in read_write().
- *
- * The entry points into this file are
- *   do_write:     call read_write to perform the WRITE system call
- *   clear_zone:   erase a zone in the middle of a file
- *   new_block:    acquire a new block
- */
-
-#include "fs.h"
-#include <string.h>
-#include "buf.h"
-#include "file.h"
-#include "fproc.h"
-#include "inode.h"
-#include "super.h"
-
-FORWARD _PROTOTYPE( void wr_indir, (struct buf *bp, int index, zone_t zone) );
-FORWARD _PROTOTYPE( int empty_indir, (struct buf *, struct super_block *) );
-
-/*===========================================================================*
- *				do_write				     *
- *===========================================================================*/
-PUBLIC int do_write()
-{
-/* Perform the write(fd, buffer, nbytes) system call. */
-
-  return(read_write(WRITING));
-}
-
-/*===========================================================================*
- *				write_map				     *
- *===========================================================================*/
-PUBLIC int write_map(rip, position, new_zone, op)
-struct inode *rip;		/* pointer to inode to be changed */
-off_t position;			/* file address to be mapped */
-zone_t new_zone;		/* zone # to be inserted */
-int op;				/* special actions */
-{
-/* Write a new zone into an inode.
- *
- * If op includes WMAP_FREE, free the data zone corresponding to that position
- * in the inode ('new_zone' is ignored then). Also free the indirect block
- * if that was the last entry in the indirect block.
- * Also free the double indirect block if that was the last entry in the
- * double indirect block.
- */
-  int scale, ind_ex, new_ind, new_dbl, zones, nr_indirects, single, zindex, ex;
-  zone_t z, z1, z2 = NO_ZONE, old_zone;
-  register block_t b;
-  long excess, zone;
-  struct buf *bp_dindir = NIL_BUF, *bp = NIL_BUF;
-
-  rip->i_dirt = DIRTY;		/* inode will be changed */
-  scale = rip->i_sp->s_log_zone_size;		/* for zone-block conversion */
-  	/* relative zone # to insert */
-  zone = (position/rip->i_sp->s_block_size) >> scale;
-  zones = rip->i_ndzones;	/* # direct zones in the inode */
-  nr_indirects = rip->i_nindirs;/* # indirect zones per indirect block */
-
-  /* Is 'position' to be found in the inode itself? */
-  if (zone < zones) {
-	zindex = (int) zone;	/* we need an integer here */
-	if(rip->i_zone[zindex] != NO_ZONE && (op & WMAP_FREE)) {
-		free_zone(rip->i_dev, rip->i_zone[zindex]);
-		rip->i_zone[zindex] = NO_ZONE;
-	} else {
-		rip->i_zone[zindex] = new_zone;
-	}
-	return(OK);
-  }
-
-  /* It is not in the inode, so it must be single or double indirect. */
-  excess = zone - zones;	/* first Vx_NR_DZONES don't count */
-  new_ind = FALSE;
-  new_dbl = FALSE;
-
-  if (excess < nr_indirects) {
-	/* 'position' can be located via the single indirect block. */
-	z1 = rip->i_zone[zones];	/* single indirect zone */
-	single = TRUE;
-  } else {
-	/* 'position' can be located via the double indirect block. */
-	if ( (z2 = z = rip->i_zone[zones+1]) == NO_ZONE &&
-	    !(op & WMAP_FREE)) {
-		/* Create the double indirect block. */
-		if ( (z = alloc_zone(rip->i_dev, rip->i_zone[0])) == NO_ZONE)
-			return(err_code);
-		rip->i_zone[zones+1] = z;
-		new_dbl = TRUE;	/* set flag for later */
-	}
-
-	/* 'z' is zone number for double indirect block, either old
-	 * or newly created.
-	 * If there wasn't one and WMAP_FREE is set, 'z' is NO_ZONE.
-	 */
-	excess -= nr_indirects;	/* single indirect doesn't count */
-	ind_ex = (int) (excess / nr_indirects);
-	excess = excess % nr_indirects;
-	if (ind_ex >= nr_indirects) return(EFBIG);
-
-	if(z == NO_ZONE) {
-		/* WMAP_FREE and no double indirect block - then no
-		 * single indirect block either.
-		 */
-		z1 = NO_ZONE;
-	} else {
-		b = (block_t) z << scale;
-		bp_dindir = get_block(rip->i_dev, b, (new_dbl?NO_READ:NORMAL));
-		if (new_dbl) zero_block(bp_dindir);
-		z1 = rd_indir(bp_dindir, ind_ex);
-	}
-	single = FALSE;
-  }
-
-  /* z1 is now single indirect zone, or NO_ZONE; 'excess' is index.
-   * We have to create the indirect zone if it's NO_ZONE. Unless
-   * we're freeing (WMAP_FREE).
-   */
-  if (z1 == NO_ZONE && !(op & WMAP_FREE)) {
-	z1 = alloc_zone(rip->i_dev, rip->i_zone[0]);
-	if (single)
-		rip->i_zone[zones] = z1; /* update inode w. single indirect */
-	else
-		wr_indir(bp_dindir, ind_ex, z1);	/* update dbl indir */
-
-	new_ind = TRUE;
-	/* If double ind, it is dirty. */
-	if (bp_dindir != NIL_BUF) bp_dindir->b_dirt = DIRTY;
-	if (z1 == NO_ZONE) {
-		/* Release dbl indirect blk. */
-		put_block(bp_dindir, INDIRECT_BLOCK);
-		return(err_code);	/* couldn't create single ind */
-	}
-  }
-
-  /* z1 is indirect block's zone number (unless it's NO_ZONE when we're
-   * freeing).
-   */
-  if(z1 != NO_ZONE) {
-  	ex = (int) excess;			/* we need an int here */
-	b = (block_t) z1 << scale;
-	bp = get_block(rip->i_dev, b, (new_ind ? NO_READ : NORMAL) );
-	if (new_ind) zero_block(bp);
-	if(op & WMAP_FREE) {
-		if((old_zone = rd_indir(bp, ex)) != NO_ZONE) {
-			free_zone(rip->i_dev, old_zone);
-			wr_indir(bp, ex, NO_ZONE);
-		}
-
-		/* Last reference in the indirect block gone? Then
-		 * Free the indirect block.
-		 */
-		if(empty_indir(bp, rip->i_sp)) {
-			free_zone(rip->i_dev, z1);
-			z1 = NO_ZONE;
-			/* Update the reference to the indirect block to
-			 * NO_ZONE - in the double indirect block if there
-			 * is one, otherwise in the inode directly.
-			 */
-			if(single) {
-				rip->i_zone[zones] = z1;
-			} else {
-				wr_indir(bp_dindir, ind_ex, z1);
-				bp_dindir->b_dirt = DIRTY;
-			}
-		}
-	} else {
-		wr_indir(bp, ex, new_zone);
-	}
-	bp->b_dirt = DIRTY;
-	put_block(bp, INDIRECT_BLOCK);
-  }
-
-  /* If the single indirect block isn't there (or was just freed),
-   * see if we have to keep the double indirect block.
-   */
-  if(z1 == NO_ZONE && !single && empty_indir(bp_dindir, rip->i_sp) &&
-     z2 != NO_ZONE) {
-	free_zone(rip->i_dev, z2);
-	rip->i_zone[zones+1] = NO_ZONE;
-  }
-
-  put_block(bp_dindir, INDIRECT_BLOCK);	/* release double indirect blk */
-
-  return(OK);
-}
-
-/*===========================================================================*
- *				wr_indir				     *
- *===========================================================================*/
-PRIVATE void wr_indir(bp, index, zone)
-struct buf *bp;			/* pointer to indirect block */
-int index;			/* index into *bp */
-zone_t zone;			/* zone to write */
-{
-/* Given a pointer to an indirect block, write one entry. */
-
-  struct super_block *sp;
-
-  if(bp == NIL_BUF)
-	panic(__FILE__, "wr_indir() on NIL_BUF", NO_NUM);
-
-  sp = get_super(bp->b_dev);	/* need super block to find file sys type */
-
-  /* write a zone into an indirect block */
-  if (sp->s_version == V1)
-	bp->b_v1_ind[index] = (zone1_t) conv2(sp->s_native, (int)  zone);
-  else
-	bp->b_v2_ind[index] = (zone_t)  conv4(sp->s_native, (long) zone);
-}
-
-/*===========================================================================*
- *				empty_indir				     *
- *===========================================================================*/
-PRIVATE int empty_indir(bp, sb)
-struct buf *bp;			/* pointer to indirect block */
-struct super_block *sb;		/* superblock of device block resides on */
-{
-/* Return nonzero if the indirect block pointed to by bp contains
- * only NO_ZONE entries.
- */
-	int i;
-	if(sb->s_version == V1) {
-		for(i = 0; i < V1_INDIRECTS; i++)
-			if(bp->b_v1_ind[i] != NO_ZONE)
-				return 0;
-	} else {
-		for(i = 0; i < V2_INDIRECTS(sb->s_block_size); i++)
-			if(bp->b_v2_ind[i] != NO_ZONE)
-				return 0;
-	}
-
-	return 1;
-}
-
-/*===========================================================================*
- *				clear_zone				     *
- *===========================================================================*/
-PUBLIC void clear_zone(rip, pos, flag)
-register struct inode *rip;	/* inode to clear */
-off_t pos;			/* points to block to clear */
-int flag;			/* 0 if called by read_write, 1 by new_block */
-{
-/* Zero a zone, possibly starting in the middle.  The parameter 'pos' gives
- * a byte in the first block to be zeroed.  Clearzone() is called from 
- * read_write and new_block().
- */
-
-  register struct buf *bp;
-  register block_t b, blo, bhi;
-  register off_t next;
-  register int scale;
-  register zone_t zone_size;
-
-  /* If the block size and zone size are the same, clear_zone() not needed. */
-  scale = rip->i_sp->s_log_zone_size;
-  if (scale == 0) return;
-
-  zone_size = (zone_t) rip->i_sp->s_block_size << scale;
-  if (flag == 1) pos = (pos/zone_size) * zone_size;
-  next = pos + rip->i_sp->s_block_size - 1;
-
-  /* If 'pos' is in the last block of a zone, do not clear the zone. */
-  if (next/zone_size != pos/zone_size) return;
-  if ( (blo = read_map(rip, next)) == NO_BLOCK) return;
-  bhi = (  ((blo>>scale)+1) << scale)   - 1;
-
-  /* Clear all the blocks between 'blo' and 'bhi'. */
-  for (b = blo; b <= bhi; b++) {
-	bp = get_block(rip->i_dev, b, NO_READ);
-	zero_block(bp);
-	put_block(bp, FULL_DATA_BLOCK);
-  }
-}
-
-/*===========================================================================*
- *				new_block				     *
- *===========================================================================*/
-PUBLIC struct buf *new_block(rip, position)
-register struct inode *rip;	/* pointer to inode */
-off_t position;			/* file pointer */
-{
-/* Acquire a new block and return a pointer to it.  Doing so may require
- * allocating a complete zone, and then returning the initial block.
- * On the other hand, the current zone may still have some unused blocks.
- */
-
-  register struct buf *bp;
-  block_t b, base_block;
-  zone_t z;
-  zone_t zone_size;
-  int scale, r;
-  struct super_block *sp;
-
-  /* Is another block available in the current zone? */
-  if ( (b = read_map(rip, position)) == NO_BLOCK) {
-	/* Choose first zone if possible. */
-	/* Lose if the file is nonempty but the first zone number is NO_ZONE
-	 * corresponding to a zone full of zeros.  It would be better to
-	 * search near the last real zone.
-	 */
-	if (rip->i_zone[0] == NO_ZONE) {
-		sp = rip->i_sp;
-		z = sp->s_firstdatazone;
-	} else {
-		z = rip->i_zone[0];	/* hunt near first zone */
-	}
-	if ( (z = alloc_zone(rip->i_dev, z)) == NO_ZONE) return(NIL_BUF);
-	if ( (r = write_map(rip, position, z, 0)) != OK) {
-		free_zone(rip->i_dev, z);
-		err_code = r;
-		return(NIL_BUF);
-	}
-
-	/* If we are not writing at EOF, clear the zone, just to be safe. */
-	if ( position != rip->i_size) clear_zone(rip, position, 1);
-	scale = rip->i_sp->s_log_zone_size;
-	base_block = (block_t) z << scale;
-	zone_size = (zone_t) rip->i_sp->s_block_size << scale;
-	b = base_block + (block_t)((position % zone_size)/rip->i_sp->s_block_size);
-  }
-
-  bp = get_block(rip->i_dev, b, NO_READ);
-  zero_block(bp);
-  return(bp);
-}
-
-/*===========================================================================*
- *				zero_block				     *
- *===========================================================================*/
-PUBLIC void zero_block(bp)
-register struct buf *bp;	/* pointer to buffer to zero */
-{
-/* Zero a block. */
-  memset(bp->b_data, 0, _MAX_BLOCK_SIZE);
-  bp->b_dirt = DIRTY;
-}
