0.96c out

The latest kernel version is 0.96c: the binary and sources can be found
on banjo.concert.net: pub/Linux/Linus as usual. I haven't made the
cdiffs yet, and I'll upload those tomorrow (at the same time I'll put it
on the other sites as well).

0.96c is actually what I called patch3 earlier this week, but as the new
features were pretty big and the cdiff's are probably going to be bigger
than the normal patches, I decided I might as well make it a totally new
minor release and make a bootimage and complete source available.

0.96c contains:
 - bugfixes (tty, console driver, pty's, sockets)
 - fifo's (names pipes - Paul Hargrove & editing by me)
 - the alpha extended filesystem (Remy Card)
 - st_blocks implemented (ie du, ls give reasonable if not exact values
   for disk-space used)
 - Makefile cleanups and warnings at compile-time removed

Note that while the extended filesystem code is there, and this kernel
successfully mounts and uses the new filesystem (with long filenames and
>64MB partitions), it's still under testing: I haven't made the mkefs
program available, and the extended filesystem features shouldn't be
used for other than testing right now.

Some of the changes are just cleanups: most of the warnings when
compiling the new kernel should be gone (not counting the scsi code
which is still the old non-cleaned-up version), and the make'ing of the
kernel is more logical now.

The bugfixes include the corrected console.c driver, the socket
corrections (without which X sometimes locks up), some pty semantics
corrections (although I'm still not certain it's correct) and some
editing in the general tty driver (including fixing the bug introduced
in 0.96b.pl2 that caused a reboot with uninitialized tty devices).

While the extended filesystem support isn't "official" yet, I can
happily report that my limited testing hasn't found any problems with
long filenames etc. It still needs a fsck program, but 1.0 looks like a
real possibility soon.

		Linus
diff --git a/Makefile b/Makefile
index 30a4fdf..c582ab2 100644
--- a/Makefile
+++ b/Makefile
@@ -42,15 +42,10 @@
 MATH_EMULATION = -DKERNEL_MATH_EMULATION
 
 #
-# uncomment this line if you are using gcc-1.40
-#
-#GCC_OPT = -fcombine-regs -fstrength-reduce
-
-#
 # standard CFLAGS
 #
 
-CFLAGS =-Wall -O6 -fomit-frame-pointer $(GCC_OPT)
+CFLAGS =-Wall -O6 -fomit-frame-pointer
 
 #
 # if you want the ram-disk device, define this to be the
@@ -64,33 +59,37 @@
 
 AS	=as
 LD	=ld
-#LDFLAGS	=-s -x -M
-LDFLAGS	= -M
-CC	=gcc $(RAMDISK)
-MAKE	=make CFLAGS="$(CFLAGS)"
-CPP	=cpp -nostdinc -Iinclude
+HOSTCC	=gcc -static
+CC	=gcc -nostdinc -I$(KERNELHDRS)
+MAKE	=make
+CPP	=$(CC) -E
+AR	=ar
 
 ARCHIVES	=kernel/kernel.o mm/mm.o fs/fs.o net/net.o
-FILESYSTEMS	=fs/minix/minix.o
+FILESYSTEMS	=fs/minix/minix.o fs/ext/ext.o
 DRIVERS		=kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \
 		 kernel/blk_drv/scsi/scsi.a
 MATH		=kernel/math/math.a
 LIBS		=lib/lib.a
+SUBDIRS		=kernel mm fs net lib
+
+KERNELHDRS	=/usr/src/linux/include
 
 .c.s:
-	$(CC) $(CFLAGS) \
-	-nostdinc -Iinclude -S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 .s.o:
 	$(AS) -c -o $*.o $<
 .c.o:
-	$(CC) $(CFLAGS) \
-	-nostdinc -Iinclude -c -o $*.o $<
+	$(CC) $(CFLAGS) -c -o $*.o $<
 
 all:	Version Image
 
+subdirs: dummy
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+
 Version:
 	@./makever.sh
-	@echo \#define UTS_RELEASE \"0.96b.pl2-`cat .version`\" > include/linux/config_rel.h
+	@echo \#define UTS_RELEASE \"0.96c-`cat .version`\" > include/linux/config_rel.h
 	@echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h
 	touch include/linux/config.h
 
@@ -105,50 +104,19 @@
 	dd bs=8192 if=Image of=/dev/PS0
 
 tools/build: tools/build.c
-	$(CC) -static $(CFLAGS) \
+	$(HOSTCC) $(CFLAGS) \
 	-o tools/build tools/build.c
 
 boot/head.o: boot/head.s
 
-tools/system:	boot/head.o init/main.o \
-		$(ARCHIVES) $(FILESYSTEMS) $(DRIVERS) $(MATH) $(LIBS)
-	$(LD) $(LDFLAGS) boot/head.o init/main.o \
-	$(ARCHIVES) \
-	$(FILESYSTEMS) \
-	$(DRIVERS) \
-	$(MATH) \
-	$(LIBS) \
-	-o tools/system > System.map
-
-kernel/math/math.a: dummy
-	(cd kernel/math; $(MAKE) MATH_EMULATION="$(MATH_EMULATION)")
-
-kernel/blk_drv/blk_drv.a: dummy
-	(cd kernel/blk_drv; $(MAKE))
-
-kernel/blk_drv/scsi/scsi.a: dummy
-	(cd kernel/blk_drv/scsi; $(MAKE))
-
-kernel/chr_drv/chr_drv.a: dummy
-	(cd kernel/chr_drv; $(MAKE) KEYBOARD="$(KEYBOARD)")
-
-kernel/kernel.o: dummy
-	(cd kernel; $(MAKE))
-
-mm/mm.o: dummy
-	(cd mm; $(MAKE))
-
-fs/fs.o: dummy
-	(cd fs; $(MAKE))
-
-net/net.o: dummy
-	(cd net; $(MAKE))
-
-fs/minix/minix.o: dummy
-	(cd fs/minix; $(MAKE))
-
-lib/lib.a: dummy
-	(cd lib; $(MAKE))
+tools/system:	boot/head.o init/main.o subdirs
+	$(LD) $(LDFLAGS) -M boot/head.o init/main.o \
+		$(ARCHIVES) \
+		$(FILESYSTEMS) \
+		$(DRIVERS) \
+		$(MATH) \
+		$(LIBS) \
+		-o tools/system > System.map
 
 boot/setup: boot/setup.s
 	$(AS86) -o boot/setup.o boot/setup.s
@@ -168,33 +136,28 @@
 	rm -f Image System.map tmp_make core boot/bootsect boot/setup \
 		boot/bootsect.s boot/setup.s init/main.s
 	rm -f init/*.o tools/system tools/build boot/*.o
-	(cd mm;make clean)
-	(cd fs;make clean)
-	(cd kernel;make clean)
-	(cd lib;make clean)
-	(cd net;make clean)
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
 
 backup: clean
-	(cd .. ; tar cf - linux | compress - > backup.Z)
+	cd .. ; tar cf - linux | compress - > backup.Z
 	sync
 
-dep:
+depend dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make
+	for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
-	(cd fs; make dep)
-	(cd kernel; make dep)
-	(cd mm; make dep)
-	(cd net;make dep)
-	(cd lib; make dep)
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
 
 dummy:
 
 ### Dependencies:
-init/main.o : init/main.c include/stddef.h include/stdarg.h include/fcntl.h include/sys/types.h \
-  include/time.h include/asm/system.h include/asm/io.h include/linux/config.h \
-  include/linux/config_rel.h include/linux/config_ver.h include/linux/config.dist.h \
-  include/linux/sched.h include/linux/head.h include/linux/fs.h include/sys/dirent.h \
-  include/limits.h include/sys/vfs.h include/linux/mm.h include/linux/kernel.h \
-  include/signal.h include/sys/param.h include/sys/time.h include/sys/resource.h \
-  include/linux/tty.h include/termios.h include/linux/unistd.h 
+init/main.o : init/main.c /usr/src/linux/include/stddef.h /usr/src/linux/include/stdarg.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/asm/system.h \
+  /usr/src/linux/include/asm/io.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/config.h \
+  /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
+  /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
+  /usr/src/linux/include/termios.h /usr/src/linux/include/linux/unistd.h 
diff --git a/fs/Makefile b/fs/Makefile
index fceab9d..f356a42 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -7,111 +7,148 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-AR	=ar
-AS	=as
-LD	=ld
-CC	=gcc -nostdinc -I../include
-CPP	=cpp -nostdinc -I../include
+SUBDIRS	=minix ext
 
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) -c $<
 .s.o:
 	$(AS) -o $*.o $<
 
 OBJS=	open.o read_write.o inode.o file_table.o buffer.o super.o \
 	block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
-	select.o
+	select.o fifo.o
+
+all: fs.o subdirs
 
 fs.o: $(OBJS)
 	$(LD) -r -o fs.o $(OBJS)
 
+subdirs: dummy
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+
 clean:
 	rm -f core *.o *.a tmp_make
-	for i in *.c;do rm -f `basename $$i .c`.s;done
-	cd minix; make clean
+	for i in *.c; do rm -f `basename $$i .c`.s;done
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
 
-dep:
+depend dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do $(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
-	cd minix; make dep
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
+
+dummy:
 
 ### Dependencies:
-block_dev.o : block_dev.c ../include/errno.h ../include/linux/sched.h ../include/linux/head.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
-  ../include/asm/segment.h ../include/asm/system.h 
-buffer.o : buffer.c ../include/stdarg.h ../include/linux/config.h ../include/linux/config_rel.h \
-  ../include/linux/config_ver.h ../include/linux/config.dist.h ../include/linux/sched.h \
-  ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h \
-  ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/asm/system.h ../include/asm/io.h 
-exec.o : exec.c ../include/signal.h ../include/sys/types.h ../include/errno.h \
-  ../include/linux/string.h ../include/linux/stat.h ../include/sys/ptrace.h ../include/a.out.h \
-  ../include/fcntl.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/sched.h ../include/linux/head.h ../include/linux/mm.h \
-  ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/asm/segment.h ../include/sys/user.h 
-fcntl.o : fcntl.c ../include/errno.h ../include/fcntl.h ../include/sys/types.h \
-  ../include/linux/stat.h ../include/asm/segment.h ../include/linux/string.h ../include/linux/sched.h \
-  ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h 
-file_table.o : file_table.c ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/sys/vfs.h 
-inode.o : inode.c ../include/linux/string.h ../include/linux/stat.h ../include/linux/sched.h \
-  ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h \
-  ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/asm/system.h 
-ioctl.o : ioctl.c ../include/linux/string.h ../include/errno.h ../include/linux/stat.h \
-  ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \
-  ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h \
-  ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
-  ../include/time.h ../include/sys/resource.h 
-namei.o : namei.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
-  ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h \
-  ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
-  ../include/linux/string.h ../include/fcntl.h ../include/errno.h ../include/const.h \
-  ../include/linux/stat.h 
-open.o : open.c ../include/errno.h ../include/fcntl.h ../include/sys/types.h \
-  ../include/utime.h ../include/sys/vfs.h ../include/linux/stat.h ../include/linux/string.h \
-  ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
-  ../include/asm/segment.h 
-pipe.o : pipe.c ../include/signal.h ../include/sys/types.h ../include/errno.h \
-  ../include/termios.h ../include/fcntl.h ../include/asm/segment.h ../include/linux/sched.h \
-  ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h 
-read_write.o : read_write.c ../include/errno.h ../include/sys/types.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/linux/stat.h ../include/linux/kernel.h ../include/linux/sched.h \
-  ../include/linux/head.h ../include/linux/fs.h ../include/sys/vfs.h ../include/linux/mm.h \
-  ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/linux/minix_fs.h ../include/asm/segment.h 
-select.o : select.c ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/sys/vfs.h ../include/linux/kernel.h ../include/linux/tty.h \
-  ../include/asm/system.h ../include/termios.h ../include/linux/sched.h ../include/linux/head.h \
-  ../include/linux/mm.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \
-  ../include/time.h ../include/sys/resource.h ../include/linux/string.h ../include/linux/stat.h \
-  ../include/asm/segment.h ../include/const.h ../include/errno.h 
-stat.o : stat.c ../include/errno.h ../include/linux/stat.h ../include/linux/fs.h \
-  ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h \
-  ../include/linux/sched.h ../include/linux/head.h ../include/linux/mm.h ../include/linux/kernel.h \
-  ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/asm/segment.h 
-super.o : super.c ../include/linux/config.h ../include/linux/config_rel.h ../include/linux/config_ver.h \
-  ../include/linux/config.dist.h ../include/linux/sched.h ../include/linux/head.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
-  ../include/linux/minix_fs.h ../include/linux/stat.h ../include/asm/system.h \
-  ../include/asm/segment.h ../include/errno.h 
+block_dev.o : block_dev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/asm/system.h 
+buffer.o : buffer.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/linux/config.h \
+  /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
+  /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \
+  /usr/src/linux/include/asm/io.h 
+exec.o : exec.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h \
+  /usr/src/linux/include/a.out.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h \
+  /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/user.h 
+fcntl.o : fcntl.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+fifo.o : fifo.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+file_table.o : file_table.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h 
+inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/asm/system.h 
+ioctl.o : ioctl.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h 
+namei.o : namei.c /usr/src/linux/include/errno.h /usr/src/linux/include/const.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \
+  /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h 
+open.o : open.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/utime.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/string.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/asm/segment.h 
+pipe.o : pipe.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+read_write.o : read_write.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/asm/segment.h 
+select.o : select.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/tty.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/const.h \
+  /usr/src/linux/include/errno.h 
+stat.o : stat.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/asm/segment.h 
+super.o : super.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+  /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/ext_fs.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/errno.h 
diff --git a/fs/buffer.c b/fs/buffer.c
index a1dc377..dbdb678 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -58,6 +58,14 @@
 
 int sys_sync(void)
 {
+	int i;
+
+	for (i=0 ; i<NR_SUPER ; i++)
+		if (super_block[i].s_dev
+		    && super_block[i].s_op 
+		    && super_block[i].s_op->write_super 
+		    && super_block[i].s_dirt)
+			super_block[i].s_op->write_super(&super_block[i]);
 	sync_inodes();		/* write out inodes into buffers */
 	sync_buffers(0);
 	return 0;
@@ -65,6 +73,11 @@
 
 int sync_dev(int dev)
 {
+	struct super_block * sb;
+
+	if (sb = get_super (dev))
+		if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
+			sb->s_op->write_super (sb);
 	sync_buffers(dev);
 	sync_inodes();
 	sync_buffers(dev);
diff --git a/fs/exec.c b/fs/exec.c
index 992adc4..4847eab 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -19,12 +19,12 @@
 
 #include <signal.h>
 #include <errno.h>
-#include <linux/string.h>
-#include <linux/stat.h>
 #include <sys/ptrace.h>
 #include <a.out.h>
-#include <fcntl.h>
 
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -275,7 +275,7 @@
 static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
 		unsigned long p, int from_kmem)
 {
-	char *tmp, *pag;
+	char *tmp, *pag = NULL;
 	int len, offset = 0;
 	unsigned long old_fs, new_fs;
 
diff --git a/fs/ext/Makefile b/fs/ext/Makefile
new file mode 100644
index 0000000..d498dda
--- /dev/null
+++ b/fs/ext/Makefile
@@ -0,0 +1,108 @@
+#
+# Makefile for the linux ext-filesystem routines.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+.c.s:
+	$(CC) $(CFLAGS) -S $<
+.c.o:
+	$(CC) $(CFLAGS) -c $<
+.s.o:
+	$(AS) -o $*.o $<
+
+OBJS=	bitmap.o freelists.o truncate.o namei.o inode.o \
+	file.o dir.o symlink.o blkdev.o chrdev.o fifo.o
+
+ext.o: $(OBJS)
+	$(LD) -r -o ext.o $(OBJS)
+
+clean:
+	rm -f core *.o *.a tmp_make
+	for i in *.c;do rm -f `basename $$i .c`.s;done
+
+dep:
+	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+	cp tmp_make Makefile
+
+### Dependencies:
+bitmap.o : bitmap.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h 
+blkdev.o : blkdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h 
+chrdev.o : chrdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h 
+dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h 
+fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h 
+file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
+  /usr/src/linux/include/linux/stat.h 
+freelists.o : freelists.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h 
+inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h 
+namei.o : namei.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
+  /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h /usr/src/linux/include/const.h 
+symlink.o : symlink.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h 
+truncate.o : truncate.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h 
diff --git a/fs/ext/bitmap.c b/fs/ext/bitmap.c
new file mode 100644
index 0000000..6125082
--- /dev/null
+++ b/fs/ext/bitmap.c
@@ -0,0 +1,241 @@
+/*
+ *  linux/fs/ext/bitmap.c
+ *
+ *  (C) 1992  Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/bitmap.c
+ *
+ *  (C) 1991  Linus Torvalds
+ */
+
+/* bitmap.c contains the code that handles the inode and block bitmaps */
+
+
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/kernel.h>
+
+#ifdef EXTFS_BITMAP
+
+#define clear_block(addr) \
+__asm__("cld\n\t" \
+	"rep\n\t" \
+	"stosl" \
+	::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
+
+#define set_bit(nr,addr) ({\
+char res; \
+__asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
+"=q" (res):"r" (nr),"m" (*(addr))); \
+res;})
+
+#define clear_bit(nr,addr) ({\
+char res; \
+__asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
+"=q" (res):"r" (nr),"m" (*(addr))); \
+res;})
+
+#define find_first_zero(addr) ({ \
+int __res; \
+__asm__("cld\n" \
+	"1:\tlodsl\n\t" \
+	"notl %%eax\n\t" \
+	"bsfl %%eax,%%edx\n\t" \
+	"jne 2f\n\t" \
+	"addl $32,%%ecx\n\t" \
+	"cmpl $8192,%%ecx\n\t" \
+	"jl 1b\n\t" \
+	"xorl %%edx,%%edx\n" \
+	"2:\taddl %%edx,%%ecx" \
+	:"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \
+__res;})
+
+static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
+
+static unsigned long count_used(struct buffer_head *map[], unsigned numblocks,
+	unsigned numbits)
+{
+	unsigned i, j, end, sum = 0;
+	struct buffer_head *bh;
+  
+	for (i=0; (i<numblocks) && numbits; i++) {
+		if (!(bh=map[i])) 
+			return(0);
+		if (numbits >= (8*BLOCK_SIZE)) { 
+			end = BLOCK_SIZE;
+			numbits -= 8*BLOCK_SIZE;
+		} else {
+			int tmp;
+			end = numbits >> 3;
+			numbits &= 0x7;
+			tmp = bh->b_data[end] & ((1<<numbits)-1);
+			sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf];
+			numbits = 0;
+		}  
+		for (j=0; j<end; j++)
+			sum += nibblemap[bh->b_data[j] & 0xf] 
+				+ nibblemap[(bh->b_data[j]>>4)&0xf];
+	}
+	return(sum);
+}
+
+int ext_free_block(int dev, int block)
+{
+	struct super_block * sb;
+	struct buffer_head * bh;
+	unsigned int bit,zone;
+
+	if (!(sb = get_super(dev)))
+		panic("trying to free block on nonexistent device");
+	if (block < sb->s_firstdatazone || block >= sb->s_nzones)
+		panic("trying to free block not in datazone");
+	bh = get_hash_table(dev,block);
+	if (bh) {
+		if (bh->b_count > 1) {
+			brelse(bh);
+			return 0;
+		}
+		bh->b_dirt=0;
+		bh->b_uptodate=0;
+		if (bh->b_count)
+			brelse(bh);
+	}
+	zone = block - sb->s_firstdatazone + 1;
+	bit = zone & 8191;
+	zone >>= 13;
+	bh = sb->s_zmap[zone];
+	if (clear_bit(bit,bh->b_data))
+		printk("free_block (%04x:%d): bit already cleared\n",dev,block);
+	bh->b_dirt = 1;
+	return 1;
+}
+
+int ext_new_block(int dev)
+{
+	struct buffer_head * bh;
+	struct super_block * sb;
+	int i,j;
+
+	if (!(sb = get_super(dev)))
+		panic("trying to get new block from nonexistant device");
+	j = 8192;
+	for (i=0 ; i<8 ; i++)
+		if (bh=sb->s_zmap[i])
+			if ((j=find_first_zero(bh->b_data))<8192)
+				break;
+	if (i>=8 || !bh || j>=8192)
+		return 0;
+	if (set_bit(j,bh->b_data))
+		panic("new_block: bit already set");
+	bh->b_dirt = 1;
+	j += i*8192 + sb->s_firstdatazone-1;
+	if (j >= sb->s_nzones)
+		return 0;
+	if (!(bh=getblk(dev,j)))
+		panic("new_block: cannot get block");
+	if (bh->b_count != 1)
+		panic("new block: count is != 1");
+	clear_block(bh->b_data);
+	bh->b_uptodate = 1;
+	bh->b_dirt = 1;
+	brelse(bh);
+#ifdef EXTFS_DEBUG
+printk("ext_new_block: allocating block %d\n", j);
+#endif
+	return j;
+}
+
+unsigned long ext_count_free_blocks(struct super_block *sb)
+{
+	return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones))
+		 << sb->s_log_zone_size;
+}
+
+void ext_free_inode(struct inode * inode)
+{
+	struct buffer_head * bh;
+
+	if (!inode)
+		return;
+	if (!inode->i_dev) {
+		memset(inode,0,sizeof(*inode));
+		return;
+	}
+	if (inode->i_count>1) {
+		printk("free_inode: inode has count=%d\n",inode->i_count);
+		return;
+	}
+	if (inode->i_nlink) {
+		printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
+		return;
+	}
+	if (!inode->i_sb) {
+		printk("free_inode: inode on nonexistent device\n");
+		return;
+	}
+	if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
+		printk("free_inode: inode 0 or nonexistent inode\n");
+		return;
+	}
+	if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) {
+		printk("free_inode: nonexistent imap in superblock\n");
+		return;
+	}
+	if (clear_bit(inode->i_ino&8191,bh->b_data))
+		printk("free_inode: bit already cleared.\n\r");
+	bh->b_dirt = 1;
+	memset(inode,0,sizeof(*inode));
+}
+
+struct inode * ext_new_inode(int dev)
+{
+	struct inode * inode;
+	struct buffer_head * bh;
+	int i,j;
+
+	if (!(inode=get_empty_inode()))
+		return NULL;
+	if (!(inode->i_sb = get_super(dev))) {
+		printk("new_inode: unknown device\n");
+		iput(inode);
+		return NULL;
+	}
+	j = 8192;
+	for (i=0 ; i<8 ; i++)
+		if (bh=inode->i_sb->s_imap[i])
+			if ((j=find_first_zero(bh->b_data))<8192)
+				break;
+	if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) {
+		iput(inode);
+		return NULL;
+	}
+	if (set_bit(j,bh->b_data)) {	/* shouldn't happen */
+		printk("new_inode: bit already set");
+		iput(inode);
+		return NULL;
+	}
+	bh->b_dirt = 1;
+	inode->i_count = 1;
+	inode->i_nlink = 1;
+	inode->i_dev = dev;
+	inode->i_uid = current->euid;
+	inode->i_gid = current->egid;
+	inode->i_dirt = 1;
+	inode->i_ino = j + i*8192;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_op = NULL;
+#ifdef EXTFS_DEBUG
+	printk("ext_new_inode : allocating inode %d\n", inode->i_ino);
+#endif
+	return inode;
+}
+
+unsigned long ext_count_free_inodes(struct super_block *sb)
+{
+	return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes);
+}
+
+#endif
diff --git a/fs/ext/blkdev.c b/fs/ext/blkdev.c
new file mode 100644
index 0000000..9931276
--- /dev/null
+++ b/fs/ext/blkdev.c
@@ -0,0 +1,68 @@
+/*
+ *  linux/fs/ext/blkdev.c
+ *
+ *  (C) 1992  Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/blkdev.c
+ *
+ *  (C) 1991  Linus Torvalds
+ */
+
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/tty.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+
+#include <errno.h>
+
+/*
+ * Called every time an ext block special file is opened
+ */
+static int blkdev_open(struct inode * inode, struct file * filp)
+{
+	int i;
+
+	i = MAJOR(inode->i_rdev);
+	if (i < MAX_BLKDEV) {
+		filp->f_op = blkdev_fops[i];
+		if (filp->f_op && filp->f_op->open)
+			return filp->f_op->open(inode,filp);
+	}
+	return 0;
+}	
+
+/*
+ * Dummy default file-operations: the only thing this does
+ * is contain the open that then fills in the correct operations
+ * depending on the special file...
+ */
+static struct file_operations def_blk_fops = {
+	NULL,		/* lseek */
+	NULL,		/* read */
+	NULL,		/* write */
+	NULL,		/* readdir */
+	NULL,		/* select */
+	NULL,		/* ioctl */
+	blkdev_open,	/* open */
+	NULL,		/* release */
+};
+
+struct inode_operations ext_blkdev_inode_operations = {
+	&def_blk_fops,		/* default file operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	ext_bmap,		/* bmap */
+	ext_truncate		/* truncate */
+};
diff --git a/fs/ext/chrdev.c b/fs/ext/chrdev.c
new file mode 100644
index 0000000..537972e
--- /dev/null
+++ b/fs/ext/chrdev.c
@@ -0,0 +1,69 @@
+/*
+ *  linux/fs/ext/chrdev.c
+ *
+ *  (C) 1992  Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/chrdev.c
+ *
+ *  (C) 1991  Linus Torvalds
+ */
+
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/tty.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+
+#include <errno.h>
+
+/*
+ * Called every time an ext character special file is opened
+ */
+static int chrdev_open(struct inode * inode, struct file * filp)
+{
+	int i;
+
+	i = MAJOR(inode->i_rdev);
+	if (i < MAX_CHRDEV) {
+		filp->f_op = chrdev_fops[i];
+		if (filp->f_op && filp->f_op->open)
+			return filp->f_op->open(inode,filp);
+	}
+	return 0;
+}
+
+/*
+ * Dummy default file-operations: the only thing this does
+ * is contain the open that then fills in the correct operations
+ * depending on the special file...
+ */
+static struct file_operations def_chr_fops = {
+	NULL,		/* lseek */
+	NULL,		/* read */
+	NULL,		/* write */
+	NULL,		/* readdir */
+	NULL,		/* select */
+	NULL,		/* ioctl */
+	chrdev_open,	/* open */
+	NULL,		/* release */
+};
+
+struct inode_operations ext_chrdev_inode_operations = {
+	&def_chr_fops,		/* default file operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	ext_bmap,		/* bmap */
+	ext_truncate		/* truncate */
+};
+
diff --git a/fs/ext/dir.c b/fs/ext/dir.c
new file mode 100644
index 0000000..730d5a1
--- /dev/null
+++ b/fs/ext/dir.c
@@ -0,0 +1,99 @@
+/*
+ *  linux/fs/ext/dir.c
+ *
+ *  (C) 1992 Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/dir.c
+ *
+ *  (C) 1991 Linus Torvalds
+ *
+ *  ext directory handling functions
+ */
+
+#include <errno.h>
+
+#include <asm/segment.h>
+
+#include <linux/fs.h>
+#include <linux/ext_fs.h>
+#include <linux/stat.h>
+
+static int ext_readdir(struct inode *, struct file *, struct dirent *, int);
+
+static struct file_operations ext_dir_operations = {
+	NULL,			/* lseek - default */
+	NULL,			/* read */
+	NULL,			/* write - bad */
+	ext_readdir,		/* readdir */
+	NULL,			/* select - default */
+	NULL,			/* ioctl - default */
+	NULL,			/* no special open code */
+	NULL			/* no special release code */
+};
+
+/*
+ * directories can handle most operations...
+ */
+struct inode_operations ext_dir_inode_operations = {
+	&ext_dir_operations,	/* default directory file-ops */
+	ext_create,		/* create */
+	ext_lookup,		/* lookup */
+	ext_link,		/* link */
+	ext_unlink,		/* unlink */
+	ext_symlink,		/* symlink */
+	ext_mkdir,		/* mkdir */
+	ext_rmdir,		/* rmdir */
+	ext_mknod,		/* mknod */
+	ext_rename,		/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	ext_bmap,		/* bmap */
+	ext_truncate		/* truncate */
+};
+
+static int ext_readdir(struct inode * inode, struct file * filp,
+	struct dirent * dirent, int count)
+{
+	unsigned int block,offset,i;
+	char c;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de;
+
+	if (!inode || !S_ISDIR(inode->i_mode))
+		return -EBADF;
+/*	if (filp->f_pos & (sizeof (struct ext_dir_entry) - 1))
+		return -EBADF; */
+	while (filp->f_pos < inode->i_size) {
+		offset = filp->f_pos & 1023;
+		block = ext_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
+		if (!block || !(bh = bread(inode->i_dev,block))) {
+			filp->f_pos += 1024-offset;
+			continue;
+		}
+		de = (struct ext_dir_entry *) (offset + bh->b_data);
+		while (offset < 1024 && filp->f_pos < inode->i_size) {
+			offset += de->rec_len;
+			filp->f_pos += de->rec_len;
+			if (de->inode) {
+				for (i = 0; i < de->name_len; i++)
+					if (c = de->name[i])
+						put_fs_byte(c,i+dirent->d_name);
+					else
+						break;
+				if (i) {
+					put_fs_long(de->inode,&dirent->d_ino);
+					put_fs_byte(0,i+dirent->d_name);
+					put_fs_word(i,&dirent->d_reclen);
+					brelse(bh);
+					return i;
+				}
+			}
+/*			de++; */
+			de = (struct ext_dir_entry *) ((char *) de + de->rec_len);
+		}
+		brelse(bh);
+	}
+	return 0;
+}
diff --git a/fs/ext/fifo.c b/fs/ext/fifo.c
new file mode 100644
index 0000000..c094393
--- /dev/null
+++ b/fs/ext/fifo.c
@@ -0,0 +1,27 @@
+/*
+ *  linux/fs/fifo.c
+ *
+ *  written by Paul H. Hargrove.
+ */
+
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+
+extern struct file_operations def_fifo_fops;
+
+struct inode_operations ext_fifo_inode_operations = {
+	&def_fifo_fops,		/* default file operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	NULL,			/* bmap */
+	NULL			/* truncate */
+};
diff --git a/fs/ext/file.c b/fs/ext/file.c
new file mode 100644
index 0000000..28b365d
--- /dev/null
+++ b/fs/ext/file.c
@@ -0,0 +1,221 @@
+/*
+ *  linux/fs/ext/file.c
+ *
+ *  (C) 1992 Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/file.c
+ *
+ *  (C) 1991 Linus Torvalds
+ *
+ *  ext regular file handling primitives
+ */
+
+#include <errno.h>
+
+#include <sys/dirent.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/kernel.h>
+#include <linux/stat.h>
+
+#define	NBUF	16
+
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+#include <linux/fs.h>
+#include <linux/ext_fs.h>
+
+static int ext_file_read(struct inode *, struct file *, char *, int);
+static int ext_file_write(struct inode *, struct file *, char *, int);
+
+/*
+ * We have mostly NULL's here: the current defaults are ok for
+ * the ext filesystem.
+ */
+static struct file_operations ext_file_operations = {
+	NULL,			/* lseek - default */
+	ext_file_read,	/* read */
+	ext_file_write,	/* write */
+	NULL,			/* readdir - bad */
+	NULL,			/* select - default */
+	NULL,			/* ioctl - default */
+	NULL,			/* no special open is needed */
+	NULL			/* release */
+};
+
+struct inode_operations ext_file_inode_operations = {
+	&ext_file_operations,	/* default file operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	ext_bmap,		/* bmap */
+	ext_truncate		/* truncate */
+};
+
+static inline void wait_on_buffer(struct buffer_head * bh)
+{
+	cli();
+	while (bh->b_lock)
+		sleep_on(&bh->b_wait);
+	sti();
+}
+
+static int ext_file_read(struct inode * inode, struct file * filp, char * buf, int count)
+{
+	int read,left,chars,nr;
+	int block, blocks, offset;
+	struct buffer_head ** bhb, ** bhe;
+	struct buffer_head * buflist[NBUF];
+
+	if (!inode) {
+		printk("ext_file_read: inode = NULL\n");
+		return -EINVAL;
+	}
+	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
+		printk("ext_file_read: mode = %07o\n",inode->i_mode);
+		return -EINVAL;
+	}
+	if (filp->f_pos > inode->i_size)
+		left = 0;
+	else
+		left = inode->i_size - filp->f_pos;
+	if (left > count)
+		left = count;
+	if (left <= 0)
+		return 0;
+	read = 0;
+	block = filp->f_pos >> BLOCK_SIZE_BITS;
+	offset = filp->f_pos & (BLOCK_SIZE-1);
+	blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE;
+	bhb = bhe = buflist;
+	do {
+		if (blocks) {
+			--blocks;
+			if (nr = ext_bmap(inode,block++)) {
+				*bhb = getblk(inode->i_dev,nr);
+				if (!(*bhb)->b_uptodate)
+					ll_rw_block(READ,*bhb);
+			} else
+				*bhb = NULL;
+
+			if (++bhb == &buflist[NBUF])
+				bhb = buflist;
+
+			if (bhb != bhe)
+				continue;
+		}
+		if (*bhe) {
+			wait_on_buffer(*bhe);
+			if (!(*bhe)->b_uptodate) {
+				do {
+					brelse(*bhe);
+					if (++bhe == &buflist[NBUF])
+						bhe = buflist;
+				} while (bhe != bhb);
+				break;
+			}
+		}
+
+		if (left < BLOCK_SIZE - offset)
+			chars = left;
+		else
+			chars = BLOCK_SIZE - offset;
+		filp->f_pos += chars;
+		left -= chars;
+		read += chars;
+		if (*bhe) {
+			memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
+			brelse(*bhe);
+			buf += chars;
+		} else {
+			while (chars-->0)
+				put_fs_byte(0,buf++);
+		}
+		offset = 0;
+		if (++bhe == &buflist[NBUF])
+			bhe = buflist;
+	} while (left > 0);
+	if (!read)
+		return -EIO;
+	inode->i_atime = CURRENT_TIME;
+	inode->i_dirt = 1;
+	return read;
+}
+
+static int ext_file_write(struct inode * inode, struct file * filp, char * buf, int count)
+{
+	off_t pos;
+	int written,block,c;
+	struct buffer_head * bh;
+	char * p;
+
+	if (!inode) {
+		printk("ext_file_write: inode = NULL\n");
+		return -EINVAL;
+	}
+	if (!S_ISREG(inode->i_mode)) {
+		printk("ext_file_write: mode = %07o\n",inode->i_mode);
+		return -EINVAL;
+	}
+/*
+ * ok, append may not work when many processes are writing at the same time
+ * but so what. That way leads to madness anyway.
+ */
+	if (filp->f_flags & O_APPEND)
+		pos = inode->i_size;
+	else
+		pos = filp->f_pos;
+	written = 0;
+	while (written<count) {
+		if (!(block = ext_create_block(inode,pos/BLOCK_SIZE))) {
+			if (!written)
+				written = -ENOSPC;
+			break;
+		}
+		c = BLOCK_SIZE - (pos % BLOCK_SIZE);
+		if (c > count-written)
+			c = count-written;
+		if (c == BLOCK_SIZE)
+			bh = getblk(inode->i_dev, block);
+		else
+			bh = bread(inode->i_dev,block);
+		if (!bh) {
+			if (!written)
+				written = -EIO;
+			break;
+		}
+		p = (pos % BLOCK_SIZE) + bh->b_data;
+		pos += c;
+		if (pos > inode->i_size) {
+			inode->i_size = pos;
+			inode->i_dirt = 1;
+		}
+		written += c;
+		memcpy_fromfs(p,buf,c);
+		buf += c;
+		bh->b_uptodate = 1;
+		bh->b_dirt = 1;
+		brelse(bh);
+	}
+	inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME;
+	filp->f_pos = pos;
+	inode->i_dirt = 1;
+	return written;
+}
diff --git a/fs/ext/freelists.c b/fs/ext/freelists.c
new file mode 100644
index 0000000..8bdcf39
--- /dev/null
+++ b/fs/ext/freelists.c
@@ -0,0 +1,340 @@
+/*
+ *  linux/fs/ext/freelists.c
+ *
+ *  (C) 1992  Remy Card (card@masi.ibp.fr)
+ *
+ */
+
+/* freelists.c contains the code that handles the inode and block free lists */
+
+
+/*
+
+   The free blocks are managed by a linked list. The super block contains the
+   number of the first free block. This block contains 254 numbers of other
+   free blocks and the number of the next block in the list.
+
+   When an ext fs is mounted, the number of the first free block is stored
+   in s->s_zmap[0] and the block header is stored in s->s_zmap[1]. s_zmap[2]
+   contains the count of free blocks.
+
+   Currently, it is a hack to allow this kind of management with the super_block
+   structure.
+   Perhaps, in the future, we may have to change the super_block structure to
+   include dedicated fields.
+
+   The free inodes are also managed by a linked list in a similar way. The
+   super block contains the number of the first free inode. This inode contains
+   14 numbers of other free inodes and the number of the next inode in the list.
+   
+   The number of the first free inode is stored in s->s_imap[0] and the header
+   of the block containing the inode is stored in s->s_imap[1]. s_imap[2] contains
+   the count of free inodes.
+
+*/
+
+#include <linux/string.h>
+
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/kernel.h>
+
+#ifdef EXTFS_FREELIST
+
+#define clear_block(addr) \
+__asm__("cld\n\t" \
+        "rep\n\t" \
+        "stosl" \
+        ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
+
+int ext_free_block(int dev, int block)
+{
+	struct super_block * sb;
+	struct buffer_head * bh;
+	struct ext_free_block * efb;
+
+	if (!(sb = get_super(dev)))
+		panic("trying to free block on nonexistent device");
+	lock_super (sb);
+	if (block < sb->s_firstdatazone || block >= sb->s_nzones)
+		panic("trying to free block not in datazone");
+	bh = get_hash_table(dev,block);
+	if (bh) {
+		if (bh->b_count > 1) {
+			brelse(bh);
+			free_super (sb);
+			return 0;
+		}
+		bh->b_dirt=0;
+		bh->b_uptodate=0;
+		if (bh->b_count)
+			brelse(bh);
+	}
+	efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
+	if (efb->count == 254) {
+#ifdef EXTFS_DEBUG
+printk("ext_free_block: block full, skipping to %d\n", block);
+#endif
+		brelse (sb->s_zmap[1]);
+		if (!(sb->s_zmap[1] = bread (dev, block)))
+			panic ("ext_free_block: unable to read block to free\n");
+		efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
+		efb->next = (unsigned long) sb->s_zmap[0];
+		efb->count = 0;
+		sb->s_zmap[0] = (struct buffer_head *) block;
+	} else {
+		efb->free[efb->count++] = block;
+	}
+	sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) + 1);
+	sb->s_dirt = 1;
+	sb->s_zmap[1]->b_dirt = 1;
+	free_super (sb);
+	return 1;
+}
+
+int ext_new_block(int dev)
+{
+	struct buffer_head * bh;
+	struct super_block * sb;
+	struct ext_free_block * efb;
+	int /* i, */ j;
+
+	if (!(sb = get_super(dev)))
+		panic("trying to get new block from nonexistant device");
+	if (!sb->s_zmap[1])
+		return 0;
+	lock_super (sb);
+	efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
+	if (efb->count) {
+		j = efb->free[--efb->count];
+		sb->s_zmap[1]->b_dirt = 1;
+	} else {
+#ifdef EXTFS_DEBUG
+printk("ext_new_block: block empty, skipping to %d\n", efb->next);
+#endif
+		j = (unsigned long) sb->s_zmap[0];
+		sb->s_zmap[0] = (struct buffer_head *) efb->next;
+		brelse (sb->s_zmap[1]);
+		if (!sb->s_zmap[0]) {
+			sb->s_zmap[1] = NULL;
+		} else {
+			if (!(sb->s_zmap[1] = bread (dev, (unsigned long) sb->s_zmap[0])))
+				panic ("ext_new_block: unable to read next free block\n");
+		}
+	}
+	if (j < sb->s_firstdatazone || j > sb->s_nzones) {
+		printk ("ext_new_block: blk = %d\n", j);
+		panic ("allocating block not in data zone\n");
+	}
+	sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) - 1);
+	sb->s_dirt = 1;
+
+	if (!(bh=getblk(dev,j)))
+		panic("new_block: cannot get block");
+	if (bh->b_count != 1)
+		panic("new block: count is != 1");
+	clear_block(bh->b_data);
+	bh->b_uptodate = 1;
+	bh->b_dirt = 1;
+	brelse(bh);
+#ifdef EXTFS_DEBUG
+printk("ext_new_block: allocating block %d\n", j);
+#endif
+	free_super (sb);
+	return j;
+}
+
+unsigned long ext_count_free_blocks(struct super_block *sb)
+{
+#ifdef EXTFS_DEBUG
+	struct buffer_head * bh;
+	struct ext_free_block * efb;
+	unsigned long count, block;
+
+	lock_super (sb);
+	if (!sb->s_zmap[1])
+		count = 0;
+	else {
+		efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
+		count = efb->count + 1;
+		block = efb->next;
+		while (block) {
+			if (!(bh = bread (sb->s_dev, block))) {
+				printk ("ext_count_free: error while reading free blocks list\n");
+				block = 0;
+			} else {
+				efb = (struct ext_free_block *) bh->b_data;
+				count += efb->count + 1;
+				block = efb->next;
+				brelse (bh);
+			}
+		}
+	}
+printk("ext_count_free_blocks: stored = %d, computed = %d\n",
+	(unsigned long) sb->s_zmap[2], count);
+	free_super (sb);
+	return count;
+#else
+	return (unsigned long) sb->s_zmap[2];
+#endif
+}
+
+void ext_free_inode(struct inode * inode)
+{
+	struct buffer_head * bh;
+	struct ext_free_inode * efi;
+	unsigned long block;
+
+	if (!inode)
+		return;
+	if (!inode->i_dev) {
+		memset(inode,0,sizeof(*inode));
+		return;
+	}
+	if (inode->i_count>1) {
+		printk("free_inode: inode has count=%d\n",inode->i_count);
+		return;
+	}
+	if (inode->i_nlink) {
+		printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
+		return;
+	}
+	if (!inode->i_sb) {
+		printk("free_inode: inode on nonexistent device\n");
+		return;
+	}
+	lock_super (inode->i_sb);
+	if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
+		printk("free_inode: inode 0 or nonexistent inode\n");
+		free_super (inode->i_sb);
+		return;
+	}
+	efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) +
+		(((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK;
+	if (efi->count == 14) {
+#ifdef EXTFS_DEBUG
+printk("ext_free_inode: inode full, skipping to %d\n", inode->i_ino);
+#endif
+		brelse (inode->i_sb->s_imap[1]);
+		block = 2 + (inode->i_ino - 1) / EXT_INODES_PER_BLOCK;
+		if (!(bh = bread(inode->i_dev, block)))
+			panic("ext_free_inode: unable to read inode block\n");
+		efi = ((struct ext_free_inode *) bh->b_data) +
+			(inode->i_ino - 1) % EXT_INODES_PER_BLOCK;
+		efi->next = (unsigned long) inode->i_sb->s_imap[0];
+		efi->count = 0;
+		inode->i_sb->s_imap[0] = (struct buffer_head *) inode->i_ino;
+		inode->i_sb->s_imap[1] = bh;
+	} else {
+		efi->free[efi->count++] = inode->i_ino;
+	}
+	inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) + 1);
+	inode->i_sb->s_dirt = 1;
+	inode->i_sb->s_imap[1]->b_dirt = 1;
+	free_super (inode->i_sb);
+	memset(inode,0,sizeof(*inode));
+}
+
+struct inode * ext_new_inode(int dev)
+{
+	struct inode * inode;
+	struct ext_free_inode * efi;
+	unsigned long block;
+	int /* i, */ j;
+
+	if (!(inode=get_empty_inode()))
+		return NULL;
+	if (!(inode->i_sb = get_super(dev))) {
+		printk("new_inode: unknown device\n");
+		iput(inode);
+		return NULL;
+	}
+	if (!inode->i_sb->s_imap[1])
+		return 0;
+	lock_super (inode->i_sb);
+	efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) +
+		(((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK;
+	if (efi->count) {
+		j = efi->free[--efi->count];
+		inode->i_sb->s_imap[1]->b_dirt = 1;
+	} else {
+#ifdef EXTFS_DEBUG
+printk("ext_free_inode: inode empty, skipping to %d\n", efi->next);
+#endif
+		j = (unsigned long) inode->i_sb->s_imap[0];
+		if (efi->next < 1 || efi->next > inode->i_sb->s_ninodes) {
+			printk ("efi->next = %d\n", efi->next);
+			panic ("ext_new_inode: bad inode number in free list\n");
+		}
+		inode->i_sb->s_imap[0] = (struct buffer_head *) efi->next;
+		block = 2 + (((unsigned long) efi->next) - 1) / EXT_INODES_PER_BLOCK;
+		brelse (inode->i_sb->s_imap[1]);
+		if (!inode->i_sb->s_imap[0]) {
+			inode->i_sb->s_imap[1] = NULL;
+		} else {
+			if (!(inode->i_sb->s_imap[1] = bread (dev, block)))
+				panic ("ext_new_inode: unable to read next free inode block\n");
+		}
+	}
+	inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) - 1);
+	inode->i_sb->s_dirt = 1;
+	inode->i_count = 1;
+	inode->i_nlink = 1;
+	inode->i_dev = dev;
+	inode->i_uid = current->euid;
+	inode->i_gid = current->egid;
+	inode->i_dirt = 1;
+	inode->i_ino = j;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_op = NULL;
+#ifdef EXTFS_DEBUG
+printk("ext_new_inode : allocating inode %d\n", inode->i_ino);
+#endif
+	free_super (inode->i_sb);
+	return inode;
+}
+
+unsigned long ext_count_free_inodes(struct super_block *sb)
+{
+#ifdef EXTFS_DEBUG
+	struct buffer_head * bh;
+	struct ext_free_inode * efi;
+	unsigned long count, block, ino;
+
+	lock_super (sb);
+	if (!sb->s_imap[1])
+		count = 0;
+	else {
+		efi = ((struct ext_free_inode *) sb->s_imap[1]->b_data) +
+			((((unsigned long) sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK);
+		count = efi->count + 1;
+		ino = efi->next;
+		while (ino) {
+			if (ino < 1 || ino > sb->s_ninodes) {
+				printk ("s_imap[0] = %d, ino = %d\n", 
+					(int) sb->s_imap[0],ino);
+				panic ("ext_count_fre_inodes: bad inode number in free list\n");
+			}
+			block = 2 + ((ino - 1) / EXT_INODES_PER_BLOCK);
+			if (!(bh = bread (sb->s_dev, block))) {
+				printk ("ext_count_free_inodes: error while reading free inodes list\n");
+				block = 0;
+			} else {
+				efi = ((struct ext_free_inode *) bh->b_data) +
+					((ino - 1) % EXT_INODES_PER_BLOCK);
+				count += efi->count + 1;
+				ino = efi->next;
+				brelse (bh);
+			}
+		}
+	}
+printk("ext_count_free_inodes: stored = %d, computed = %d\n",
+	(unsigned long) sb->s_imap[2], count);
+	free_super (sb);
+	return count;
+#else
+	return (unsigned long) sb->s_imap[2];
+#endif
+}
+
+#endif
diff --git a/fs/ext/inode.c b/fs/ext/inode.c
new file mode 100644
index 0000000..807f883
--- /dev/null
+++ b/fs/ext/inode.c
@@ -0,0 +1,374 @@
+/*
+ *  linux/fs/ext/inode.c
+ *
+ *  (C) 1992  Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/inode.c
+ *
+ *  (C) 1991  Linus Torvalds
+ */
+
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+
+int sync_dev(int dev);
+
+void ext_put_inode(struct inode *inode)
+{
+	inode->i_size = 0;
+	ext_truncate(inode);
+	ext_free_inode(inode);
+}
+
+void ext_put_super(struct super_block *sb)
+{
+#ifdef EXTFS_BITMAP
+	int i;
+#endif
+
+	lock_super(sb);
+	sb->s_dev = 0;
+#ifdef EXTFS_BITMAP
+	for(i = 0 ; i < EXT_I_MAP_SLOTS ; i++)
+		brelse(sb->s_imap[i]);
+	for(i = 0 ; i < EXT_Z_MAP_SLOTS ; i++)
+		brelse(sb->s_zmap[i]);
+#endif
+#ifdef EXTFS_FREELIST
+	if (sb->s_imap[1])
+		brelse (sb->s_imap[1]);
+	if (sb->s_zmap[1])
+		brelse (sb->s_zmap[1]);
+#endif
+	free_super(sb);
+	return;
+}
+
+static struct super_operations ext_sops = { 
+	ext_read_inode,
+	ext_write_inode,
+	ext_put_inode,
+	ext_put_super,
+	ext_write_super,
+	ext_statfs
+};
+
+struct super_block *ext_read_super(struct super_block *s,void *data)
+{
+	struct buffer_head *bh;
+	struct ext_super_block *es;
+	int dev=s->s_dev,block;
+#ifdef EXTFS_BITMAP
+	int i;
+#endif
+
+	lock_super(s);
+	if (!(bh = bread(dev,1))) {
+		s->s_dev=0;
+		free_super(s);
+		printk("bread failed\n");
+		return NULL;
+	}
+/*	*((struct ext_super_block *) s) =
+		*((struct ext_super_block *) bh->b_data); */
+	es = (struct ext_super_block *) bh->b_data;
+	s->s_ninodes = es->s_ninodes;
+	s->s_nzones = es->s_nzones;
+#ifdef EXTFS_BITMAP
+	s->s_imap_blocks = es->s_imap_blocks;
+	s->s_zmap_blocks = es->s_zmap_blocks;
+#endif
+	s->s_firstdatazone = es->s_firstdatazone;
+	s->s_log_zone_size = es->s_log_zone_size;
+	s->s_max_size = es->s_max_size;
+	s->s_magic = es->s_magic;
+#ifdef EXTFS_FREELIST
+	s->s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock;
+	s->s_zmap[2] = (struct buffer_head *) es->s_freeblockscount;
+	s->s_imap[0] = (struct buffer_head *) es->s_firstfreeinode;
+	s->s_imap[2] = (struct buffer_head *) es->s_freeinodescount;
+#endif
+	brelse(bh);
+	if (s->s_magic != EXT_SUPER_MAGIC) {
+		s->s_dev = 0;
+		free_super(s);
+		printk("magic match failed\n");
+		return NULL;
+	}
+#ifdef EXTFS_BITMAP
+	for (i=0;i < EXT_I_MAP_SLOTS;i++)
+		s->s_imap[i] = NULL;
+	for (i=0;i < EXT_Z_MAP_SLOTS;i++)
+		s->s_zmap[i] = NULL;
+	block=2;
+	for (i=0 ; i < s->s_imap_blocks ; i++)
+		if (s->s_imap[i]=bread(dev,block))
+			block++;
+		else
+			break;
+	for (i=0 ; i < s->s_zmap_blocks ; i++)
+		if (s->s_zmap[i]=bread(dev,block))
+			block++;
+		else
+			break;
+	if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
+		for(i=0;i<EXT_I_MAP_SLOTS;i++)
+			brelse(s->s_imap[i]);
+		for(i=0;i<EXT_Z_MAP_SLOTS;i++)
+			brelse(s->s_zmap[i]);
+		s->s_dev=0;
+		free_super(s);
+		printk("block failed\n");
+		return NULL;
+	}
+	s->s_imap[0]->b_data[0] |= 1;
+	s->s_zmap[0]->b_data[0] |= 1;
+#endif
+#ifdef EXTFS_FREELIST
+	if (!s->s_zmap[0])
+		s->s_zmap[1] = NULL;
+	else
+		if (!(s->s_zmap[1] = bread (dev, (unsigned long) s->s_zmap[0]))) {
+			printk ("ext_read_super: unable to read first free block\n");
+			s->s_dev = 0;
+			free_super(s);
+			return NULL;
+		}
+	if (!s->s_imap[0])
+		s->s_imap[1] = NULL;
+	else {
+		block = 2 + (((unsigned long) s->s_imap[0]) - 1) / EXT_INODES_PER_BLOCK;
+		if (!(s->s_imap[1] = bread (dev, block))) {
+			printk ("ext_read_super: unable to read first free inode block\n");
+			brelse(s->s_zmap[1]);
+			s->s_dev = 0;
+			free_super (s);
+			return NULL;
+		}
+	}
+#endif
+
+	free_super(s);
+	/* set up enough so that it can read an inode */
+	s->s_dev = dev;
+	s->s_op = &ext_sops;
+	if (!(s->s_mounted = iget(dev,EXT_ROOT_INO))) {
+		s->s_dev=0;
+		printk("get root inode failed\n");
+		return NULL;
+	}
+	return s;
+}
+
+void ext_write_super (struct super_block *sb)
+{
+#ifdef EXTFS_FREELIST
+	struct buffer_head * bh;
+	struct ext_super_block * es;
+
+#ifdef EXTFS_DEBUG
+	printk ("ext_write_super called\n");
+#endif
+	if (!(bh = bread (sb->s_dev, 1))) {
+		printk ("ext_write_super: bread failed\n");
+		return;
+	}
+	es = (struct ext_super_block *) bh->b_data;
+	es->s_firstfreeblock = (unsigned long) sb->s_zmap[0];
+	es->s_freeblockscount = (unsigned long) sb->s_zmap[2];
+	es->s_firstfreeinode = (unsigned long) sb->s_imap[0];
+	es->s_freeinodescount = (unsigned long) sb->s_imap[2];
+	bh->b_dirt = 1;
+	brelse (bh);
+	sb->s_dirt = 0;
+#endif
+}
+
+void ext_statfs (struct super_block *sb, struct statfs *buf)
+{
+	long tmp;
+
+	put_fs_long(EXT_SUPER_MAGIC, &buf->f_type);
+	put_fs_long(1024, &buf->f_bsize);
+	put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks);
+	tmp = ext_count_free_blocks(sb);
+	put_fs_long(tmp, &buf->f_bfree);
+	put_fs_long(tmp, &buf->f_bavail);
+	put_fs_long(sb->s_ninodes, &buf->f_files);
+	put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree);
+	/* Don't know what value to put in buf->f_fsid */
+}
+
+static int _ext_bmap(struct inode * inode,int block,int create)
+{
+	struct buffer_head * bh;
+	int i;
+
+	if (block<0) {
+		printk("_ext_bmap: block<0");
+		return 0;
+	}
+	if (block >= 9+256+256*256+256*256*256) {
+		printk("_ext_bmap: block>big");
+		return 0;
+	}
+	if (block<9) {
+		if (create && !inode->i_data[block])
+			if (inode->i_data[block]=ext_new_block(inode->i_dev)) {
+				inode->i_ctime=CURRENT_TIME;
+				inode->i_dirt=1;
+			}
+		return inode->i_data[block];
+	}
+	block -= 9;
+	if (block<256) {
+		if (create && !inode->i_data[9])
+			if (inode->i_data[9]=ext_new_block(inode->i_dev)) {
+				inode->i_dirt=1;
+				inode->i_ctime=CURRENT_TIME;
+			}
+		if (!inode->i_data[9])
+			return 0;
+		if (!(bh = bread(inode->i_dev,inode->i_data[9])))
+			return 0;
+		i = ((unsigned long *) (bh->b_data))[block];
+		if (create && !i)
+			if (i=ext_new_block(inode->i_dev)) {
+				((unsigned long *) (bh->b_data))[block]=i;
+				bh->b_dirt=1;
+			}
+		brelse(bh);
+		return i;
+	}
+	block -= 256;
+	if (block<256*256) {
+		if (create && !inode->i_data[10])
+			if (inode->i_data[10]=ext_new_block(inode->i_dev)) {
+				inode->i_dirt=1;
+				inode->i_ctime=CURRENT_TIME;
+			}
+		if (!inode->i_data[10])
+			return 0;
+		if (!(bh=bread(inode->i_dev,inode->i_data[10])))
+			return 0;
+		i = ((unsigned long *)bh->b_data)[block>>8];
+		if (create && !i)
+			if (i=ext_new_block(inode->i_dev)) {
+				((unsigned long *) (bh->b_data))[block>>8]=i;
+				bh->b_dirt=1;
+			}
+		brelse(bh);
+		if (!i)
+			return 0;
+		if (!(bh=bread(inode->i_dev,i)))
+			return 0;
+		i = ((unsigned long *)bh->b_data)[block&255];
+		if (create && !i)
+			if (i=ext_new_block(inode->i_dev)) {
+				((unsigned long *) (bh->b_data))[block&255]=i;
+				bh->b_dirt=1;
+			}
+		brelse(bh);
+		return i;
+	}
+	printk("ext_bmap: triple indirection not yet implemented\n");
+	return 0;
+}
+
+int ext_bmap(struct inode * inode,int block)
+{
+	return _ext_bmap(inode,block,0);
+}
+
+int ext_create_block(struct inode * inode, int block)
+{
+	return _ext_bmap(inode,block,1);
+}
+
+void ext_read_inode(struct inode * inode)
+{
+	struct buffer_head * bh;
+	struct ext_inode * raw_inode;
+	int block;
+
+#ifdef EXTFS_BITMAP
+	block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
+		(inode->i_ino-1)/EXT_INODES_PER_BLOCK;
+#endif
+#ifdef EXTFS_FREELIST
+	block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
+#endif
+	if (!(bh=bread(inode->i_dev,block)))
+		panic("unable to read i-node block");
+	raw_inode = ((struct ext_inode *) bh->b_data) +
+		(inode->i_ino-1)%EXT_INODES_PER_BLOCK;
+	inode->i_mode = raw_inode->i_mode;
+	inode->i_uid = raw_inode->i_uid;
+	inode->i_gid = raw_inode->i_gid;
+	inode->i_nlink = raw_inode->i_nlinks;
+	inode->i_size = raw_inode->i_size;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+		inode->i_rdev = raw_inode->i_zone[0];
+	else for (block = 0; block < 12; block++)
+		inode->i_data[block] = raw_inode->i_zone[block];
+	brelse(bh);
+	inode->i_op = NULL;
+	if (S_ISREG(inode->i_mode))
+		inode->i_op = &ext_file_inode_operations;
+	else if (S_ISDIR(inode->i_mode))
+		inode->i_op = &ext_dir_inode_operations;
+	else if (S_ISLNK(inode->i_mode))
+		inode->i_op = &ext_symlink_inode_operations;
+	else if (S_ISCHR(inode->i_mode))
+		inode->i_op = &ext_chrdev_inode_operations;
+	else if (S_ISBLK(inode->i_mode))
+		inode->i_op = &ext_blkdev_inode_operations;
+	else if (S_ISFIFO(inode->i_mode)) {
+		inode->i_op = &ext_fifo_inode_operations;
+		inode->i_size = 0;
+		inode->i_pipe = 1;
+		PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
+		PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
+	}
+}
+
+void ext_write_inode(struct inode * inode)
+{
+	struct buffer_head * bh;
+	struct ext_inode * raw_inode;
+	int block;
+
+#ifdef EXTFS_BITMAP
+	block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
+		(inode->i_ino-1)/EXT_INODES_PER_BLOCK;
+#endif
+#ifdef EXTFS_FREELIST
+	block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
+#endif
+	if (!(bh=bread(inode->i_dev,block)))
+		panic("unable to read i-node block");
+	raw_inode = ((struct ext_inode *)bh->b_data) +
+		(inode->i_ino-1)%EXT_INODES_PER_BLOCK;
+	raw_inode->i_mode = inode->i_mode;
+	raw_inode->i_uid = inode->i_uid;
+	raw_inode->i_gid = inode->i_gid;
+	raw_inode->i_nlinks = inode->i_nlink;
+	raw_inode->i_size = inode->i_size;
+	raw_inode->i_time = inode->i_mtime;
+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+		raw_inode->i_zone[0] = inode->i_rdev;
+	else for (block = 0; block < 12; block++)
+		raw_inode->i_zone[block] = inode->i_data[block];
+	bh->b_dirt=1;
+	inode->i_dirt=0;
+	brelse(bh);
+}
diff --git a/fs/ext/namei.c b/fs/ext/namei.c
new file mode 100644
index 0000000..9fe48d4
--- /dev/null
+++ b/fs/ext/namei.c
@@ -0,0 +1,896 @@
+/*
+ *  linux/fs/ext/namei.c
+ *
+ *  (C) 1992  Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/namei.c
+ *
+ *  (C) 1991  Linus Torvalds
+ */
+
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <asm/segment.h>
+
+#include <errno.h>
+#include <const.h>
+
+/*
+ * comment out this line if you want names > EXT_NAME_LEN chars to be
+ * truncated. Else they will be disallowed.
+ */
+/* #define NO_TRUNCATE */
+
+/*
+ * EXT_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a power of 2 and must be greater or equal than 8
+ * because a directory entry needs 8 bytes for its fixed part
+ * (4 bytes for the inode, 2 bytes for the entry length and 2 bytes
+ * for the name length)
+ */
+#define EXT_DIR_PAD 8
+
+/*
+ *
+ * EXT_DIR_MIN_SIZE is the minimal size of a directory entry
+ *
+ * During allocations, a directory entry is split into 2 ones
+ * *ONLY* if the size of the unused part is greater than or 
+ * equal to EXT_DIR_MIN_SIZE
+ */
+#define EXT_DIR_MIN_SIZE 12
+
+/*
+ * ok, we cannot use strncmp, as the name is not in our data space.
+ * Thus we'll have to use ext_match. No big problem. Match also makes
+ * some sanity tests.
+ *
+ * NOTE! unlike strncmp, ext_match returns 1 for success, 0 for failure.
+ */
+static int ext_match(int len,const char * name,struct ext_dir_entry * de)
+{
+	register int same __asm__("ax");
+
+	if (!de || !de->inode || len > EXT_NAME_LEN)
+		return 0;
+	/* "" means "." ---> so paths like "/usr/lib//libc.a" work */
+	if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
+		return 1;
+/*	if (len < EXT_NAME_LEN && de->name[len])
+		return 0; */
+	if (len < EXT_NAME_LEN && len != de->name_len)
+		return 0;
+	__asm__("cld\n\t"
+		"fs ; repe ; cmpsb\n\t"
+		"setz %%al"
+		:"=a" (same)
+		:"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len)
+		:"cx","di","si");
+	return same;
+}
+
+/*
+ *	ext_find_entry()
+ *
+ * finds an entry in the specified directory with the wanted name. It
+ * returns the cache buffer in which the entry was found, and the entry
+ * itself (as a parameter - res_dir). It does NOT read the inode of the
+ * entry - you'll have to do that yourself if you want to.
+ *
+ * addition for the ext file system : this function returns the previous
+ * and next directory entries in the parameters prev_dir and next_dir
+ */
+static struct buffer_head * ext_find_entry(struct inode * dir,
+	const char * name, int namelen, struct ext_dir_entry ** res_dir,
+	struct ext_dir_entry ** prev_dir, struct ext_dir_entry ** next_dir)
+{
+/*	int entries; */
+	int block /* ,i */;
+	long offset;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de;
+
+	*res_dir = NULL;
+	if (!dir)
+		return NULL;
+#ifdef NO_TRUNCATE
+	if (namelen > EXT_NAME_LEN)
+		return NULL;
+#else
+	if (namelen > EXT_NAME_LEN)
+		namelen = EXT_NAME_LEN;
+#endif
+/*	entries = dir->i_size / (sizeof (struct ext_dir_entry)); */
+	if (!(block = dir->i_data[0]))
+		return NULL;
+	if (!(bh = bread(dir->i_dev,block)))
+		return NULL;
+	if (prev_dir)
+		*prev_dir = NULL;
+	if (next_dir)
+		*next_dir = NULL;
+/*	i = 0; */
+	offset = 0;
+	de = (struct ext_dir_entry *) bh->b_data;
+	while (offset < dir->i_size) {
+		if ((char *)de >= BLOCK_SIZE+bh->b_data) {
+			brelse(bh);
+			bh = NULL;
+			if (!(block = ext_bmap(dir,offset>>BLOCK_SIZE_BITS)) ||
+			    !(bh = bread(dir->i_dev,block))) {
+/*				i += EXT_DIR_ENTRIES_PER_BLOCK; */
+/* 				offset += BLOCK_SIZE; */
+				continue;
+			}
+			de = (struct ext_dir_entry *) bh->b_data;
+			if (prev_dir)
+				*prev_dir = NULL;
+		}
+		if (ext_match(namelen,name,de)) {
+			*res_dir = de;
+			if (next_dir)
+				if (offset + de->rec_len < dir->i_size)
+					*next_dir = (struct ext_dir_entry *)
+						((char *) de + de->rec_len);
+				else
+					*next_dir = NULL;
+			return bh;
+		}
+		offset += de->rec_len;
+		if (prev_dir)
+			*prev_dir = de;
+		de = (struct ext_dir_entry *) ((char *) de + de->rec_len);
+/*		i++; */
+	}
+	brelse(bh);
+	return NULL;
+}
+
+int ext_lookup(struct inode * dir,const char * name, int len,
+	struct inode ** result)
+{
+	int ino;
+	struct ext_dir_entry * de;
+	struct buffer_head * bh;
+
+	*result = NULL;
+	if (!dir)
+		return -ENOENT;
+	if (!S_ISDIR(dir->i_mode)) {
+		iput(dir);
+		return -ENOENT;
+	}
+	if (!(bh = ext_find_entry(dir,name,len,&de,NULL,NULL))) {
+		iput(dir);
+		return -ENOENT;
+	}
+	ino = de->inode;
+	brelse(bh);
+	if (!(*result = iget(dir->i_dev,ino))) {
+		iput(dir);
+		return -EACCES;
+	}
+	iput(dir);
+	return 0;
+}
+
+/*
+ *	ext_add_entry()
+ *
+ * adds a file entry to the specified directory, using the same
+ * semantics as ext_find_entry(). It returns NULL if it failed.
+ *
+ * NOTE!! The inode part of 'de' is left at 0 - which means you
+ * may not sleep between calling this and putting something into
+ * the entry, as someone else might have used it while you slept.
+ */
+static struct buffer_head * ext_add_entry(struct inode * dir,
+	const char * name, int namelen, struct ext_dir_entry ** res_dir)
+{
+	int block,i;
+	long offset;
+	unsigned short rec_len;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de, * de1;
+
+	*res_dir = NULL;
+	if (!dir)
+		return NULL;
+#ifdef NO_TRUNCATE
+	if (namelen > EXT_NAME_LEN)
+		return NULL;
+#else
+	if (namelen > EXT_NAME_LEN)
+		namelen = EXT_NAME_LEN;
+#endif
+	if (!namelen)
+		return NULL;
+	if (!(block = dir->i_data[0]))
+		return NULL;
+	if (!(bh = bread(dir->i_dev,block)))
+		return NULL;
+	rec_len = ((8 + namelen + EXT_DIR_PAD - 1) / EXT_DIR_PAD) * EXT_DIR_PAD;
+/*	i = 0; */
+	offset = 0;
+	de = (struct ext_dir_entry *) bh->b_data;
+	while (1) {
+		if ((char *)de >= BLOCK_SIZE+bh->b_data && offset < dir->i_size) {
+#ifdef EXTFS_DEBUG
+printk ("ext_add_entry: skipping to next block\n");
+#endif
+			brelse(bh);
+			bh = NULL;
+			block = ext_create_block(dir,offset>>BLOCK_SIZE_BITS);
+			if (!block)
+				return NULL;
+			if (!(bh = bread(dir->i_dev,block))) {
+/*				i += EXT_DIR_ENTRIES_PER_BLOCK; */
+				offset += BLOCK_SIZE;
+				continue;
+			}
+			de = (struct ext_dir_entry *) bh->b_data;
+		}
+		if (offset >= dir->i_size) {
+			/* Check that the directory entry fits in the block */
+			if (offset % BLOCK_SIZE == 0 
+			    || (BLOCK_SIZE - (offset % BLOCK_SIZE)) < rec_len) {
+				if ((offset % BLOCK_SIZE) != 0) {
+					/* If the entry does not fit in the
+					   block, the remainder of the block
+					   becomes an unused entry */
+					de->inode = 0;
+					de->rec_len = BLOCK_SIZE
+						- (offset & (BLOCK_SIZE - 1));
+					de->name_len = 0;
+					offset += de->rec_len;
+					dir->i_size += de->rec_len;
+					dir->i_dirt = 1;
+					dir->i_ctime = CURRENT_TIME;
+					bh->b_dirt = 1;
+				}
+				brelse (bh);
+				bh = NULL;
+				block = ext_create_block (dir,offset>>BLOCK_SIZE_BITS);
+#ifdef EXTFS_DEBUG
+printk ("ext_add_entry : creating next block\n");
+#endif
+				if (!block)
+					return NULL;
+				if (!(bh = bread(dir->i_dev,block)))
+					return NULL; /* Other thing to do ??? */
+				de = (struct ext_dir_entry *) bh->b_data;
+			}
+			/* Allocate the entry */
+			de->inode=0;
+			de->rec_len = rec_len;
+/*			dir->i_size = (i+1)*sizeof(struct ext_dir_entry); */
+			dir->i_size += de->rec_len;
+			dir->i_dirt = 1;
+			dir->i_ctime = CURRENT_TIME;
+		}
+		if (!de->inode && de->rec_len >= rec_len) {
+			if (de->rec_len > rec_len
+			    && de->rec_len - rec_len >= EXT_DIR_MIN_SIZE) {
+				/* The found entry is too big : it is split
+				   into 2 ones :
+				   - the 1st one will be used to hold the name,
+				   - the 2nd one is unused */
+				de1 = (struct ext_dir_entry *) ((char *) de + rec_len);
+				de1->inode = 0;
+				de1->rec_len = de->rec_len - rec_len;
+				de1->name_len = 0;
+				de->rec_len = rec_len;
+			}
+			dir->i_mtime = CURRENT_TIME;
+			de->name_len = namelen;
+			for (i=0; i < namelen ; i++)
+				de->name[i]=/*(i<namelen)?*/get_fs_byte(name+i)/*:0*/;
+			bh->b_dirt = 1;
+			*res_dir = de;
+			return bh;
+		}
+		offset += de->rec_len;
+		de = (struct ext_dir_entry *) ((char *) de + de->rec_len);
+	}
+	brelse(bh);
+	return NULL;
+}
+
+int ext_create(struct inode * dir,const char * name, int len, int mode,
+	struct inode ** result)
+{
+	struct inode * inode;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de;
+
+	*result = NULL;
+	if (!dir)
+		return -ENOENT;
+	inode = ext_new_inode(dir->i_dev);
+	if (!inode) {
+		iput(dir);
+		return -ENOSPC;
+	}
+	inode->i_op = &ext_file_inode_operations;
+	inode->i_mode = mode;
+	inode->i_dirt = 1;
+	bh = ext_add_entry(dir,name,len,&de);
+	if (!bh) {
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		iput(dir);
+		return -ENOSPC;
+	}
+	de->inode = inode->i_ino;
+	bh->b_dirt = 1;
+	brelse(bh);
+	iput(dir);
+	*result = inode;
+	return 0;
+}
+
+int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev)
+{
+	struct inode * inode;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de;
+
+	if (!dir)
+		return -ENOENT;
+	bh = ext_find_entry(dir,name,len,&de,NULL,NULL);
+	if (bh) {
+		brelse(bh);
+		iput(dir);
+		return -EEXIST;
+	}
+	inode = ext_new_inode(dir->i_dev);
+	if (!inode) {
+		iput(dir);
+		return -ENOSPC;
+	}
+	inode->i_uid = current->euid;
+	inode->i_mode = mode;
+	inode->i_op = NULL;
+	if (S_ISREG(inode->i_mode))
+		inode->i_op = &ext_file_inode_operations;
+	else if (S_ISDIR(inode->i_mode))
+		inode->i_op = &ext_dir_inode_operations;
+	else if (S_ISLNK(inode->i_mode))
+		inode->i_op = &ext_symlink_inode_operations;
+	else if (S_ISCHR(inode->i_mode))
+		inode->i_op = &ext_chrdev_inode_operations;
+	else if (S_ISBLK(inode->i_mode))
+		inode->i_op = &ext_blkdev_inode_operations;
+	else if (S_ISFIFO(inode->i_mode)) {
+		inode->i_op = &ext_fifo_inode_operations;
+		inode->i_size = 0;
+		inode->i_pipe = 1;
+		PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
+		PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
+	}
+	if (S_ISBLK(mode) || S_ISCHR(mode))
+		inode->i_rdev = rdev;
+	inode->i_mtime = inode->i_atime = CURRENT_TIME;
+	inode->i_dirt = 1;
+	bh = ext_add_entry(dir,name,len,&de);
+	if (!bh) {
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		iput(dir);
+		return -ENOSPC;
+	}
+	de->inode = inode->i_ino;
+	bh->b_dirt = 1;
+	brelse(bh);
+	iput(dir);
+	iput(inode);
+	return 0;
+}
+
+int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
+{
+	struct inode * inode;
+	struct buffer_head * bh, *dir_block;
+	struct ext_dir_entry * de;
+	
+	bh = ext_find_entry(dir,name,len,&de,NULL,NULL);
+	if (bh) {
+		brelse(bh);
+		iput(dir);
+		return -EEXIST;
+	}
+	inode = ext_new_inode(dir->i_dev);
+	if (!inode) {
+		iput(dir);
+		return -ENOSPC;
+	}
+	inode->i_op = &ext_dir_inode_operations;
+	inode->i_size = 2 * 16; /* Each entry is coded on 16 bytes for "." and ".."
+					- 4 bytes for the inode number,
+					- 2 bytes for the record length
+					- 2 bytes for the name length
+					- 8 bytes for the name */
+	inode->i_mtime = inode->i_atime = CURRENT_TIME;
+	if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) {
+		iput(dir);
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		return -ENOSPC;
+	}
+	inode->i_dirt = 1;
+	if (!(dir_block = bread(inode->i_dev,inode->i_data[0]))) {
+		iput(dir);
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		return -EIO;
+	}
+	de = (struct ext_dir_entry *) dir_block->b_data;
+	de->inode=inode->i_ino;
+	de->rec_len=16;
+	de->name_len=1;
+	strcpy(de->name,".");
+/*	de++; */
+	de = (struct ext_dir_entry *) ((char *) de + de->rec_len);
+	de->inode = dir->i_ino;
+	de->rec_len=16;
+	de->name_len=2;
+	strcpy(de->name,"..");
+	inode->i_nlink = 2;
+	dir_block->b_dirt = 1;
+	brelse(dir_block);
+	inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);
+	inode->i_dirt = 1;
+	bh = ext_add_entry(dir,name,len,&de);
+	if (!bh) {
+		iput(dir);
+		inode->i_nlink=0;
+		iput(inode);
+		return -ENOSPC;
+	}
+	de->inode = inode->i_ino;
+	bh->b_dirt = 1;
+	dir->i_nlink++;
+	dir->i_dirt = 1;
+	iput(dir);
+	iput(inode);
+	brelse(bh);
+	return 0;
+}
+
+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+static int empty_dir(struct inode * inode)
+{
+	int /* nr, */ block;
+/*	int len; */
+	unsigned long offset;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de, * de1;
+
+/*	len = inode->i_size / sizeof (struct ext_dir_entry); */
+	if (inode->i_size < 2 * 12 || !inode->i_data[0] ||
+	    !(bh=bread(inode->i_dev,inode->i_data[0]))) {
+	    	printk("warning - bad directory on dev %04x\n",inode->i_dev);
+		return 0;
+	}
+	de = (struct ext_dir_entry *) bh->b_data;
+	de1 = (struct ext_dir_entry *) ((char *) de + de->rec_len);
+	if (de->inode != inode->i_ino || !de1->inode || 
+	    strcmp(".",de->name) || strcmp("..",de1->name)) {
+	    	printk("warning - bad directory on dev %04x\n",inode->i_dev);
+		return 0;
+	}
+/*	nr = 2; */
+	offset = de->rec_len + de1->rec_len;
+	de = (struct ext_dir_entry *) ((char *) de1 + de1->rec_len);
+	while (offset < inode->i_size ) {
+		if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {
+			brelse(bh);
+			block = ext_bmap(inode, offset >> BLOCK_SIZE_BITS);
+			if (!block) {
+				offset += BLOCK_SIZE;
+				continue;
+			}
+			if (!(bh=bread(inode->i_dev,block)))
+				return 0;
+			de = (struct ext_dir_entry *) bh->b_data;
+		}
+		if (de->inode) {
+			brelse(bh);
+			return 0;
+		}
+		offset += de->rec_len;
+		de = (struct ext_dir_entry *) ((char *) de + de->rec_len);
+	}
+	brelse(bh);
+	return 1;
+}
+
+static inline void ext_merge_entries (struct ext_dir_entry * de,
+	struct ext_dir_entry * pde, struct ext_dir_entry * nde)
+{
+	if (! nde->inode)
+		de->rec_len += nde->rec_len;
+	if (! pde->inode)
+		pde->rec_len += de->rec_len;
+}
+
+int ext_rmdir(struct inode * dir, const char * name, int len)
+{
+	int retval;
+	struct inode * inode;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de, * pde, * nde;
+
+	inode = NULL;
+	bh = ext_find_entry(dir,name,len,&de,&pde,&nde);
+	retval = -ENOENT;
+	if (!bh)
+		goto end_rmdir;
+	retval = -EPERM;
+	if (!(inode = iget(dir->i_dev, de->inode)))
+		goto end_rmdir;
+	if ((dir->i_mode & S_ISVTX) && current->euid &&
+	   inode->i_uid != current->euid)
+		goto end_rmdir;
+	if (inode->i_dev != dir->i_dev)
+		goto end_rmdir;
+	if (inode == dir)	/* we may not delete ".", but "../dir" is ok */
+		goto end_rmdir;
+	if (!S_ISDIR(inode->i_mode)) {
+		retval = -ENOTDIR;
+		goto end_rmdir;
+	}
+	if (!empty_dir(inode)) {
+		retval = -ENOTEMPTY;
+		goto end_rmdir;
+	}
+	if (inode->i_count > 1) {
+		retval = -EBUSY;
+		goto end_rmdir;
+	}
+	if (inode->i_nlink != 2)
+		printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
+	de->inode = 0;
+	de->name_len = 0;
+	ext_merge_entries (de, pde, nde);
+	bh->b_dirt = 1;
+	inode->i_nlink=0;
+	inode->i_dirt=1;
+	dir->i_nlink--;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_dirt=1;
+	retval = 0;
+end_rmdir:
+	iput(dir);
+	iput(inode);
+	brelse(bh);
+	return retval;
+}
+
+int ext_unlink(struct inode * dir, const char * name, int len)
+{
+	int retval;
+	struct inode * inode;
+	struct buffer_head * bh;
+	struct ext_dir_entry * de, * pde, * nde;
+
+	retval = -ENOENT;
+	inode = NULL;
+	bh = ext_find_entry(dir,name,len,&de,&pde,&nde);
+	if (!bh)
+		goto end_unlink;
+	if (!(inode = iget(dir->i_dev, de->inode)))
+		goto end_unlink;
+	retval = -EPERM;
+	if ((dir->i_mode & S_ISVTX) && !suser() &&
+	    current->euid != inode->i_uid &&
+	    current->euid != dir->i_uid)
+		goto end_unlink;
+	if (S_ISDIR(inode->i_mode))
+		goto end_unlink;
+	if (!inode->i_nlink) {
+		printk("Deleting nonexistent file (%04x:%d), %d\n",
+			inode->i_dev,inode->i_ino,inode->i_nlink);
+		inode->i_nlink=1;
+	}
+	de->inode = 0;
+	de->name_len = 0;
+	ext_merge_entries (de, pde, nde);
+	bh->b_dirt = 1;
+	inode->i_nlink--;
+	inode->i_dirt = 1;
+	inode->i_ctime = CURRENT_TIME;
+	retval = 0;
+end_unlink:
+	brelse(bh);
+	iput(inode);
+	iput(dir);
+	return retval;
+}
+
+int ext_symlink(struct inode * dir, const char * name, int len, const char * symname)
+{
+	struct ext_dir_entry * de;
+	struct inode * inode = NULL;
+	struct buffer_head * bh = NULL, * name_block = NULL;
+	int i;
+	char c;
+
+	if (!(inode = ext_new_inode(dir->i_dev))) {
+		iput(dir);
+		return -ENOSPC;
+	}
+	inode->i_mode = S_IFLNK | 0777;
+	inode->i_op = &ext_symlink_inode_operations;
+	if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) {
+		iput(dir);
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		return -ENOSPC;
+	}
+	inode->i_dirt = 1;
+	if (!(name_block = bread(inode->i_dev,inode->i_data[0]))) {
+		iput(dir);
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		return -EIO;
+	}
+	i = 0;
+	while (i < 1023 && (c=get_fs_byte(symname++)))
+		name_block->b_data[i++] = c;
+	name_block->b_data[i] = 0;
+	name_block->b_dirt = 1;
+	brelse(name_block);
+	inode->i_size = i;
+	inode->i_dirt = 1;
+	bh = ext_find_entry(dir,name,len,&de,NULL,NULL);
+	if (bh) {
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		brelse(bh);
+		iput(dir);
+		return -EEXIST;
+	}
+	bh = ext_add_entry(dir,name,len,&de);
+	if (!bh) {
+		inode->i_nlink--;
+		inode->i_dirt = 1;
+		iput(inode);
+		iput(dir);
+		return -ENOSPC;
+	}
+	de->inode = inode->i_ino;
+	bh->b_dirt = 1;
+	brelse(bh);
+	iput(dir);
+	iput(inode);
+	return 0;
+}
+
+int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int len)
+{
+	struct ext_dir_entry * de;
+	struct buffer_head * bh;
+
+	if (S_ISDIR(oldinode->i_mode)) {
+		iput(oldinode);
+		iput(dir);
+		return -EPERM;
+	}
+	bh = ext_find_entry(dir,name,len,&de,NULL,NULL);
+	if (bh) {
+		brelse(bh);
+		iput(dir);
+		iput(oldinode);
+		return -EEXIST;
+	}
+	bh = ext_add_entry(dir,name,len,&de);
+	if (!bh) {
+		iput(dir);
+		iput(oldinode);
+		return -ENOSPC;
+	}
+	de->inode = oldinode->i_ino;
+	bh->b_dirt = 1;
+	brelse(bh);
+	iput(dir);
+	oldinode->i_nlink++;
+	oldinode->i_ctime = CURRENT_TIME;
+	oldinode->i_dirt = 1;
+	iput(oldinode);
+	return 0;
+}
+
+static int subdir(struct inode * new, struct inode * old)
+{
+	unsigned short fs;
+	int ino;
+	int result;
+
+	__asm__("mov %%fs,%0":"=r" (fs));
+	__asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+	new->i_count++;
+	result = 0;
+	for (;;) {
+		if (new == old) {
+			result = 1;
+			break;
+		}
+		if (new->i_dev != old->i_dev)
+			break;
+		ino = new->i_ino;
+		if (ext_lookup(new,"..",2,&new))
+			break;
+		if (new->i_ino == ino)
+			break;
+	}
+	iput(new);
+	__asm__("mov %0,%%fs"::"r" (fs));
+	return result;
+}
+
+#define PARENT_INO(buffer) \
+((struct ext_dir_entry *) ((char *) buffer + \
+((struct ext_dir_entry *) buffer)->rec_len))->inode
+/* (((struct ext_dir_entry *) (buffer))[1].inode) */
+
+#define PARENT_NAME(buffer) \
+((struct ext_dir_entry *) ((char *) buffer + \
+((struct ext_dir_entry *) buffer)->rec_len))->name
+/* (((struct ext_dir_entry *) (buffer))[1].name) */
+
+/*
+ * rename uses retrying to avoid race-conditions: at least they should be minimal.
+ * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
+ * checks fail, it tries to restart itself again. Very practical - no changes
+ * are done until we know everything works ok.. and then all the changes can be
+ * done in one fell swoop when we have claimed all the buffers needed.
+ *
+ * Anybody can rename anything with this: the permission checks are left to the
+ * higher-level routines.
+ */
+static int do_ext_rename(struct inode * old_dir, const char * old_name, int old_len,
+	struct inode * new_dir, const char * new_name, int new_len)
+{
+	struct inode * old_inode, * new_inode;
+	struct buffer_head * old_bh, * new_bh, * dir_bh;
+	struct ext_dir_entry * old_de, * new_de, * pde, * nde;
+	int retval;
+
+	goto start_up;
+try_again:
+	brelse(old_bh);
+	brelse(new_bh);
+	brelse(dir_bh);
+	iput(old_inode);
+	iput(new_inode);
+	current->counter = 0;
+	schedule();
+start_up:
+	old_inode = new_inode = NULL;
+	old_bh = new_bh = dir_bh = NULL;
+	old_bh = ext_find_entry(old_dir,old_name,old_len,&old_de,&pde,&nde);
+	retval = -ENOENT;
+	if (!old_bh)
+		goto end_rename;
+	old_inode = iget(old_dir->i_dev, old_de->inode);
+	if (!old_inode)
+		goto end_rename;
+	if ((old_dir->i_mode & S_ISVTX) && 
+	    current->euid != old_inode->i_uid &&
+	    current->euid != old_dir->i_uid && !suser())
+		goto end_rename;
+	new_bh = ext_find_entry(new_dir,new_name,new_len,&new_de,NULL,NULL);
+	if (new_bh) {
+		new_inode = iget(new_dir->i_dev, new_de->inode);
+		if (!new_inode) {
+			brelse(new_bh);
+			new_bh = NULL;
+		}
+	}
+	if (new_inode == old_inode) {
+		retval = 0;
+		goto end_rename;
+	}
+	if (S_ISDIR(old_inode->i_mode)) {
+		retval = -EEXIST;
+		if (new_bh)
+			goto end_rename;
+		retval = -EACCES;
+		if (!permission(old_inode, MAY_WRITE))
+			goto end_rename;
+		retval = -EINVAL;
+		if (subdir(new_dir, old_inode))
+			goto end_rename;
+		retval = -EIO;
+		if (!old_inode->i_data[0])
+			goto end_rename;
+		if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0])))
+			goto end_rename;
+		if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
+			goto end_rename;
+	}
+	if (!new_bh)
+		new_bh = ext_add_entry(new_dir,new_name,new_len,&new_de);
+	retval = -ENOSPC;
+	if (!new_bh)
+		goto end_rename;
+/* sanity checking before doing the rename - avoid races */
+	if (new_inode && (new_de->inode != new_inode->i_ino))
+		goto try_again;
+	if (new_de->inode && !new_inode)
+		goto try_again;
+	if (old_de->inode != old_inode->i_ino)
+		goto try_again;
+/* ok, that's it */
+	old_de->inode = 0;
+	old_de->name_len = 0;
+	ext_merge_entries (old_de, pde, nde);
+	new_de->inode = old_inode->i_ino;
+	if (new_inode) {
+		new_inode->i_nlink--;
+		new_inode->i_dirt = 1;
+	}
+	old_bh->b_dirt = 1;
+	new_bh->b_dirt = 1;
+	if (dir_bh) {
+		PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
+		dir_bh->b_dirt = 1;
+		old_dir->i_nlink--;
+		new_dir->i_nlink++;
+		old_dir->i_dirt = 1;
+		new_dir->i_dirt = 1;
+	}
+	retval = 0;
+end_rename:
+	brelse(dir_bh);
+	brelse(old_bh);
+	brelse(new_bh);
+	iput(old_inode);
+	iput(new_inode);
+	iput(old_dir);
+	iput(new_dir);
+	return retval;
+}
+
+/*
+ * Ok, rename also locks out other renames, as they can change the parent of
+ * a directory, and we don't want any races. Other races are checked for by
+ * "do_rename()", which restarts if there are inconsistencies.
+ *
+ * Note that there is no race between different filesystems: it's only within
+ * the same device that races occur: many renames can happen at once, as long
+ * as they are on different partitions.
+ */
+int ext_rename(struct inode * old_dir, const char * old_name, int old_len,
+	struct inode * new_dir, const char * new_name, int new_len)
+{
+	static struct task_struct * wait = NULL;
+	static int lock = 0;
+	int result;
+
+	while (lock)
+		sleep_on(&wait);
+	lock = 1;
+	result = do_ext_rename(old_dir, old_name, old_len,
+		new_dir, new_name, new_len);
+	lock = 0;
+	wake_up(&wait);
+	return result;
+}
diff --git a/fs/ext/symlink.c b/fs/ext/symlink.c
new file mode 100644
index 0000000..eeef2b4
--- /dev/null
+++ b/fs/ext/symlink.c
@@ -0,0 +1,107 @@
+/*
+ *  linux/fs/ext/symlink.c
+ *
+ *  (C) 1992 Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/symlink.c
+ *
+ *  (C) 1991 Linus Torvalds
+ *
+ *  ext symlink handling code
+ */
+
+#include <errno.h>
+
+#include <asm/segment.h>
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/ext_fs.h>
+#include <linux/stat.h>
+
+static int ext_readlink(struct inode *, char *, int);
+static struct inode * ext_follow_link(struct inode *, struct inode *);
+
+/*
+ * symlinks can't do much...
+ */
+struct inode_operations ext_symlink_inode_operations = {
+	NULL,			/* no file-operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	ext_readlink,		/* readlink */
+	ext_follow_link,	/* follow_link */
+	NULL,			/* bmap */
+	NULL			/* truncate */
+};
+
+static struct inode * ext_follow_link(struct inode * dir, struct inode * inode)
+{
+	unsigned short fs;
+	struct buffer_head * bh;
+
+	if (!dir) {
+		dir = current->root;
+		dir->i_count++;
+	}
+	if (!inode) {
+		iput(dir);
+		return NULL;
+	}
+	if (!S_ISLNK(inode->i_mode)) {
+		iput(dir);
+		return inode;
+	}
+	__asm__("mov %%fs,%0":"=r" (fs));
+	if ((current->link_count > 5) || !inode->i_data[0] ||
+	   !(bh = bread(inode->i_dev, inode->i_data[0]))) {
+		iput(dir);
+		iput(inode);
+		return NULL;
+	}
+	iput(inode);
+	__asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+	current->link_count++;
+	inode = _namei(bh->b_data,dir,1);
+	current->link_count--;
+	__asm__("mov %0,%%fs"::"r" (fs));
+	brelse(bh);
+	return inode;
+}
+
+static int ext_readlink(struct inode * inode, char * buffer, int buflen)
+{
+	struct buffer_head * bh;
+	int i;
+	char c;
+
+	if (!S_ISLNK(inode->i_mode)) {
+		iput(inode);
+		return -EINVAL;
+	}
+	if (buflen > 1023)
+		buflen = 1023;
+	if (inode->i_data[0])
+		bh = bread(inode->i_dev, inode->i_data[0]);
+	else
+		bh = NULL;
+	iput(inode);
+	if (!bh)
+		return 0;
+	i = 0;
+	while (i<buflen && (c = bh->b_data[i])) {
+		i++;
+		put_fs_byte(c,buffer++);
+	}
+	brelse(bh);
+	return i;
+}
diff --git a/fs/ext/truncate.c b/fs/ext/truncate.c
new file mode 100644
index 0000000..04c0b2e
--- /dev/null
+++ b/fs/ext/truncate.c
@@ -0,0 +1,157 @@
+/*
+ *  linux/fs/ext/truncate.c
+ *
+ *  (C) 1992  Remy Card (card@masi.ibp.fr)
+ *
+ *  from
+ *
+ *  linux/fs/minix/truncate.c
+ *
+ *  (C) 1991  Linus Torvalds
+ */
+
+#include <linux/sched.h>
+#include <linux/ext_fs.h>
+#include <linux/tty.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+
+#include <errno.h>
+
+/*
+ * Truncate has the most races in the whole filesystem: coding it is
+ * a pain in the a**. Especially as I don't do any locking...
+ *
+ * The code may look a bit weird, but that's just because I've tried to
+ * handle things like file-size changes in a somewhat graceful manner.
+ * Anyway, truncating a file at the same time somebody else writes to it
+ * is likely to result in pretty weird behaviour...
+ *
+ * The new code handles normal truncates (size = 0) as well as the more
+ * general case (size = XXX). I hope.
+ */
+
+static int trunc_direct(struct inode * inode)
+{
+	int i;
+	int result = 0;
+#define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
+
+repeat:
+	for (i = DIRECT_BLOCK ; i < 9 ; i++) {
+		if (i < DIRECT_BLOCK)
+			goto repeat;
+		if (!inode->i_data[i])
+			continue;
+		result = 1;
+		if (ext_free_block(inode->i_dev,inode->i_data[i]))
+			inode->i_data[i] = 0;
+	}
+	return result;
+}
+
+static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
+{
+	int i;
+	struct buffer_head * bh = NULL;
+	unsigned long * ind;
+	int result = 0;
+#define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
+
+	if (*p)
+		bh = bread(inode->i_dev,*p);
+	if (!bh)
+		return 0;
+repeat:
+	for (i = INDIRECT_BLOCK ; i < 256 ; i++) {
+		if (i < 0)
+			i = 0;
+		if (i < INDIRECT_BLOCK)
+			goto repeat;
+		ind = i+(unsigned long *) bh->b_data;
+		if (!*ind)
+			continue;
+		result = 1;
+		if (ext_free_block(inode->i_dev,*ind))
+			*ind = 0;
+	}
+	ind = (unsigned long *) bh->b_data;
+	for (i = 0; i < 256; i++)
+		if (*(ind++))
+			break;
+	brelse(bh);
+	if (i >= 256) {
+		result = 1;
+		if (ext_free_block(inode->i_dev,*p))
+			*p = 0;
+	}
+	return result;
+}
+		
+static int trunc_dindirect(struct inode * inode)
+{
+	int i;
+	struct buffer_head * bh = NULL;
+	unsigned long * dind;
+	int result = 0;
+#define DINDIRECT_BLOCK ((DIRECT_BLOCK-(256+9))>>8)
+
+	if (inode->i_data[10])
+		bh = bread(inode->i_dev,inode->i_data[10]);
+	if (!bh)
+		return 0;
+repeat:
+	for (i = DINDIRECT_BLOCK ; i < 256 ; i ++) {
+		if (i < 0)
+			i = 0;
+		if (i < DINDIRECT_BLOCK)
+			goto repeat;
+		dind = i+(unsigned long *) bh->b_data;
+		if (!*dind)
+			continue;
+		result |= trunc_indirect(inode,9+256+(i<<8),dind);
+	}
+	dind = (unsigned long *) bh->b_data;
+	for (i = 0; i < 256; i++)
+		if (*(dind++))
+			break;
+	brelse(bh);
+	if (i >= 256) {
+		result = 1;
+		if (ext_free_block(inode->i_dev,inode->i_data[10]))
+			inode->i_data[10] = 0;
+	}
+	return result;
+}
+		
+void ext_truncate(struct inode * inode)
+{
+	int flag;
+
+	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+	     S_ISLNK(inode->i_mode)))
+		return;
+/*	if (inode->i_data[7] & 0xffff0000)
+		printk("BAD! ext inode has 16 high bits set\n"); */
+	while (1) {
+		flag = trunc_direct(inode);
+		flag |= trunc_indirect(inode,9,(unsigned long *)&inode->i_data[9]);
+		flag |= trunc_dindirect(inode);
+		if (!flag)
+			break;
+		current->counter = 0;
+		schedule();
+	}
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_dirt = 1;
+}
+
+/*
+ * Called when a inode is released. Note that this is different
+ * from ext_open: open gets called at every open, but release
+ * gets called only when /all/ the files are closed.
+ */
+void ext_release(struct inode * inode, struct file * filp)
+{
+	printk("ext_release not implemented\n");
+}
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 555c901..02b5af1 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -5,12 +5,11 @@
  */
 
 #include <errno.h>
-#include <fcntl.h>
-
-#include <linux/stat.h>
 
 #include <asm/segment.h>
 
+#include <linux/stat.h>
+#include <linux/fcntl.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
diff --git a/fs/fifo.c b/fs/fifo.c
new file mode 100644
index 0000000..8e1a7d2
--- /dev/null
+++ b/fs/fifo.c
@@ -0,0 +1,115 @@
+/*
+ *  linux/fs/fifo.c
+ *
+ *  written by Paul H. Hargrove
+ */
+
+#include <errno.h>
+
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+
+extern struct file_operations read_pipe_fops;
+extern struct file_operations write_pipe_fops;
+extern struct file_operations rdwr_pipe_fops;
+
+static int fifo_open(struct inode * inode,struct file * filp)
+{
+	int retval = 0;
+	unsigned long page;
+
+	switch( filp->f_mode ) {
+
+	case 1:
+	/*
+	 *  O_RDONLY
+	 *  POSIX.1 says that O_NONBLOCK means return with the FIFO
+	 *  opened, even when there is no process writing the FIFO.
+	 */
+		filp->f_op = &read_pipe_fops;
+		PIPE_READERS(*inode)++;
+		if (!(filp->f_flags & O_NONBLOCK))
+			while (!PIPE_WRITERS(*inode)) {
+				if (PIPE_HEAD(*inode) != PIPE_TAIL(*inode))
+					break;
+				if (current->signal & ~current->blocked) {
+					retval = -ERESTARTSYS;
+					break;
+				}
+				interruptible_sleep_on(&PIPE_READ_WAIT(*inode));
+			}
+		if (retval)
+			PIPE_READERS(*inode)--;
+		break;
+	
+	case 2:
+	/*
+	 *  O_WRONLY
+	 *  POSIX.1 says that O_NONBLOCK means return -1 with
+	 *  errno=ENXIO when there is no process reading the FIFO.
+	 */
+		if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
+			retval = -ENXIO;
+			break;
+		}
+		filp->f_op = &write_pipe_fops;
+		PIPE_WRITERS(*inode)++;
+		while (!PIPE_READERS(*inode)) {
+			if (current->signal & ~current->blocked) {
+				retval = -ERESTARTSYS;
+				break;
+			}
+			interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
+		}
+		if (retval)
+			PIPE_WRITERS(*inode)--;
+		break;
+	
+	case 3:
+	/*
+	 *  O_RDWR
+	 *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
+	 *  This implementation will NEVER block on a O_RDWR open, since
+	 *  the process can at least talk to itself.
+	 */
+		filp->f_op = &rdwr_pipe_fops;
+		PIPE_WRITERS(*inode) += 1;
+		PIPE_READERS(*inode) += 1;
+		break;
+
+	default:
+		retval = -EINVAL;
+	}
+	if (PIPE_WRITERS(*inode))
+		wake_up(&PIPE_READ_WAIT(*inode));
+	if (PIPE_READERS(*inode))
+		wake_up(&PIPE_WRITE_WAIT(*inode));
+	if (retval || inode->i_size)
+		return retval;
+	page = get_free_page();
+	if (inode->i_size) {
+		free_page(page);
+		return 0;
+	}
+	if (!page)
+		return -ENOMEM;
+	inode->i_size = page;
+	return 0;
+}
+
+/*
+ * Dummy default file-operations: the only thing this does
+ * is contain the open that then fills in the correct operations
+ * depending on the access mode of the file...
+ */
+struct file_operations def_fifo_fops = {
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	fifo_open,		/* will set read or write pipe_fops */
+	NULL
+};
diff --git a/fs/inode.c b/fs/inode.c
index 24c5316..f515afb 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -6,10 +6,10 @@
 
 #include <linux/string.h>
 #include <linux/stat.h>
-
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+
 #include <asm/system.h>
 
 struct inode inode_table[NR_INODE]={{0,},};
@@ -100,7 +100,7 @@
 	inode = 0+inode_table;
 	for(i=0 ; i<NR_INODE ; i++,inode++) {
 		wait_on_inode(inode);
-		if (inode->i_dirt && !inode->i_pipe)
+		if (inode->i_dirt)
 			write_inode(inode);
 	}
 }
@@ -119,28 +119,26 @@
 	if (inode->i_pipe) {
 		wake_up(&inode->i_wait);
 		wake_up(&inode->i_wait2);
-		if (--inode->i_count)
-			return;
-		free_page(inode->i_size);
-		inode->i_count=0;
-		inode->i_dirt=0;
-		inode->i_pipe=0;
-		return;
-	}
-	if (!inode->i_dev) {
-		inode->i_count--;
-		return;
 	}
 repeat:
 	if (inode->i_count>1) {
 		inode->i_count--;
 		return;
 	}
-	if (!inode->i_nlink) {
-		if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode)
-			inode->i_sb->s_op->put_inode(inode);
+	if (inode->i_pipe) {
+		free_page(inode->i_size);
+		inode->i_size = 0;
+	}
+	if (!inode->i_dev) {
+		inode->i_count--;
 		return;
 	}
+	if (!inode->i_nlink) {
+		if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
+			inode->i_sb->s_op->put_inode(inode);
+			return;
+		}
+	}
 	if (inode->i_dirt) {
 		write_inode(inode);	/* we can sleep - so do again */
 		wait_on_inode(inode);
@@ -190,12 +188,13 @@
 
 	if (!(inode = get_empty_inode()))
 		return NULL;
-	if (!(inode->i_size=get_free_page())) {
+	if (!(inode->i_size = get_free_page())) {
 		inode->i_count = 0;
 		return NULL;
 	}
 	inode->i_count = 2;	/* sum of readers/writers */
 	PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
+	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 	inode->i_pipe = 1;
 	return inode;
 }
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 7aedb24..84d6a9a 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -4,9 +4,9 @@
  *  (C) 1991  Linus Torvalds
  */
 
-#include <linux/string.h>
 #include <errno.h>
 
+#include <linux/string.h>
 #include <linux/stat.h>
 #include <linux/sched.h>
 
diff --git a/fs/minix/Makefile b/fs/minix/Makefile
index 6ccddb8..0fdd188 100644
--- a/fs/minix/Makefile
+++ b/fs/minix/Makefile
@@ -7,23 +7,15 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-AR	=ar
-AS	=as
-LD	=ld
-CC	=gcc -nostdinc -I../../include
-CPP	=cpp -nostdinc -I../../include
-
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) -c $<
 .s.o:
 	$(AS) -o $*.o $<
 
 OBJS=	bitmap.o truncate.o namei.o inode.o \
-	file.o dir.o symlink.o blkdev.o chrdev.o
+	file.o dir.o symlink.o blkdev.o chrdev.o fifo.o
 
 minix.o: $(OBJS)
 	$(LD) -r -o minix.o $(OBJS)
@@ -34,61 +26,78 @@
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do $(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
 
 ### Dependencies:
-bitmap.o : bitmap.c ../../include/linux/string.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/minix_fs.h 
-blkdev.o : blkdev.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/linux/tty.h \
-  ../../include/asm/system.h ../../include/termios.h ../../include/linux/stat.h \
-  ../../include/errno.h ../../include/fcntl.h 
-chrdev.o : chrdev.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/linux/tty.h \
-  ../../include/asm/system.h ../../include/termios.h ../../include/linux/stat.h \
-  ../../include/errno.h ../../include/fcntl.h 
-dir.o : dir.c ../../include/errno.h ../../include/asm/segment.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/minix_fs.h ../../include/linux/stat.h 
-file.o : file.c ../../include/errno.h ../../include/fcntl.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/asm/segment.h \
-  ../../include/asm/system.h ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/linux/stat.h 
-inode.o : inode.c ../../include/linux/string.h ../../include/linux/stat.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/minix_fs.h \
-  ../../include/asm/system.h ../../include/asm/segment.h 
-namei.o : namei.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/linux/string.h \
-  ../../include/linux/stat.h ../../include/asm/segment.h ../../include/fcntl.h \
-  ../../include/errno.h ../../include/const.h 
-symlink.o : symlink.c ../../include/errno.h ../../include/asm/segment.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/minix_fs.h \
-  ../../include/linux/stat.h 
-truncate.o : truncate.c ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/linux/tty.h \
-  ../../include/asm/system.h ../../include/termios.h ../../include/linux/stat.h \
-  ../../include/errno.h ../../include/fcntl.h 
+bitmap.o : bitmap.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h 
+blkdev.o : blkdev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h 
+chrdev.o : chrdev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h 
+dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/stat.h 
+fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h 
+file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
+  /usr/src/linux/include/linux/stat.h 
+inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/asm/system.h \
+  /usr/src/linux/include/asm/segment.h 
+namei.o : namei.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
+  /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h /usr/src/linux/include/const.h 
+symlink.o : symlink.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/stat.h 
+truncate.o : truncate.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h 
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index fe185a7..e4295db 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -5,8 +5,8 @@
  */
 
 /* bitmap.c contains the code that handles the inode and block bitmaps */
-#include <linux/string.h>
 
+#include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/minix_fs.h>
 #include <linux/kernel.h>
diff --git a/fs/minix/blkdev.c b/fs/minix/blkdev.c
index eec544d..144d19f 100644
--- a/fs/minix/blkdev.c
+++ b/fs/minix/blkdev.c
@@ -4,13 +4,13 @@
  *  (C) 1991  Linus Torvalds
  */
 
+#include <errno.h>
+
 #include <linux/sched.h>
 #include <linux/minix_fs.h>
 #include <linux/tty.h>
 #include <linux/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
+#include <linux/fcntl.h>
 
 /*
  * Called every time a minix block special file is opened
diff --git a/fs/minix/chrdev.c b/fs/minix/chrdev.c
index da7e9fc..c9e61d3 100644
--- a/fs/minix/chrdev.c
+++ b/fs/minix/chrdev.c
@@ -4,13 +4,13 @@
  *  (C) 1991  Linus Torvalds
  */
 
+#include <errno.h>
+
 #include <linux/sched.h>
 #include <linux/minix_fs.h>
 #include <linux/tty.h>
 #include <linux/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
+#include <linux/fcntl.h>
 
 /*
  * Called every time a minix character special file is opened
diff --git a/fs/minix/fifo.c b/fs/minix/fifo.c
new file mode 100644
index 0000000..671604b
--- /dev/null
+++ b/fs/minix/fifo.c
@@ -0,0 +1,27 @@
+/*
+ *  linux/fs/fifo.c
+ *
+ *  written by Paul H. Hargrove
+ */
+
+#include <linux/sched.h>
+#include <linux/minix_fs.h>
+
+extern struct file_operations def_fifo_fops;
+
+struct inode_operations minix_fifo_inode_operations = {
+	&def_fifo_fops,		/* default file operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	NULL,			/* readlink */
+	NULL,			/* follow_link */
+	NULL,			/* bmap */
+	NULL			/* truncate */
+};
diff --git a/fs/minix/file.c b/fs/minix/file.c
index 6c6bf75..dba5631 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -7,13 +7,13 @@
  */
 
 #include <errno.h>
-#include <fcntl.h>
 
 #include <sys/dirent.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
 
+#include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/minix_fs.h>
 #include <linux/kernel.h>
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 485295e..71b45bc 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -41,6 +41,7 @@
 	minix_write_inode,
 	minix_put_inode,
 	minix_put_super,
+	NULL,
 	minix_statfs
 };
 
@@ -243,6 +244,13 @@
 		inode->i_op = &minix_chrdev_inode_operations;
 	else if (S_ISBLK(inode->i_mode))
 		inode->i_op = &minix_blkdev_inode_operations;
+	else if (S_ISFIFO(inode->i_mode)) {
+		inode->i_op = &minix_fifo_inode_operations;
+		inode->i_size = 0;
+		inode->i_pipe = 1;
+		PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
+		PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
+	}
 }
 
 void minix_write_inode(struct inode * inode)
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 4df81df..6538c25 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -9,9 +9,9 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/stat.h>
+#include <linux/fcntl.h>
 #include <asm/segment.h>
 
-#include <fcntl.h>
 #include <errno.h>
 #include <const.h>
 
@@ -266,6 +266,13 @@
 		inode->i_op = &minix_chrdev_inode_operations;
 	else if (S_ISBLK(inode->i_mode))
 		inode->i_op = &minix_blkdev_inode_operations;
+	else if (S_ISFIFO(inode->i_mode)) {
+		inode->i_op = &minix_fifo_inode_operations;
+		inode->i_size = 0;
+		inode->i_pipe = 1;
+		PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
+		PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
+	}
 	if (S_ISBLK(mode) || S_ISCHR(mode))
 		inode->i_rdev = rdev;
 	inode->i_mtime = inode->i_atime = CURRENT_TIME;
diff --git a/fs/minix/truncate.c b/fs/minix/truncate.c
index 9b35e05..e9c7a82 100644
--- a/fs/minix/truncate.c
+++ b/fs/minix/truncate.c
@@ -4,13 +4,13 @@
  *  (C) 1991  Linus Torvalds
  */
 
+#include <errno.h>
+
 #include <linux/sched.h>
 #include <linux/minix_fs.h>
 #include <linux/tty.h>
 #include <linux/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
+#include <linux/fcntl.h>
 
 /*
  * Truncate has the most races in the whole filesystem: coding it is
diff --git a/fs/namei.c b/fs/namei.c
index ef5131a..510d38d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -8,14 +8,15 @@
  * Some corrections by tytso.
  */
 
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <asm/segment.h>
-
-#include <linux/string.h>
-#include <fcntl.h>
 #include <errno.h>
 #include <const.h>
+
+#include <asm/segment.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
 #include <linux/stat.h>
 
 struct inode * _namei(const char * filename, struct inode * base,
@@ -277,7 +278,7 @@
 
 int sys_mknod(const char * filename, int mode, int dev)
 {
-	if (suser())
+	if (S_ISFIFO(mode) || suser())
 		return do_mknod(filename,mode,dev);
 	return -EPERM;
 }
diff --git a/fs/open.c b/fs/open.c
index 8aef2fb..b047d39 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -5,12 +5,12 @@
  */
 
 #include <errno.h>
-#include <fcntl.h>
 #include <sys/types.h>
 #include <utime.h>
 
 #include <sys/vfs.h>
 
+#include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/sched.h>
@@ -101,6 +101,10 @@
 	return 0;
 }
 
+/* If times==NULL, set access and modification to current time,
+ * must be owner or have write permission.
+ * Else, update from *times, must be owner or super user.
+ */
 int sys_utime(char * filename, struct utimbuf * times)
 {
 	struct inode * inode;
@@ -109,15 +113,20 @@
 	if (!(inode=namei(filename)))
 		return -ENOENT;
 	if (times) {
-		if (current->euid != inode->i_uid &&
+		if ((current->euid != inode->i_uid) && !suser()) {
+			iput(inode);
+			return -EPERM;
+		}
+		actime = get_fs_long((unsigned long *) &times->actime);
+		modtime = get_fs_long((unsigned long *) &times->modtime);
+	} else {
+		if ((current->euid != inode->i_uid) &&
 		    !permission(inode,MAY_WRITE)) {
 			iput(inode);
 			return -EACCES;
 		}
-		actime = get_fs_long((unsigned long *) &times->actime);
-		modtime = get_fs_long((unsigned long *) &times->modtime);
-	} else
 		actime = modtime = CURRENT_TIME;
+	}
 	inode->i_atime = actime;
 	inode->i_mtime = modtime;
 	inode->i_dirt = 1;
diff --git a/fs/pipe.c b/fs/pipe.c
index c508957..01c4b4b 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -7,10 +7,10 @@
 #include <signal.h>
 #include <errno.h>
 #include <termios.h>
-#include <fcntl.h>
 
 #include <asm/segment.h>
 
+#include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 
@@ -21,7 +21,7 @@
 	if (!(filp->f_flags & O_NONBLOCK))
 		while (!PIPE_SIZE(*inode)) {
 			wake_up(& PIPE_WRITE_WAIT(*inode));
-			if (inode->i_count != 2) /* are there any writers? */
+			if (!PIPE_WRITERS(*inode)) /* are there any writers? */
 				return 0;
 			if (current->signal & ~current->blocked)
 				return -ERESTARTSYS;
@@ -33,13 +33,12 @@
 			chars = count;
 		if (chars > size)
 			chars = size;
-		count -= chars;
+		memcpy_tofs(buf, (char *)inode->i_size+PIPE_TAIL(*inode), chars );
 		read += chars;
-		size = PIPE_TAIL(*inode);
 		PIPE_TAIL(*inode) += chars;
 		PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
-		while (chars-->0)
-			put_fs_byte(((char *)inode->i_size)[size++],buf++);
+		count -= chars;
+		buf += chars;
 	}
 	wake_up(& PIPE_WRITE_WAIT(*inode));
 	return read?read:-EAGAIN;
@@ -49,35 +48,44 @@
 {
 	int chars, size, written = 0;
 
-	if (inode->i_count != 2) { /* no readers */
+	if (!PIPE_READERS(*inode)) { /* no readers */
 		send_sig(SIGPIPE,current,0);
-		return -EINTR;
+		return -EPIPE;
 	}
+/* if count < PAGE_SIZE, we have to make it atomic */
+	if (count < PAGE_SIZE)
+		size = PAGE_SIZE-count;
+	else
+		size = PAGE_SIZE-1;
 	while (count>0) {
-		while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
-			wake_up(& PIPE_READ_WAIT(*inode));
-			if (inode->i_count != 2) { /* no readers */
+		while (PIPE_SIZE(*inode) >= size) {
+			if (!PIPE_READERS(*inode)) { /* no readers */
 				send_sig(SIGPIPE,current,0);
-				return written?written:-EINTR;
+				return written?written:-EPIPE;
 			}
 			if (current->signal & ~current->blocked)
-				return written?written:-EINTR;
-			interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
+				return written?written:-ERESTARTSYS;
+			if (filp->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+			else
+				interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
 		}
-		chars = PAGE_SIZE-PIPE_HEAD(*inode);
-		if (chars > count)
-			chars = count;
-		if (chars > size)
-			chars = size;
-		count -= chars;
-		written += chars;
-		size = PIPE_HEAD(*inode);
-		PIPE_HEAD(*inode) += chars;
-		PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
-		while (chars-->0)
-			((char *)inode->i_size)[size++]=get_fs_byte(buf++);
+		while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
+			chars = PAGE_SIZE-PIPE_HEAD(*inode);
+			if (chars > count)
+				chars = count;
+			if (chars > size)
+				chars = size;
+			memcpy_fromfs((char *)inode->i_size+PIPE_HEAD(*inode), buf, chars );
+			written += chars;
+			PIPE_HEAD(*inode) += chars;
+			PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
+			count -= chars;
+			buf += chars;
+		}
+		wake_up(& PIPE_READ_WAIT(*inode));
+		size = PAGE_SIZE-1;
 	}
-	wake_up(& PIPE_READ_WAIT(*inode));
 	return written;
 }
 
@@ -110,18 +118,34 @@
 }
 
 /*
- * Ok, these two routines should keep track of readers/writers,
- * but it's currently done with the inode->i_count checking.
+ * Ok, these three routines NOW keep track of readers/writers,
+ * Linus previously did it with inode->i_count checking.
  */
 static void pipe_read_release(struct inode * inode, struct file * filp)
 {
+	PIPE_READERS(*inode)--;
+	wake_up(&PIPE_WRITE_WAIT(*inode));
 }
 
 static void pipe_write_release(struct inode * inode, struct file * filp)
 {
+	PIPE_WRITERS(*inode)--;
+	wake_up(&PIPE_READ_WAIT(*inode));
 }
 
-static struct file_operations read_pipe_fops = {
+static void pipe_rdwr_release(struct inode * inode, struct file * filp)
+{
+	PIPE_READERS(*inode)--;
+	PIPE_WRITERS(*inode)--;
+	wake_up(&PIPE_READ_WAIT(*inode));
+	wake_up(&PIPE_WRITE_WAIT(*inode));
+}
+
+/*
+ * The three file_operations structs are not static because they
+ * are also used in linux/fs/fifo.c to do operations on fifo's.
+ */
+struct file_operations read_pipe_fops = {
 	pipe_lseek,
 	pipe_read,
 	bad_pipe_rw,
@@ -132,7 +156,7 @@
 	pipe_read_release
 };
 
-static struct file_operations write_pipe_fops = {
+struct file_operations write_pipe_fops = {
 	pipe_lseek,
 	bad_pipe_rw,
 	pipe_write,
@@ -143,6 +167,17 @@
 	pipe_write_release
 };
 
+struct file_operations rdwr_pipe_fops = {
+	pipe_lseek,
+	pipe_read,
+	pipe_write,
+	pipe_readdir,
+	NULL,		/* pipe_select */
+	pipe_ioctl,
+	NULL,		/* no special open code */
+	pipe_rdwr_release
+};
+
 int sys_pipe(unsigned long * fildes)
 {
 	struct inode * inode;
diff --git a/fs/read_write.c b/fs/read_write.c
index 91d4bfa..f7919fd 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -36,7 +36,7 @@
 int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
 {
 	struct file * file;
-	int tmp;
+	int tmp = -1;
 
 	if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode))
 		return -EBADF;
@@ -80,7 +80,6 @@
 	verify_area(buf,count);
 	if (file->f_op && file->f_op->read)
 		return file->f_op->read(inode,file,buf,count);
-	printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
 	return -EINVAL;
 }
 
@@ -97,6 +96,5 @@
 		return 0;
 	if (file->f_op && file->f_op->write)
 		return file->f_op->write(inode,file,buf,count);
-	printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode);
 	return -EINVAL;
 }
diff --git a/fs/select.c b/fs/select.c
index 64386b4..2bb4892 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -125,7 +125,7 @@
 		else
 			add_wait(&tty->secondary->proc_list, wait);
 	else if (inode->i_pipe)
-		if (!PIPE_EMPTY(*inode) || inode->i_count < 2)
+		if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
 			return 1;
 		else
 			add_wait(&inode->i_wait, wait);
@@ -169,7 +169,7 @@
 		else
 			return 0;
 	else if (inode->i_pipe)
-		if (inode->i_count < 2)
+		if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 			return 1;
 		else
 			add_wait(&inode->i_wait,wait);
diff --git a/fs/stat.c b/fs/stat.c
index a169de5..3f1dbf6 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -26,7 +26,10 @@
 	tmp.st_uid = inode->i_uid;
 	tmp.st_gid = inode->i_gid;
 	tmp.st_rdev = inode->i_rdev;
-	tmp.st_size = inode->i_size;
+	if( S_ISFIFO(inode->i_mode) )
+		tmp.st_size = 0;
+	else
+		tmp.st_size = inode->i_size;
 	tmp.st_atime = inode->i_atime;
 	tmp.st_mtime = inode->i_mtime;
 	tmp.st_ctime = inode->i_ctime;
@@ -36,6 +39,7 @@
 static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
 {
 	struct new_stat tmp = {0, };
+	unsigned int blocks, indirect;
 
 	verify_area(statbuf,sizeof (*statbuf));
 	tmp.st_dev = inode->i_dev;
@@ -45,10 +49,34 @@
 	tmp.st_uid = inode->i_uid;
 	tmp.st_gid = inode->i_gid;
 	tmp.st_rdev = inode->i_rdev;
-	tmp.st_size = inode->i_size;
+	if( S_ISFIFO(inode->i_mode) )
+		tmp.st_size = 0;
+	else
+		tmp.st_size = inode->i_size;
 	tmp.st_atime = inode->i_atime;
 	tmp.st_mtime = inode->i_mtime;
 	tmp.st_ctime = inode->i_ctime;
+/*
+ * Right now we fake the st_blocks numbers: we'll eventually have to
+ * add st_blocks to the inode, and let the vfs routines keep track of
+ * it all. This algorithm doesn't guarantee correct block numbers, but
+ * at least it tries to come up with a plausible answer...
+ *
+ * In fact, the minix fs doesn't use these numbers (it uses 7 and 512
+ * instead of 10 and 256), but who cares... It's not that exact anyway.
+ */
+	blocks = (tmp.st_size + 1023) / 1024;
+	if (blocks > 10) {
+		indirect = (blocks - 11)/256+1;
+		if (blocks > 10+256) {
+			indirect += (blocks - 267)/(256*256)+1;
+			if (blocks > 10+256+256*256)
+				indirect++;
+		}
+		blocks += indirect;
+	}
+	tmp.st_blksize = 1024;
+	tmp.st_blocks = blocks;
 	memcpy_tofs(statbuf,&tmp,sizeof(tmp));
 }
 
diff --git a/fs/super.c b/fs/super.c
index a3b6802..e85eeae 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -10,6 +10,7 @@
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/minix_fs.h>
+#include <linux/ext_fs.h>
 #include <linux/kernel.h>
 #include <linux/stat.h>
 #include <asm/system.h>
@@ -34,6 +35,7 @@
 
 static struct file_system_type file_systems[] = {
 	{minix_read_super,"minix"},
+	{ext_read_super,"ext"},
 	{NULL,NULL}
 };
 
@@ -174,6 +176,8 @@
 	sb->s_covered = NULL;
 	iput(sb->s_mounted);
 	sb->s_mounted = NULL;
+	if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
+		sb->s_op->write_super (sb);
         put_super(dev);
         sync_dev(dev);
 	return 0;
diff --git a/include/linux/config_rel.h b/include/linux/config_rel.h
index eb7c320..c286ac2 100644
--- a/include/linux/config_rel.h
+++ b/include/linux/config_rel.h
@@ -1 +1 @@
-#define UTS_RELEASE "0.96a-37"
+#define UTS_RELEASE "0.96b-63"
diff --git a/include/linux/config_ver.h b/include/linux/config_ver.h
index e68ebe8..d32d8b2 100644
--- a/include/linux/config_ver.h
+++ b/include/linux/config_ver.h
@@ -1 +1 @@
-#define UTS_VERSION "06/20/92"
+#define UTS_VERSION "07/04/92"
diff --git a/include/linux/ext_fs.h b/include/linux/ext_fs.h
new file mode 100644
index 0000000..0877bdb
--- /dev/null
+++ b/include/linux/ext_fs.h
@@ -0,0 +1,130 @@
+/*
+ * The ext filesystem constants/structures
+ */
+
+#ifndef _EXT_FS_H
+#define _EXT_FS_H
+
+#include <sys/types.h>
+
+/*
+ * Free blocks/inodes management style
+ *
+ * One of these two constants must be defined
+ *
+ */
+/* #define EXTFS_BITMAP	*/	/* use a bitmap */
+#define EXTFS_FREELIST		/* use a linked list */
+
+#define EXT_NAME_LEN 255
+#define EXT_ROOT_INO 1
+
+#define EXT_I_MAP_SLOTS 8
+#define EXT_Z_MAP_SLOTS 8
+#define EXT_SUPER_MAGIC 0x137D
+
+#define EXT_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct ext_inode)))
+/* #define EXT_DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct ext_dir_entry))) */
+
+struct ext_inode {
+	unsigned short i_mode;
+	unsigned short i_uid;
+	unsigned long i_size;
+	unsigned long i_time;
+	unsigned short i_gid;
+	unsigned short i_nlinks;
+	unsigned long i_zone[12];
+};
+
+struct ext_free_inode {
+	unsigned long count;
+	unsigned long free[14];
+	unsigned long next;
+};
+
+struct ext_free_block {
+	unsigned long count;
+	unsigned long free[254];
+	unsigned long next;
+};
+
+struct ext_super_block {
+	unsigned long s_ninodes;
+	unsigned long s_nzones;
+#ifdef EXTFS_BITMAP
+	unsigned long s_imap_blocks;
+	unsigned long s_zmap_blocks;
+#endif
+#ifdef EXTFS_FREELIST
+	unsigned long s_firstfreeblock;
+	unsigned long s_freeblockscount;
+	unsigned long s_firstfreeinode;
+	unsigned long s_freeinodescount;
+#endif
+	unsigned long s_firstdatazone;
+	unsigned long s_log_zone_size;
+	unsigned long s_max_size;
+	unsigned long s_reserved1;
+	unsigned long s_reserved2;
+	unsigned long s_reserved3;
+	unsigned long s_reserved4;
+	unsigned long s_reserved5;
+	unsigned short s_magic;
+};
+
+struct ext_dir_entry {
+	unsigned long inode;
+	unsigned short rec_len;
+	unsigned short name_len;
+	char name[EXT_NAME_LEN];
+};
+
+extern int ext_open(struct inode * inode, struct file * filp);
+extern void ext_release(struct inode * inode, struct file * filp);
+extern int ext_lookup(struct inode * dir,const char * name, int len,
+	struct inode ** result);
+extern int ext_create(struct inode * dir,const char * name, int len, int mode,
+	struct inode ** result);
+extern int ext_mkdir(struct inode * dir, const char * name, int len, int mode);
+extern int ext_rmdir(struct inode * dir, const char * name, int len);
+extern int ext_unlink(struct inode * dir, const char * name, int len);
+extern int ext_symlink(struct inode * inode, const char * name, int len,
+	const char * symname);
+extern int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int len);
+extern int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev);
+extern int ext_rename(struct inode * old_dir, const char * old_name, int old_len,
+	struct inode * new_dir, const char * new_name, int new_len);
+extern struct inode * ext_new_inode(int dev);
+extern void ext_free_inode(struct inode * inode);
+extern unsigned long ext_count_free_inodes(struct super_block *sb);
+extern int ext_new_block(int dev);
+extern int ext_free_block(int dev, int block);
+extern unsigned long ext_count_free_blocks(struct super_block *sb);
+
+extern int ext_create_block(struct inode *, int);
+extern int ext_bmap(struct inode *,int);
+
+extern void ext_truncate(struct inode *);
+extern void ext_put_super(struct super_block *);
+extern void ext_write_super(struct super_block *);
+extern struct super_block *ext_read_super(struct super_block *,void *);
+extern void ext_read_inode(struct inode *);
+extern void ext_write_inode(struct inode *);
+extern void ext_put_inode(struct inode *);
+extern void ext_statfs(struct super_block *, struct statfs *);
+
+extern int ext_lseek(struct inode *, struct file *, off_t, int);
+extern int ext_read(struct inode *, struct file *, char *, int);
+extern int ext_write(struct inode *, struct file *, char *, int);
+
+extern struct inode_operations ext_file_inode_operations;
+extern struct inode_operations ext_dir_inode_operations;
+extern struct inode_operations ext_symlink_inode_operations;
+extern struct inode_operations ext_chrdev_inode_operations;
+extern struct inode_operations ext_blkdev_inode_operations;
+extern struct inode_operations ext_fifo_inode_operations;
+
+extern struct file_operations ext_file_operations;
+extern struct file_operations ext_dir_operations;
+
+#endif
diff --git a/include/fcntl.h b/include/linux/fcntl.h
similarity index 84%
rename from include/fcntl.h
rename to include/linux/fcntl.h
index 6d4bc22..15a205a 100644
--- a/include/fcntl.h
+++ b/include/linux/fcntl.h
@@ -48,16 +48,4 @@
 	pid_t l_pid;
 };
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int creat(const char * filename,mode_t mode);
-extern int fcntl(int fildes,int cmd, ...);
-extern int open(const char * filename, int flags, ...);
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif
diff --git a/include/linux/fd.h b/include/linux/fd.h
index 990dce5..d490194 100644
--- a/include/linux/fd.h
+++ b/include/linux/fd.h
@@ -1,4 +1,4 @@
-#ifndef _FD_H_
+#ifndef _FD_H
 #define _FD_H
 
 #define FDCLRPRM 0 /* clear user-defined parameters */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 639f458..cd6834d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -60,6 +60,8 @@
 #define PIPE_WRITE_WAIT(inode) ((inode).i_wait2)
 #define PIPE_HEAD(inode) ((inode).i_data[0])
 #define PIPE_TAIL(inode) ((inode).i_data[1])
+#define PIPE_READERS(inode) ((inode).i_data[2])
+#define PIPE_WRITERS(inode) ((inode).i_data[3])
 #define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
 #define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode))
 #define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))
@@ -192,6 +194,7 @@
 	void (*write_inode) (struct inode *inode);
 	void (*put_inode) (struct inode *inode);
 	void (*put_super)(struct super_block *sb);
+	void (*write_super) (struct super_block *sb);
 	void (*statfs) (struct super_block *sb, struct statfs *buf);
 };
 
@@ -212,6 +215,7 @@
 extern int nr_buffers;
 
 extern void check_disk_change(int dev);
+extern void invalidate_inodes(int dev);
 extern int floppy_change(struct buffer_head * first_block);
 extern int ticks_to_floppy_on(unsigned int dev);
 extern void floppy_on(unsigned int dev);
@@ -242,6 +246,7 @@
 extern struct buffer_head * breada(int dev,int block,...);
 extern int sync_dev(int dev);
 extern struct super_block * get_super(int dev);
+extern void put_super(int dev);
 extern int ROOT_DEV;
 
 extern void mount_root(void);
diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h
index 76f8f51..99b9f45 100644
--- a/include/linux/minix_fs.h
+++ b/include/linux/minix_fs.h
@@ -86,6 +86,7 @@
 extern struct inode_operations minix_symlink_inode_operations;
 extern struct inode_operations minix_chrdev_inode_operations;
 extern struct inode_operations minix_blkdev_inode_operations;
+extern struct inode_operations minix_fifo_inode_operations;
 
 extern struct file_operations minix_file_operations;
 extern struct file_operations minix_dir_operations;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e1eacea..4b3b61b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -17,11 +17,29 @@
 #define write_swap_page(nr,buf) \
 	rw_swap_page(WRITE,(nr),(buf))
 
+/* memory.c */
+	
 extern unsigned long get_free_page(void);
 extern unsigned long put_dirty_page(unsigned long page,unsigned long address);
 extern void free_page(unsigned long addr);
-void swap_free(int page_nr);
-void swap_in(unsigned long *table_ptr);
+extern int free_page_tables(unsigned long from,unsigned long size);
+extern int copy_page_tables(unsigned long from,unsigned long to,long size);
+extern int unmap_page_range(unsigned long from, unsigned long size);
+extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
+	 int permiss);
+extern void un_wp_page(unsigned long * table_entry);
+extern void do_wp_page(unsigned long error_code,unsigned long address);
+extern void write_verify(unsigned long address);
+extern void do_no_page(unsigned long error_code, unsigned long address,
+	struct task_struct *tsk, unsigned long user_esp);
+extern void mem_init(long start_mem, long end_mem);
+extern void show_mem(void);
+extern void do_page_fault(unsigned long *esp, unsigned long error_code);
+
+/* swap.c */
+
+extern void swap_free(int page_nr);
+extern void swap_in(unsigned long *table_ptr);
 
 extern inline volatile void oom(void)
 {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 249f8c0..e1e3559 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -60,10 +60,8 @@
 
 #define MAX_SHARED_LIBS 6
 
-extern int copy_page_tables(unsigned long from, unsigned long to, long size);
-extern int free_page_tables(unsigned long from, unsigned long size);
-
 extern void sched_init(void);
+extern void show_state(void);
 extern void schedule(void);
 extern void trap_init(void);
 extern void panic(const char * str);
diff --git a/include/linux/string.h b/include/linux/string.h
index 7da1793..1cd607b 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -1,15 +1,12 @@
 #ifndef _STRING_H_
 #define _STRING_H_
 
+#include <sys/types.h>
+
 #ifndef NULL
 #define NULL ((void *) 0)
 #endif
 
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
 extern char * strerror(int errno);
 
 /*
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 848d132..7e54066 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -66,34 +66,11 @@
 #define FULL(a) (!LEFT(a))
 #define CHARS(a) (((a)->head-(a)->tail)&(TTY_BUF_SIZE-1))
 
-static inline void PUTCH(char c, struct tty_queue * queue)
-{
-	int head;
-	unsigned long flags;
+extern void put_tty_queue(char c, struct tty_queue * queue);
+extern int get_tty_queue(struct tty_queue * queue);
 
-	__asm__("pushfl ; popl %0 ; cli":"=r" (flags));
-	head = (queue->head + 1) & (TTY_BUF_SIZE-1);
-	if (head != queue->tail) {
-		queue->buf[queue->head] = c;
-		queue->head = head;
-	}
-	__asm__("pushl %0 ; popfl"::"r" (flags));
-}
-
-static inline int GETCH(struct tty_queue * queue)
-{
-	int result = -1;
-	unsigned long flags;
-
-	__asm__("pushfl ; popl %0 ; cli":"=r" (flags));
-	if (queue->tail != queue->head) {
-		result = 0xff & queue->buf[queue->tail];
-		queue->tail = (queue->tail + 1) & (TTY_BUF_SIZE-1);
-	}
-	__asm__("pushl %0 ; popfl"::"r" (flags));
-	return result;
-}
-	
+#define PUTCH(c,queue) put_tty_queue((c),(queue))
+#define GETCH(queue) get_tty_queue(queue)
 #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR])
 #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT])
 #define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE])
@@ -138,7 +115,7 @@
 	int pgrp;
 	int session;
 	int stopped;
-	int busy;
+	int flags;
 	int count;
 	struct winsize winsize;
 	void (*write)(struct tty_struct * tty);
@@ -151,36 +128,17 @@
 /*
  * so that interrupts won't be able to mess up the
  * queues, copy_to_cooked must be atomic with repect
- * to itself, as must tty->write.
+ * to itself, as must tty->write. These are the flag bits.
  */
 #define TTY_WRITE_BUSY 1
 #define TTY_READ_BUSY 2
+#define TTY_CR_PENDING 4
 
-#define TTY_WRITE_FLUSH(tty) \
-do { \
-	cli(); \
-	if (!EMPTY((tty)->write_q) && !(TTY_WRITE_BUSY & (tty)->busy)) { \
-		(tty)->busy |= TTY_WRITE_BUSY; \
-		sti(); \
-		(tty)->write((tty)); \
-		cli(); \
-		(tty)->busy &= ~TTY_WRITE_BUSY; \
-	} \
-	sti(); \
-} while (0)
+#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
+#define TTY_READ_FLUSH(tty) tty_read_flush((tty))
 
-#define TTY_READ_FLUSH(tty) \
-do { \
-	cli(); \
-	if (!EMPTY((tty)->read_q) && !(TTY_READ_BUSY & (tty)->busy)) { \
-		(tty)->busy |= TTY_READ_BUSY; \
-		sti(); \
-		copy_to_cooked((tty)); \
-		cli(); \
-		(tty)->busy &= ~TTY_READ_BUSY; \
-	} \
-	sti(); \
-} while (0)
+extern void tty_write_flush(struct tty_struct *);
+extern void tty_read_flush(struct tty_struct *);
 
 extern struct tty_struct tty_table[];
 extern struct serial_struct serial_table[];
diff --git a/include/stddef.h b/include/stddef.h
index 697c4f4..2828f8e 100644
--- a/include/stddef.h
+++ b/include/stddef.h
@@ -8,7 +8,7 @@
 
 #ifndef _SIZE_T
 #define _SIZE_T
-typedef unsigned long size_t;
+typedef unsigned int size_t;
 #endif
 
 #undef NULL
diff --git a/include/sys/dirent.h b/include/sys/dirent.h
index d0873a9..2df2c83 100644
--- a/include/sys/dirent.h
+++ b/include/sys/dirent.h
@@ -2,6 +2,7 @@
 #define _SYS_DIRENT_H
 
 #include <limits.h>
+#include <sys/types.h>
 
 struct dirent {
 	long		d_ino;
diff --git a/include/sys/types.h b/include/sys/types.h
index 8529532..46b57b5 100644
--- a/include/sys/types.h
+++ b/include/sys/types.h
@@ -1,16 +1,28 @@
 #ifndef _SYS_TYPES_H
 #define _SYS_TYPES_H
 
+#include <stddef.h>
+
 #ifndef _SIZE_T
 #define _SIZE_T
 typedef unsigned int size_t;
 #endif
 
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef int ssize_t;
+#endif
+
 #ifndef _TIME_T
 #define _TIME_T
 typedef long time_t;
 #endif
 
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef long clock_t;
+#endif
+
 #ifndef _PTRDIFF_T
 #define _PTRDIFF_T
 typedef long ptrdiff_t;
@@ -24,16 +36,29 @@
 typedef unsigned short uid_t;
 typedef unsigned short gid_t;
 typedef unsigned short dev_t;
+#ifdef OLD_LINUX
 typedef unsigned short ino_t;
+#else
+typedef unsigned long ino_t;
+#endif
 typedef unsigned short mode_t;
 typedef unsigned short umode_t;
 typedef unsigned short nlink_t;
 typedef int daddr_t;
 typedef long off_t;
+
+/* bsd */
 typedef unsigned char u_char;
 typedef unsigned short u_short;
+typedef unsigned int u_int;
 typedef unsigned long u_long;
+
+/* sysv */
+typedef unsigned char unchar;
 typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
 typedef char *caddr_t;
 
 typedef unsigned char cc_t;
diff --git a/include/time.h b/include/time.h
index fa096d9..66aa634 100644
--- a/include/time.h
+++ b/include/time.h
@@ -17,7 +17,10 @@
 
 #define CLOCKS_PER_SEC 100
 
+#ifndef _CLOCK_T
+#define _CLOCK_T
 typedef long clock_t;
+#endif
 
 struct tm {
 	int tm_sec;
diff --git a/init/main.c b/init/main.c
index 80bbe0f..c6ede55 100644
--- a/init/main.c
+++ b/init/main.c
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 #include <stdarg.h>
-#include <fcntl.h>
 #include <time.h>
 
 #include <sys/types.h>
@@ -14,6 +13,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
+#include <linux/fcntl.h>
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
@@ -40,6 +40,7 @@
 static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
 static inline _syscall1(int,dup,int,fd)
 static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
 static inline _syscall1(int,close,int,fd)
 static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
 
@@ -52,8 +53,8 @@
 
 extern int vsprintf();
 extern void init(void);
-extern void blk_dev_init(void);
-extern long chr_dev_init(long);
+extern long blk_dev_init(long,long);
+extern long chr_dev_init(long,long);
 extern void hd_init(void);
 extern void floppy_init(void);
 extern void sock_init(void);
@@ -162,13 +163,10 @@
 	else
 		buffer_memory_end = 1*1024*1024;
 	main_memory_start = buffer_memory_end;
-#ifdef RAMDISK
-	main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
-#endif
 	trap_init();
 	sched_init();
-	main_memory_start = chr_dev_init(main_memory_start);
-	blk_dev_init();
+	main_memory_start = chr_dev_init(main_memory_start,memory_end);
+	main_memory_start = blk_dev_init(main_memory_start,memory_end);
 	mem_init(main_memory_start,memory_end);
 	time_init();
 	printk("Linux version " UTS_RELEASE " " __DATE__ " " __TIME__ "\n");
diff --git a/kernel/Makefile b/kernel/Makefile
index 1359900..d72629e 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -7,33 +7,30 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-AR	=ar
-AS	=as
-LD	=ld
-LDFLAGS	=-s -x
-CC	=gcc -nostdinc -I../include
-CPP	=cpp -nostdinc -I../include
-
-
 .S.s:
 	$(CPP) -traditional $< -o $*.s
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 .s.o:
 	$(AS) -c -o $*.o $<
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) -c $<
+
+SUBDIRS	= chr_drv blk_drv math
 
 OBJS  = sched.o sys_call.o traps.o asm.o fork.o \
 	panic.o printk.o vsprintf.o sys.o exit.o \
 	signal.o mktime.o ptrace.o ioport.o itimer.o
 
+all: kernel.o subdirs
+
 kernel.o: $(OBJS)
 	$(LD) -r -o kernel.o $(OBJS)
 	sync
 
+subdirs: dummy
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+
 sys_call.s: sys_call.S
 
 sys_call.o: sys_call.s
@@ -44,76 +41,97 @@
 clean:
 	rm -f core *.o *.a tmp_make sys_call.s
 	for i in *.c;do rm -f `basename $$i .c`.s;done
-	(cd chr_drv; make clean)
-	(cd blk_drv; make clean)
-	(cd math; make clean)
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
-		$(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
-	(cd chr_drv; make dep)
-	(cd blk_drv; make dep)
-	(cd math; make dep)
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
+
+dummy:
 
 ### Dependencies:
-exit.s exit.o : exit.c ../include/errno.h ../include/signal.h ../include/sys/types.h \
-  ../include/sys/wait.h ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
-  ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h \
-  ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/linux/tty.h ../include/asm/system.h ../include/termios.h \
-  ../include/asm/segment.h 
-fork.s fork.o : fork.c ../include/errno.h ../include/stddef.h ../include/linux/sched.h \
-  ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h \
-  ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/asm/segment.h ../include/asm/system.h 
-ioport.s ioport.o : ioport.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
-  ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h \
-  ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/errno.h 
-itimer.s itimer.o : itimer.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
-  ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h \
-  ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
-  ../include/errno.h 
-mktime.s mktime.o : mktime.c ../include/time.h 
-panic.s panic.o : panic.c ../include/linux/kernel.h ../include/linux/sched.h ../include/linux/head.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/signal.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h 
-printk.s printk.o : printk.c ../include/stdarg.h ../include/stddef.h ../include/errno.h \
-  ../include/asm/segment.h ../include/asm/system.h ../include/linux/sched.h ../include/linux/head.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h 
-ptrace.s ptrace.o : ptrace.c ../include/linux/head.h ../include/linux/kernel.h ../include/linux/sched.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/signal.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
-  ../include/asm/system.h ../include/errno.h ../include/sys/ptrace.h 
-sched.s sched.o : sched.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
-  ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h \
-  ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/linux/timer.h \
-  ../include/linux/sys.h ../include/linux/fdreg.h ../include/asm/system.h ../include/asm/io.h \
-  ../include/asm/segment.h ../include/errno.h 
-signal.s signal.o : signal.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
-  ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h \
-  ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \
-  ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \
-  ../include/sys/wait.h ../include/sys/ptrace.h ../include/errno.h 
-sys.s sys.o : sys.c ../include/errno.h ../include/linux/sched.h ../include/linux/head.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
-  ../include/linux/tty.h ../include/asm/system.h ../include/termios.h ../include/linux/config.h \
-  ../include/linux/config_rel.h ../include/linux/config_ver.h ../include/linux/config.dist.h \
-  ../include/asm/segment.h ../include/sys/times.h ../include/linux/utsname.h ../include/linux/string.h 
-traps.s traps.o : traps.c ../include/linux/string.h ../include/linux/head.h ../include/linux/sched.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
-  ../include/asm/system.h ../include/asm/segment.h ../include/asm/io.h ../include/errno.h 
-vsprintf.s vsprintf.o : vsprintf.c ../include/stdarg.h ../include/linux/string.h 
+exit.o : exit.c /usr/src/linux/include/errno.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/wait.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/asm/segment.h 
+fork.o : fork.c /usr/src/linux/include/errno.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/asm/system.h 
+ioport.o : ioport.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/errno.h 
+itimer.o : itimer.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h 
+mktime.o : mktime.c /usr/src/linux/include/time.h 
+panic.o : panic.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h 
+printk.o : printk.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+ptrace.o : ptrace.c /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
+  /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h 
+sched.o : sched.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/sys.h \
+  /usr/src/linux/include/linux/fdreg.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h 
+signal.o : signal.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/wait.h \
+  /usr/src/linux/include/sys/ptrace.h /usr/src/linux/include/errno.h 
+sys.o : sys.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/config.h \
+  /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
+  /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/sys/times.h /usr/src/linux/include/linux/utsname.h /usr/src/linux/include/linux/string.h 
+traps.o : traps.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/errno.h 
+vsprintf.o : vsprintf.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/linux/string.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h 
diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile
index 01b51f4..99d573a 100644
--- a/kernel/blk_drv/Makefile
+++ b/kernel/blk_drv/Makefile
@@ -9,69 +9,72 @@
 # parent makefile.
 #
 
-AR	=ar
-AS	=as
-LD	=ld
-LDFLAGS	=-s -x
-CC	=gcc -nostdinc -I../../include
-CPP	=cpp -nostdinc -I../../include
-
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) $(RAMDISK) -S $<
 .s.o:
 	$(AS) -c -o $*.o $<
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) $(RAMDISK) -c $<
+
+SUBDIRS	= scsi
 
 OBJS = hd.o ll_rw_blk.o floppy.o ramdisk.o
 
-all: blk_drv.a
+all: blk_drv.a subdirs
 
 blk_drv.a: $(OBJS)
 	rm -f blk_drv.a
 	$(AR) rcs blk_drv.a $(OBJS)
 	sync
 
+subdirs: dummy
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+
 clean:
 	rm -f core *.o *.a tmp_make
 	for i in *.c;do rm -f `basename $$i .c`.s;done
-	(cd scsi; make clean)
+	cd scsi; $(MAKE) clean
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
-		$(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
 
+dummy:
+
 ### Dependencies:
-floppy.s floppy.o : floppy.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/timer.h ../../include/linux/fdreg.h \
-  ../../include/linux/fd.h ../../include/asm/system.h ../../include/asm/io.h ../../include/asm/segment.h \
-  ../../include/errno.h blk.h 
-hd.s hd.o : hd.c ../../include/errno.h ../../include/linux/config.h ../../include/linux/config_rel.h \
-  ../../include/linux/config_ver.h ../../include/linux/config.dist.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/timer.h \
-  ../../include/linux/hdreg.h ../../include/asm/system.h ../../include/asm/io.h \
-  ../../include/asm/segment.h blk.h 
-ll_rw_blk.s ll_rw_blk.o : ll_rw_blk.c ../../include/errno.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/asm/system.h \
+floppy.o : floppy.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/fdreg.h \
+  /usr/src/linux/include/linux/fd.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
+  /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h blk.h 
+hd.o : hd.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/config.h \
+  /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
+  /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h \
+  /usr/src/linux/include/linux/hdreg.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
+  /usr/src/linux/include/asm/segment.h blk.h 
+ll_rw_blk.o : ll_rw_blk.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \
   blk.h 
-ramdisk.s ramdisk.o : ramdisk.c ../../include/linux/string.h ../../include/linux/config.h \
-  ../../include/linux/config_rel.h ../../include/linux/config_ver.h ../../include/linux/config.dist.h \
-  ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/asm/system.h \
-  ../../include/asm/segment.h ../../include/asm/memory.h blk.h 
+ramdisk.o : ramdisk.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+  /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/memory.h \
+  blk.h 
diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c
index c4af79e..dde66a9 100644
--- a/kernel/blk_drv/floppy.c
+++ b/kernel/blk_drv/floppy.c
@@ -785,7 +785,7 @@
 		if (current_drive != (format_req.device & 3))
 			current_track = NO_TRACK;
 		current_drive = format_req.device & 3;
-		if (format_req.track < 0 || format_req.track >= floppy->track ||
+		if (((unsigned) format_req.track) >= floppy->track ||
 		    (format_req.head & 0xfffe) || probing) {
 			request_done(0);
 			goto repeat;
diff --git a/kernel/blk_drv/ll_rw_blk.c b/kernel/blk_drv/ll_rw_blk.c
index cd6aef7..9a09e7e 100644
--- a/kernel/blk_drv/ll_rw_blk.c
+++ b/kernel/blk_drv/ll_rw_blk.c
@@ -14,6 +14,8 @@
 
 #include "blk.h"
 
+extern long rd_init(long mem_start, int length);
+
 /*
  * The request-struct contains all necessary data
  * to load a nr of sectors into memory
@@ -241,7 +243,7 @@
 	make_request(major,rw,bh);
 }
 
-void blk_dev_init(void)
+long blk_dev_init(long mem_start, long mem_end)
 {
 	int i;
 
@@ -249,6 +251,10 @@
 		request[i].dev = -1;
 		request[i].next = NULL;
 	}
+#ifdef RAMDISK
+	mem_start += rd_init(mem_start, RAMDISK*1024);
+#endif
+	return mem_start;
 }
 
 void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
diff --git a/kernel/blk_drv/scsi/Makefile b/kernel/blk_drv/scsi/Makefile
index acfeec7..fd978dd 100644
--- a/kernel/blk_drv/scsi/Makefile
+++ b/kernel/blk_drv/scsi/Makefile
@@ -8,22 +8,12 @@
 
 #DEBUG = -DDEBUG=0xffffffff -DDEBUG_NO_CMD
 
-AR	=ar
-AS	=as
-LD	=ld
-LDFLAGS	=-s -x
-CC	=cc
-
-CPP	=cc -E -nostdinc -I../../../include
-
 .c.s:
-	$(CC) -nostdinc $(CFLAGS) $(DEBUG) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) $(DEBUG) -S $<
 .s.o:
 	$(AS) -c -o $*.o $<
 .c.o:
-	$(CC) -nostdinc -I../../../include $(CFLAGS) $(DEBUG) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) $(DEBUG) -c $<
 
 LOWLEVELCSRC = aha1542.c seagate.c ultrastor.c 
 LOWLEVELHSRC = aha1542.c seagate.h ultrastor.h
@@ -36,14 +26,14 @@
 
 all: scsi.a
 
-config.out : config.in ../../../include/linux/config.h
+config.out : config.in $(KERNELHDRS)/linux/config.h
 	rm -f  foo.c
 	ln -s config.in foo.c	
 	$(CPP) foo.c | grep '\.o' > config.out 
 	rm foo.c
 
-figure : hosts.h ../../../include/linux/config.h hosts.c config.out
-	$(CC) -I../../../include -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
+figure : hosts.h $(KERNELHDRS)/linux/config.h hosts.c config.out
+	$(HOSTCC) -I$(KERNELHDRS) -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
 
 max_hosts.h : figure
 	(echo "#ifndef _MAX_HOSTS_H"; \
@@ -70,12 +60,11 @@
   ../../../include/sys/param.h ../../../include/sys/time.h \
   ../../../include/time.h ../../../include/sys/resource.h \
   ../../../include/linux/string.h seagate.h scsi.h hosts.h max_hosts.h 
-	cc -nostdinc -I../../../include -Wall -c seagate.c $(DEBUG) 
+	$(CC) -Wall -c seagate.c $(DEBUG) 
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c ;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
-		$(CPP) -M $$i;done) >> tmp_make
+	for i in *.c ;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
 
 ### Dependencies:
diff --git a/kernel/blk_drv/scsi/aha1542.c b/kernel/blk_drv/scsi/aha1542.c
index 9547dda..635c080 100644
--- a/kernel/blk_drv/scsi/aha1542.c
+++ b/kernel/blk_drv/scsi/aha1542.c
@@ -10,6 +10,7 @@
 #include <linux/string.h>
 #include <asm/system.h>
 #include <asm/io.h>
+#include <sys/types.h>
 #include "scsi.h"
 #include "hosts.h"
 
diff --git a/kernel/blk_drv/scsi/aha1542.h b/kernel/blk_drv/scsi/aha1542.h
index 6609a4e..47848d8 100644
--- a/kernel/blk_drv/scsi/aha1542.h
+++ b/kernel/blk_drv/scsi/aha1542.h
@@ -16,8 +16,6 @@
  *
  */
 
-typedef unsigned char unchar;
-
 /* I/O Port interface 4.2 */
 /* READ */
 #define STATUS base
diff --git a/kernel/blk_drv/scsi/hosts.c b/kernel/blk_drv/scsi/hosts.c
index 71f7450..268bc71 100644
--- a/kernel/blk_drv/scsi/hosts.c
+++ b/kernel/blk_drv/scsi/hosts.c
@@ -30,6 +30,7 @@
 #include "hosts.h"
 
 #ifdef CONFIG_SCSI_AHA1542
+#include <sys/types.h>
 #include "aha1542.h"
 #endif
 
diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile
index 61956be..e9127ae 100644
--- a/kernel/chr_drv/Makefile
+++ b/kernel/chr_drv/Makefile
@@ -9,21 +9,12 @@
 # parent makes..
 #
 
-AR	=ar
-AS	=as
-LD	=ld
-LDFLAGS	=-s -x
-CC	=gcc -nostdinc -I../../include
-CPP	=cpp -nostdinc -I../../include
-
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 .s.o:
 	$(AS) -c -o $*.o $<
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) -c $<
 
 OBJS  = tty_io.o console.o keyboard.o serial.o \
 	tty_ioctl.o pty.o lp.o vt.o mem.o
@@ -41,67 +32,82 @@
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
-		$(CPP) -M -DKBD_FINNISH $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M -DKBD_FINNISH $$i;done >> tmp_make
 	cp tmp_make Makefile
 
 ### Dependencies:
-console.s console.o : console.c ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/timer.h ../../include/linux/tty.h \
-  ../../include/asm/system.h ../../include/termios.h ../../include/linux/config.h \
-  ../../include/linux/config_rel.h ../../include/linux/config_ver.h ../../include/linux/config.dist.h \
-  ../../include/asm/io.h ../../include/asm/segment.h ../../include/linux/string.h \
-  ../../include/errno.h ../../include/sys/kd.h vt_kern.h 
-keyboard.s keyboard.o : keyboard.c ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/ctype.h ../../include/linux/tty.h \
-  ../../include/asm/system.h ../../include/termios.h ../../include/asm/io.h 
-lp.s lp.o : lp.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/lp.h ../../include/errno.h \
-  ../../include/asm/io.h ../../include/asm/segment.h 
-mem.s mem.o : mem.c ../../include/errno.h ../../include/sys/types.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/tty.h ../../include/asm/system.h \
-  ../../include/termios.h ../../include/asm/segment.h ../../include/asm/io.h 
-pty.s pty.o : pty.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
-  ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/tty.h ../../include/asm/system.h \
-  ../../include/termios.h ../../include/asm/io.h 
-serial.s serial.o : serial.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \
-  ../../include/linux/timer.h ../../include/linux/tty.h ../../include/asm/system.h \
-  ../../include/termios.h ../../include/asm/io.h 
-tty_io.s tty_io.o : tty_io.c ../../include/errno.h ../../include/signal.h ../../include/sys/types.h \
-  ../../include/fcntl.h ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h \
-  ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/tty.h \
-  ../../include/asm/system.h ../../include/termios.h ../../include/linux/ctype.h \
-  ../../include/asm/io.h ../../include/asm/segment.h ../../include/sys/kd.h vt_kern.h 
-tty_ioctl.s tty_ioctl.o : tty_ioctl.c ../../include/errno.h ../../include/termios.h ../../include/sys/types.h \
-  ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/tty.h \
-  ../../include/asm/system.h ../../include/asm/io.h ../../include/asm/segment.h 
-vt.s vt.o : vt.c ../../include/errno.h ../../include/sys/types.h ../../include/sys/kd.h \
-  ../../include/sys/vt.h ../../include/asm/io.h ../../include/asm/segment.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h ../../include/linux/tty.h ../../include/asm/system.h \
-  ../../include/termios.h ../../include/linux/timer.h vt_kern.h 
+console.o : console.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/tty.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/config.h \
+  /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
+  /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/linux/string.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/kd.h \
+  vt_kern.h 
+keyboard.o : keyboard.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/linux/tty.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/asm/io.h 
+lp.o : lp.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/lp.h /usr/src/linux/include/errno.h \
+  /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h 
+mem.o : mem.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/asm/io.h 
+pty.o : pty.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/asm/io.h 
+serial.o : serial.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h 
+tty_io.o : tty_io.c /usr/src/linux/include/errno.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/sys/kd.h vt_kern.h 
+tty_ioctl.o : tty_ioctl.c /usr/src/linux/include/errno.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
+  /usr/src/linux/include/asm/segment.h 
+vt.o : vt.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/kd.h /usr/src/linux/include/sys/vt.h \
+  /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+  /usr/src/linux/include/linux/timer.h vt_kern.h 
diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c
index dd7c4c7..79b0d15 100644
--- a/kernel/chr_drv/console.c
+++ b/kernel/chr_drv/console.c
@@ -92,7 +92,8 @@
 static int can_do_color = 0;
 
 static struct {
-	unsigned short	vc_video_erase_char;	/* Current attributes & space */
+	unsigned short	vc_video_erase_char;	/* Background erase character */
+	unsigned char	vc_attr;		/* Current attributes */
 	unsigned char	vc_def_color;		/* Default colors */
 	unsigned char	vc_color;		/* Foreground & background */
 	unsigned char	vc_s_color;		/* Saved foreground & background */
@@ -160,7 +161,7 @@
 #define npar		(vc_cons[currcons].vc_npar)
 #define par		(vc_cons[currcons].vc_par)
 #define ques		(vc_cons[currcons].vc_ques)
-#define attr		(vc_cons[currcons].vc_video_erase_char >> 8)
+#define attr		(vc_cons[currcons].vc_attr)
 #define saved_x		(vc_cons[currcons].vc_saved_x)
 #define saved_y		(vc_cons[currcons].vc_saved_y)
 #define translate	(vc_cons[currcons].vc_translate)
@@ -201,7 +202,6 @@
 #define kbdmode		(vc_cons[currcons].vc_kbdmode)
 #define tab_stop	(vc_cons[currcons].vc_tab_stop)
 #define kbdraw		(vt_cons[currcons].vc_kbdraw)
-#define kbde0		(vt_cons[currcons].vc_kbde0)
 #define kbdleds		(vt_cons[currcons].vc_kbdleds)
 #define vtmode		(vt_cons[currcons].vt_mode)
 
@@ -288,6 +288,7 @@
 		else
 			y = new_y;
 	pos = origin + y*video_size_row + (x<<1);
+	need_wrap = 0;
 }
 
 static void set_origin(int currcons)
@@ -385,6 +386,7 @@
 		return;
 	} else 
 		scrup(currcons,top,bottom);
+	need_wrap = 0;
 }
 
 static void ri(int currcons)
@@ -395,20 +397,31 @@
 		return;
 	} else
 		scrdown(currcons,top,bottom);
+	need_wrap = 0;
 }
 
 static inline void cr(int currcons)
 {
 	pos -= x<<1;
-	x=0;
+	need_wrap = x = 0;
 }
 
-static void del(int currcons)
+static inline void bs(int currcons)
+{
+	if (x) {
+		pos -= 2;
+		x--;
+		need_wrap = 0;
+	}
+}
+
+static inline void del(int currcons)
 {
 	if (x) {
 		pos -= 2;
 		x--;
 		*(unsigned short *)pos = video_erase_char;
+		need_wrap = 0;
 	}
 }
 
@@ -439,6 +452,7 @@
 		::"c" (count),
 		"D" (start),"a" (video_erase_char)
 		:"cx","di");
+	need_wrap = 0;
 }
 
 static void csi_K(int currcons, int vpar)
@@ -468,6 +482,7 @@
 		::"c" (count),
 		"D" (start),"a" (video_erase_char)
 		:"cx","di");
+	need_wrap = 0;
 }
 
 /*
@@ -475,27 +490,38 @@
  */
 static void update_attr(int currcons)
 {
-	unsigned char a = color;
-
+	attr = color;
 	if (can_do_color) {
 		if (underline)
-			a = (a & 0xf8) | ulcolor;
+			attr = (attr & 0xf0) | ulcolor;
 		else if (intensity == 0)
-			a = (a & 0xf0) | halfcolor;
+			attr = (attr & 0xf0) | halfcolor;
 	}
 	if (reverse ^ decscnm)
-		a = (a & 0x88) | (((a >> 4) | (a << 4)) & 0x77);
+		attr = (attr & 0x88) | (((attr >> 4) | (attr << 4)) & 0x77);
 	if (blink)
-		a |= 0x80;
+		attr ^= 0x80;
 	if (intensity == 2)
-		a |= 0x08;
+		attr ^= 0x08;
 	if (!can_do_color) {
 		if (underline)
-			a = (a & 0xf8) | 0x01;
+			attr = (attr & 0xf8) | 0x01;
 		else if (intensity == 0)
-			a = (a & 0xf0) | 0x08;
+			attr = (attr & 0xf0) | 0x08;
 	}
-	video_erase_char = (a << 8) | ' ';
+	if (decscnm)
+		video_erase_char = ((color & 0x88) | (((color >> 4) |
+			(color << 4)) & 0x77) << 8) | ' ';
+	else
+		video_erase_char = (color << 8) | ' ';
+}
+
+static void default_attr(int currcons) {
+	intensity = 1;
+	underline = 0;
+	reverse = 0;
+	blink = 0;
+	color = def_color;
 }
 
 static void csi_m(int currcons)
@@ -505,11 +531,7 @@
 	for (i=0;i<=npar;i++)
 		switch (par[i]) {
 			case 0:	/* all attributes off */
-				intensity = 1;
-				underline = 0;
-				reverse = 0;
-				blink = 0;
-				color = def_color;
+				default_attr(currcons);
 				break;
 			case 1:
 				intensity = 2;
@@ -630,10 +652,10 @@
 
 	if (can_do_color)
 		for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2)
-			*p = (*p & 0x88) | ((*p & 0x70) >> 4) | ((*p & 0x07) << 4);
+			*p = (*p & 0x88) | (((*p >> 4) | (*p << 4)) & 0x77);
 	else
 		for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2)
-			*p = *p ^ (*p & 0x07 == 1 ? 0x70 : 0x77);
+			*p ^= *p & 0x07 == 1 ? 0x70 : 0x77;
 }
 
 static void set_mode(int currcons, int on_off)
@@ -698,7 +720,9 @@
 			}
 			break;
 		case 8:	/* store colors as defaults */
-			def_color = color;
+			def_color = attr;
+			default_attr(currcons);
+			update_attr(currcons);
 			break;
 		case 9:	/* set blanking interval */
 			blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
@@ -718,11 +742,13 @@
 		old = tmp;
 		p++;
 	}
+	need_wrap = 0;
 }
 
 static void insert_line(int currcons)
 {
 	scrdown(currcons,y,bottom);
+	need_wrap = 0;
 }
 
 static void delete_char(int currcons)
@@ -735,11 +761,13 @@
 		p++;
 	}
 	*p = video_erase_char;
+	need_wrap = 0;
 }
 
 static void delete_line(int currcons)
 {
 	scrup(currcons,y,bottom);
+	need_wrap = 0;
 }
 
 static void csi_at(int currcons, unsigned int nr)
@@ -787,7 +815,6 @@
 	saved_x		= x;
 	saved_y		= y;
 	s_intensity	= intensity;
-	s_blink		= blink;
 	s_underline	= underline;
 	s_blink		= blink;
 	s_reverse	= reverse;
@@ -799,11 +826,8 @@
 
 static void restore_cur(int currcons)
 {
-	x		= saved_x;
-	y		= saved_y;
-	pos		= origin + y*video_size_row + (x<<1);
+	gotoxy(currcons,saved_x,saved_y);
 	intensity	= s_intensity;
-	blink		= s_blink;
 	underline	= s_underline;
 	blink		= s_blink;
 	reverse		= s_reverse;
@@ -813,6 +837,7 @@
 	G1_charset	= saved_G1;
 	translate	= charset ? G1_charset : G0_charset;
 	update_attr(currcons);
+	need_wrap = 0;
 }
 
 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, 
@@ -820,24 +845,14 @@
 
 static void reset_terminal(int currcons, int do_clear)
 {
-	vtmode		= KD_TEXT;
 	top		= 0;
 	bottom		= video_num_lines;
-	/* Default colors. */
-	def_color	= 0x07;	/* light gray */
-	ulcolor		= 0x0f;	/* bold white */
-	halfcolor	= 0x08;	/* dark gray */
-	color		= def_color;
 	state		= ESnormal;
 	ques		= 0;
 	translate	= NORM_TRANS;
 	G0_charset	= NORM_TRANS;
 	G1_charset	= GRAF_TRANS;
 	charset		= 0;
-	kbdleds		= 2;
-	kbdmode		= 0;
-	kbdraw		= 0;
-	kbde0		= 0;
 	need_wrap	= 0;
 
 	decscnm		= 0;
@@ -845,15 +860,25 @@
 	decawm		= 1;
 	deccm		= 1;
 	decim		= 0;
-	SET(decarm,krepeat,1);
-	SET(decckm,ckmode,0);
-	SET(kbdapplic,kapplic,0);
-	SET(lnm,lfnlmode,0);
 
-	intensity	= 1;
-	underline	= 0;
-	blink		= 0;
-	reverse		= 0;
+	if (currcons == fg_console) {
+		krepeat		= 1;
+		ckmode		= 0;
+		kapplic		= 0;
+		lfnlmode	= 0;
+		kleds		= 2;
+		kmode		= 0;
+		set_leds();
+	} else {
+		decarm		= 1;
+		decckm		= 0;
+		kbdapplic	= 0;
+		lnm		= 0;
+		kbdleds		= 2;
+		kbdmode		= 0;
+	}
+
+	default_attr(currcons);
 	update_attr(currcons);
 
 	tab_stop[0]	= 0x01010100;
@@ -865,9 +890,8 @@
 	if (do_clear) {
 		gotoxy(currcons,0,0);
 		csi_J(currcons,2);
+		save_cur(currcons);
 	}
-
-	save_cur(currcons);
 }
 
 void con_write(struct tty_struct * tty)
@@ -886,22 +910,20 @@
 			if (need_wrap) {
 				cr(currcons);
 				lf(currcons);
-				need_wrap = 0;
 			}
 			if (decim)
 				insert_char(currcons);
 			c = translate[c];
 			*(char *) pos = c;
 			*(char *) (pos+1) = attr;
-			if (x == video_num_columns - 1) {
+			if (x == video_num_columns - 1)
 				need_wrap = decawm;
-				continue;
+			else {
+				x++;
+				pos+=2;
 			}
-			x++;
-			pos+=2;
 			continue;
 		}
-		need_wrap = 0;
 
 		/*
 		 *  Control characters can be used in the _middle_
@@ -912,10 +934,7 @@
 				sysbeep();
 				break;
 			case 8:
-				if (x) {
-					x--;
-					pos -= 2;
-				}
+				bs(currcons);
 				break;
 			case 9:
 				pos -= (x << 1);
@@ -1301,14 +1320,21 @@
 		pos = origin = video_mem_start = base;
 		scr_end = video_mem_end = (base += screen_size);
 		vc_scrbuf[currcons] = (unsigned short *) origin;
+		vtmode		= KD_TEXT;
+		kbdraw		= 0;
+		def_color	= 0x07;   /* white */
+		ulcolor		= 0x0f;   /* bold white */
+		halfcolor	= 0x08;   /* grey */
 		reset_terminal(currcons, currcons);
 	}
 	currcons = fg_console = 0;
 
 	video_mem_start = video_mem_base;
 	video_mem_end = video_mem_term;
-	origin	= video_mem_start;
+	origin = video_mem_start;
 	scr_end	= video_mem_start + video_num_lines * video_size_row;
+	gotoxy(currcons,0,0);
+	save_cur(currcons);
 	gotoxy(currcons,orig_x,orig_y);
 	update_screen(fg_console);
 
@@ -1325,7 +1351,6 @@
 	int currcons = fg_console;
 	kbdmode = kmode;
 	kbdraw = kraw;
-	kbde0 = ke0;
 	kbdleds = kleds;
 	kbdapplic = kapplic;
 	decckm = ckmode;
@@ -1334,7 +1359,6 @@
 	currcons = new_console;
 	kmode = (kmode & 0x3F) | (kbdmode & 0xC0);
 	kraw = kbdraw;
-	ke0 = kbde0;
 	kleds = kbdleds;
 	kapplic = kbdapplic;
 	ckmode = decckm;
diff --git a/kernel/chr_drv/keyboard.c b/kernel/chr_drv/keyboard.c
index 8a9483a..fad6a84 100644
--- a/kernel/chr_drv/keyboard.c
+++ b/kernel/chr_drv/keyboard.c
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/ctype.h>
 #include <linux/tty.h>
+#include <linux/mm.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -40,7 +41,6 @@
 
 extern void do_keyboard_interrupt(void);
 extern void ctrl_alt_del(void);
-extern void show_mem(void), show_state(void);
 extern void change_console(unsigned int new_console);
 extern struct tty_queue *table_list[];
 
@@ -679,7 +679,7 @@
           0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,
-          0,    0,    0,    0,    0,    0,  '|',    0,
+          0,    0,    0,    0,    0,    0,  '\\',    0,
           0,    0,    0,    0,    0,    0,    0,    0,
           0 };
 
@@ -874,7 +874,7 @@
 }
 		
 
-#if defined KBD_FR
+#if defined KBD_FR || defined KBD_US
 static unsigned char num_table[] = "789-456+1230.";
 #else
 static unsigned char num_table[] = "789-456+1230,";
diff --git a/kernel/chr_drv/mem.c b/kernel/chr_drv/mem.c
index 1432c84..179816e 100644
--- a/kernel/chr_drv/mem.c
+++ b/kernel/chr_drv/mem.c
@@ -241,10 +241,10 @@
 	NULL		/* no special release code */
 };
 
-long chr_dev_init(long kmem_start)
+long chr_dev_init(long mem_start, long mem_end)
 {
 	chrdev_fops[1] = &mem_fops;
-	kmem_start = tty_init(kmem_start);
-	kmem_start = lp_init(kmem_start);
-	return kmem_start;
+	mem_start = tty_init(mem_start);
+	mem_start = lp_init(mem_start);
+	return mem_start;
 }
diff --git a/kernel/chr_drv/pty.c b/kernel/chr_drv/pty.c
index eaf24fd..a0625c7 100644
--- a/kernel/chr_drv/pty.c
+++ b/kernel/chr_drv/pty.c
@@ -12,15 +12,15 @@
  *	void spty_write(struct tty_struct * queue);
  */
 
+#include <errno.h>
+
 #include <linux/sched.h>
 #include <linux/tty.h>
+#include <linux/fcntl.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 
-#include<errno.h>
-#include<fcntl.h>
-
 int pty_open(unsigned int dev, struct file * filp)
 {
 	struct tty_struct * tty;
@@ -31,14 +31,14 @@
 	wake_up(&tty->read_q->proc_list);
 	if (filp->f_flags & O_NDELAY)
 		return 0;
-	if (IS_A_PTY_MASTER(dev))
+	if (IS_A_PTY_MASTER(dev)) {
+		tty->link->count++;
 		return 0;
-#if 0
+	}
 	while (!tty->link->count && !(current->signal & ~current->blocked))
 		interruptible_sleep_on(&tty->link->read_q->proc_list);
 	if (!tty->link->count)
 		return -ERESTARTSYS;
-#endif
 	return 0;
 }
 
@@ -49,6 +49,7 @@
 	tty = tty_table + dev;
 	wake_up(&tty->read_q->proc_list);
 	if (IS_A_PTY_MASTER(dev)) {
+		tty->link->count--;
 		if (tty->link->pgrp > 0)
 			kill_pg(tty->link->pgrp,SIGHUP,1);
 	}
diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c
index d419f8a..c4b3a77 100644
--- a/kernel/chr_drv/tty_io.c
+++ b/kernel/chr_drv/tty_io.c
@@ -13,7 +13,8 @@
 
 #include <errno.h>
 #include <signal.h>
-#include <fcntl.h>
+
+#include <linux/fcntl.h>
 
 #define ALRMMASK (1<<(SIGALRM-1))
 
@@ -59,6 +60,64 @@
  */
 struct tty_queue * table_list[] = { NULL, NULL };
 
+void put_tty_queue(char c, struct tty_queue * queue)
+{
+	int head;
+	unsigned long flags;
+
+	__asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
+	head = (queue->head + 1) & (TTY_BUF_SIZE-1);
+	if (head != queue->tail) {
+		queue->buf[queue->head] = c;
+		queue->head = head;
+	}
+	__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
+}
+
+int get_tty_queue(struct tty_queue * queue)
+{
+	int result = -1;
+	unsigned long flags;
+
+	__asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
+	if (queue->tail != queue->head) {
+		result = 0xff & queue->buf[queue->tail];
+		queue->tail = (queue->tail + 1) & (TTY_BUF_SIZE-1);
+	}
+	__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
+	return result;
+}
+
+void tty_write_flush(struct tty_struct * tty)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
+	if (!EMPTY(tty->write_q) && !(TTY_WRITE_BUSY & tty->flags)) {
+		tty->flags |= TTY_WRITE_BUSY;
+		__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
+		tty->write(tty);
+		cli();
+		tty->flags &= ~TTY_WRITE_BUSY;
+	}
+	__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
+}
+
+void tty_read_flush(struct tty_struct * tty)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
+	if (!EMPTY(tty->read_q) && !(TTY_READ_BUSY & tty->flags)) {
+		tty->flags |= TTY_READ_BUSY;
+		__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
+		copy_to_cooked(tty);
+		cli();
+		tty->flags &= ~TTY_READ_BUSY;
+	}
+	__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
+}
+
 void change_console(unsigned int new_console)
 {
 	if (vt_cons[fg_console].vt_mode == KD_GRAPHICS)
@@ -336,7 +395,6 @@
 
 static int write_chan(unsigned int channel, struct file * file, char * buf, int nr)
 {
-	static cr_flag=0;
 	struct tty_struct * tty;
 	char c, *b=buf;
 
@@ -376,8 +434,8 @@
 					c='\n';
 				else if (c=='\n' && O_NLRET(tty))
 					c='\r';
-				if (c=='\n' && !cr_flag && O_NLCR(tty)) {
-					cr_flag = 1;
+				if (c=='\n' && !(tty->flags & TTY_CR_PENDING) && O_NLCR(tty)) {
+					tty->flags |= TTY_CR_PENDING;
 					PUTCH(13,tty->write_q);
 					continue;
 				}
@@ -385,7 +443,7 @@
 					c=toupper(c);
 			}
 			b++; nr--;
-			cr_flag = 0;
+			tty->flags &= ~TTY_CR_PENDING;
 			PUTCH(c,tty->write_q);
 		}
 		if (nr>0)
@@ -568,7 +626,7 @@
 			-1,		/* initial pgrp */
 			0,			/* initial session */
 			0,			/* initial stopped */
-			0,			/* initial busy */
+			0,			/* initial flags */
 			0,			/* initial count */
 			{video_num_lines,video_num_columns,0,0},
 			con_write,
diff --git a/kernel/chr_drv/tty_ioctl.c b/kernel/chr_drv/tty_ioctl.c
index a9f0e04..c06bff5 100644
--- a/kernel/chr_drv/tty_ioctl.c
+++ b/kernel/chr_drv/tty_ioctl.c
@@ -33,11 +33,15 @@
 
 void flush_input(struct tty_struct * tty)
 {
-	flush(tty->read_q);
-	flush(tty->secondary);
-	tty->secondary->data = 0;
-	wake_up(&tty->read_q->proc_list);
-	if (tty = tty->link) {
+	if (tty->read_q) {
+		flush(tty->read_q);
+		wake_up(&tty->read_q->proc_list);
+	}
+	if (tty->secondary) {
+		flush(tty->secondary);
+		tty->secondary->data = 0;
+	}
+	if ((tty = tty->link) && tty->write_q) {
 		flush(tty->write_q);
 		wake_up(&tty->write_q->proc_list);
 	}
@@ -45,13 +49,19 @@
 
 void flush_output(struct tty_struct * tty)
 {
-	flush(tty->write_q);
-	wake_up(&tty->write_q->proc_list);
+	if (tty->write_q) {
+		flush(tty->write_q);
+		wake_up(&tty->write_q->proc_list);
+	}
 	if (tty = tty->link) {
-		flush(tty->read_q);
-		flush(tty->secondary);
-		tty->secondary->data = 0;
-		wake_up(&tty->read_q->proc_list);
+		if (tty->read_q) {
+			flush(tty->read_q);
+			wake_up(&tty->read_q->proc_list);
+		}
+		if (tty->secondary) {
+			flush(tty->secondary);
+			tty->secondary->data = 0;
+		}
 	}
 }
 
diff --git a/kernel/exit.c b/kernel/exit.c
index 21d40f3..fda0b7b 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -12,6 +12,7 @@
 
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/mm.h>
 #include <linux/tty.h>
 #include <asm/segment.h>
 
@@ -295,6 +296,7 @@
 	struct task_struct *p;
 	int i;
 
+fake_volatile:
 	free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
 	free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
 	for (i=0 ; i<NR_OPEN ; i++)
@@ -389,6 +391,20 @@
 	audit_ptree();
 #endif
 	schedule();
+/*
+ * In order to get rid of the "volatile function does return" message
+ * I did this little loop that confuses gcc to think do_exit really
+ * is volatile. In fact it's schedule() that is volatile in some
+ * circumstances: when current->state = ZOMBIE, schedule() never
+ * returns.
+ *
+ * In fact the natural way to do all this is to have the label and the
+ * goto right after each other, but I put the fake_volatile label at
+ * the start of the function just in case something /really/ bad
+ * happens, and the schedule returns. This way we can try again. I'm
+ * not paranoid: it's just that everybody is out to get me.
+ */
+	goto fake_volatile;
 }
 
 int sys_exit(int error_code)
diff --git a/kernel/fork.c b/kernel/fork.c
index 96464bc..335c137 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -15,11 +15,10 @@
 
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/mm.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 
-extern void write_verify(unsigned long address);
-
 long last_pid=0;
 
 void verify_area(void * addr,int size)
diff --git a/kernel/itimer.c b/kernel/itimer.c
index f7e5ba3..d04e2e7 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -7,6 +7,7 @@
 /* These are all the functions necessary to implement itimers */
 
 #include <linux/sched.h>
+#include <linux/string.h>
 #include <asm/segment.h>
 
 #include <signal.h>
diff --git a/kernel/math/Makefile b/kernel/math/Makefile
index c7e9c90..67828ab 100644
--- a/kernel/math/Makefile
+++ b/kernel/math/Makefile
@@ -6,21 +6,12 @@
 # unless it's something special (ie not a .c file).
 #
 
-AR	=ar
-AS	=as
-LD	=ld
-LDFLAGS	=-s -x
-CC	=gcc -nostdinc -I../../include
-CPP	=cpp -nostdinc -I../../include
-
 .c.s:
-	$(CC) $(CFLAGS) $(MATH_EMULATION) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) $(MATH_EMULATION) -S $<
 .s.o:
 	$(AS) -c -o $*.o $<
 .c.o:
-	$(CC) $(CFLAGS) $(MATH_EMULATION) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) $(MATH_EMULATION) -c $<
 
 OBJS  = emulate.o error.o convert.o ea.o get_put.o \
 	add.o mul.o div.o compare.o sqrt.o
@@ -35,56 +26,67 @@
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
-		$(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
 
 ### Dependencies:
-add.s add.o : add.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h 
-compare.s compare.o : compare.c ../../include/linux/math_emu.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h 
-convert.s convert.o : convert.c ../../include/linux/math_emu.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h 
-div.s div.o : div.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h 
-ea.s ea.o : ea.c ../../include/stddef.h ../../include/linux/math_emu.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
-  ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/asm/segment.h 
-emulate.s emulate.o : emulate.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h 
-error.s error.o : error.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/sched.h \
-  ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h 
-get_put.s get_put.o : get_put.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/math_emu.h \
-  ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
-  ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
-  ../../include/linux/kernel.h ../../include/sys/param.h ../../include/sys/time.h \
-  ../../include/time.h ../../include/sys/resource.h ../../include/asm/segment.h 
-mul.s mul.o : mul.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h 
-sqrt.s sqrt.o : sqrt.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \
-  ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \
-  ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
-  ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
-  ../../include/sys/resource.h 
+add.o : add.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+compare.o : compare.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+convert.o : convert.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+div.o : div.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+ea.o : ea.c /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/math_emu.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h 
+emulate.o : emulate.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h 
+error.o : error.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h 
+get_put.o : get_put.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h 
+mul.o : mul.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+sqrt.o : sqrt.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
diff --git a/kernel/sched.c b/kernel/sched.c
index a994ee3..6e6716e 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -28,7 +28,7 @@
 #define _S(nr) (1<<((nr)-1))
 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
 
-void show_task(int nr,struct task_struct * p)
+static void show_task(int nr,struct task_struct * p)
 {
 	int i,j = 4096-sizeof(struct task_struct);
 
diff --git a/lib/Makefile b/lib/Makefile
index e1dd559..bbfc3b4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -6,21 +6,12 @@
 # unless it's something special (ie not a .c file).
 #
 
-AR	=ar
-AS	=as
-LD	=ld
-LDFLAGS	=-s -x
-CC	=gcc -nostdinc -I../include
-CPP	=gcc -E -nostdinc -I../include
-
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 .s.o:
 	$(AS) -c -o $*.o $<
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) -c $<
 
 OBJS  = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \
 	execve.o wait.o string.o malloc.o itimer.o
@@ -35,24 +26,28 @@
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
-		$(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
 
 ### Dependencies:
-_exit.s _exit.o : _exit.c ../include/linux/unistd.h 
-close.s close.o : close.c ../include/linux/unistd.h 
-ctype.s ctype.o : ctype.c ../include/linux/ctype.h 
-dup.s dup.o : dup.c ../include/linux/unistd.h 
-errno.s errno.o : errno.c 
-execve.s execve.o : execve.c ../include/linux/unistd.h 
-itimer.s itimer.o : itimer.c ../include/linux/unistd.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/types.h 
-malloc.s malloc.o : malloc.c ../include/linux/kernel.h ../include/linux/mm.h ../include/linux/fs.h \
-  ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h \
-  ../include/signal.h ../include/asm/system.h 
-open.s open.o : open.c ../include/linux/unistd.h ../include/stdarg.h 
-setsid.s setsid.o : setsid.c ../include/sys/types.h ../include/linux/unistd.h 
-string.s string.o : string.c ../include/linux/string.h 
-wait.s wait.o : wait.c ../include/linux/unistd.h ../include/sys/wait.h ../include/sys/types.h 
-write.s write.o : write.c ../include/linux/unistd.h ../include/sys/types.h 
+_exit.o : _exit.c /usr/src/linux/include/linux/unistd.h 
+close.o : close.c /usr/src/linux/include/linux/unistd.h 
+ctype.o : ctype.c /usr/src/linux/include/linux/ctype.h 
+dup.o : dup.c /usr/src/linux/include/linux/unistd.h 
+errno.o : errno.c 
+execve.o : execve.c /usr/src/linux/include/linux/unistd.h 
+itimer.o : itimer.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h 
+malloc.o : malloc.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/asm/system.h 
+open.o : open.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/stdarg.h 
+setsid.o : setsid.c /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
+  /usr/src/linux/include/linux/unistd.h 
+string.o : string.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h 
+wait.o : wait.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/wait.h \
+  /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h 
+write.o : write.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h 
diff --git a/lib/_exit.c b/lib/_exit.c
index 4b1985a..a1630f4 100644
--- a/lib/_exit.c
+++ b/lib/_exit.c
@@ -9,6 +9,8 @@
 
 volatile void _exit(int exit_code)
 {
+fake_volatile:
 	__asm__("movl %1,%%ebx\n\t"
 		"int $0x80"::"a" (__NR_exit),"g" (exit_code));
+	goto fake_volatile;
 }
diff --git a/mm/Makefile b/mm/Makefile
index fb00fdf..c5ad9d3 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -7,20 +7,12 @@
 #
 # Note 2! The CFLAGS definition is now in the main makefile...
 
-AS	=as
-AR	=ar
-LD	=ld
-CC	=gcc -nostdinc -I../include
-CPP	=cpp -nostdinc -I../include
-
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) -c $<
 .s.o:
 	$(AS) -o $*.o $<
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 
 OBJS	= memory.o swap.o mmap.o
 
@@ -33,21 +25,27 @@
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do $(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
 
 ### Dependencies:
-memory.o : memory.c ../include/signal.h ../include/sys/types.h ../include/asm/system.h \
-  ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h 
-mmap.o : mmap.c ../include/linux/stat.h ../include/linux/sched.h ../include/linux/head.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
-  ../include/asm/segment.h ../include/asm/system.h ../include/errno.h ../include/sys/mman.h 
-swap.o : swap.c ../include/errno.h ../include/linux/stat.h ../include/linux/mm.h \
-  ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \
-  ../include/sys/vfs.h ../include/linux/kernel.h ../include/signal.h ../include/linux/string.h \
-  ../include/linux/sched.h ../include/linux/head.h ../include/sys/param.h ../include/sys/time.h \
-  ../include/time.h ../include/sys/resource.h 
+memory.o : memory.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h 
+mmap.o : mmap.c /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+  /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/mman.h 
+swap.o : swap.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+  /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
+  /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+  /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
+  /usr/src/linux/include/sys/resource.h 
diff --git a/mm/memory.c b/mm/memory.c
index 52fabfb..6fea346 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -189,8 +189,7 @@
  * a more complete version of free_page_tables which performs with page
  * granularity.
  */
-int
-unmap_page_range(unsigned long from, unsigned long size)
+int unmap_page_range(unsigned long from, unsigned long size)
 {
 	unsigned long page, page_dir;
 	unsigned long *page_table, *dir;
@@ -256,8 +255,7 @@
  * write/copy:	yes/copy	copy/copy
  * exec:	yes		yes
  */
-int
-remap_page_range(unsigned long from, unsigned long to, unsigned long size,
+int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
 		 int permiss)
 {
 	unsigned long *page_table, *dir;
@@ -489,7 +487,7 @@
 	return;
 }
 
-void get_empty_page(unsigned long address)
+static void get_empty_page(unsigned long address)
 {
 	unsigned long tmp;
 
diff --git a/mm/mmap.c b/mm/mmap.c
index ae1fd66..281da97 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -6,6 +6,7 @@
 #include <linux/stat.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/mm.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <errno.h>
@@ -37,16 +38,11 @@
 #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \
 			  current->start_code + current->end_code)
 
-extern int remap_page_range(unsigned long from, unsigned long to,
-			    unsigned long size, int permiss);
-extern int unmap_page_range(unsigned long from, unsigned long size);
-
 static caddr_t
 mmap_chr(unsigned long addr, size_t len, int prot, int flags,
 	 struct inode *inode, unsigned long off)
 {
 	int major, minor;
-	extern unsigned long HIGH_MEMORY;
 
 	major = MAJOR(inode->i_rdev);
 	minor = MINOR(inode->i_rdev);
diff --git a/net/Makefile b/net/Makefile
index 6ceb492..1292340 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -7,20 +7,12 @@
 #
 # Note 2! The CFLAGS definition is now in the main makefile...
 
-AS	=as
-AR	=ar
-LD	=ld
-CC	=gcc -nostdinc -I../include -Wall # -DSOCK_DEBUG
-CPP	=cpp -nostdinc -I../include
-
 .c.o:
-	$(CC) $(CFLAGS) \
-	-c -o $*.o $<
+	$(CC) $(CFLAGS) -c $<
 .s.o:
 	$(AS) -o $*.o $<
 .c.s:
-	$(CC) $(CFLAGS) \
-	-S -o $*.s $<
+	$(CC) $(CFLAGS) -S $<
 
 OBJS	=  socket.o unix.o
 
@@ -33,20 +25,25 @@
 
 dep:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	(for i in *.c;do $(CPP) -M $$i;done) >> tmp_make
+	for i in *.c;do $(CPP) -M $$i;done >> tmp_make
 	cp tmp_make Makefile
 
 ### Dependencies:
-socket.o : socket.c ../include/signal.h ../include/sys/types.h ../include/errno.h \
-  ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \
-  ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h ../include/linux/kernel.h \
-  ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \
-  ../include/linux/stat.h ../include/asm/system.h ../include/asm/segment.h ../include/sys/socket.h \
-  ../include/fcntl.h ../include/termios.h kern_sock.h socketcall.h 
-unix.o : unix.c ../include/signal.h ../include/sys/types.h ../include/errno.h \
-  ../include/linux/string.h ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
-  ../include/sys/dirent.h ../include/limits.h ../include/sys/vfs.h ../include/linux/mm.h \
-  ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \
-  ../include/sys/resource.h ../include/linux/stat.h ../include/asm/system.h ../include/asm/segment.h \
-  ../include/sys/socket.h ../include/sys/un.h ../include/fcntl.h ../include/termios.h \
-  kern_sock.h 
+socket.o : socket.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
+  /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
+  /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
+  /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
+  /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/stat.h \
+  /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/socket.h \
+  /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/termios.h kern_sock.h \
+  socketcall.h 
+unix.o : unix.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
+  /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \
+  /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+  /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
+  /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \
+  /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+  /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \
+  /usr/src/linux/include/sys/socket.h /usr/src/linux/include/sys/un.h /usr/src/linux/include/linux/fcntl.h \
+  /usr/src/linux/include/termios.h kern_sock.h 
diff --git a/net/socket.c b/net/socket.c
index b5ba72e..91c9b21 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -6,7 +6,7 @@
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <sys/socket.h>
-#include <fcntl.h>
+#include <linux/fcntl.h>
 #include <termios.h>
 #include "kern_sock.h"
 #include "socketcall.h"
@@ -587,7 +587,7 @@
 		interruptible_sleep_on(sock->wait);
 		if (current->signal & ~current->blocked) {
 			PRINTK("sys_accept: sleep was interrupted\n");
-			return -EINTR;
+			return -ERESTARTSYS;
 		}
 	}
 
diff --git a/net/unix.c b/net/unix.c
index 534a3d4..e9ef7a4 100644
--- a/net/unix.c
+++ b/net/unix.c
@@ -8,7 +8,7 @@
 #include <asm/segment.h>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include <fcntl.h>
+#include <linux/fcntl.h>
 #include <termios.h>
 #include "kern_sock.h"
 
@@ -466,11 +466,11 @@
 	while (!(space = UN_BUF_SPACE(pupd))) {
 		PRINTK("unix_proto_write: no space left...\n");
 		if (nonblock)
-			return 0;
+			return -EAGAIN;
 		interruptible_sleep_on(sock->wait);
 		if (current->signal & ~current->blocked) {
 			PRINTK("unix_proto_write: interrupted\n");
-			return -EINTR;
+			return -ERESTARTSYS;
 		}
 		if (sock->state == SS_DISCONNECTING) {
 			PRINTK("unix_proto_write: disconnected (SIGPIPE)\n");