Whamcloud - gitweb
- unused patches removed
authoralex <alex>
Sun, 5 Oct 2003 11:27:46 +0000 (11:27 +0000)
committeralex <alex>
Sun, 5 Oct 2003 11:27:46 +0000 (11:27 +0000)
lustre/kernel_patches/patches/uml-patch-2.6.0-test3-1.patch [deleted file]
lustre/kernel_patches/pc/uml-patch-2.6.0-test3-1.pc [deleted file]

diff --git a/lustre/kernel_patches/patches/uml-patch-2.6.0-test3-1.patch b/lustre/kernel_patches/patches/uml-patch-2.6.0-test3-1.patch
deleted file mode 100644 (file)
index 8ea5a43..0000000
+++ /dev/null
@@ -1,8716 +0,0 @@
-diff -Naur a/arch/um/Kconfig b/arch/um/Kconfig
---- a/arch/um/Kconfig  Fri Aug 15 15:05:57 2003
-+++ b/arch/um/Kconfig  Fri Aug 15 15:11:53 2003
-@@ -61,6 +61,20 @@
- config NET
-       bool "Networking support"
-+      help
-+      Unless you really know what you are doing, you should say Y here.
-+      The reason is that some programs need kernel networking support even
-+      when running on a stand-alone machine that isn't connected to any
-+      other computer. If you are upgrading from an older kernel, you
-+      should consider updating your networking tools too because changes
-+      in the kernel and the tools often go hand in hand. The tools are
-+      contained in the package net-tools, the location and version number
-+      of which are given in Documentation/Changes.
-+
-+      For a general introduction to Linux networking, it is highly
-+      recommended to read the NET-HOWTO, available from
-+      <http://www.tldp.org/docs.html#howto>.
-+
- source "fs/Kconfig.binfmt"
-@@ -85,6 +99,19 @@
-         If you'd like to be able to work with files stored on the host, 
-         say Y or M here; otherwise say N.
-+config HPPFS
-+      tristate "HoneyPot ProcFS"
-+      help
-+      hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 
-+      entries to be overridden, removed, or fabricated from the host.
-+      Its purpose is to allow a UML to appear to be a physical machine
-+      by removing or changing anything in /proc which gives away the
-+      identity of a UML.
-+
-+      See http://user-mode-linux.sf.net/hppfs.html for more information.
-+
-+      You only need this if you are setting up a UML honeypot.  Otherwise,
-+      it is safe to say 'N' here.
- config MCONSOLE
-       bool "Management console"
-@@ -105,6 +132,16 @@
- config MAGIC_SYSRQ
-       bool "Magic SysRq key"
-       depends on MCONSOLE
-+      help
-+      If you say Y here, you will have some control over the system even
-+      if the system crashes for example during kernel debugging (e.g., you
-+      will be able to flush the buffer cache to disk, reboot the system
-+      immediately or dump some status information). This is accomplished
-+      by pressing various keys while holding SysRq (Alt+PrintScreen). It
-+      also works on a serial console (on PC hardware at least), if you
-+      send a BREAK and then within 5 seconds a command keypress. The
-+      keys are documented in Documentation/sysrq.txt. Don't say Y
-+      unless you really know what this hack does.
- config HOST_2G_2G
-       bool "2G/2G host address space split"
-@@ -159,6 +196,9 @@
- config HIGHMEM
-       bool "Highmem support"
-+config PROC_MM
-+      bool "/proc/mm support"
-+
- config KERNEL_STACK_ORDER
-       int "Kernel stack size order"
-       default 2
-@@ -239,6 +279,10 @@
- config PT_PROXY
-       bool "Enable ptrace proxy"
-       depends on XTERM_CHAN && DEBUG_INFO
-+      help
-+      This option enables a debugging interface which allows gdb to debug
-+      the kernel without needing to actually attach to kernel threads.
-+      If you want to do kernel debugging, say Y here; otherwise say N.
- config GPROF
-       bool "Enable gprof support"
-diff -Naur a/arch/um/Kconfig_block b/arch/um/Kconfig_block
---- a/arch/um/Kconfig_block    Fri Aug 15 15:07:32 2003
-+++ b/arch/um/Kconfig_block    Fri Aug 15 15:12:56 2003
-@@ -29,6 +29,20 @@
-         wise choice too.  In all other cases (for example, if you're just
-         playing around with User-Mode Linux) you can choose N.
-+# Turn this back on when the driver actually works
-+#
-+#config BLK_DEV_COW
-+#     tristate "COW block device"
-+#     help
-+#     This is a layered driver which sits above two other block devices.
-+#     One is read-only, and the other is a read-write layer which stores
-+#     all changes.  This provides the illusion that the read-only layer
-+#     can be mounted read-write and changed.
-+
-+config BLK_DEV_COW_COMMON
-+      bool
-+      default BLK_DEV_COW || BLK_DEV_UBD
-+
- config BLK_DEV_LOOP
-       tristate "Loopback device support"
-diff -Naur a/arch/um/Kconfig_net b/arch/um/Kconfig_net
---- a/arch/um/Kconfig_net      Fri Aug 15 15:06:52 2003
-+++ b/arch/um/Kconfig_net      Fri Aug 15 15:12:43 2003
-@@ -1,5 +1,5 @@
--menu "Network Devices"
-+menu "UML Network Devices"
-       depends on NET
- # UML virtual driver
-@@ -176,73 +176,5 @@
-       
-         Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
--
--# Below are hardware-independent drivers mirrored from
--# drivers/net/Config.in. It would be nice if Linux
--# had HW independent drivers separated from the other
--# but it does not. Until then each non-ISA/PCI arch
--# needs to provide it's own menu of network drivers
--config DUMMY
--      tristate "Dummy net driver support"
--
--config BONDING
--      tristate "Bonding driver support"
--
--config EQUALIZER
--      tristate "EQL (serial line load balancing) support"
--
--config TUN
--      tristate "Universal TUN/TAP device driver support"
--
--config ETHERTAP
--      tristate "Ethertap network tap (OBSOLETE)"
--      depends on EXPERIMENTAL && NETLINK
--
--config PPP
--      tristate "PPP (point-to-point protocol) support"
--
--config PPP_MULTILINK
--      bool "PPP multilink support (EXPERIMENTAL)"
--      depends on PPP && EXPERIMENTAL
--
--config PPP_FILTER
--      bool "PPP filtering"
--      depends on PPP && FILTER
--
--config PPP_ASYNC
--      tristate "PPP support for async serial ports"
--      depends on PPP
--
--config PPP_SYNC_TTY
--      tristate "PPP support for sync tty ports"
--      depends on PPP
--
--config PPP_DEFLATE
--      tristate "PPP Deflate compression"
--      depends on PPP
--
--config PPP_BSDCOMP
--      tristate "PPP BSD-Compress compression"
--      depends on PPP
--
--config PPPOE
--      tristate "PPP over Ethernet (EXPERIMENTAL)"
--      depends on PPP && EXPERIMENTAL
--
--config SLIP
--      tristate "SLIP (serial line) support"
--
--config SLIP_COMPRESSED
--      bool "CSLIP compressed headers"
--      depends on SLIP=y
--
--config SLIP_SMART
--      bool "Keepalive and linefill"
--      depends on SLIP=y
--
--config SLIP_MODE_SLIP6
--      bool "Six bit SLIP encapsulation"
--      depends on SLIP=y
--
- endmenu
-diff -Naur a/arch/um/Makefile b/arch/um/Makefile
---- a/arch/um/Makefile Fri Aug 15 15:07:18 2003
-+++ b/arch/um/Makefile Fri Aug 15 15:12:45 2003
-@@ -24,15 +24,17 @@
- # Have to precede the include because the included Makefiles reference them.
- SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
-       include/asm-um/sigcontext.h include/asm-um/processor.h \
--      include/asm-um/ptrace.h include/asm-um/arch-signal.h
-+      include/asm-um/ptrace.h include/asm-um/arch-signal.h \
-+      include/asm-um/module.h
- ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
-       $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
- GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
--include $(ARCH_DIR)/Makefile-$(SUBARCH)
--include $(ARCH_DIR)/Makefile-os-$(OS)
-+.PHONY: sys_prepare
-+sys_prepare:
-+      @:
- MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
- MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
-@@ -41,6 +43,9 @@
-   include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
- endif
-+include $(ARCH_DIR)/Makefile-$(SUBARCH)
-+include $(ARCH_DIR)/Makefile-os-$(OS)
-+
- EXTRAVERSION := $(EXTRAVERSION)-1um
- ARCH_INCLUDE = -I$(ARCH_DIR)/include
-@@ -52,14 +57,14 @@
- CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
-       -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
--      $(MODE_INCLUDE)
-+      -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
- LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
- SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
- ifeq ($(CONFIG_MODE_SKAS), y)
--$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
-+$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
- endif
- include/linux/version.h: arch/$(ARCH)/Makefile
-@@ -116,6 +121,7 @@
- USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
- USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
-+USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
- USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-       $(MODE_INCLUDE)
-@@ -123,9 +129,10 @@
- USER_CFLAGS += -D_GNU_SOURCE
- CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
--      $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
-+      $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
-+      $(GEN_HEADERS)
--$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
-+$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
-       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
- archmrproper:
-@@ -161,19 +168,23 @@
- $(ARCH_DIR)/os:
-       cd $(ARCH_DIR) && ln -sf os-$(OS) os
--$(ARCH_DIR)/include/uml-config.h :
-+$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
-       sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
-+filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
-+
- $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
--      $< > $@
-+      $(call filechk,$@)
-+
-+filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
- $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
--      $< > $@
-+      $(call filechk,$@)
--$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
--      $(ARCH_DIR)/util FORCE ;
-+$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
-+      sys_prepare FORCE ;
- $(ARCH_DIR)/util: FORCE
--      @$(call descend,$@,)
-+      $(MAKE) -f scripts/Makefile.build obj=$@
--export SUBARCH USER_CFLAGS OS
-+export SUBARCH USER_CFLAGS OS 
-diff -Naur a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
---- a/arch/um/Makefile-i386    Fri Aug 15 15:07:46 2003
-+++ b/arch/um/Makefile-i386    Fri Aug 15 15:13:14 2003
-@@ -16,22 +16,28 @@
- SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
-+sys_prepare: $(SYS_DIR)/sc.h
-+
- prepare: $(SYS_HEADERS)
-+filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
-+
- $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
--      $< > $@
-+      $(call filechk,$@)
-+
-+filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread 
- $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
--      $< > $@
-+      $(call filechk,$@)
--$(SYS_UTIL_DIR)/mk_sc: FORCE ; 
--      @$(call descend,$(SYS_UTIL_DIR),$@)
-+$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ; 
-+      +@$(call descend,$(SYS_UTIL_DIR),$@)
--$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ; 
--      @$(call descend,$(SYS_UTIL_DIR),$@)
-+$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ; 
-+      +@$(call descend,$(SYS_UTIL_DIR),$@)
- $(SYS_UTIL_DIR): include/asm FORCE
--      @$(call descend,$@,)
-+      +@$(call descend,$@,)
- sysclean :
-       rm -f $(SYS_HEADERS)
-diff -Naur a/arch/um/Makefile-skas b/arch/um/Makefile-skas
---- a/arch/um/Makefile-skas    Fri Aug 15 15:05:43 2003
-+++ b/arch/um/Makefile-skas    Fri Aug 15 15:11:52 2003
-@@ -14,7 +14,7 @@
- LINK_SKAS = -Wl,-rpath,/lib 
- LD_SCRIPT_SKAS = dyn.lds.s
--GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
-+GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
--$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
--      $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
-+$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
-+      $(call descend,$(ARCH_DIR)/kernel/skas,$@)
-diff -Naur a/arch/um/config.release b/arch/um/config.release
---- a/arch/um/config.release   Fri Aug 15 15:09:05 2003
-+++ b/arch/um/config.release   Fri Aug 15 15:13:48 2003
-@@ -228,7 +228,6 @@
- CONFIG_EXT2_FS=y
- CONFIG_SYSV_FS=m
- CONFIG_UDF_FS=m
--# CONFIG_UDF_RW is not set
- CONFIG_UFS_FS=m
- # CONFIG_UFS_FS_WRITE is not set
-diff -Naur a/arch/um/defconfig b/arch/um/defconfig
---- a/arch/um/defconfig        Fri Aug 15 15:07:30 2003
-+++ b/arch/um/defconfig        Fri Aug 15 15:12:54 2003
-@@ -6,7 +6,6 @@
- CONFIG_SWAP=y
- CONFIG_UID16=y
- CONFIG_RWSEM_GENERIC_SPINLOCK=y
--CONFIG_CONFIG_LOG_BUF_SHIFT=14
- #
- # Code maturity level options
-@@ -116,7 +115,6 @@
- CONFIG_PACKET_MMAP=y
- # CONFIG_NETLINK_DEV is not set
- # CONFIG_NETFILTER is not set
--# CONFIG_FILTER is not set
- CONFIG_UNIX=y
- # CONFIG_NET_KEY is not set
- CONFIG_INET=y
-@@ -385,7 +383,6 @@
- #
- # Disk-On-Chip Device Drivers
- #
--# CONFIG_MTD_DOC1000 is not set
- # CONFIG_MTD_DOC2000 is not set
- # CONFIG_MTD_DOC2001 is not set
-diff -Naur a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
---- a/arch/um/drivers/Makefile Fri Aug 15 15:06:42 2003
-+++ b/arch/um/drivers/Makefile Fri Aug 15 15:12:40 2003
-@@ -1,5 +1,5 @@
- # 
--# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
-+# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
- # Licensed under the GPL
- #
-@@ -39,6 +39,8 @@
- obj-$(CONFIG_TTY_CHAN) += tty.o 
- obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
- obj-$(CONFIG_UML_WATCHDOG) += harddog.o
-+obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
-+obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
- obj-y += stdio_console.o $(CHAN_OBJS)
-@@ -46,7 +48,7 @@
- USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
-       null.o pty.o tty.o xterm.o
--USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
-+USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
- $(USER_OBJS) : %.o: %.c
-       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
-diff -Naur a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
---- a/arch/um/drivers/chan_kern.c      Fri Aug 15 15:09:13 2003
-+++ b/arch/um/drivers/chan_kern.c      Fri Aug 15 15:13:51 2003
-@@ -8,6 +8,7 @@
- #include <linux/list.h>
- #include <linux/slab.h>
- #include <linux/tty.h>
-+#include <linux/string.h>
- #include <linux/tty_flip.h>
- #include <asm/irq.h>
- #include "chan_kern.h"
-diff -Naur a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
---- a/arch/um/drivers/chan_user.c      Fri Aug 15 15:03:46 2003
-+++ b/arch/um/drivers/chan_user.c      Fri Aug 15 15:10:09 2003
-@@ -188,8 +188,8 @@
-       if(!isatty(fd)) return;
-       pid = tcgetpgrp(fd);
--      if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
--         (pid == -1)){
-+      if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
-+                           device_data) && (pid == -1)){
-               thread = winch_tramp(fd, device_data, &thread_fd);
-               if(fd != -1){
-                       register_winch_irq(thread_fd, fd, thread, device_data);
-diff -Naur a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
---- a/arch/um/drivers/cow.h    Wed Dec 31 19:00:00 1969
-+++ b/arch/um/drivers/cow.h    Fri Aug 15 15:10:34 2003
-@@ -0,0 +1,40 @@
-+#ifndef __COW_H__
-+#define __COW_H__
-+
-+#include <asm/types.h>
-+
-+#if __BYTE_ORDER == __BIG_ENDIAN
-+# define ntohll(x) (x)
-+# define htonll(x) (x)
-+#elif __BYTE_ORDER == __LITTLE_ENDIAN
-+# define ntohll(x)  bswap_64(x)
-+# define htonll(x)  bswap_64(x)
-+#else
-+#error "__BYTE_ORDER not defined"
-+#endif
-+
-+extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
-+                       int sectorsize, int *bitmap_offset_out, 
-+                       unsigned long *bitmap_len_out, int *data_offset_out);
-+
-+extern int file_reader(__u64 offset, char *buf, int len, void *arg);
-+extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
-+                         void *arg, __u32 *magic_out, 
-+                         char **backing_file_out, time_t *mtime_out, 
-+                         __u64 *size_out, int *sectorsize_out, 
-+                         int *bitmap_offset_out);
-+
-+extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
-+                          int sectorsize, long long *size);
-+
-+extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
-+                    unsigned long *bitmap_len_out, int *data_offset_out);
-+
-+#endif
-+
-+/*
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/arch/um/drivers/cow_kern.c b/arch/um/drivers/cow_kern.c
---- a/arch/um/drivers/cow_kern.c       Wed Dec 31 19:00:00 1969
-+++ b/arch/um/drivers/cow_kern.c       Fri Aug 15 15:13:51 2003
-@@ -0,0 +1,628 @@
-+#define COW_MAJOR 60
-+#define MAJOR_NR COW_MAJOR
-+
-+#include <linux/stddef.h>
-+#include <linux/kernel.h>
-+#include <linux/ctype.h>
-+#include <linux/stat.h>
-+#include <linux/vmalloc.h>
-+#include <linux/blkdev.h>
-+#include <linux/blk.h>
-+#include <linux/fs.h>
-+#include <linux/genhd.h>
-+#include <linux/devfs_fs.h>
-+#include <asm/uaccess.h>
-+#include "2_5compat.h"
-+#include "cow.h"
-+#include "ubd_user.h"
-+
-+#define COW_SHIFT 4
-+
-+struct cow {
-+      int count;
-+      char *cow_path;
-+      dev_t cow_dev;
-+      struct block_device *cow_bdev;
-+      char *backing_path;
-+      dev_t backing_dev;
-+      struct block_device *backing_bdev;
-+      int sectorsize;
-+      unsigned long *bitmap;
-+      unsigned long bitmap_len;
-+      int bitmap_offset;
-+      int data_offset;
-+      devfs_handle_t devfs;
-+      struct semaphore sem;
-+      struct semaphore io_sem;
-+      atomic_t working;
-+      spinlock_t io_lock;
-+      struct buffer_head *bh;
-+      struct buffer_head *bhtail;
-+      void *end_io;
-+};
-+
-+#define DEFAULT_COW { \
-+      .count                  = 0, \
-+      .cow_path               = NULL, \
-+      .cow_dev                = 0, \
-+      .backing_path           = NULL, \
-+      .backing_dev            = 0, \
-+        .bitmap                       = NULL, \
-+      .bitmap_len             = 0, \
-+      .bitmap_offset          = 0, \
-+        .data_offset          = 0, \
-+      .devfs                  = NULL, \
-+      .working                = ATOMIC_INIT(0), \
-+      .io_lock                = SPIN_LOCK_UNLOCKED, \
-+}
-+
-+#define MAX_DEV (8)
-+#define MAX_MINOR (MAX_DEV << COW_SHIFT)
-+
-+struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
-+
-+/* Not modified by this driver */
-+static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
-+static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
-+
-+/* Protected by cow_lock */
-+static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
-+
-+static struct hd_struct       cow_part[MAX_MINOR] =
-+      { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
-+
-+/* Protected by io_request_lock */
-+static request_queue_t *cow_queue;
-+
-+static int cow_open(struct inode *inode, struct file *filp);
-+static int cow_release(struct inode * inode, struct file * file);
-+static int cow_ioctl(struct inode * inode, struct file * file,
-+                   unsigned int cmd, unsigned long arg);
-+static int cow_revalidate(kdev_t rdev);
-+
-+static struct block_device_operations cow_blops = {
-+       .open          = cow_open,
-+       .release       = cow_release,
-+       .ioctl         = cow_ioctl,
-+       .revalidate    = cow_revalidate,
-+};
-+
-+/* Initialized in an initcall, and unchanged thereafter */
-+devfs_handle_t cow_dir_handle;
-+
-+#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
-+{ \
-+      .major          = maj, \
-+      .major_name     = name, \
-+      .minor_shift    = shift, \
-+      .max_p          = 1 << shift, \
-+      .part           = parts, \
-+      .sizes          = bsizes, \
-+      .nr_real        = max, \
-+      .real_devices   = NULL, \
-+      .next           = NULL, \
-+      .fops           = blops, \
-+      .de_arr         = NULL, \
-+      .flags          = 0 \
-+}
-+
-+static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
-+
-+static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
-+                                               COW_SHIFT, sizes, MAX_DEV, 
-+                                               &cow_blops);
-+
-+static int cow_add(int n)
-+{
-+      struct cow *dev = &cow_dev[n];
-+      char name[sizeof("nnnnnn\0")];
-+      int err = -ENODEV;
-+
-+      if(dev->cow_path == NULL)
-+              goto out;
-+
-+      sprintf(name, "%d", n);
-+      dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
-+                                  MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
-+                                  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-+                                  &cow_blops, NULL);
-+
-+      init_MUTEX_LOCKED(&dev->sem);
-+      init_MUTEX(&dev->io_sem);
-+
-+      return(0);
-+
-+out:
-+      return(err);
-+}
-+
-+/*
-+* Add buffer_head to back of pending list
-+*/
-+static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&cow->io_lock, flags);
-+      if(cow->bhtail != NULL){
-+              cow->bhtail->b_reqnext = bh;
-+              cow->bhtail = bh;
-+      }
-+      else {
-+              cow->bh = bh;
-+              cow->bhtail = bh;
-+      }
-+      spin_unlock_irqrestore(&cow->io_lock, flags);
-+}
-+
-+/*
-+* Grab first pending buffer
-+*/
-+static struct buffer_head *cow_get_bh(struct cow *cow)
-+{
-+      struct buffer_head *bh;
-+
-+      spin_lock_irq(&cow->io_lock);
-+      bh = cow->bh;
-+      if(bh != NULL){
-+              if(bh == cow->bhtail)
-+                      cow->bhtail = NULL;
-+              cow->bh = bh->b_reqnext;
-+              bh->b_reqnext = NULL;
-+      }
-+      spin_unlock_irq(&cow->io_lock);
-+
-+      return(bh);
-+}
-+
-+static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
-+                        struct buffer_head **cow_bh, int ncow_bh)
-+{
-+      int i;
-+
-+      if(ncow_bh > 0)
-+              ll_rw_block(WRITE, ncow_bh, cow_bh);
-+
-+      for(i = 0; i < ncow_bh ; i++){
-+              wait_on_buffer(cow_bh[i]);
-+              brelse(cow_bh[i]);
-+      }
-+
-+      ll_rw_block(WRITE, 1, &bh);
-+      brelse(bh);
-+}
-+
-+static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
-+{
-+      struct buffer_head *bh;
-+
-+      sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
-+      bh = getblk(dev->cow_dev, sector, dev->sectorsize);
-+      memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
-+             dev->sectorsize);
-+      return(bh);
-+}
-+
-+/* Copied from loop.c, needed to avoid deadlocking in make_request. */
-+
-+static int cow_thread(void *data)
-+{
-+      struct cow *dev = data;
-+      struct buffer_head *bh;
-+
-+      daemonize();
-+      exit_files(current);
-+
-+      sprintf(current->comm, "cow%d", dev - cow_dev);
-+
-+      spin_lock_irq(&current->sigmask_lock);
-+      sigfillset(&current->blocked);
-+      flush_signals(current);
-+      spin_unlock_irq(&current->sigmask_lock);
-+
-+      atomic_inc(&dev->working);
-+
-+      current->policy = SCHED_OTHER;
-+      current->nice = -20;
-+
-+      current->flags |= PF_NOIO;
-+
-+      /*
-+       * up sem, we are running
-+       */
-+      up(&dev->sem);
-+
-+      for(;;){
-+              int start, len, nbh, i, update_bitmap = 0;
-+              struct buffer_head *cow_bh[2];
-+
-+              down_interruptible(&dev->io_sem);
-+              /*
-+               * could be upped because of tear-down, not because of
-+               * pending work
-+               */
-+              if(!atomic_read(&dev->working))
-+                      break;
-+
-+              bh = cow_get_bh(dev);
-+              if(bh == NULL){
-+                      printk(KERN_ERR "cow: missing bh\n");
-+                      continue;
-+              }
-+
-+              start = bh->b_blocknr * bh->b_size / dev->sectorsize;
-+              len = bh->b_size / dev->sectorsize;
-+              for(i = 0; i < len ; i++){
-+                      if(ubd_test_bit(start +ni, 
-+                                      (unsigned char *) dev->bitmap))
-+                              continue;
-+
-+                      update_bitmap = 1;
-+                      ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
-+              }
-+
-+              cow_bh[0] = NULL;
-+              cow_bh[1] = NULL;
-+              nbh = 0;
-+              if(update_bitmap){
-+                      cow_bh[0] = cow_new_bh(dev, start);
-+                      nbh++;
-+                      if(start / dev->sectorsize != 
-+                         (start + len) / dev->sectorsize){
-+                              cow_bh[1] = cow_new_bh(dev, start + len);
-+                              nbh++;
-+                      }
-+              }
-+              
-+              bh->b_dev = dev->cow_dev;
-+              bh->b_blocknr += dev->data_offset / dev->sectorsize;
-+
-+              cow_handle_bh(dev, bh, cow_bh, nbh);
-+
-+              /*
-+               * upped both for pending work and tear-down, lo_pending
-+               * will hit zero then
-+               */
-+              if(atomic_dec_and_test(&dev->working))
-+                      break;
-+      }
-+
-+      up(&dev->sem);
-+      return(0);
-+}
-+
-+static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
-+{
-+      struct cow *dev;
-+      int n, minor;
-+
-+      minor = MINOR(bh->b_rdev);
-+      n = minor >> COW_SHIFT;
-+      dev = &cow_dev[n];
-+
-+      dev->end_io = NULL;
-+      if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
-+              bh->b_rdev = dev->cow_dev;
-+              bh->b_rsector += dev->data_offset / dev->sectorsize;
-+      }
-+      else if(rw == WRITE){
-+              bh->b_dev = dev->cow_dev;
-+              bh->b_blocknr += dev->data_offset / dev->sectorsize;
-+
-+              cow_add_bh(dev, bh);
-+              up(&dev->io_sem);
-+              return(0);
-+      }
-+      else {
-+              bh->b_rdev = dev->backing_dev;
-+      }
-+
-+      return(1);
-+}
-+
-+int cow_init(void)
-+{
-+      int i;
-+
-+      cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
-+      if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
-+              printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
-+              return -1;
-+      }
-+      read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
-+      blksize_size[MAJOR_NR] = blk_sizes;
-+      blk_size[MAJOR_NR] = sizes;
-+      INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
-+
-+      cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
-+      blk_init_queue(cow_queue, NULL);
-+      INIT_ELV(cow_queue, &cow_queue->elevator);
-+      blk_queue_make_request(cow_queue, cow_make_request);
-+
-+       add_gendisk(&cow_gendisk);
-+
-+      for(i=0;i<MAX_DEV;i++) 
-+              cow_add(i);
-+
-+      return(0);
-+}
-+
-+__initcall(cow_init);
-+
-+static int reader(__u64 start, char *buf, int count, void *arg)
-+{
-+      dev_t dev = *((dev_t *) arg);
-+      struct buffer_head *bh;
-+      __u64 block;
-+      int cur, offset, left, n, blocksize = get_hardsect_size(dev);
-+
-+      if(blocksize == 0)
-+              panic("Zero blocksize");
-+
-+      block = start / blocksize;
-+      offset = start % blocksize;
-+      left = count;
-+      cur = 0;
-+      while(left > 0){
-+              n = (left > blocksize) ? blocksize : left;
-+
-+              bh = bread(dev, block, (n < 512) ? 512 : n);
-+              if(bh == NULL)
-+                      return(-EIO);
-+
-+              n -= offset;
-+              memcpy(&buf[cur], bh->b_data + offset, n);
-+              block++;
-+              left -= n;
-+              cur += n;
-+              offset = 0;
-+              brelse(bh);
-+      }
-+
-+      return(count);
-+}
-+
-+static int cow_open(struct inode *inode, struct file *filp)
-+{
-+      int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
-+                       unsigned long);
-+      mm_segment_t fs;
-+      struct cow *dev;
-+      __u64 size;
-+      __u32 magic;
-+      time_t mtime;
-+      char *backing_file;
-+      int n, offset, err = 0;
-+
-+      n = DEVICE_NR(inode->i_rdev);
-+      if(n >= MAX_DEV)
-+              return(-ENODEV);
-+      dev = &cow_dev[n];
-+      offset = n << COW_SHIFT;
-+
-+      spin_lock(&cow_lock);
-+
-+      if(dev->count == 0){
-+              dev->cow_dev = name_to_kdev_t(dev->cow_path);
-+              if(dev->cow_dev == 0){
-+                      printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
-+                             "failed\n", dev->cow_path);
-+                      err = -ENODEV;
-+              }
-+
-+              dev->backing_dev = name_to_kdev_t(dev->backing_path);
-+              if(dev->backing_dev == 0){
-+                      printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
-+                             "failed\n", dev->backing_path);
-+                      err = -ENODEV;
-+              }
-+
-+              if(err) 
-+                      goto out;
-+
-+              dev->cow_bdev = bdget(dev->cow_dev);
-+              if(dev->cow_bdev == NULL){
-+                      printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
-+                             dev->cow_path);
-+                      err = -ENOMEM;
-+              }
-+              dev->backing_bdev = bdget(dev->backing_dev);
-+              if(dev->backing_bdev == NULL){
-+                      printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
-+                             dev->backing_path);
-+                      err = -ENOMEM;
-+              }
-+
-+              if(err) 
-+                      goto out;
-+
-+              err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
-+                               BDEV_RAW);
-+              if(err){
-+                      printk("cow_open - blkdev_get of COW device failed, "
-+                             "error = %d\n", err);
-+                      goto out;
-+              }
-+              
-+              err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
-+              if(err){
-+                      printk("cow_open - blkdev_get of backing device "
-+                             "failed, error = %d\n", err);
-+                      goto out;
-+              }
-+              
-+              err = read_cow_header(reader, &dev->cow_dev, &magic, 
-+                                    &backing_file, &mtime, &size,
-+                                    &dev->sectorsize, &dev->bitmap_offset);
-+              if(err){
-+                      printk(KERN_ERR "cow_open - read_cow_header failed, "
-+                             "err = %d\n", err);
-+                      goto out;
-+              }
-+
-+              cow_sizes(size, dev->sectorsize, dev->bitmap_offset, 
-+                        &dev->bitmap_len, &dev->data_offset);
-+              dev->bitmap = (void *) vmalloc(dev->bitmap_len);
-+              if(dev->bitmap == NULL){
-+                      err = -ENOMEM;
-+                      printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
-+                      goto out;
-+              }
-+              flush_tlb_kernel_vm();
-+              
-+              err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
-+                           dev->bitmap_len, &dev->cow_dev);
-+              if(err < 0){
-+                      printk(KERN_ERR "Failed to read COW bitmap\n");
-+                      vfree(dev->bitmap);
-+                      goto out;
-+              }
-+
-+              dev_ioctl = dev->backing_bdev->bd_op->ioctl;
-+              fs = get_fs();
-+              set_fs(KERNEL_DS);
-+              err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
-+                                 (unsigned long) &sizes[offset]);
-+              set_fs(fs);
-+              if(err){
-+                      printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
-+                             "error = %d\n", err);
-+                      goto out;
-+              }
-+
-+              kernel_thread(cow_thread, dev, 
-+                            CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+              down(&dev->sem);
-+      }
-+      dev->count++;
-+out:
-+      spin_unlock(&cow_lock);
-+      return(err);
-+}
-+
-+static int cow_release(struct inode * inode, struct file * file)
-+{
-+      struct cow *dev;
-+      int n, err;
-+
-+      n = DEVICE_NR(inode->i_rdev);
-+      if(n >= MAX_DEV)
-+              return(-ENODEV);
-+      dev = &cow_dev[n];
-+
-+      spin_lock(&cow_lock);
-+
-+      if(--dev->count > 0)
-+              goto out;
-+
-+      err = blkdev_put(dev->cow_bdev, BDEV_RAW);
-+      if(err)
-+              printk("cow_release - blkdev_put of cow device failed, "
-+                     "error = %d\n", err);
-+      bdput(dev->cow_bdev);
-+      dev->cow_bdev = 0;
-+
-+      err = blkdev_put(dev->backing_bdev, BDEV_RAW);
-+      if(err)
-+              printk("cow_release - blkdev_put of backing device failed, "
-+                     "error = %d\n", err);
-+      bdput(dev->backing_bdev);
-+      dev->backing_bdev = 0;
-+
-+out:
-+      spin_unlock(&cow_lock);
-+      return(0);
-+}
-+
-+static int cow_ioctl(struct inode * inode, struct file * file,
-+                   unsigned int cmd, unsigned long arg)
-+{
-+      struct cow *dev;
-+      int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
-+                       unsigned long);
-+      int n;
-+
-+      n = DEVICE_NR(inode->i_rdev);
-+      if(n >= MAX_DEV)
-+              return(-ENODEV);
-+      dev = &cow_dev[n];
-+
-+      dev_ioctl = dev->backing_bdev->bd_op->ioctl;
-+      return((*dev_ioctl)(inode, file, cmd, arg));
-+}
-+
-+static int cow_revalidate(kdev_t rdev)
-+{
-+      printk(KERN_ERR "Need to implement cow_revalidate\n");
-+      return(0);
-+}
-+
-+static int parse_unit(char **ptr)
-+{
-+      char *str = *ptr, *end;
-+      int n = -1;
-+
-+      if(isdigit(*str)) {
-+              n = simple_strtoul(str, &end, 0);
-+              if(end == str)
-+                      return(-1);
-+              *ptr = end;
-+      }
-+      else if (('a' <= *str) && (*str <= 'h')) {
-+              n = *str - 'a';
-+              str++;
-+              *ptr = str;
-+      }
-+      return(n);
-+}
-+
-+static int cow_setup(char *str)
-+{
-+      struct cow *dev;
-+      char *cow_name, *backing_name;
-+      int unit;
-+
-+      unit = parse_unit(&str);
-+      if(unit < 0){
-+              printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
-+              return(1);
-+      }
-+
-+      if(*str != '='){
-+              printk(KERN_ERR "cow_setup - Missing '=' after unit "
-+                     "number\n");
-+              return(1);
-+      }
-+      str++;
-+
-+      cow_name = str;
-+      backing_name = strchr(str, ',');
-+      if(backing_name == NULL){
-+              printk(KERN_ERR "cow_setup - missing backing device name\n");
-+              return(0);
-+      }
-+      *backing_name = '\0';
-+      backing_name++;
-+
-+      spin_lock(&cow_lock);
-+
-+      dev = &cow_dev[unit];
-+      dev->cow_path = cow_name;
-+      dev->backing_path = backing_name;
-+      
-+      spin_unlock(&cow_lock);
-+      return(0);
-+}
-+
-+__setup("cow", cow_setup);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
---- a/arch/um/drivers/cow_sys.h        Wed Dec 31 19:00:00 1969
-+++ b/arch/um/drivers/cow_sys.h        Fri Aug 15 15:12:37 2003
-@@ -0,0 +1,48 @@
-+#ifndef __COW_SYS_H__
-+#define __COW_SYS_H__
-+
-+#include "kern_util.h"
-+#include "user_util.h"
-+#include "os.h"
-+#include "user.h"
-+
-+static inline void *cow_malloc(int size)
-+{
-+      return(um_kmalloc(size));
-+}
-+
-+static inline void cow_free(void *ptr)
-+{
-+      kfree(ptr);
-+}
-+
-+#define cow_printf printk
-+
-+static inline char *cow_strdup(char *str)
-+{
-+      return(uml_strdup(str));
-+}
-+
-+static inline int cow_seek_file(int fd, __u64 offset)
-+{
-+      return(os_seek_file(fd, offset));
-+}
-+
-+static inline int cow_file_size(char *file, __u64 *size_out)
-+{
-+      return(os_file_size(file, size_out));
-+}
-+
-+static inline int cow_write_file(int fd, char *buf, int size)
-+{
-+      return(os_write_file(fd, buf, size));
-+}
-+
-+#endif
-+
-+/*
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
---- a/arch/um/drivers/cow_user.c       Wed Dec 31 19:00:00 1969
-+++ b/arch/um/drivers/cow_user.c       Fri Aug 15 15:12:34 2003
-@@ -0,0 +1,296 @@
-+#include <stddef.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <byteswap.h>
-+#include <sys/stat.h>
-+#include <sys/time.h>
-+#include <sys/param.h>
-+#include <netinet/in.h>
-+
-+#include "cow.h"
-+#include "cow_sys.h"
-+
-+#define PATH_LEN_V1 256
-+
-+struct cow_header_v1 {
-+      int magic;
-+      int version;
-+      char backing_file[PATH_LEN_V1];
-+      time_t mtime;
-+      __u64 size;
-+      int sectorsize;
-+};
-+
-+#define PATH_LEN_V2 MAXPATHLEN
-+
-+struct cow_header_v2 {
-+      unsigned long magic;
-+      unsigned long version;
-+      char backing_file[PATH_LEN_V2];
-+      time_t mtime;
-+      __u64 size;
-+      int sectorsize;
-+};
-+
-+union cow_header {
-+      struct cow_header_v1 v1;
-+      struct cow_header_v2 v2;
-+};
-+
-+#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
-+#define COW_VERSION 2
-+
-+void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
-+             unsigned long *bitmap_len_out, int *data_offset_out)
-+{
-+      *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
-+
-+      *data_offset_out = bitmap_offset + *bitmap_len_out;
-+      *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
-+      *data_offset_out *= sectorsize;
-+}
-+
-+static int absolutize(char *to, int size, char *from)
-+{
-+      char save_cwd[256], *slash;
-+      int remaining;
-+
-+      if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
-+              cow_printf("absolutize : unable to get cwd - errno = %d\n", 
-+                         errno);
-+              return(-1);
-+      }
-+      slash = strrchr(from, '/');
-+      if(slash != NULL){
-+              *slash = '\0';
-+              if(chdir(from)){
-+                      *slash = '/';
-+                      cow_printf("absolutize : Can't cd to '%s' - " 
-+                                 "errno = %d\n", from, errno);
-+                      return(-1);
-+              }
-+              *slash = '/';
-+              if(getcwd(to, size) == NULL){
-+                      cow_printf("absolutize : unable to get cwd of '%s' - "
-+                             "errno = %d\n", from, errno);
-+                      return(-1);
-+              }
-+              remaining = size - strlen(to);
-+              if(strlen(slash) + 1 > remaining){
-+                      cow_printf("absolutize : unable to fit '%s' into %d "
-+                             "chars\n", from, size);
-+                      return(-1);
-+              }
-+              strcat(to, slash);
-+      }
-+      else {
-+              if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
-+                      cow_printf("absolutize : unable to fit '%s' into %d "
-+                             "chars\n", from, size);
-+                      return(-1);
-+              }
-+              strcpy(to, save_cwd);
-+              strcat(to, "/");
-+              strcat(to, from);
-+      }
-+      chdir(save_cwd);
-+      return(0);
-+}
-+
-+int write_cow_header(char *cow_file, int fd, char *backing_file, 
-+                   int sectorsize, long long *size)
-+{
-+      struct cow_header_v2 *header;
-+      struct stat64 buf;
-+      int err;
-+
-+      err = cow_seek_file(fd, 0);
-+      if(err != 0){
-+              cow_printf("write_cow_header - lseek failed, errno = %d\n", 
-+                         errno);
-+              return(-errno);
-+      }
-+
-+      err = -ENOMEM;
-+      header = cow_malloc(sizeof(*header));
-+      if(header == NULL){
-+              cow_printf("Failed to allocate COW V2 header\n");
-+              goto out;
-+      }
-+      header->magic = htonl(COW_MAGIC);
-+      header->version = htonl(COW_VERSION);
-+
-+      err = -EINVAL;
-+      if(strlen(backing_file) > sizeof(header->backing_file) - 1){
-+              cow_printf("Backing file name \"%s\" is too long - names are "
-+                         "limited to %d characters\n", backing_file, 
-+                         sizeof(header->backing_file) - 1);
-+              goto out_free;
-+      }
-+
-+      if(absolutize(header->backing_file, sizeof(header->backing_file), 
-+                    backing_file))
-+              goto out_free;
-+
-+      err = stat64(header->backing_file, &buf);
-+      if(err < 0){
-+              cow_printf("Stat of backing file '%s' failed, errno = %d\n",
-+                         header->backing_file, errno);
-+              err = -errno;
-+              goto out_free;
-+      }
-+
-+      err = cow_file_size(header->backing_file, size);
-+      if(err){
-+              cow_printf("Couldn't get size of backing file '%s', "
-+                         "errno = %d\n", header->backing_file, -*size);
-+              goto out_free;
-+      }
-+
-+      header->mtime = htonl(buf.st_mtime);
-+      header->size = htonll(*size);
-+      header->sectorsize = htonl(sectorsize);
-+
-+      err = write(fd, header, sizeof(*header));
-+      if(err != sizeof(*header)){
-+              cow_printf("Write of header to new COW file '%s' failed, "
-+                         "errno = %d\n", cow_file, errno);
-+              goto out_free;
-+      }
-+      err = 0;
-+ out_free:
-+      cow_free(header);
-+ out:
-+      return(err);
-+}
-+
-+int file_reader(__u64 offset, char *buf, int len, void *arg)
-+{
-+      int fd = *((int *) arg);
-+
-+      return(pread(fd, buf, len, offset));
-+}
-+
-+int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
-+                  __u32 *magic_out, char **backing_file_out, 
-+                  time_t *mtime_out, __u64 *size_out, 
-+                  int *sectorsize_out, int *bitmap_offset_out)
-+{
-+      union cow_header *header;
-+      char *file;
-+      int err, n;
-+      unsigned long version, magic;
-+
-+      header = cow_malloc(sizeof(*header));
-+      if(header == NULL){
-+              cow_printf("read_cow_header - Failed to allocate header\n");
-+              return(-ENOMEM);
-+      }
-+      err = -EINVAL;
-+      n = (*reader)(0, (char *) header, sizeof(*header), arg);
-+      if(n < offsetof(typeof(header->v1), backing_file)){
-+              cow_printf("read_cow_header - short header\n");
-+              goto out;
-+      }
-+
-+      magic = header->v1.magic;
-+      if(magic == COW_MAGIC) {
-+              version = header->v1.version;
-+      }
-+      else if(magic == ntohl(COW_MAGIC)){
-+              version = ntohl(header->v1.version);
-+      }
-+      /* No error printed because the non-COW case comes through here */
-+      else goto out;
-+
-+      *magic_out = COW_MAGIC;
-+
-+      if(version == 1){
-+              if(n < sizeof(header->v1)){
-+                      cow_printf("read_cow_header - failed to read V1 "
-+                                 "header\n");
-+                      goto out;
-+              }
-+              *mtime_out = header->v1.mtime;
-+              *size_out = header->v1.size;
-+              *sectorsize_out = header->v1.sectorsize;
-+              *bitmap_offset_out = sizeof(header->v1);
-+              file = header->v1.backing_file;
-+      }
-+      else if(version == 2){
-+              if(n < sizeof(header->v2)){
-+                      cow_printf("read_cow_header - failed to read V2 "
-+                                 "header\n");
-+                      goto out;
-+              }
-+              *mtime_out = ntohl(header->v2.mtime);
-+              *size_out = ntohll(header->v2.size);
-+              *sectorsize_out = ntohl(header->v2.sectorsize);
-+              *bitmap_offset_out = sizeof(header->v2);
-+              file = header->v2.backing_file;
-+      }
-+      else {
-+              cow_printf("read_cow_header - invalid COW version\n");
-+              goto out;
-+      }
-+      err = -ENOMEM;
-+      *backing_file_out = cow_strdup(file);
-+      if(*backing_file_out == NULL){
-+              cow_printf("read_cow_header - failed to allocate backing "
-+                         "file\n");
-+              goto out;
-+      }
-+      err = 0;
-+ out:
-+      cow_free(header);
-+      return(err);
-+}
-+
-+int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
-+                int *bitmap_offset_out, unsigned long *bitmap_len_out, 
-+                int *data_offset_out)
-+{
-+      __u64 size, offset;
-+      char zero = 0;
-+      int err;
-+
-+      err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
-+      if(err) 
-+              goto out;
-+      
-+      cow_sizes(size, sectorsize, sizeof(struct cow_header_v2), 
-+                bitmap_len_out, data_offset_out);
-+      *bitmap_offset_out = sizeof(struct cow_header_v2);
-+
-+      offset = *data_offset_out + size - sizeof(zero);
-+      err = cow_seek_file(fd, offset);
-+      if(err != 0){
-+              cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
-+              goto out;
-+      }
-+
-+      /* does not really matter how much we write it is just to set EOF 
-+       * this also sets the entire COW bitmap
-+       * to zero without having to allocate it 
-+       */
-+      err = cow_write_file(fd, &zero, sizeof(zero));
-+      if(err != sizeof(zero)){
-+              err = -EINVAL;
-+              cow_printf("Write of bitmap to new COW file '%s' failed, "
-+                         "errno = %d\n", cow_file, errno);
-+              goto out;
-+      }
-+
-+      return(0);
-+
-+ out:
-+      return(err);
-+}
-+
-+/*
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
---- a/arch/um/drivers/hostaudio_kern.c Fri Aug 15 15:09:05 2003
-+++ b/arch/um/drivers/hostaudio_kern.c Fri Aug 15 15:13:48 2003
-@@ -11,6 +11,7 @@
- #include "linux/fs.h"
- #include "linux/sound.h"
- #include "linux/soundcard.h"
-+#include "asm/uaccess.h"
- #include "kern_util.h"
- #include "init.h"
- #include "hostaudio.h"
-@@ -22,7 +23,7 @@
- #ifndef MODULE
- static int set_dsp(char *name, int *add)
- {
--      dsp = uml_strdup(name);
-+      dsp = name;
-       return(0);
- }
-@@ -34,7 +35,7 @@
- static int set_mixer(char *name, int *add)
- {
--      mixer = uml_strdup(name);
-+      mixer = name;
-       return(0);
- }
-@@ -51,23 +52,55 @@
-                             loff_t *ppos)
- {
-         struct hostaudio_state *state = file->private_data;
-+      void *kbuf;
-+      int err;
- #ifdef DEBUG
-         printk("hostaudio: read called, count = %d\n", count);
- #endif
--        return(hostaudio_read_user(state, buffer, count, ppos));
-+      kbuf = kmalloc(count, GFP_KERNEL);
-+      if(kbuf == NULL)
-+              return(-ENOMEM);
-+
-+        err = hostaudio_read_user(state, kbuf, count, ppos);
-+      if(err < 0)
-+              goto out;
-+
-+      if(copy_to_user(buffer, kbuf, err))
-+              err = -EFAULT;
-+
-+ out:
-+      kfree(kbuf);
-+      return(err);
- }
- static ssize_t hostaudio_write(struct file *file, const char *buffer, 
-                              size_t count, loff_t *ppos)
- {
-         struct hostaudio_state *state = file->private_data;
-+      void *kbuf;
-+      int err;
- #ifdef DEBUG
-         printk("hostaudio: write called, count = %d\n", count);
- #endif
--        return(hostaudio_write_user(state, buffer, count, ppos));
-+
-+      kbuf = kmalloc(count, GFP_KERNEL);
-+      if(kbuf == NULL)
-+              return(-ENOMEM);
-+
-+      err = -EFAULT;
-+      if(copy_from_user(kbuf, buffer, count))
-+              goto out;
-+
-+        err = hostaudio_write_user(state, kbuf, count, ppos);
-+      if(err < 0)
-+              goto out;
-+
-+ out:
-+      kfree(kbuf);
-+      return(err);
- }
- static unsigned int hostaudio_poll(struct file *file, 
-@@ -86,12 +119,43 @@
-                          unsigned int cmd, unsigned long arg)
- {
-         struct hostaudio_state *state = file->private_data;
-+      unsigned long data = 0;
-+      int err;
- #ifdef DEBUG
-         printk("hostaudio: ioctl called, cmd = %u\n", cmd);
- #endif
-+      switch(cmd){
-+      case SNDCTL_DSP_SPEED:
-+      case SNDCTL_DSP_STEREO:
-+      case SNDCTL_DSP_GETBLKSIZE:
-+      case SNDCTL_DSP_CHANNELS:
-+      case SNDCTL_DSP_SUBDIVIDE:
-+      case SNDCTL_DSP_SETFRAGMENT:
-+              if(get_user(data, (int *) arg))
-+                      return(-EFAULT);
-+              break;
-+      default:
-+              break;
-+      }
-+
-+        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
-+
-+      switch(cmd){
-+      case SNDCTL_DSP_SPEED:
-+      case SNDCTL_DSP_STEREO:
-+      case SNDCTL_DSP_GETBLKSIZE:
-+      case SNDCTL_DSP_CHANNELS:
-+      case SNDCTL_DSP_SUBDIVIDE:
-+      case SNDCTL_DSP_SETFRAGMENT:
-+              if(put_user(data, (int *) arg))
-+                      return(-EFAULT);
-+              break;
-+      default:
-+              break;
-+      }
--        return(hostaudio_ioctl_user(state, cmd, arg));
-+      return(err);
- }
- static int hostaudio_open(struct inode *inode, struct file *file)
-@@ -225,7 +289,8 @@
- static int __init hostaudio_init_module(void)
- {
--        printk(KERN_INFO "UML Audio Relay\n");
-+        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
-+             dsp, mixer);
-       module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
-         if(module_data.dev_audio < 0){
-diff -Naur a/arch/um/drivers/line.c b/arch/um/drivers/line.c
---- a/arch/um/drivers/line.c   Fri Aug 15 15:08:24 2003
-+++ b/arch/um/drivers/line.c   Fri Aug 15 15:13:28 2003
-@@ -6,8 +6,8 @@
- #include "linux/sched.h"
- #include "linux/slab.h"
- #include "linux/list.h"
-+#include "linux/interrupt.h"
- #include "linux/devfs_fs_kernel.h"
--#include "asm/irq.h"
- #include "asm/uaccess.h"
- #include "chan_kern.h"
- #include "irq_user.h"
-@@ -16,16 +16,18 @@
- #include "user_util.h"
- #include "kern_util.h"
- #include "os.h"
-+#include "irq_kern.h"
- #define LINE_BUFSIZE 4096
--void line_interrupt(int irq, void *data, struct pt_regs *unused)
-+irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
- {
-       struct line *dev = data;
-       if(dev->count > 0) 
-               chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
-                              dev);
-+      return IRQ_HANDLED;
- }
- void line_timer_cb(void *arg)
-@@ -136,20 +138,22 @@
-       return(len);
- }
--void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
-+irqreturn_t line_write_interrupt(int irq, void *data, struct pt_regs *unused)
- {
-       struct line *dev = data;
-       struct tty_struct *tty = dev->tty;
-       int err;
-       err = flush_buffer(dev);
--      if(err == 0) return;
-+      if(err == 0) 
-+              return(IRQ_NONE);
-       else if(err < 0){
-               dev->head = dev->buffer;
-               dev->tail = dev->buffer;
-       }
--      if(tty == NULL) return;
-+      if(tty == NULL) 
-+              return(IRQ_NONE);
-       if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
-          (tty->ldisc.write_wakeup != NULL))
-@@ -161,9 +165,9 @@
-        * writes.
-        */
--      if (waitqueue_active(&tty->write_wait))
-+      if(waitqueue_active(&tty->write_wait))
-               wake_up_interruptible(&tty->write_wait);
--
-+      return(IRQ_HANDLED);
- }
- int line_write_room(struct tty_struct *tty)
-@@ -369,7 +373,7 @@
-       dev = simple_strtoul(name, &end, 0);
-       if((*end != '\0') || (end == name)){
--              *error_out = "line_setup failed to parse device number";
-+              *error_out = "line_get_config failed to parse device number";
-               return(0);
-       }
-@@ -379,15 +383,15 @@
-       }
-       line = &lines[dev];
-+
-       down(&line->sem);
--      
-       if(!line->valid)
-               CONFIG_CHUNK(str, size, n, "none", 1);
-       else if(line->count == 0)
-               CONFIG_CHUNK(str, size, n, line->init_str, 1);
-       else n = chan_config_string(&line->chan_list, str, size, error_out);
--
-       up(&line->sem);
-+
-       return(n);
- }
-@@ -412,7 +416,8 @@
-               return NULL;
-       driver->driver_name = line_driver->name;
--      driver->name = line_driver->devfs_name;
-+      driver->name = line_driver->device_name;
-+      driver->devfs_name = line_driver->devfs_name;
-       driver->major = line_driver->major;
-       driver->minor_start = line_driver->minor_start;
-       driver->type = line_driver->type;
-@@ -432,7 +437,7 @@
-       for(i = 0; i < nlines; i++){
-               if(!lines[i].valid) 
--                      tty_unregister_devfs(driver, i);
-+                      tty_unregister_device(driver, i);
-       }
-       mconsole_register_dev(&line_driver->mc);
-@@ -465,24 +470,25 @@
-       struct line *line;
- };
--void winch_interrupt(int irq, void *data, struct pt_regs *unused)
-+irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
- {
-       struct winch *winch = data;
-       struct tty_struct *tty;
-       int err;
-       char c;
--      err = generic_read(winch->fd, &c, NULL);
--      if(err < 0){
--              if(err != -EAGAIN){
--                      printk("winch_interrupt : read failed, errno = %d\n", 
--                             -err);
--                      printk("fd %d is losing SIGWINCH support\n", 
--                             winch->tty_fd);
--                      free_irq(irq, data);
--                      return;
-+      if(winch->fd != -1){
-+              err = generic_read(winch->fd, &c, NULL);
-+              if(err < 0){
-+                      if(err != -EAGAIN){
-+                              printk("winch_interrupt : read failed, "
-+                                     "errno = %d\n", -err);
-+                              printk("fd %d is losing SIGWINCH support\n", 
-+                                     winch->tty_fd);
-+                              return(IRQ_HANDLED);
-+                      }
-+                      goto out;
-               }
--              goto out;
-       }
-       tty = winch->line->tty;
-       if(tty != NULL){
-@@ -492,7 +498,9 @@
-               kill_pg(tty->pgrp, SIGWINCH, 1);
-       }
-  out:
--      reactivate_fd(winch->fd, WINCH_IRQ);
-+      if(winch->fd != -1)
-+              reactivate_fd(winch->fd, WINCH_IRQ);
-+      return(IRQ_HANDLED);
- }
- DECLARE_MUTEX(winch_handler_sem);
-@@ -529,7 +537,10 @@
-       list_for_each(ele, &winch_handlers){
-               winch = list_entry(ele, struct winch, list);
--              close(winch->fd);
-+              if(winch->fd != -1){
-+                      deactivate_fd(winch->fd, WINCH_IRQ);
-+                      close(winch->fd);
-+              }
-               if(winch->pid != -1) 
-                       os_kill_process(winch->pid, 1);
-       }
-diff -Naur a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
---- a/arch/um/drivers/mconsole_kern.c  Fri Aug 15 15:03:47 2003
-+++ b/arch/um/drivers/mconsole_kern.c  Fri Aug 15 15:10:11 2003
-@@ -27,6 +27,7 @@
- #include "init.h"
- #include "os.h"
- #include "umid.h"
-+#include "irq_kern.h"
- static int do_unlink_socket(struct notifier_block *notifier, 
-                           unsigned long what, void *data)
-@@ -67,7 +68,7 @@
- DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
--void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
- {
-       int fd;
-       struct mconsole_entry *new;
-@@ -88,6 +89,7 @@
-       }
-       if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
-       reactivate_fd(fd, MCONSOLE_IRQ);
-+      return(IRQ_HANDLED);
- }
- void mconsole_version(struct mc_request *req)
-@@ -100,20 +102,34 @@
-       mconsole_reply(req, version, 0, 0);
- }
-+void mconsole_log(struct mc_request *req)
-+{
-+      int len;
-+      char *ptr = req->request.data;
-+      
-+      ptr += strlen("log");
-+      while(isspace(*ptr)) ptr++;
-+
-+      len = ptr - req->request.data;
-+      printk("%.*s", len, ptr);
-+      mconsole_reply(req, "", 0, 0);
-+}
-+
- #define UML_MCONSOLE_HELPTEXT \
--"Commands:
--    version - Get kernel version
--    help - Print this message
--    halt - Halt UML
--    reboot - Reboot UML
--    config <dev>=<config> - Add a new device to UML; 
--      same syntax as command line
--    config <dev> - Query the configuration of a device
--    remove <dev> - Remove a device from UML
--    sysrq <letter> - Performs the SysRq action controlled by the letter
--    cad - invoke the Ctl-Alt-Del handler
--    stop - pause the UML; it will do nothing until it receives a 'go'
--    go - continue the UML after a 'stop'
-+"Commands: \n\
-+    version - Get kernel version \n\
-+    help - Print this message \n\
-+    halt - Halt UML \n\
-+    reboot - Reboot UML \n\
-+    config <dev>=<config> - Add a new device to UML;  \n\
-+      same syntax as command line \n\
-+    config <dev> - Query the configuration of a device \n\
-+    remove <dev> - Remove a device from UML \n\
-+    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
-+    cad - invoke the Ctl-Alt-Del handler \n\
-+    stop - pause the UML; it will do nothing until it receives a 'go' \n\
-+    go - continue the UML after a 'stop' \n\
-+    log <string> - make UML enter <string> into the kernel log\n\
- "
- void mconsole_help(struct mc_request *req)
-@@ -302,7 +318,7 @@
-       if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
-       snprintf(mconsole_socket_name, sizeof(file), "%s", file);
--      sock = create_unix_socket(file, sizeof(file));
-+      sock = create_unix_socket(file, sizeof(file), 1);
-       if (sock < 0){
-               printk("Failed to initialize management console\n");
-               return(1);
-diff -Naur a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
---- a/arch/um/drivers/mconsole_user.c  Fri Aug 15 15:04:47 2003
-+++ b/arch/um/drivers/mconsole_user.c  Fri Aug 15 15:10:35 2003
-@@ -28,6 +28,7 @@
-       { "cad", mconsole_cad, 1 },
-       { "stop", mconsole_stop, 0 },
-       { "go", mconsole_go, 1 },
-+      { "log", mconsole_log, 1 },
- };
- /* Initialized in mconsole_init, which is an initcall */
-@@ -139,6 +140,7 @@
-               memcpy(reply.data, str, len);
-               reply.data[len] = '\0';
-               total -= len;
-+              str += len;
-               reply.len = len + 1;
-               len = sizeof(reply) + reply.len - sizeof(reply.data);
-diff -Naur a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
---- a/arch/um/drivers/mmapper_kern.c   Fri Aug 15 15:04:33 2003
-+++ b/arch/um/drivers/mmapper_kern.c   Fri Aug 15 15:10:32 2003
-@@ -120,7 +120,10 @@
-       printk(KERN_INFO "Mapper v0.1\n");
-       v_buf = (char *) find_iomem("mmapper", &mmapper_size);
--      if(mmapper_size == 0) return(0);
-+      if(mmapper_size == 0){
-+              printk(KERN_ERR "mmapper_init - find_iomem failed\n");
-+              return(0);
-+      }
-       p_buf = __pa(v_buf);
-diff -Naur a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
---- a/arch/um/drivers/net_kern.c       Fri Aug 15 15:05:49 2003
-+++ b/arch/um/drivers/net_kern.c       Fri Aug 15 15:11:52 2003
-@@ -26,6 +26,7 @@
- #include "mconsole_kern.h"
- #include "init.h"
- #include "irq_user.h"
-+#include "irq_kern.h"
- static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
- LIST_HEAD(opened);
-@@ -61,14 +62,14 @@
-       return pkt_len;
- }
--void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
- {
-       struct net_device *dev = dev_id;
-       struct uml_net_private *lp = dev->priv;
-       int err;
-       if(!netif_running(dev))
--              return;
-+              return(IRQ_NONE);
-       spin_lock(&lp->lock);
-       while((err = uml_net_rx(dev)) > 0) ;
-@@ -83,6 +84,7 @@
-  out:
-       spin_unlock(&lp->lock);
-+      return(IRQ_HANDLED);
- }
- static int uml_net_open(struct net_device *dev)
-@@ -292,7 +294,7 @@
-       struct uml_net *device;
-       struct net_device *dev;
-       struct uml_net_private *lp;
--      int err, size;
-+      int save, err, size;
-       size = transport->private_size + sizeof(struct uml_net_private) + 
-               sizeof(((struct uml_net_private *) 0)->user);
-@@ -362,21 +364,29 @@
-               return 1;
-       lp = dev->priv;
--      INIT_LIST_HEAD(&lp->list);
--      spin_lock_init(&lp->lock);
--      lp->dev = dev;
--      lp->fd = -1;
--      lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
--      lp->have_mac = device->have_mac;
--      lp->protocol = transport->kern->protocol;
--      lp->open = transport->user->open;
--      lp->close = transport->user->close;
--      lp->remove = transport->user->remove;
--      lp->read = transport->kern->read;
--      lp->write = transport->kern->write;
--      lp->add_address = transport->user->add_address;
--      lp->delete_address = transport->user->delete_address;
--      lp->set_mtu = transport->user->set_mtu;
-+      /* lp.user is the first four bytes of the transport data, which
-+       * has already been initialized.  This structure assignment will
-+       * overwrite that, so we make sure that .user gets overwritten with
-+       * what it already has.
-+       */
-+      save = lp->user[0];
-+      *lp = ((struct uml_net_private) 
-+              { .list                 = LIST_HEAD_INIT(lp->list),
-+                .lock                 = SPIN_LOCK_UNLOCKED,
-+                .dev                  = dev,
-+                .fd                   = -1,
-+                .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
-+                .have_mac             = device->have_mac,
-+                .protocol             = transport->kern->protocol,
-+                .open                 = transport->user->open,
-+                .close                = transport->user->close,
-+                .remove               = transport->user->remove,
-+                .read                 = transport->kern->read,
-+                .write                = transport->kern->write,
-+                .add_address          = transport->user->add_address,
-+                .delete_address       = transport->user->delete_address,
-+                .set_mtu              = transport->user->set_mtu,
-+                .user                 = { save } });
-       init_timer(&lp->tl);
-       lp->tl.function = uml_net_user_timer_expire;
-diff -Naur a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
---- a/arch/um/drivers/port_kern.c      Fri Aug 15 15:04:01 2003
-+++ b/arch/um/drivers/port_kern.c      Fri Aug 15 15:10:18 2003
-@@ -6,6 +6,7 @@
- #include "linux/list.h"
- #include "linux/sched.h"
- #include "linux/slab.h"
-+#include "linux/interrupt.h"
- #include "linux/irq.h"
- #include "linux/spinlock.h"
- #include "linux/errno.h"
-@@ -14,6 +15,7 @@
- #include "kern_util.h"
- #include "kern.h"
- #include "irq_user.h"
-+#include "irq_kern.h"
- #include "port.h"
- #include "init.h"
- #include "os.h"
-@@ -44,7 +46,7 @@
-       struct port_list *port;
- };
--static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
-+static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
- {
-       struct connection *conn = data;
-       int fd;
-@@ -52,7 +54,7 @@
-       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
-       if(fd < 0){
-               if(fd == -EAGAIN)
--                      return;
-+                      return(IRQ_NONE);
-               printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
-                      -fd);
-@@ -65,6 +67,7 @@
-       list_add(&conn->list, &conn->port->connections);
-       up(&conn->port->sem);
-+      return(IRQ_HANDLED);
- }
- static int port_accept(struct port_list *port)
-@@ -138,12 +141,13 @@
- DECLARE_WORK(port_work, port_work_proc, NULL);
--static void port_interrupt(int irq, void *data, struct pt_regs *regs)
-+static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
- {
-       struct port_list *port = data;
-       port->has_connection = 1;
-       schedule_work(&port_work);
-+      return(IRQ_HANDLED);
- } 
- void *port_data(int port_num)
-diff -Naur a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
---- a/arch/um/drivers/ssl.c    Fri Aug 15 15:06:09 2003
-+++ b/arch/um/drivers/ssl.c    Fri Aug 15 15:12:30 2003
-@@ -53,8 +53,9 @@
- static struct line_driver driver = {
-       .name                   = "UML serial line",
--      .devfs_name             = "tts/%d",
--      .major                  = TTYAUX_MAJOR,
-+      .device_name            = "ttS",
-+      .devfs_name             = "tts/",
-+      .major                  = TTY_MAJOR,
-       .minor_start            = 64,
-       .type                   = TTY_DRIVER_TYPE_SERIAL,
-       .subtype                = 0,
-diff -Naur a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
---- a/arch/um/drivers/stdio_console.c  Fri Aug 15 15:04:51 2003
-+++ b/arch/um/drivers/stdio_console.c  Fri Aug 15 15:10:56 2003
-@@ -83,7 +83,8 @@
- static struct line_driver driver = {
-       .name                   = "UML console",
--      .devfs_name             = "vc/%d",
-+      .device_name            = "tty",
-+      .devfs_name             = "vc/",
-       .major                  = TTY_MAJOR,
-       .minor_start            = 0,
-       .type                   = TTY_DRIVER_TYPE_CONSOLE,
-@@ -159,6 +160,15 @@
- static int con_init_done = 0;
-+static struct tty_operations console_ops = {
-+      .open                   = con_open,
-+      .close                  = con_close,
-+      .write                  = con_write,
-+      .chars_in_buffer        = chars_in_buffer,
-+      .set_termios            = set_termios,
-+      .write_room             = line_write_room,
-+};
-+
- int stdio_init(void)
- {
-       char *new_title;
-@@ -166,7 +176,8 @@
-       printk(KERN_INFO "Initializing stdio console driver\n");
-       console_driver = line_register_devfs(&console_lines, &driver,
--                              &console_ops, vts, sizeof(vts)/sizeof(vts[0]));
-+                                           &console_ops, vts,
-+                                           sizeof(vts)/sizeof(vts[0]));
-       lines_init(vts, sizeof(vts)/sizeof(vts[0]));
-@@ -188,15 +199,6 @@
-       if(con_init_done) up(&vts[console->index].sem);
- }
--static struct tty_operations console_ops = {
--      .open                   = con_open,
--      .close                  = con_close,
--      .write                  = con_write,
--      .chars_in_buffer        = chars_in_buffer,
--      .set_termios            = set_termios,
--      .write_room             = line_write_room,
--};
--
- static struct tty_driver *console_device(struct console *c, int *index)
- {
-       *index = c->index;
-@@ -212,12 +214,14 @@
-                                              console_device, console_setup,
-                                              CON_PRINTBUFFER);
--static void __init stdio_console_init(void)
-+static int __init stdio_console_init(void)
- {
-       INIT_LIST_HEAD(&vts[0].chan_list);
-       list_add(&init_console_chan.list, &vts[0].chan_list);
-       register_console(&stdiocons);
-+      return(0);
- }
-+
- console_initcall(stdio_console_init);
- static int console_chan_setup(char *str)
-diff -Naur a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
---- a/arch/um/drivers/ubd_kern.c       Fri Aug 15 15:05:56 2003
-+++ b/arch/um/drivers/ubd_kern.c       Fri Aug 15 15:11:53 2003
-@@ -8,6 +8,13 @@
-  * old style ubd by setting UBD_SHIFT to 0
-  * 2002-09-27...2002-10-18 massive tinkering for 2.5
-  * partitions have changed in 2.5
-+ * 2003-01-29 more tinkering for 2.5.59-1
-+ * This should now address the sysfs problems and has
-+ * the symlink for devfs to allow for booting with
-+ * the common /dev/ubd/discX/... names rather than
-+ * only /dev/ubdN/discN this version also has lots of
-+ * clean ups preparing for ubd-many.
-+ * James McMechan
-  */
- #define MAJOR_NR UBD_MAJOR
-@@ -40,6 +47,7 @@
- #include "mconsole_kern.h"
- #include "init.h"
- #include "irq_user.h"
-+#include "irq_kern.h"
- #include "ubd_user.h"
- #include "2_5compat.h"
- #include "os.h"
-@@ -70,7 +78,7 @@
- static request_queue_t *ubd_queue;
- /* Protected by ubd_lock */
--static int fake_major = 0;
-+static int fake_major = MAJOR_NR;
- static struct gendisk *ubd_gendisk[MAX_DEV];
- static struct gendisk *fake_gendisk[MAX_DEV];
-@@ -99,12 +107,12 @@
- struct ubd {
-       char *file;
--      int is_dir;
-       int count;
-       int fd;
-       __u64 size;
-       struct openflags boot_openflags;
-       struct openflags openflags;
-+      int no_cow;
-       struct cow cow;
- };
-@@ -118,12 +126,12 @@
- #define DEFAULT_UBD { \
-       .file =                 NULL, \
--      .is_dir =               0, \
-       .count =                0, \
-       .fd =                   -1, \
-       .size =                 -1, \
-       .boot_openflags =       OPEN_FLAGS, \
-       .openflags =            OPEN_FLAGS, \
-+        .no_cow =               0, \
-         .cow =                        DEFAULT_COW, \
- }
-@@ -131,8 +139,10 @@
- static int ubd0_init(void)
- {
--      if(ubd_dev[0].file == NULL)
--              ubd_dev[0].file = "root_fs";
-+      struct ubd *dev = &ubd_dev[0];
-+
-+      if(dev->file == NULL)
-+              dev->file = "root_fs";
-       return(0);
- }
-@@ -199,19 +209,39 @@
- "    Create ide0 entries that map onto ubd devices.\n\n"
- );
-+static int parse_unit(char **ptr)
-+{
-+      char *str = *ptr, *end;
-+      int n = -1;
-+
-+      if(isdigit(*str)) {
-+              n = simple_strtoul(str, &end, 0);
-+              if(end == str)
-+                      return(-1);
-+              *ptr = end;
-+      }
-+      else if (('a' <= *str) && (*str <= 'h')) {
-+              n = *str - 'a';
-+              str++;
-+              *ptr = str;
-+      }
-+      return(n);
-+}
-+
- static int ubd_setup_common(char *str, int *index_out)
- {
-+      struct ubd *dev;
-       struct openflags flags = global_openflags;
-       char *backing_file;
-       int n, err;
-       if(index_out) *index_out = -1;
--      n = *str++;
-+      n = *str;
-       if(n == '='){
--              static int fake_major_allowed = 1;
-               char *end;
-               int major;
-+              str++;
-               if(!strcmp(str, "sync")){
-                       global_openflags.s = 1;
-                       return(0);
-@@ -223,20 +253,14 @@
-                       return(1);
-               }
--              if(!fake_major_allowed){
--                      printk(KERN_ERR "Can't assign a fake major twice\n");
--                      return(1);
--              }
--
-               err = 1;
-               spin_lock(&ubd_lock);
--              if(!fake_major_allowed){
-+              if(fake_major != MAJOR_NR){
-                       printk(KERN_ERR "Can't assign a fake major twice\n");
-                       goto out1;
-               }
-  
-               fake_major = major;
--              fake_major_allowed = 0;
-               printk(KERN_INFO "Setting extra ubd major number to %d\n",
-                      major);
-@@ -246,25 +270,23 @@
-               return(err);
-       }
--      if(n < '0'){
--              printk(KERN_ERR "ubd_setup : index out of range\n"); }
--
--      if((n >= '0') && (n <= '9')) n -= '0';
--      else if((n >= 'a') && (n <= 'z')) n -= 'a';
--      else {
--              printk(KERN_ERR "ubd_setup : device syntax invalid\n");
-+      n = parse_unit(&str);
-+      if(n < 0){
-+              printk(KERN_ERR "ubd_setup : couldn't parse unit number "
-+                     "'%s'\n", str);
-               return(1);
-       }
-       if(n >= MAX_DEV){
--              printk(KERN_ERR "ubd_setup : index out of range "
--                     "(%d devices)\n", MAX_DEV);      
-+              printk(KERN_ERR "ubd_setup : index %d out of range "
-+                     "(%d devices)\n", n, MAX_DEV);
-               return(1);
-       }
-       err = 1;
-       spin_lock(&ubd_lock);
--      if(ubd_dev[n].file != NULL){
-+      dev = &ubd_dev[n];
-+      if(dev->file != NULL){
-               printk(KERN_ERR "ubd_setup : device already configured\n");
-               goto out2;
-       }
-@@ -279,6 +301,11 @@
-               flags.s = 1;
-               str++;
-       }
-+      if (*str == 'd'){
-+              dev->no_cow = 1;
-+              str++;
-+      }
-+
-       if(*str++ != '='){
-               printk(KERN_ERR "ubd_setup : Expected '='\n");
-               goto out2;
-@@ -287,14 +314,17 @@
-       err = 0;
-       backing_file = strchr(str, ',');
-       if(backing_file){
--              *backing_file = '\0';
--              backing_file++;
-+              if(dev->no_cow)
-+                      printk(KERN_ERR "Can't specify both 'd' and a "
-+                             "cow file\n");
-+              else {
-+                      *backing_file = '\0';
-+                      backing_file++;
-+              }
-       }
--      ubd_dev[n].file = str;
--      if(ubd_is_dir(ubd_dev[n].file))
--              ubd_dev[n].is_dir = 1;
--      ubd_dev[n].cow.file = backing_file;
--      ubd_dev[n].boot_openflags = flags;
-+      dev->file = str;
-+      dev->cow.file = backing_file;
-+      dev->boot_openflags = flags;
-  out2:
-       spin_unlock(&ubd_lock);
-       return(err);
-@@ -324,8 +354,7 @@
- static int fakehd_set = 0;
- static int fakehd(char *str)
- {
--      printk(KERN_INFO 
--             "fakehd : Changing ubd name to \"hd\".\n");
-+      printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
-       fakehd_set = 1;
-       return 1;
- }
-@@ -394,9 +423,10 @@
-       do_ubd_request(ubd_queue);
- }
--static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
-+static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
- {
-       ubd_handler();
-+      return(IRQ_HANDLED);
- }
- /* Only changed by ubd_init, which is an initcall. */
-@@ -432,16 +462,18 @@
- static int ubd_open_dev(struct ubd *dev)
- {
-       struct openflags flags;
--      int err, n, create_cow, *create_ptr;
-+      char **back_ptr;
-+      int err, create_cow, *create_ptr;
-+      dev->openflags = dev->boot_openflags;
-       create_cow = 0;
-       create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
--      dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
-+      back_ptr = dev->no_cow ? NULL : &dev->cow.file;
-+      dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
-                               &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
-                               &dev->cow.data_offset, create_ptr);
-       if((dev->fd == -ENOENT) && create_cow){
--              n = dev - ubd_dev;
-               dev->fd = create_cow_file(dev->file, dev->cow.file, 
-                                         dev->openflags, 1 << 9,
-                                         &dev->cow.bitmap_offset, 
-@@ -458,7 +490,10 @@
-       if(dev->cow.file != NULL){
-               err = -ENOMEM;
-               dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
--              if(dev->cow.bitmap == NULL) goto error;
-+              if(dev->cow.bitmap == NULL){
-+                      printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
-+                      goto error;
-+              }
-               flush_tlb_kernel_vm();
-               err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
-@@ -484,17 +519,31 @@
-                       
- {
-       struct gendisk *disk;
-+      char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
-+      int err;
-       disk = alloc_disk(1 << UBD_SHIFT);
--      if (!disk)
--              return -ENOMEM;
-+      if(disk == NULL)
-+              return(-ENOMEM);
-       disk->major = major;
-       disk->first_minor = unit << UBD_SHIFT;
-       disk->fops = &ubd_blops;
-       set_capacity(disk, size / 512);
--      sprintf(disk->disk_name, "ubd");
--      sprintf(disk->devfs_name, "ubd/disc%d", unit);
-+      if(major == MAJOR_NR){
-+              sprintf(disk->disk_name, "ubd%d", unit);
-+              sprintf(disk->devfs_name, "ubd/disc%d", unit);
-+              sprintf(from, "ubd/%d", unit);
-+              sprintf(to, "disc%d/disc", unit);
-+              err = devfs_mk_symlink(from, to);
-+              if(err)
-+                      printk("ubd_new_disk failed to make link from %s to "
-+                             "%s, error = %d\n", from, to, err);
-+      }
-+      else {
-+              sprintf(disk->disk_name, "ubd_fake%d", unit);
-+              sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
-+      }
-       disk->private_data = &ubd_dev[unit];
-       disk->queue = ubd_queue;
-@@ -509,10 +558,7 @@
-       struct ubd *dev = &ubd_dev[n];
-       int err;
--      if(dev->is_dir)
--              return(-EISDIR);
--
--      if (!dev->file)
-+      if(dev->file == NULL)
-               return(-ENODEV);
-       if (ubd_open_dev(dev))
-@@ -526,7 +572,7 @@
-       if(err) 
-               return(err);
-  
--      if(fake_major)
-+      if(fake_major != MAJOR_NR)
-               ubd_new_disk(fake_major, dev->size, n, 
-                            &fake_gendisk[n]);
-@@ -564,42 +610,42 @@
-       return(err);
- }
--static int ubd_get_config(char *dev, char *str, int size, char **error_out)
-+static int ubd_get_config(char *name, char *str, int size, char **error_out)
- {
--      struct ubd *ubd;
-+      struct ubd *dev;
-       char *end;
--      int major, n = 0;
-+      int n, len = 0;
--      major = simple_strtoul(dev, &end, 0);
--      if((*end != '\0') || (end == dev)){
--              *error_out = "ubd_get_config : didn't parse major number";
-+      n = simple_strtoul(name, &end, 0);
-+      if((*end != '\0') || (end == name)){
-+              *error_out = "ubd_get_config : didn't parse device number";
-               return(-1);
-       }
--      if((major >= MAX_DEV) || (major < 0)){
--              *error_out = "ubd_get_config : major number out of range";
-+      if((n >= MAX_DEV) || (n < 0)){
-+              *error_out = "ubd_get_config : device number out of range";
-               return(-1);
-       }
--      ubd = &ubd_dev[major];
-+      dev = &ubd_dev[n];
-       spin_lock(&ubd_lock);
--      if(ubd->file == NULL){
--              CONFIG_CHUNK(str, size, n, "", 1);
-+      if(dev->file == NULL){
-+              CONFIG_CHUNK(str, size, len, "", 1);
-               goto out;
-       }
--      CONFIG_CHUNK(str, size, n, ubd->file, 0);
-+      CONFIG_CHUNK(str, size, len, dev->file, 0);
--      if(ubd->cow.file != NULL){
--              CONFIG_CHUNK(str, size, n, ",", 0);
--              CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
-+      if(dev->cow.file != NULL){
-+              CONFIG_CHUNK(str, size, len, ",", 0);
-+              CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
-       }
--      else CONFIG_CHUNK(str, size, n, "", 1);
-+      else CONFIG_CHUNK(str, size, len, "", 1);
-  out:
-       spin_unlock(&ubd_lock);
--      return(n);
-+      return(len);
- }
- static int ubd_remove(char *str)
-@@ -607,11 +653,9 @@
-       struct ubd *dev;
-       int n, err = -ENODEV;
--      if(!isdigit(*str))
--              return(err);    /* it should be a number 0-7/a-h */
-+      n = parse_unit(&str);
--      n = *str - '0';
--      if(n >= MAX_DEV) 
-+      if((n < 0) || (n >= MAX_DEV))
-               return(err);
-       dev = &ubd_dev[n];
-@@ -672,7 +716,7 @@
-               
-       elevator_init(ubd_queue, &elevator_noop);
--      if (fake_major != 0) {
-+      if (fake_major != MAJOR_NR) {
-               char name[sizeof("ubd_nnn\0")];
-               snprintf(name, sizeof(name), "ubd_%d", fake_major);
-@@ -717,15 +761,9 @@
- {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ubd *dev = disk->private_data;
--      int err = -EISDIR;
--
--      if(dev->is_dir == 1)
--              goto out;
-+      int err = 0;
--      err = 0;
-       if(dev->count == 0){
--              dev->openflags = dev->boot_openflags;
--
-               err = ubd_open_dev(dev);
-               if(err){
-                       printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
-@@ -799,15 +837,6 @@
-       if(req->rq_status == RQ_INACTIVE) return(1);
--      if(dev->is_dir){
--              strcpy(req->buffer, "HOSTFS:");
--              strcat(req->buffer, dev->file);
--              spin_lock(&ubd_io_lock);
--              end_request(req, 1);
--              spin_unlock(&ubd_io_lock);
--              return(1);
--      }
--
-       if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
-               printk("Write attempted on readonly ubd device %s\n", 
-                      disk->disk_name);
-diff -Naur a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
---- a/arch/um/drivers/ubd_user.c       Fri Aug 15 15:04:51 2003
-+++ b/arch/um/drivers/ubd_user.c       Fri Aug 15 15:10:54 2003
-@@ -24,142 +24,24 @@
- #include "user.h"
- #include "ubd_user.h"
- #include "os.h"
-+#include "cow.h"
- #include <endian.h>
- #include <byteswap.h>
--#if __BYTE_ORDER == __BIG_ENDIAN
--# define ntohll(x) (x)
--# define htonll(x) (x)
--#elif __BYTE_ORDER == __LITTLE_ENDIAN
--# define ntohll(x)  bswap_64(x)
--# define htonll(x)  bswap_64(x)
--#else
--#error "__BYTE_ORDER not defined"
--#endif
--
--#define PATH_LEN_V1 256
--
--struct cow_header_v1 {
--      int magic;
--      int version;
--      char backing_file[PATH_LEN_V1];
--      time_t mtime;
--      __u64 size;
--      int sectorsize;
--};
--
--#define PATH_LEN_V2 MAXPATHLEN
--
--struct cow_header_v2 {
--      unsigned long magic;
--      unsigned long version;
--      char backing_file[PATH_LEN_V2];
--      time_t mtime;
--      __u64 size;
--      int sectorsize;
--};
--
--union cow_header {
--      struct cow_header_v1 v1;
--      struct cow_header_v2 v2;
--};
--
--#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
--#define COW_VERSION 2
--
--static void sizes(__u64 size, int sectorsize, int bitmap_offset, 
--                unsigned long *bitmap_len_out, int *data_offset_out)
--{
--      *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
--
--      *data_offset_out = bitmap_offset + *bitmap_len_out;
--      *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
--      *data_offset_out *= sectorsize;
--}
--
--static int read_cow_header(int fd, int *magic_out, char **backing_file_out, 
--                         time_t *mtime_out, __u64 *size_out, 
--                         int *sectorsize_out, int *bitmap_offset_out)
--{
--      union cow_header *header;
--      char *file;
--      int err, n;
--      unsigned long version, magic;
--
--      header = um_kmalloc(sizeof(*header));
--      if(header == NULL){
--              printk("read_cow_header - Failed to allocate header\n");
--              return(-ENOMEM);
--      }
--      err = -EINVAL;
--      n = read(fd, header, sizeof(*header));
--      if(n < offsetof(typeof(header->v1), backing_file)){
--              printk("read_cow_header - short header\n");
--              goto out;
--      }
--
--      magic = header->v1.magic;
--      if(magic == COW_MAGIC) {
--              version = header->v1.version;
--      }
--      else if(magic == ntohl(COW_MAGIC)){
--              version = ntohl(header->v1.version);
--      }
--      else goto out;
--
--      *magic_out = COW_MAGIC;
--
--      if(version == 1){
--              if(n < sizeof(header->v1)){
--                      printk("read_cow_header - failed to read V1 header\n");
--                      goto out;
--              }
--              *mtime_out = header->v1.mtime;
--              *size_out = header->v1.size;
--              *sectorsize_out = header->v1.sectorsize;
--              *bitmap_offset_out = sizeof(header->v1);
--              file = header->v1.backing_file;
--      }
--      else if(version == 2){
--              if(n < sizeof(header->v2)){
--                      printk("read_cow_header - failed to read V2 header\n");
--                      goto out;
--              }
--              *mtime_out = ntohl(header->v2.mtime);
--              *size_out = ntohll(header->v2.size);
--              *sectorsize_out = ntohl(header->v2.sectorsize);
--              *bitmap_offset_out = sizeof(header->v2);
--              file = header->v2.backing_file;
--      }
--      else {
--              printk("read_cow_header - invalid COW version\n");
--              goto out;
--      }
--      err = -ENOMEM;
--      *backing_file_out = uml_strdup(file);
--      if(*backing_file_out == NULL){
--              printk("read_cow_header - failed to allocate backing file\n");
--              goto out;
--      }
--      err = 0;
-- out:
--      kfree(header);
--      return(err);
--}
- static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
- {
--      struct stat buf1, buf2;
-+      struct stat64 buf1, buf2;
-       if(from_cmdline == NULL) return(1);
-       if(!strcmp(from_cmdline, from_cow)) return(1);
--      if(stat(from_cmdline, &buf1) < 0){
-+      if(stat64(from_cmdline, &buf1) < 0){
-               printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
-                      errno);
-               return(1);
-       }
--      if(stat(from_cow, &buf2) < 0){
-+      if(stat64(from_cow, &buf2) < 0){
-               printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
-               return(1);
-       }
-@@ -178,6 +60,7 @@
-       long long actual;
-       int err;
-+      printk("%ld", htonll(size));
-       if(stat64(file, &buf) < 0){
-               printk("Failed to stat backing file \"%s\", errno = %d\n",
-                      file, errno);
-@@ -215,118 +98,6 @@
-       return(0);
- }
--static int absolutize(char *to, int size, char *from)
--{
--      char save_cwd[256], *slash;
--      int remaining;
--
--      if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
--              printk("absolutize : unable to get cwd - errno = %d\n", errno);
--              return(-1);
--      }
--      slash = strrchr(from, '/');
--      if(slash != NULL){
--              *slash = '\0';
--              if(chdir(from)){
--                      *slash = '/';
--                      printk("absolutize : Can't cd to '%s' - errno = %d\n",
--                             from, errno);
--                      return(-1);
--              }
--              *slash = '/';
--              if(getcwd(to, size) == NULL){
--                      printk("absolutize : unable to get cwd of '%s' - "
--                             "errno = %d\n", from, errno);
--                      return(-1);
--              }
--              remaining = size - strlen(to);
--              if(strlen(slash) + 1 > remaining){
--                      printk("absolutize : unable to fit '%s' into %d "
--                             "chars\n", from, size);
--                      return(-1);
--              }
--              strcat(to, slash);
--      }
--      else {
--              if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
--                      printk("absolutize : unable to fit '%s' into %d "
--                             "chars\n", from, size);
--                      return(-1);
--              }
--              strcpy(to, save_cwd);
--              strcat(to, "/");
--              strcat(to, from);
--      }
--      chdir(save_cwd);
--      return(0);
--}
--
--static int write_cow_header(char *cow_file, int fd, char *backing_file, 
--                          int sectorsize, long long *size)
--{
--        struct cow_header_v2 *header;
--      struct stat64 buf;
--      int err;
--
--      err = os_seek_file(fd, 0);
--      if(err != 0){
--              printk("write_cow_header - lseek failed, errno = %d\n", errno);
--              return(-errno);
--      }
--
--      err = -ENOMEM;
--      header = um_kmalloc(sizeof(*header));
--      if(header == NULL){
--              printk("Failed to allocate COW V2 header\n");
--              goto out;
--      }
--      header->magic = htonl(COW_MAGIC);
--      header->version = htonl(COW_VERSION);
--
--      err = -EINVAL;
--      if(strlen(backing_file) > sizeof(header->backing_file) - 1){
--              printk("Backing file name \"%s\" is too long - names are "
--                     "limited to %d characters\n", backing_file, 
--                     sizeof(header->backing_file) - 1);
--              goto out_free;
--      }
--
--      if(absolutize(header->backing_file, sizeof(header->backing_file), 
--                    backing_file))
--              goto out_free;
--
--      err = stat64(header->backing_file, &buf);
--      if(err < 0){
--              printk("Stat of backing file '%s' failed, errno = %d\n",
--                     header->backing_file, errno);
--              err = -errno;
--              goto out_free;
--      }
--
--      err = os_file_size(header->backing_file, size);
--      if(err){
--              printk("Couldn't get size of backing file '%s', errno = %d\n",
--                     header->backing_file, -*size);
--              goto out_free;
--      }
--
--      header->mtime = htonl(buf.st_mtime);
--      header->size = htonll(*size);
--      header->sectorsize = htonl(sectorsize);
--
--      err = write(fd, header, sizeof(*header));
--      if(err != sizeof(*header)){
--              printk("Write of header to new COW file '%s' failed, "
--                     "errno = %d\n", cow_file, errno);
--              goto out_free;
--      }
--      err = 0;
-- out_free:
--      kfree(header);
-- out:
--      return(err);
--}
--
- int open_ubd_file(char *file, struct openflags *openflags, 
-                 char **backing_file_out, int *bitmap_offset_out, 
-                 unsigned long *bitmap_len_out, int *data_offset_out, 
-@@ -346,10 +117,17 @@
-                 if((fd = os_open_file(file, *openflags, mode)) < 0) 
-                       return(fd);
-         }
-+
-+      err = os_lock_file(fd, openflags->w);
-+      if(err){
-+              printk("Failed to lock '%s', errno = %d\n", file, -err);
-+              goto error;
-+      }
-+      
-       if(backing_file_out == NULL) return(fd);
--      err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
--                            &sectorsize, bitmap_offset_out);
-+      err = read_cow_header(file_reader, &fd, &magic, &backing_file, &mtime, 
-+                            &size, &sectorsize, bitmap_offset_out);
-       if(err && (*backing_file_out != NULL)){
-               printk("Failed to read COW header from COW file \"%s\", "
-                      "errno = %d\n", file, err);
-@@ -376,12 +154,12 @@
-               if(err) goto error;
-       }
--      sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
--            data_offset_out);
-+      cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
-+                data_offset_out);
-         return(fd);
-  error:
--      close(fd);
-+      os_close_file(fd);
-       return(err);
- }
-@@ -389,10 +167,7 @@
-                   int sectorsize, int *bitmap_offset_out, 
-                   unsigned long *bitmap_len_out, int *data_offset_out)
- {
--      __u64 blocks;
--      long zero;
--      int err, fd, i;
--      long long size;
-+      int err, fd;
-       flags.c = 1;
-       fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
-@@ -403,29 +178,12 @@
-               goto out;
-       }
--      err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
--      if(err) goto out_close;
--
--      blocks = (size + sectorsize - 1) / sectorsize;
--      blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
--      zero = 0;
--      for(i = 0; i < blocks; i++){
--              err = write(fd, &zero, sizeof(zero));
--              if(err != sizeof(zero)){
--                      printk("Write of bitmap to new COW file '%s' failed, "
--                             "errno = %d\n", cow_file, errno);
--                      goto out_close;
--              }
--      }
--
--      sizes(size, sectorsize, sizeof(struct cow_header_v2), 
--            bitmap_len_out, data_offset_out);
--      *bitmap_offset_out = sizeof(struct cow_header_v2);
--
--      return(fd);
--
-- out_close:
--      close(fd);
-+      err = init_cow_file(fd, cow_file, backing_file, sectorsize, 
-+                          bitmap_offset_out, bitmap_len_out, 
-+                          data_offset_out);
-+      if(!err)
-+              return(fd);
-+      os_close_file(fd);
-  out:
-       return(err);
- }
-@@ -448,14 +206,6 @@
-       else return(n);
- }
--int ubd_is_dir(char *file)
--{
--      struct stat64 buf;
--
--      if(stat64(file, &buf) < 0) return(0);
--      return(S_ISDIR(buf.st_mode));
--}
--
- void do_io(struct io_thread_req *req)
- {
-       char *buf;
-diff -Naur a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
---- a/arch/um/drivers/xterm.c  Fri Aug 15 15:04:00 2003
-+++ b/arch/um/drivers/xterm.c  Fri Aug 15 15:10:18 2003
-@@ -108,7 +108,7 @@
-       }
-       close(fd);
--      fd = create_unix_socket(file, sizeof(file));
-+      fd = create_unix_socket(file, sizeof(file), 1);
-       if(fd < 0){
-               printk("xterm_open : create_unix_socket failed, errno = %d\n", 
-                      -fd);
-diff -Naur a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
---- a/arch/um/drivers/xterm_kern.c     Fri Aug 15 15:07:37 2003
-+++ b/arch/um/drivers/xterm_kern.c     Fri Aug 15 15:13:03 2003
-@@ -5,9 +5,12 @@
- #include "linux/errno.h"
- #include "linux/slab.h"
-+#include "linux/signal.h"
-+#include "linux/interrupt.h"
- #include "asm/semaphore.h"
- #include "asm/irq.h"
- #include "irq_user.h"
-+#include "irq_kern.h"
- #include "kern_util.h"
- #include "os.h"
- #include "xterm.h"
-@@ -19,17 +22,18 @@
-       int new_fd;
- };
--static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
-+static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
- {
-       struct xterm_wait *xterm = data;
-       int fd;
-       fd = os_rcv_fd(xterm->fd, &xterm->pid);
-       if(fd == -EAGAIN)
--              return;
-+              return(IRQ_NONE);
-       xterm->new_fd = fd;
-       up(&xterm->sem);
-+      return(IRQ_HANDLED);
- }
- int xterm_fd(int socket, int *pid_out)
-diff -Naur a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S
---- a/arch/um/dyn.lds.S        Fri Aug 15 15:06:20 2003
-+++ b/arch/um/dyn.lds.S        Fri Aug 15 15:12:31 2003
-@@ -15,7 +15,11 @@
-   . = ALIGN(4096);            /* Init code and data */
-   _stext = .;
-   __init_begin = .;
--  .text.init : { *(.text.init) }
-+  .init.text : { 
-+      _sinittext = .;
-+      *(.init.text)
-+      _einittext = .;
-+  }
-   . = ALIGN(4096);
-@@ -67,7 +71,7 @@
-   #include "asm/common.lds.S"
--  .data.init : { *(.data.init) }
-+  init.data : { *(.init.data) }
-   /* Ensure the __preinit_array_start label is properly aligned.  We
-      could instead move the label definition inside the section, but
-diff -Naur a/arch/um/include/irq_kern.h b/arch/um/include/irq_kern.h
---- a/arch/um/include/irq_kern.h       Wed Dec 31 19:00:00 1969
-+++ b/arch/um/include/irq_kern.h       Fri Aug 15 15:11:53 2003
-@@ -0,0 +1,28 @@
-+/* 
-+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __IRQ_KERN_H__
-+#define __IRQ_KERN_H__
-+
-+#include "linux/interrupt.h"
-+
-+extern int um_request_irq(unsigned int irq, int fd, int type,
-+                        irqreturn_t (*handler)(int, void *, 
-+                                               struct pt_regs *),
-+                        unsigned long irqflags,  const char * devname,
-+                        void *dev_id);
-+
-+#endif
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
---- a/arch/um/include/kern_util.h      Fri Aug 15 15:05:04 2003
-+++ b/arch/um/include/kern_util.h      Fri Aug 15 15:11:18 2003
-@@ -63,10 +63,9 @@
- extern void *syscall_sp(void *t);
- extern void syscall_trace(void);
- extern int hz(void);
--extern void idle_timer(void);
-+extern void uml_idle_timer(void);
- extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
- extern int external_pid(void *t);
--extern int pid_to_processor_id(int pid);
- extern void boot_timer_handler(int sig);
- extern void interrupt_end(void);
- extern void initial_thread_cb(void (*proc)(void *), void *arg);
-@@ -90,9 +89,7 @@
- extern char *uml_strdup(char *string);
- extern void unprotect_kernel_mem(void);
- extern void protect_kernel_mem(void);
--extern void set_kmem_end(unsigned long);
- extern void uml_cleanup(void);
--extern int pid_to_processor_id(int pid);
- extern void set_current(void *t);
- extern void lock_signalled_task(void *t);
- extern void IPI_handler(int cpu);
-@@ -101,7 +98,9 @@
- extern int clear_user_proc(void *buf, int size);
- extern int copy_to_user_proc(void *to, void *from, int size);
- extern int copy_from_user_proc(void *to, void *from, int size);
-+extern int strlen_user_proc(char *str);
- extern void bus_handler(int sig, union uml_pt_regs *regs);
-+extern void winch(int sig, union uml_pt_regs *regs);
- extern long execute_syscall(void *r);
- extern int smp_sigio_handler(void);
- extern void *get_current(void);
-diff -Naur a/arch/um/include/line.h b/arch/um/include/line.h
---- a/arch/um/include/line.h   Fri Aug 15 15:07:40 2003
-+++ b/arch/um/include/line.h   Fri Aug 15 15:13:11 2003
-@@ -9,12 +9,14 @@
- #include "linux/list.h"
- #include "linux/workqueue.h"
- #include "linux/tty.h"
-+#include "linux/interrupt.h"
- #include "asm/semaphore.h"
- #include "chan_user.h"
- #include "mconsole_kern.h"
- struct line_driver {
-       char *name;
-+      char *device_name;
-       char *devfs_name;
-       short major;
-       short minor_start;
-@@ -67,8 +69,9 @@
- #define LINES_INIT(n) {  num :                n }
--extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
--extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
-+extern irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused);
-+extern irqreturn_t line_write_interrupt(int irq, void *data, 
-+                                      struct pt_regs *unused);
- extern void line_close(struct line *lines, struct tty_struct *tty);
- extern int line_open(struct line *lines, struct tty_struct *tty, 
-                    struct chan_opts *opts);
-diff -Naur a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
---- a/arch/um/include/mconsole.h       Fri Aug 15 15:05:26 2003
-+++ b/arch/um/include/mconsole.h       Fri Aug 15 15:11:43 2003
-@@ -77,6 +77,7 @@
- extern void mconsole_cad(struct mc_request *req);
- extern void mconsole_stop(struct mc_request *req);
- extern void mconsole_go(struct mc_request *req);
-+extern void mconsole_log(struct mc_request *req);
- extern int mconsole_get_request(int fd, struct mc_request *req);
- extern int mconsole_notify(char *sock_name, int type, const void *data, 
-diff -Naur a/arch/um/include/mem.h b/arch/um/include/mem.h
---- a/arch/um/include/mem.h    Fri Aug 15 15:09:22 2003
-+++ b/arch/um/include/mem.h    Fri Aug 15 15:14:01 2003
-@@ -13,7 +13,6 @@
- };
- extern void set_usable_vm(unsigned long start, unsigned long end);
--extern void set_kmem_end(unsigned long new);
- #endif
-diff -Naur a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
---- a/arch/um/include/mem_user.h       Fri Aug 15 15:07:31 2003
-+++ b/arch/um/include/mem_user.h       Fri Aug 15 15:12:54 2003
-@@ -51,9 +51,6 @@
- extern int init_mem_user(void);
- extern int create_mem_file(unsigned long len);
--extern void setup_range(int fd, char *driver, unsigned long start,
--                      unsigned long pfn, unsigned long total, int need_vm, 
--                      struct mem_region *region, void *reserved);
- extern void setup_memory(void *entry);
- extern unsigned long find_iomem(char *driver, unsigned long *len_out);
- extern int init_maps(struct mem_region *region);
-diff -Naur a/arch/um/include/os.h b/arch/um/include/os.h
---- a/arch/um/include/os.h     Fri Aug 15 15:04:50 2003
-+++ b/arch/um/include/os.h     Fri Aug 15 15:10:48 2003
-@@ -103,10 +103,11 @@
- extern int os_shutdown_socket(int fd, int r, int w);
- extern void os_close_file(int fd);
- extern int os_rcv_fd(int fd, int *helper_pid_out);
--extern int create_unix_socket(char *file, int len);
-+extern int create_unix_socket(char *file, int len, int close_on_exec);
- extern int os_connect_socket(char *name);
- extern int os_file_type(char *file);
- extern int os_file_mode(char *file, struct openflags *mode_out);
-+extern int os_lock_file(int fd, int excl);
- extern unsigned long os_process_pc(int pid);
- extern int os_process_parent(int pid);
-@@ -120,6 +121,7 @@
- extern int os_protect_memory(void *addr, unsigned long len, 
-                            int r, int w, int x);
- extern int os_unmap_memory(void *addr, int len);
-+extern void os_flush_stdout(void);
- #endif
-diff -Naur a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
---- a/arch/um/include/sysdep-i386/sigcontext.h Fri Aug 15 15:07:37 2003
-+++ b/arch/um/include/sysdep-i386/sigcontext.h Fri Aug 15 15:13:03 2003
-@@ -28,8 +28,8 @@
-  */
- #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
--/* These are General Protection and Page Fault */
--#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
-+/* This is Page Fault */
-+#define SEGV_IS_FIXABLE(trap) (trap == 14)
- #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
-diff -Naur a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
---- a/arch/um/include/ubd_user.h       Fri Aug 15 15:06:34 2003
-+++ b/arch/um/include/ubd_user.h       Fri Aug 15 15:12:37 2003
-@@ -39,7 +39,6 @@
- extern int write_ubd_fs(int fd, char *buffer, int len);
- extern int start_io_thread(unsigned long sp, int *fds_out);
- extern void do_io(struct io_thread_req *req);
--extern int ubd_is_dir(char *file);
- static inline int ubd_test_bit(__u64 bit, unsigned char *data)
- {
-diff -Naur a/arch/um/include/user.h b/arch/um/include/user.h
---- a/arch/um/include/user.h   Fri Aug 15 15:03:58 2003
-+++ b/arch/um/include/user.h   Fri Aug 15 15:10:14 2003
-@@ -14,7 +14,7 @@
- extern void kfree(void *ptr);
- extern int in_aton(char *str);
- extern int open_gdb_chan(void);
--
-+extern int strlcpy(char *, const char *, int);
- #endif
- /*
-diff -Naur a/arch/um/include/user_util.h b/arch/um/include/user_util.h
---- a/arch/um/include/user_util.h      Fri Aug 15 15:04:33 2003
-+++ b/arch/um/include/user_util.h      Fri Aug 15 15:10:32 2003
-@@ -59,7 +59,6 @@
- extern void *add_signal_handler(int sig, void (*handler)(int));
- extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
-                           int clone_flags, int (*tramp)(void *));
--extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
- extern int linux_main(int argc, char **argv);
- extern void set_cmdline(char *cmd);
- extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
-@@ -90,7 +89,8 @@
- extern int arch_fixup(unsigned long address, void *sc_ptr);
- extern void forward_pending_sigio(int target);
- extern int can_do_skas(void);
-- 
-+extern void arch_init_thread(void);
-+
- #endif
- /*
-diff -Naur a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
---- a/arch/um/kernel/Makefile  Fri Aug 15 15:07:32 2003
-+++ b/arch/um/kernel/Makefile  Fri Aug 15 15:12:57 2003
-@@ -19,6 +19,8 @@
- obj-$(CONFIG_MODE_TT) += tt/
- obj-$(CONFIG_MODE_SKAS) += skas/
-+clean-files   := config.c
-+
- user-objs-$(CONFIG_TTY_LOG) += tty_log.o
- USER_OBJS := $(filter %_user.o,$(obj-y))  $(user-objs-y) config.o helper.o \
-@@ -43,17 +45,13 @@
- $(obj)/frame.o: $(src)/frame.c
-       $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
--QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
-+QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
- $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
-       $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
- $(obj)/config.o : $(obj)/config.c
--clean:
--      rm -f config.c
--      for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
--
- modules:
- fastdep:
-diff -Naur a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
---- a/arch/um/kernel/config.c.in       Fri Aug 15 15:07:37 2003
-+++ b/arch/um/kernel/config.c.in       Fri Aug 15 15:13:03 2003
-@@ -7,9 +7,7 @@
- #include <stdlib.h>
- #include "init.h"
--static __initdata char *config = "
--CONFIG
--";
-+static __initdata char *config = "CONFIG";
- static int __init print_config(char *line, int *add)
- {
-diff -Naur a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
---- a/arch/um/kernel/exec_kern.c       Fri Aug 15 15:04:54 2003
-+++ b/arch/um/kernel/exec_kern.c       Fri Aug 15 15:11:03 2003
-@@ -32,10 +32,15 @@
-       CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
- }
-+extern void log_exec(char **argv, void *tty);
-+
- static int execve1(char *file, char **argv, char **env)
- {
-         int error;
-+#ifdef CONFIG_TTY_LOG
-+      log_exec(argv, current->tty);
-+#endif
-         error = do_execve(file, argv, env, &current->thread.regs);
-         if (error == 0){
-                 current->ptrace &= ~PT_DTRACE;
-diff -Naur a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
---- a/arch/um/kernel/init_task.c       Fri Aug 15 15:09:24 2003
-+++ b/arch/um/kernel/init_task.c       Fri Aug 15 15:14:04 2003
-@@ -17,6 +17,7 @@
- struct mm_struct init_mm = INIT_MM(init_mm);
- static struct files_struct init_files = INIT_FILES;
- static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
- /*
-  * Initial task structure.
-@@ -38,26 +39,12 @@
- __attribute__((__section__(".data.init_task"))) = 
- { INIT_THREAD_INFO(init_task) };
--struct task_struct *alloc_task_struct(void)
--{
--      return((struct task_struct *) 
--             __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
--}
--
- void unprotect_stack(unsigned long stack)
- {
-       protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
-                      1, 1, 0, 1);
- }
--void free_task_struct(struct task_struct *task)
--{
--      /* free_pages decrements the page counter and only actually frees
--       * the pages if they are now not accessed by anything.
--       */
--      free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
--}
--
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
-diff -Naur a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
---- a/arch/um/kernel/irq.c     Fri Aug 15 15:07:53 2003
-+++ b/arch/um/kernel/irq.c     Fri Aug 15 15:13:18 2003
-@@ -28,6 +28,7 @@
- #include "user_util.h"
- #include "kern_util.h"
- #include "irq_user.h"
-+#include "irq_kern.h"
- static void register_irq_proc (unsigned int irq);
-@@ -82,65 +83,52 @@
-       end_none
- };
--/* Not changed */
--volatile unsigned long irq_err_count;
--
- /*
-  * Generic, controller-independent functions:
-  */
--int get_irq_list(char *buf)
-+int show_interrupts(struct seq_file *p, void *v)
- {
-       int i, j;
--      unsigned long flags;
-       struct irqaction * action;
--      char *p = buf;
-+      unsigned long flags;
--      p += sprintf(p, "           ");
--      for (j=0; j<num_online_cpus(); j++)
--              p += sprintf(p, "CPU%d       ",j);
--      *p++ = '\n';
-+      seq_printf(p, "           ");
-+      for (j=0; j<NR_CPUS; j++)
-+              if (cpu_online(j))
-+                      seq_printf(p, "CPU%d       ",j);
-+      seq_putc(p, '\n');
-       for (i = 0 ; i < NR_IRQS ; i++) {
-               spin_lock_irqsave(&irq_desc[i].lock, flags);
-               action = irq_desc[i].action;
-               if (!action) 
--                      goto end;
--              p += sprintf(p, "%3d: ",i);
-+                      goto skip;
-+              seq_printf(p, "%3d: ",i);
- #ifndef CONFIG_SMP
--              p += sprintf(p, "%10u ", kstat_irqs(i));
-+              seq_printf(p, "%10u ", kstat_irqs(i));
- #else
--              for (j = 0; j < num_online_cpus(); j++)
--                      p += sprintf(p, "%10u ",
--                              kstat_cpu(cpu_logical_map(j)).irqs[i]);
-+              for (j = 0; j < NR_CPUS; j++)
-+                      if (cpu_online(j))
-+                              seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
- #endif
--              p += sprintf(p, " %14s", irq_desc[i].handler->typename);
--              p += sprintf(p, "  %s", action->name);
-+              seq_printf(p, " %14s", irq_desc[i].handler->typename);
-+              seq_printf(p, "  %s", action->name);
-               for (action=action->next; action; action = action->next)
--                      p += sprintf(p, ", %s", action->name);
--              *p++ = '\n';
--      end:
-+                      seq_printf(p, ", %s", action->name);
-+
-+              seq_putc(p, '\n');
-+skip:
-               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-       }
--      p += sprintf(p, "\n");
--#ifdef notdef
--#ifdef CONFIG_SMP
--      p += sprintf(p, "LOC: ");
--      for (j = 0; j < num_online_cpus(); j++)
--              p += sprintf(p, "%10u ",
--                      apic_timer_irqs[cpu_logical_map(j)]);
--      p += sprintf(p, "\n");
--#endif
--#endif
--      p += sprintf(p, "ERR: %10lu\n", irq_err_count);
--      return p - buf;
--}
--
-+      seq_printf(p, "NMI: ");
-+      for (j = 0; j < NR_CPUS; j++)
-+              if (cpu_online(j))
-+                      seq_printf(p, "%10u ", nmi_count(j));
-+      seq_putc(p, '\n');
--int show_interrupts(struct seq_file *p, void *v)
--{
--      return(0);
-+      return 0;
- }
- /*
-@@ -281,13 +269,12 @@
-        * 0 return value means that this irq is already being
-        * handled by some other CPU. (or is disabled)
-        */
--      int cpu = smp_processor_id();
-       irq_desc_t *desc = irq_desc + irq;
-       struct irqaction * action;
-       unsigned int status;
-       irq_enter();
--      kstat_cpu(cpu).irqs[irq]++;
-+      kstat_this_cpu.irqs[irq]++;
-       spin_lock(&desc->lock);
-       desc->handler->ack(irq);
-       /*
-@@ -384,7 +371,7 @@
-  */
-  
- int request_irq(unsigned int irq,
--              void (*handler)(int, void *, struct pt_regs *),
-+              irqreturn_t (*handler)(int, void *, struct pt_regs *),
-               unsigned long irqflags, 
-               const char * devname,
-               void *dev_id)
-@@ -430,15 +417,19 @@
- }
- int um_request_irq(unsigned int irq, int fd, int type,
--                 void (*handler)(int, void *, struct pt_regs *),
-+                 irqreturn_t (*handler)(int, void *, struct pt_regs *),
-                  unsigned long irqflags, const char * devname,
-                  void *dev_id)
- {
--      int retval;
-+      int err;
--      retval = request_irq(irq, handler, irqflags, devname, dev_id);
--      if(retval) return(retval);
--      return(activate_fd(irq, fd, type, dev_id));
-+      err = request_irq(irq, handler, irqflags, devname, dev_id);
-+      if(err) 
-+              return(err);
-+
-+      if(fd != -1)
-+              err = activate_fd(irq, fd, type, dev_id);
-+      return(err);
- }
- /* this was setup_x86_irq but it seems pretty generic */
-diff -Naur a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
---- a/arch/um/kernel/mem.c     Fri Aug 15 15:05:20 2003
-+++ b/arch/um/kernel/mem.c     Fri Aug 15 15:11:21 2003
-@@ -119,11 +119,6 @@
-       return(kmem_top);
- }
--void set_kmem_end(unsigned long new)
--{
--      kmem_top = new;
--}
--
- #ifdef CONFIG_HIGHMEM
- /* Changed during early boot */
- pte_t *kmap_pte;
-@@ -218,7 +213,7 @@
-               if(regions[i] == NULL) break;           
-       }
-       if(i == NREGIONS){
--              printk("setup_range : no free regions\n");
-+              printk("setup_one_range : no free regions\n");
-               i = -1;
-               goto out;
-       }
-@@ -227,7 +222,9 @@
-               fd = create_mem_file(len);
-       if(region == NULL){
--              region = alloc_bootmem_low_pages(sizeof(*region));
-+              if(kmalloc_ok)
-+                      region = kmalloc(sizeof(*region), GFP_KERNEL);
-+              else region = alloc_bootmem_low_pages(sizeof(*region));
-               if(region == NULL)
-                       panic("Failed to allocating mem_region");
-       }
-@@ -528,9 +525,9 @@
-       return(NREGIONS);
- }
--void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
--               unsigned long len, int need_vm, struct mem_region *region, 
--               void *reserved)
-+static void setup_range(int fd, char *driver, unsigned long start, 
-+                      unsigned long pfn, unsigned long len, int need_vm, 
-+                      struct mem_region *region, void *reserved)
- {
-       int i, cur;
-diff -Naur a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
---- a/arch/um/kernel/mem_user.c        Fri Aug 15 15:06:25 2003
-+++ b/arch/um/kernel/mem_user.c        Fri Aug 15 15:12:36 2003
-@@ -111,6 +111,11 @@
-               offset = 0;
-       }
-+      if(offset >= region->len){
-+              printf("%d bytes of physical memory is insufficient\n",
-+                     region->len);
-+              exit(1);
-+      }
-       loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
-                  MAP_SHARED | MAP_FIXED, region->fd, offset);
-       if(loc != start){
-@@ -122,26 +127,26 @@
- static int __init parse_iomem(char *str, int *add)
- {
--      struct stat buf;
-+      struct stat64 buf;
-       char *file, *driver;
-       int fd;
-       driver = str;
-       file = strchr(str,',');
-       if(file == NULL){
--              printk("parse_iomem : failed to parse iomem\n");
-+              printf("parse_iomem : failed to parse iomem\n");
-               return(1);
-       }
-       *file = '\0';
-       file++;
-       fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
-       if(fd < 0){
--              printk("parse_iomem - Couldn't open io file, errno = %d\n", 
-+              printf("parse_iomem - Couldn't open io file, errno = %d\n", 
-                      errno);
-               return(1);
-       }
--      if(fstat(fd, &buf) < 0) {
--              printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
-+      if(fstat64(fd, &buf) < 0) {
-+              printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
-               return(1);
-       }
-       add_iomem(driver, fd, buf.st_size);
-diff -Naur a/arch/um/kernel/process.c b/arch/um/kernel/process.c
---- a/arch/um/kernel/process.c Fri Aug 15 15:08:15 2003
-+++ b/arch/um/kernel/process.c Fri Aug 15 15:13:26 2003
-@@ -72,7 +72,6 @@
-                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
-       set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
-                   SA_NOMASK | flags, -1);
--      (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
-       signal(SIGHUP, SIG_IGN);
-       init_irq_signals(altstack);
-@@ -127,7 +126,8 @@
-       if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
-                         errno);
-       if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
--              panic("outer trampoline didn't exit with SIGKILL");
-+              panic("outer trampoline didn't exit with SIGKILL, "
-+                    "status = %d", status);
-       return(arg.pid);
- }
-diff -Naur a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
---- a/arch/um/kernel/process_kern.c    Fri Aug 15 15:06:24 2003
-+++ b/arch/um/kernel/process_kern.c    Fri Aug 15 15:12:35 2003
-@@ -52,17 +52,12 @@
- struct task_struct *get_task(int pid, int require)
- {
--        struct task_struct *task, *ret;
-+        struct task_struct *ret;
--        ret = NULL;
-         read_lock(&tasklist_lock);
--        for_each_process(task){
--                if(task->pid == pid){
--                        ret = task;
--                        break;
--                }
--        }
-+      ret = find_task_by_pid(pid);
-         read_unlock(&tasklist_lock);
-+
-         if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
-         return(ret);
- }
-@@ -103,13 +98,14 @@
- int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
--      struct task_struct *p;
-+      int pid;
-       current->thread.request.u.thread.proc = fn;
-       current->thread.request.u.thread.arg = arg;
--      p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
--      if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
--      return(p->pid);
-+      pid = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
-+      if(pid < 0)
-+              panic("do_fork failed in kernel_thread, errno = %d", pid);
-+      return(pid);
- }
- void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
-@@ -157,6 +153,10 @@
-       return(current);
- }
-+void prepare_to_copy(struct task_struct *tsk)
-+{
-+}
-+
- int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
-               unsigned long stack_top, struct task_struct * p, 
-               struct pt_regs *regs)
-@@ -190,7 +190,7 @@
- void default_idle(void)
- {
--      idle_timer();
-+      uml_idle_timer();
-       atomic_inc(&init_mm.mm_count);
-       current->mm = &init_mm;
-@@ -363,6 +363,11 @@
-       return(clear_user(buf, size));
- }
-+int strlen_user_proc(char *str)
-+{
-+      return(strlen_user(str));
-+}
-+
- int smp_sigio_handler(void)
- {
- #ifdef CONFIG_SMP
-diff -Naur a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
---- a/arch/um/kernel/ptrace.c  Fri Aug 15 15:04:36 2003
-+++ b/arch/um/kernel/ptrace.c  Fri Aug 15 15:10:33 2003
-@@ -311,11 +311,8 @@
-       /* the 0x80 provides a way for the tracing parent to distinguish
-          between a syscall stop and SIGTRAP delivery */
--      current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
--                                      ? 0x80 : 0);
--      current->state = TASK_STOPPED;
--      notify_parent(current, SIGCHLD);
--      schedule();
-+      ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-+                               ? 0x80 : 0));
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-diff -Naur a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
---- a/arch/um/kernel/sigio_kern.c      Fri Aug 15 15:04:52 2003
-+++ b/arch/um/kernel/sigio_kern.c      Fri Aug 15 15:10:59 2003
-@@ -6,18 +6,21 @@
- #include "linux/kernel.h"
- #include "linux/list.h"
- #include "linux/slab.h"
--#include "asm/irq.h"
-+#include "linux/signal.h"
-+#include "linux/interrupt.h"
- #include "init.h"
- #include "sigio.h"
- #include "irq_user.h"
-+#include "irq_kern.h"
- /* Protected by sigio_lock() called from write_sigio_workaround */
- static int sigio_irq_fd = -1;
--void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
-+irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
- {
-       read_sigio_fd(sigio_irq_fd);
-       reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
-+      return(IRQ_HANDLED);
- }
- int write_sigio_irq(int fd)
-diff -Naur a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
---- a/arch/um/kernel/signal_kern.c     Fri Aug 15 15:06:38 2003
-+++ b/arch/um/kernel/signal_kern.c     Fri Aug 15 15:12:40 2003
-@@ -36,7 +36,7 @@
-       if(sig == SIGSEGV){
-               struct k_sigaction *ka;
--              ka = &current->sig->action[SIGSEGV - 1];
-+              ka = &current->sighand->action[SIGSEGV - 1];
-               ka->sa.sa_handler = SIG_DFL;
-       }
-       force_sig(SIGSEGV, current);
-@@ -142,7 +142,7 @@
-               return(0);
-       /* Whee!  Actually deliver the signal.  */
--      ka = &current->sig->action[sig -1 ];
-+      ka = &current->sighand->action[sig -1 ];
-       err = handle_signal(regs, sig, ka, &info, oldset, error);
-       if(!err) return(1);
-@@ -201,7 +201,7 @@
-       }
- }
--int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
-+int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
- {
-       sigset_t saveset, newset;
-@@ -227,6 +227,42 @@
-       }
- }
-+int sys_sigaction(int sig, const struct old_sigaction __user *act,
-+                       struct old_sigaction __user *oact)
-+{
-+      struct k_sigaction new_ka, old_ka;
-+      int ret;
-+
-+      if (act) {
-+              old_sigset_t mask;
-+              if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
-+                  __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-+                  __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
-+                      return -EFAULT;
-+              __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-+              __get_user(mask, &act->sa_mask);
-+              siginitset(&new_ka.sa.sa_mask, mask);
-+      }
-+
-+      ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-+
-+      if (!ret && oact) {
-+              if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-+                  __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-+                  __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
-+                      return -EFAULT;
-+              __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-+              __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
-+      }
-+
-+      return ret;
-+}
-+
-+int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
-+{
-+      return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
-+}
-+
- static int copy_sc_from_user(struct pt_regs *to, void *from, 
-                            struct arch_frame_data *arch)
- {
-@@ -239,8 +275,8 @@
- int sys_sigreturn(struct pt_regs regs)
- {
--      void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
--      void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
-+      void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
-+      void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
-       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
-       spin_lock_irq(&current->sighand->siglock);
-@@ -257,7 +293,8 @@
- int sys_rt_sigreturn(struct pt_regs regs)
- {
--      struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
-+      unsigned long sp = PT_REGS_SP(&current->thread.regs);
-+      struct ucontext __user *uc = sp_to_uc(sp);
-       void *fp;
-       int sig_size = _NSIG_WORDS * sizeof(unsigned long);
-diff -Naur a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
---- a/arch/um/kernel/skas/Makefile     Fri Aug 15 15:05:00 2003
-+++ b/arch/um/kernel/skas/Makefile     Fri Aug 15 15:11:08 2003
-@@ -7,18 +7,22 @@
-       process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
-       sys-$(SUBARCH)/
-+host-progs    := util/mk_ptregs
-+clean-files   := include/skas_ptregs.h
-+
- USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
- USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
--include/skas_ptregs.h : util/mk_ptregs
--      util/mk_ptregs > $@
--
--util/mk_ptregs :
--      $(MAKE) -C util
-+$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
-+      @echo -n '  Generating $@'
-+      @$< > $@.tmp
-+      @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
-+              echo ' (unchanged)'; \
-+              rm -f $@.tmp; \
-+      else \
-+              echo ' (updated)'; \
-+              mv -f $@.tmp $@; \
-+      fi
- $(USER_OBJS) : %.o: %.c
-       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
--
--clean :
--      $(MAKE) -C util clean
--      $(RM) -f include/skas_ptregs.h
-diff -Naur a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h
---- a/arch/um/kernel/skas/include/mode.h       Fri Aug 15 15:06:34 2003
-+++ b/arch/um/kernel/skas/include/mode.h       Fri Aug 15 15:12:37 2003
-@@ -20,6 +20,7 @@
- extern void halt_skas(void);
- extern void reboot_skas(void);
- extern void kill_off_processes_skas(void);
-+extern int is_skas_winch(int pid, int fd, void *data);
- #endif
-diff -Naur a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
---- a/arch/um/kernel/skas/include/uaccess.h    Fri Aug 15 15:05:28 2003
-+++ b/arch/um/kernel/skas/include/uaccess.h    Fri Aug 15 15:11:44 2003
-@@ -19,7 +19,7 @@
- #define access_ok_skas(type, addr, size) \
-       ((segment_eq(get_fs(), KERNEL_DS)) || \
-        (((unsigned long) (addr) < TASK_SIZE) && \
--        ((unsigned long) (addr) + (size) < TASK_SIZE)))
-+        ((unsigned long) (addr) + (size) <= TASK_SIZE)))
- static inline int verify_area_skas(int type, const void * addr, 
-                                  unsigned long size)
-diff -Naur a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
---- a/arch/um/kernel/skas/process.c    Fri Aug 15 15:08:54 2003
-+++ b/arch/um/kernel/skas/process.c    Fri Aug 15 15:13:46 2003
-@@ -4,6 +4,7 @@
-  */
- #include <stdlib.h>
-+#include <unistd.h>
- #include <errno.h>
- #include <signal.h>
- #include <setjmp.h>
-@@ -24,6 +25,16 @@
- #include "os.h"
- #include "proc_mm.h"
- #include "skas_ptrace.h"
-+#include "chan_user.h"
-+
-+int is_skas_winch(int pid, int fd, void *data)
-+{
-+      if(pid != getpid())
-+              return(0);
-+
-+      register_winch_irq(-1, fd, -1, data);
-+      return(1);
-+}
- unsigned long exec_regs[FRAME_SIZE];
- unsigned long exec_fp_regs[HOST_FP_SIZE];
-@@ -72,8 +83,6 @@
-       handle_syscall(regs);
- }
--int userspace_pid;
--
- static int userspace_tramp(void *arg)
- {
-       init_new_thread_signals(0);
-@@ -83,6 +92,8 @@
-       return(0);
- }
-+int userspace_pid;
-+
- void start_userspace(void)
- {
-       void *stack;
-@@ -149,6 +160,7 @@
-                       case SIGILL:
-                       case SIGBUS:
-                       case SIGFPE:
-+                      case SIGWINCH:
-                               user_signal(WSTOPSIG(status), regs);
-                               break;
-                       default:
-@@ -328,7 +340,8 @@
- int new_mm(int from)
- {
-       struct proc_mm_op copy;
--      int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
-+      int n, fd = os_open_file("/proc/mm", 
-+                               of_cloexec(of_write(OPENFLAGS())), 0);
-       if(fd < 0)
-               return(-errno);
-@@ -342,6 +355,7 @@
-                       printk("new_mm : /proc/mm copy_segments failed, "
-                              "errno = %d\n", errno);
-       }
-+
-       return(fd);
- }
-diff -Naur a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
---- a/arch/um/kernel/skas/process_kern.c       Fri Aug 15 15:04:51 2003
-+++ b/arch/um/kernel/skas/process_kern.c       Fri Aug 15 15:10:56 2003
-@@ -61,9 +61,8 @@
-       thread_wait(&current->thread.mode.skas.switch_buf, 
-                   current->thread.mode.skas.fork_buf);
--#ifdef CONFIG_SMP
--      schedule_tail(NULL);
--#endif
-+      if(current->thread.prev_sched != NULL)
-+              schedule_tail(current->thread.prev_sched);
-       current->thread.prev_sched = NULL;
-       n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
-@@ -93,9 +92,8 @@
-                   current->thread.mode.skas.fork_buf);
-       
-       force_flush_all();
--#ifdef CONFIG_SMP
--      schedule_tail(current->thread.prev_sched);
--#endif
-+      if(current->thread.prev_sched != NULL)
-+              schedule_tail(current->thread.prev_sched);
-       current->thread.prev_sched = NULL;
-       unblock_signals();
-@@ -164,7 +162,7 @@
-       capture_signal_stack();
-       init_new_thread_signals(1);
--      idle_timer();
-+      uml_idle_timer();
-       init_task.thread.request.u.thread.proc = start_kernel_proc;
-       init_task.thread.request.u.thread.arg = NULL;
-diff -Naur a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs.c
---- a/arch/um/kernel/skas/util/mk_ptregs.c     Fri Aug 15 15:05:20 2003
-+++ b/arch/um/kernel/skas/util/mk_ptregs.c     Fri Aug 15 15:11:21 2003
-@@ -1,3 +1,4 @@
-+#include <stdio.h>
- #include <asm/ptrace.h>
- #include <asm/user.h>
-diff -Naur a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
---- a/arch/um/kernel/smp.c     Fri Aug 15 15:04:50 2003
-+++ b/arch/um/kernel/smp.c     Fri Aug 15 15:10:52 2003
-@@ -140,8 +140,10 @@
-         current->thread.request.u.thread.proc = idle_proc;
-         current->thread.request.u.thread.arg = (void *) cpu;
--      new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
--      if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
-+      new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, 
-+                              NULL);
-+      if(IS_ERR(new_task)) 
-+              panic("copy_process failed in idle_thread");
-       cpu_tasks[cpu] = ((struct cpu_task) 
-                         { .pid =      new_task->thread.mode.tt.extern_pid,
-@@ -150,6 +152,7 @@
-       CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
-                         sizeof(c)),
-                   ({ panic("skas mode doesn't support SMP"); }));
-+      wake_up_forked_process(new_task);
-       return(new_task);
- }
-@@ -254,15 +257,19 @@
-       atomic_inc(&scf_finished);
- }
--int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
--                    int wait)
-+int smp_call_function_on_cpu(void (*_func)(void *info), void *_info, int wait,
-+                              unsigned long mask)
- {
--      int cpus = num_online_cpus() - 1;
--      int i;
--
--      if (!cpus)
--              return 0;
-+      int i, cpu, num_cpus;
-+      cpu = get_cpu();
-+      mask &= ~(1UL << cpu);
-+      num_cpus = hweight32(mask);
-+      if(num_cpus == 0){
-+              put_cpu_no_resched();
-+              return(0);
-+      }
-+      
-       spin_lock_bh(&call_lock);
-       atomic_set(&scf_started, 0);
-       atomic_set(&scf_finished, 0);
-@@ -270,19 +277,25 @@
-       info = _info;
-       for (i=0;i<NR_CPUS;i++)
--              if((i != current->thread_info->cpu) && 
--                 test_bit(i, &cpu_online_map))
-+              if(cpu_online(i) && ((1UL << i) & mask))
-                       write(cpu_data[i].ipi_pipe[1], "C", 1);
--      while (atomic_read(&scf_started) != cpus)
-+      while(atomic_read(&scf_started) != num_cpus)
-               barrier();
--      if (wait)
--              while (atomic_read(&scf_finished) != cpus)
-+      if(wait)
-+              while(atomic_read(&scf_finished) != num_cpus)
-                       barrier();
-       spin_unlock_bh(&call_lock);
--      return 0;
-+      put_cpu_no_resched();
-+      return(0);
-+}
-+
-+int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
-+                    int wait)
-+{
-+      return(smp_call_function_on_cpu(_func, _info, wait, cpu_online_map));
- }
- #endif
-diff -Naur a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
---- a/arch/um/kernel/sys_call_table.c  Fri Aug 15 15:07:57 2003
-+++ b/arch/um/kernel/sys_call_table.c  Fri Aug 15 15:13:24 2003
-@@ -219,6 +219,18 @@
- extern syscall_handler_t sys_gettid;
- extern syscall_handler_t sys_readahead;
- extern syscall_handler_t sys_tkill;
-+extern syscall_handler_t sys_setxattr;
-+extern syscall_handler_t sys_lsetxattr;
-+extern syscall_handler_t sys_fsetxattr;
-+extern syscall_handler_t sys_getxattr;
-+extern syscall_handler_t sys_lgetxattr;
-+extern syscall_handler_t sys_fgetxattr;
-+extern syscall_handler_t sys_listxattr;
-+extern syscall_handler_t sys_llistxattr;
-+extern syscall_handler_t sys_flistxattr;
-+extern syscall_handler_t sys_removexattr;
-+extern syscall_handler_t sys_lremovexattr;
-+extern syscall_handler_t sys_fremovexattr;
- extern syscall_handler_t sys_sendfile64;
- extern syscall_handler_t sys_futex;
- extern syscall_handler_t sys_sched_setaffinity;
-@@ -235,6 +247,19 @@
- extern syscall_handler_t sys_epoll_wait;
- extern syscall_handler_t sys_remap_file_pages;
- extern syscall_handler_t sys_set_tid_address;
-+extern syscall_handler_t sys_timer_create;
-+extern syscall_handler_t sys_timer_settime;
-+extern syscall_handler_t sys_timer_gettime;
-+extern syscall_handler_t sys_timer_getoverrun;
-+extern syscall_handler_t sys_timer_delete;
-+extern syscall_handler_t sys_clock_settime;
-+extern syscall_handler_t sys_clock_gettime;
-+extern syscall_handler_t sys_clock_getres;
-+extern syscall_handler_t sys_clock_nanosleep;
-+extern syscall_handler_t sys_statfs64;
-+extern syscall_handler_t sys_fstatfs64;
-+extern syscall_handler_t sys_tgkill;
-+extern syscall_handler_t sys_utimes;
- #ifdef CONFIG_NFSD
- #define NFSSERVCTL sys_nfsservctl
-@@ -459,18 +484,18 @@
-       [ __NR_getdents64 ] = sys_getdents64,
-       [ __NR_gettid ] = sys_gettid,
-       [ __NR_readahead ] = sys_readahead,
--      [ __NR_setxattr ] = sys_ni_syscall,
--      [ __NR_lsetxattr ] = sys_ni_syscall,
--      [ __NR_fsetxattr ] = sys_ni_syscall,
--      [ __NR_getxattr ] = sys_ni_syscall,
--      [ __NR_lgetxattr ] = sys_ni_syscall,
--      [ __NR_fgetxattr ] = sys_ni_syscall,
--      [ __NR_listxattr ] = sys_ni_syscall,
--      [ __NR_llistxattr ] = sys_ni_syscall,
--      [ __NR_flistxattr ] = sys_ni_syscall,
--      [ __NR_removexattr ] = sys_ni_syscall,
--      [ __NR_lremovexattr ] = sys_ni_syscall,
--      [ __NR_fremovexattr ] = sys_ni_syscall,
-+      [ __NR_setxattr ] = sys_setxattr,
-+      [ __NR_lsetxattr ] = sys_lsetxattr,
-+      [ __NR_fsetxattr ] = sys_fsetxattr,
-+      [ __NR_getxattr ] = sys_getxattr,
-+      [ __NR_lgetxattr ] = sys_lgetxattr,
-+      [ __NR_fgetxattr ] = sys_fgetxattr,
-+      [ __NR_listxattr ] = sys_listxattr,
-+      [ __NR_llistxattr ] = sys_llistxattr,
-+      [ __NR_flistxattr ] = sys_flistxattr,
-+      [ __NR_removexattr ] = sys_removexattr,
-+      [ __NR_lremovexattr ] = sys_lremovexattr,
-+      [ __NR_fremovexattr ] = sys_fremovexattr,
-       [ __NR_tkill ] = sys_tkill,
-       [ __NR_sendfile64 ] = sys_sendfile64,
-       [ __NR_futex ] = sys_futex,
-@@ -488,6 +513,19 @@
-       [ __NR_epoll_wait ] = sys_epoll_wait,
-         [ __NR_remap_file_pages ] = sys_remap_file_pages,
-         [ __NR_set_tid_address ] = sys_set_tid_address,
-+      [ __NR_timer_create ] = sys_timer_create,
-+      [ __NR_timer_settime ] = sys_timer_settime,
-+      [ __NR_timer_gettime ] = sys_timer_gettime,
-+      [ __NR_timer_getoverrun ] = sys_timer_getoverrun,
-+      [ __NR_timer_delete ] = sys_timer_delete,
-+      [ __NR_clock_settime ] = sys_clock_settime,
-+      [ __NR_clock_gettime ] = sys_clock_gettime,
-+      [ __NR_clock_getres ] = sys_clock_getres,
-+      [ __NR_clock_nanosleep ] = sys_clock_nanosleep,
-+      [ __NR_statfs64 ] = sys_statfs64,
-+      [ __NR_fstatfs64 ] = sys_fstatfs64,
-+      [ __NR_tgkill ] = sys_tgkill,
-+      [ __NR_utimes ] = sys_utimes,
-       ARCH_SYSCALLS
-       [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
-diff -Naur a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
---- a/arch/um/kernel/syscall_kern.c    Fri Aug 15 15:07:37 2003
-+++ b/arch/um/kernel/syscall_kern.c    Fri Aug 15 15:13:03 2003
-@@ -35,39 +35,40 @@
- long sys_fork(void)
- {
--      struct task_struct *p;
-+      long ret;
-       current->thread.forking = 1;
--        p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
-+        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
-       current->thread.forking = 0;
--      return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
-+      return(ret);
- }
--long sys_clone(unsigned long clone_flags, unsigned long newsp)
-+long sys_clone(unsigned long clone_flags, unsigned long newsp, 
-+             int *parent_tid, int *child_tid)
- {
--      struct task_struct *p;
-+      long ret;
-       current->thread.forking = 1;
--      p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
-+      ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
-       current->thread.forking = 0;
--      return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
-+      return(ret);
- }
- long sys_vfork(void)
- {
--      struct task_struct *p;
-+      long ret;
-       current->thread.forking = 1;
--      p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
-+      ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, 
-+                    NULL);
-       current->thread.forking = 0;
--      return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
-+      return(ret);
- }
- /* common code for old and new mmaps */
--static inline long do_mmap2(
--      unsigned long addr, unsigned long len,
--      unsigned long prot, unsigned long flags,
--      unsigned long fd, unsigned long pgoff)
-+long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
-+            unsigned long prot, unsigned long flags, unsigned long fd,
-+            unsigned long pgoff)
- {
-       int error = -EBADF;
-       struct file * file = NULL;
-@@ -79,9 +80,9 @@
-                       goto out;
-       }
--      down_write(&current->mm->mmap_sem);
--      error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--      up_write(&current->mm->mmap_sem);
-+      down_write(&mm->mmap_sem);
-+      error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+      up_write(&mm->mmap_sem);
-       if (file)
-               fput(file);
-@@ -93,7 +94,7 @@
-              unsigned long prot, unsigned long flags,
-              unsigned long fd, unsigned long pgoff)
- {
--      return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+      return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- /*
-@@ -120,7 +121,8 @@
-       if (offset & ~PAGE_MASK)
-               goto out;
--      err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
-+      err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
-+                     offset >> PAGE_SHIFT);
-  out:
-       return err;
- }
-@@ -141,37 +143,6 @@
-         return error;
- }
--int sys_sigaction(int sig, const struct old_sigaction *act,
--                       struct old_sigaction *oact)
--{
--      struct k_sigaction new_ka, old_ka;
--      int ret;
--
--      if (act) {
--              old_sigset_t mask;
--              if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
--                  __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
--                  __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
--                      return -EFAULT;
--              __get_user(new_ka.sa.sa_flags, &act->sa_flags);
--              __get_user(mask, &act->sa_mask);
--              siginitset(&new_ka.sa.sa_mask, mask);
--      }
--
--      ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
--
--      if (!ret && oact) {
--              if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
--                  __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
--                  __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
--                      return -EFAULT;
--              __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
--              __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
--      }
--
--      return ret;
--}
--
- /*
-  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
-  *
-@@ -253,7 +224,7 @@
-               return sys_shmctl (first, second,
-                                  (struct shmid_ds *) ptr);
-       default:
--              return -EINVAL;
-+              return -ENOSYS;
-       }
- }
-@@ -302,11 +273,6 @@
-       return error;
- }
--int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
--{
--      return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
--}
--
- long execute_syscall(void *r)
- {
-       return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
-diff -Naur a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
---- a/arch/um/kernel/sysrq.c   Fri Aug 15 15:05:01 2003
-+++ b/arch/um/kernel/sysrq.c   Fri Aug 15 15:11:13 2003
-@@ -11,6 +11,14 @@
- #include "sysrq.h"
- #include "user_util.h"
-+void show_stack(struct task_struct *task, unsigned long *sp)
-+{
-+      if(task)
-+              show_trace_task(task);
-+      else
-+              show_trace(sp);
-+}
-+
- void show_trace(unsigned long * stack)
- {
-         int i;
-diff -Naur a/arch/um/kernel/time.c b/arch/um/kernel/time.c
---- a/arch/um/kernel/time.c    Fri Aug 15 15:04:49 2003
-+++ b/arch/um/kernel/time.c    Fri Aug 15 15:10:46 2003
-@@ -15,12 +15,16 @@
- #include "process.h"
- #include "signal_user.h"
- #include "time_user.h"
-+#include "kern_constants.h"
- extern struct timeval xtime;
-+struct timeval local_offset = { 0, 0 };
-+
- void timer(void)
- {
-       gettimeofday(&xtime, NULL);
-+      timeradd(&xtime, &local_offset, &xtime);
- }
- void set_interval(int timer_type)
-@@ -65,7 +69,7 @@
-                      errno);
- }
--void idle_timer(void)
-+void uml_idle_timer(void)
- {
-       if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
-               panic("Couldn't unset SIGVTALRM handler");
-@@ -82,8 +86,6 @@
-       set_interval(ITIMER_VIRTUAL);
- }
--struct timeval local_offset = { 0, 0 };
--
- void do_gettimeofday(struct timeval *tv)
- {
-       unsigned long flags;
-@@ -100,7 +102,7 @@
-       unsigned long flags;
-       struct timeval tv_in;
--      if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-+      if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
-               return -EINVAL;
-       tv_in.tv_sec = tv->tv_sec;
-@@ -110,6 +112,8 @@
-       gettimeofday(&now, NULL);
-       timersub(&tv_in, &now, &local_offset);
-       time_unlock(flags);
-+
-+      return(0);
- }
- void idle_sleep(int secs)
-diff -Naur a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
---- a/arch/um/kernel/time_kern.c       Fri Aug 15 15:07:19 2003
-+++ b/arch/um/kernel/time_kern.c       Fri Aug 15 15:12:46 2003
-@@ -55,12 +55,13 @@
-       do_timer(&regs);
- }
--void um_timer(int irq, void *dev, struct pt_regs *regs)
-+irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
- {
-       do_timer(regs);
--      write_seqlock(&xtime_lock);
-+      write_seqlock_irq(&xtime_lock);
-       timer();
--      write_sequnlock(&xtime_lock);
-+      write_sequnlock_irq(&xtime_lock);
-+      return(IRQ_HANDLED);
- }
- long um_time(int * tloc)
-@@ -78,12 +79,12 @@
- long um_stime(int * tptr)
- {
-       int value;
--      struct timeval new;
-+      struct timespec new;
-       if (get_user(value, tptr))
-                 return -EFAULT;
-       new.tv_sec = value;
--      new.tv_usec = 0;
-+      new.tv_nsec = 0;
-       do_settimeofday(&new);
-       return 0;
- }
-@@ -122,7 +123,9 @@
- void timer_handler(int sig, union uml_pt_regs *regs)
- {
- #ifdef CONFIG_SMP
-+      local_irq_disable();
-       update_process_times(user_context(UPT_SP(regs)));
-+      local_irq_enable();
- #endif
-       if(current->thread_info->cpu == 0)
-               timer_irq(regs);
-diff -Naur a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
---- a/arch/um/kernel/trap_kern.c       Fri Aug 15 15:04:01 2003
-+++ b/arch/um/kernel/trap_kern.c       Fri Aug 15 15:10:18 2003
-@@ -16,6 +16,7 @@
- #include "asm/tlbflush.h"
- #include "asm/a.out.h"
- #include "asm/current.h"
-+#include "asm/irq.h"
- #include "user_util.h"
- #include "kern_util.h"
- #include "kern.h"
-@@ -180,6 +181,11 @@
-       else relay_signal(sig, regs);
- }
-+void winch(int sig, union uml_pt_regs *regs)
-+{
-+      do_IRQ(WINCH_IRQ, regs);
-+}
-+
- void trap_init(void)
- {
- }
-diff -Naur a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
---- a/arch/um/kernel/trap_user.c       Fri Aug 15 15:05:45 2003
-+++ b/arch/um/kernel/trap_user.c       Fri Aug 15 15:11:52 2003
-@@ -82,6 +82,8 @@
-                    .is_irq            = 0 },
-       [ SIGILL ] { .handler           = relay_signal,
-                    .is_irq            = 0 },
-+      [ SIGWINCH ] { .handler         = winch,
-+                     .is_irq          = 1 },
-       [ SIGBUS ] { .handler           = bus_handler,
-                    .is_irq            = 0 },
-       [ SIGSEGV] { .handler           = segv_handler,
-diff -Naur a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h
---- a/arch/um/kernel/tt/include/uaccess.h      Fri Aug 15 15:07:25 2003
-+++ b/arch/um/kernel/tt/include/uaccess.h      Fri Aug 15 15:12:52 2003
-@@ -46,18 +46,20 @@
- static inline int copy_from_user_tt(void *to, const void *from, int n)
- {
--      return(access_ok_tt(VERIFY_READ, from, n) ?
--             __do_copy_from_user(to, from, n, 
--                                 &current->thread.fault_addr,
--                                 &current->thread.fault_catcher) : n);
-+      if(!access_ok_tt(VERIFY_READ, from, n)) 
-+              return(n);
-+
-+      return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
-+                                 &current->thread.fault_catcher));
- }
- static inline int copy_to_user_tt(void *to, const void *from, int n)
- {
--      return(access_ok_tt(VERIFY_WRITE, to, n) ?
--             __do_copy_to_user(to, from, n, 
--                                 &current->thread.fault_addr,
--                                 &current->thread.fault_catcher) : n);
-+      if(!access_ok_tt(VERIFY_WRITE, to, n))
-+              return(n);
-+              
-+      return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
-+                               &current->thread.fault_catcher));
- }
- extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
-@@ -67,7 +69,9 @@
- {
-       int n;
--      if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
-+      if(!access_ok_tt(VERIFY_READ, src, 1)) 
-+              return(-EFAULT);
-+
-       n = __do_strncpy_from_user(dst, src, count, 
-                                  &current->thread.fault_addr,
-                                  &current->thread.fault_catcher);
-@@ -87,10 +91,11 @@
- static inline int clear_user_tt(void *mem, int len)
- {
--      return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
--             __do_clear_user(mem, len, 
--                             &current->thread.fault_addr,
--                             &current->thread.fault_catcher) : len);
-+      if(!access_ok_tt(VERIFY_WRITE, mem, len))
-+              return(len);
-+
-+      return(__do_clear_user(mem, len, &current->thread.fault_addr,
-+                             &current->thread.fault_catcher));
- }
- extern int __do_strnlen_user(const char *str, unsigned long n,
-diff -Naur a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
---- a/arch/um/kernel/tt/process_kern.c Fri Aug 15 15:07:55 2003
-+++ b/arch/um/kernel/tt/process_kern.c Fri Aug 15 15:13:23 2003
-@@ -104,7 +104,10 @@
- void release_thread_tt(struct task_struct *task)
- {
--      os_kill_process(task->thread.mode.tt.extern_pid, 0);
-+      int pid = task->thread.mode.tt.extern_pid;
-+
-+      if(os_getpid() != pid)
-+              os_kill_process(pid, 0);
- }
- void exit_thread_tt(void)
-@@ -125,27 +128,27 @@
-       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
-       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
--      block_signals();
-+      force_flush_all();
-+      if(current->thread.prev_sched != NULL)
-+              schedule_tail(current->thread.prev_sched);
-+      current->thread.prev_sched = NULL;
-+
-       init_new_thread_signals(1);
--#ifdef CONFIG_SMP
--      schedule_tail(current->thread.prev_sched);
--#endif
-       enable_timer();
-       free_page(current->thread.temp_stack);
-       set_cmdline("(kernel thread)");
--      force_flush_all();
--      current->thread.prev_sched = NULL;
-       change_sig(SIGUSR1, 1);
-       change_sig(SIGVTALRM, 1);
-       change_sig(SIGPROF, 1);
--      unblock_signals();
-+      local_irq_enable();
-       if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
-               do_exit(0);
- }
- static int new_thread_proc(void *stack)
- {
-+      local_irq_disable();
-       init_new_thread_stack(stack, new_thread_handler);
-       os_usr1_process(os_getpid());
-       return(0);
-@@ -165,35 +168,32 @@
-       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
-       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
--#ifdef CONFIG_SMP     
--      schedule_tail(NULL);
--#endif
-+      force_flush_all();
-+      if(current->thread.prev_sched != NULL)
-+              schedule_tail(current->thread.prev_sched);
-+      current->thread.prev_sched = NULL;
-+
-       enable_timer();
-       change_sig(SIGVTALRM, 1);
-       local_irq_enable();
--      force_flush_all();
-       if(current->mm != current->parent->mm)
-               protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
-                              1, 0, 1);
-       task_protections((unsigned long) current->thread_info);
--      current->thread.prev_sched = NULL;
--
-       free_page(current->thread.temp_stack);
-+      local_irq_disable();
-       change_sig(SIGUSR1, 0);
-       set_user_mode(current);
- }
--static int sigusr1 = SIGUSR1;
--
- int fork_tramp(void *stack)
- {
--      int sig = sigusr1;
--
-       local_irq_disable();
-+      arch_init_thread();
-       init_new_thread_stack(stack, finish_fork_handler);
--      kill(os_getpid(), sig);
-+      os_usr1_process(os_getpid());
-       return(0);
- }
-diff -Naur a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
---- a/arch/um/kernel/tt/ptproxy/proxy.c        Fri Aug 15 15:07:01 2003
-+++ b/arch/um/kernel/tt/ptproxy/proxy.c        Fri Aug 15 15:12:44 2003
-@@ -293,10 +293,10 @@
- }
- char gdb_init_string[] = 
--"att 1
--b panic
--b stop
--handle SIGWINCH nostop noprint pass
-+"att 1 \n\
-+b panic \n\
-+b stop \n\
-+handle SIGWINCH nostop noprint pass \n\
- ";
- int start_debugger(char *prog, int startup, int stop, int *fd_out)
-diff -Naur a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
---- a/arch/um/kernel/tt/tracer.c       Fri Aug 15 15:03:51 2003
-+++ b/arch/um/kernel/tt/tracer.c       Fri Aug 15 15:10:12 2003
-@@ -39,7 +39,7 @@
-               return(0);
-       register_winch_irq(tracer_winch[0], fd, -1, data);
--      return(0);
-+      return(1);
- }
- static void tracer_winch_handler(int sig)
-@@ -401,7 +401,7 @@
-               
-               if(!strcmp(line, "go")) debug_stop = 0;
-               else if(!strcmp(line, "parent")) debug_parent = 1;
--              else printk("Unknown debug option : '%s'\n", line);
-+              else printf("Unknown debug option : '%s'\n", line);
-               line = next;
-       }
-diff -Naur a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
---- a/arch/um/kernel/tt/uaccess_user.c Fri Aug 15 15:05:00 2003
-+++ b/arch/um/kernel/tt/uaccess_user.c Fri Aug 15 15:11:10 2003
-@@ -8,15 +8,20 @@
- #include <string.h>
- #include "user_util.h"
- #include "uml_uaccess.h"
-+#include "task.h"
-+#include "kern_util.h"
- int __do_copy_from_user(void *to, const void *from, int n,
-                       void **fault_addr, void **fault_catcher)
- {
-+      struct tt_regs save = TASK_REGS(get_current())->tt;
-       unsigned long fault;
-       int faulted;
-       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
-                              __do_copy, &faulted);
-+      TASK_REGS(get_current())->tt = save;
-+
-       if(!faulted) return(0);
-       else return(n - (fault - (unsigned long) from));
- }
-@@ -29,11 +34,14 @@
- int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
-                          void **fault_addr, void **fault_catcher)
- {
-+      struct tt_regs save = TASK_REGS(get_current())->tt;
-       unsigned long fault;
-       int faulted;
-       fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
-                              __do_strncpy, &faulted);
-+      TASK_REGS(get_current())->tt = save;
-+
-       if(!faulted) return(strlen(dst));
-       else return(-1);
- }
-@@ -46,11 +54,14 @@
- int __do_clear_user(void *mem, unsigned long len,
-                   void **fault_addr, void **fault_catcher)
- {
-+      struct tt_regs save = TASK_REGS(get_current())->tt;
-       unsigned long fault;
-       int faulted;
-       fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
-                              __do_clear, &faulted);
-+      TASK_REGS(get_current())->tt = save;
-+
-       if(!faulted) return(0);
-       else return(len - (fault - (unsigned long) mem));
- }
-@@ -58,6 +69,7 @@
- int __do_strnlen_user(const char *str, unsigned long n,
-                     void **fault_addr, void **fault_catcher)
- {
-+      struct tt_regs save = TASK_REGS(get_current())->tt;
-       int ret;
-       unsigned long *faddrp = (unsigned long *)fault_addr;
-       jmp_buf jbuf;
-@@ -71,6 +83,8 @@
-       }
-       *fault_addr = NULL;
-       *fault_catcher = NULL;
-+
-+      TASK_REGS(get_current())->tt = save;
-       return ret;
- }
-diff -Naur a/arch/um/kernel/tty_log.c b/arch/um/kernel/tty_log.c
---- a/arch/um/kernel/tty_log.c Fri Aug 15 15:07:04 2003
-+++ b/arch/um/kernel/tty_log.c Fri Aug 15 15:12:44 2003
-@@ -13,6 +13,7 @@
- #include <sys/time.h>
- #include "init.h"
- #include "user.h"
-+#include "kern_util.h"
- #include "os.h"
- #define TTY_LOG_DIR "./"
-@@ -24,29 +25,40 @@
- #define TTY_LOG_OPEN 1
- #define TTY_LOG_CLOSE 2
- #define TTY_LOG_WRITE 3
-+#define TTY_LOG_EXEC 4
-+
-+#define TTY_READ 1
-+#define TTY_WRITE 2
- struct tty_log_buf {
-       int what;
-       unsigned long tty;
-       int len;
-+      int direction;
-+      unsigned long sec;
-+      unsigned long usec;
- };
--int open_tty_log(void *tty)
-+int open_tty_log(void *tty, void *current_tty)
- {
-       struct timeval tv;
-       struct tty_log_buf data;
-       char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
-       int fd;
-+      gettimeofday(&tv, NULL);
-       if(tty_log_fd != -1){
--              data = ((struct tty_log_buf) { what :   TTY_LOG_OPEN,
--                                             tty : (unsigned long) tty,
--                                             len : 0 });
-+              data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
-+                                             .tty  = (unsigned long) tty,
-+                                             .len  = sizeof(current_tty),
-+                                             .direction = 0,
-+                                             .sec = tv.tv_sec,
-+                                             .usec = tv.tv_usec } );
-               write(tty_log_fd, &data, sizeof(data));
-+              write(tty_log_fd, &current_tty, data.len);
-               return(tty_log_fd);
-       }
--      gettimeofday(&tv, NULL);
-       sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
-               (unsigned int) tv.tv_usec);
-@@ -62,30 +74,114 @@
- void close_tty_log(int fd, void *tty)
- {
-       struct tty_log_buf data;
-+      struct timeval tv;
-       if(tty_log_fd != -1){
--              data = ((struct tty_log_buf) { what :   TTY_LOG_CLOSE,
--                                             tty : (unsigned long) tty,
--                                             len : 0 });
-+              gettimeofday(&tv, NULL);
-+              data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
-+                                             .tty  = (unsigned long) tty,
-+                                             .len  = 0,
-+                                             .direction = 0,
-+                                             .sec = tv.tv_sec,
-+                                             .usec = tv.tv_usec } );
-               write(tty_log_fd, &data, sizeof(data));
-               return;
-       }
-       close(fd);
- }
--int write_tty_log(int fd, char *buf, int len, void *tty)
-+static int log_chunk(int fd, const char *buf, int len)
- {
-+      int total = 0, try, missed, n;
-+      char chunk[64];
-+
-+      while(len > 0){
-+              try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
-+              missed = copy_from_user_proc(chunk, (char *) buf, try);
-+              try -= missed;
-+              n = write(fd, chunk, try);
-+              if(n != try)
-+                      return(-errno);
-+              if(missed != 0)
-+                      return(-EFAULT);
-+
-+              len -= try;
-+              total += try;
-+              buf += try;
-+      }
-+
-+      return(total);
-+}
-+
-+int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
-+{
-+      struct timeval tv;
-       struct tty_log_buf data;
-+      int direction;
-       if(fd == tty_log_fd){
--              data = ((struct tty_log_buf) { what :   TTY_LOG_WRITE,
--                                             tty : (unsigned long) tty,
--                                             len : len });
-+              gettimeofday(&tv, NULL);
-+              direction = is_read ? TTY_READ : TTY_WRITE;
-+              data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
-+                                             .tty  = (unsigned long) tty,
-+                                             .len  = len,
-+                                             .direction = direction,
-+                                             .sec = tv.tv_sec,
-+                                             .usec = tv.tv_usec } );
-               write(tty_log_fd, &data, sizeof(data));
-       }
--      return(write(fd, buf, len));
-+
-+      return(log_chunk(fd, buf, len));
- }
-+void log_exec(char **argv, void *tty)
-+{
-+      struct timeval tv;
-+      struct tty_log_buf data;
-+      char **ptr,*arg;
-+      int len;
-+      
-+      if(tty_log_fd == -1) return;
-+
-+      gettimeofday(&tv, NULL);
-+
-+      len = 0;
-+      for(ptr = argv; ; ptr++){
-+              if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
-+                      return;
-+              if(arg == NULL) break;
-+              len += strlen_user_proc(arg);
-+      }
-+
-+      data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
-+                                     .tty  = (unsigned long) tty,
-+                                     .len  = len,
-+                                     .direction = 0,
-+                                     .sec = tv.tv_sec,
-+                                     .usec = tv.tv_usec } );
-+      write(tty_log_fd, &data, sizeof(data));
-+
-+      for(ptr = argv; ; ptr++){
-+              if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
-+                      return;
-+              if(arg == NULL) break;
-+              log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
-+      }
-+}
-+
-+extern void register_tty_logger(int (*opener)(void *, void *),
-+                              int (*writer)(int, const char *, int, 
-+                                            void *, int),
-+                              void (*closer)(int, void *));
-+
-+static int register_logger(void)
-+{
-+      register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
-+      return(0);
-+}
-+
-+__uml_initcall(register_logger);
-+
- static int __init set_tty_log_dir(char *name, int *add)
- {
-       tty_log_dir = name;
-@@ -104,7 +200,7 @@
-       tty_log_fd = strtoul(name, &end, 0);
-       if((*end != '\0') || (end == name)){
--              printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
-+              printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
-               tty_log_fd = -1;
-       }
-       return 0;
-diff -Naur a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
---- a/arch/um/kernel/um_arch.c Fri Aug 15 15:07:48 2003
-+++ b/arch/um/kernel/um_arch.c Fri Aug 15 15:13:14 2003
-@@ -38,13 +38,18 @@
- #include "mode_kern.h"
- #include "mode.h"
--#define DEFAULT_COMMAND_LINE "root=6200"
-+#define DEFAULT_COMMAND_LINE "root=ubd0"
- struct cpuinfo_um boot_cpu_data = { 
-       .loops_per_jiffy        = 0,
-       .ipi_pipe               = { -1, -1 }
- };
-+/* Placeholder to make UML link until the vsyscall stuff is actually 
-+ * implemented
-+ */
-+void *__kernel_vsyscall;
-+
- unsigned long thread_saved_pc(struct task_struct *task)
- {
-       return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
-@@ -61,10 +66,14 @@
-               return 0;
- #endif
--      seq_printf(m, "bogomips\t: %lu.%02lu\n",
-+      seq_printf(m, "processor\t: %d\n", index);
-+      seq_printf(m, "vendor_id\t: User Mode Linux\n");
-+      seq_printf(m, "model name\t: UML\n");
-+      seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
-+      seq_printf(m, "host\t\t: %s\n", host_info);
-+      seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
-                  loops_per_jiffy/(500000/HZ),
-                  (loops_per_jiffy/(5000/HZ)) % 100);
--      seq_printf(m, "host\t\t: %s\n", host_info);
-       return(0);
- }
-@@ -134,12 +143,12 @@
-       if(umid != NULL){
-               snprintf(argv1_begin, 
-                        (argv1_end - argv1_begin) * sizeof(*ptr), 
--                       "(%s)", umid);
-+                       "(%s) ", umid);
-               ptr = &argv1_begin[strlen(argv1_begin)];
-       }
-       else ptr = argv1_begin;
--      snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
-+      snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
-       memset(argv1_begin + strlen(argv1_begin), '\0', 
-              argv1_end - argv1_begin - strlen(argv1_begin));
- #endif
-@@ -179,7 +188,7 @@
- static int __init uml_ncpus_setup(char *line, int *add)
- {
-        if (!sscanf(line, "%d", &ncpus)) {
--               printk("Couldn't parse [%s]\n", line);
-+               printf("Couldn't parse [%s]\n", line);
-                return -1;
-        }
-@@ -210,7 +219,7 @@
- static int __init mode_tt_setup(char *line, int *add)
- {
--      printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
-+      printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
-       return(0);
- }
-@@ -221,7 +230,7 @@
- static int __init mode_tt_setup(char *line, int *add)
- {
--      printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
-+      printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
-       return(0);
- }
-@@ -369,6 +378,7 @@
-               2 * PAGE_SIZE;
-       task_protections((unsigned long) &init_thread_info);
-+      os_flush_stdout();
-       return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
- }
-diff -Naur a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
---- a/arch/um/kernel/umid.c    Fri Aug 15 15:08:44 2003
-+++ b/arch/um/kernel/umid.c    Fri Aug 15 15:13:39 2003
-@@ -33,18 +33,19 @@
- static int umid_is_random = 1;
- static int umid_inited = 0;
--static int make_umid(void);
-+static int make_umid(int (*printer)(const char *fmt, ...));
--static int __init set_umid(char *name, int is_random)
-+static int __init set_umid(char *name, int is_random, 
-+                         int (*printer)(const char *fmt, ...))
- {
-       if(umid_inited){
--              printk("Unique machine name can't be set twice\n");
-+              (*printer)("Unique machine name can't be set twice\n");
-               return(-1);
-       }
-       if(strlen(name) > UMID_LEN - 1)
--              printk("Unique machine name is being truncated to %s "
--                     "characters\n", UMID_LEN);
-+              (*printer)("Unique machine name is being truncated to %s "
-+                         "characters\n", UMID_LEN);
-       strlcpy(umid, name, sizeof(umid));
-       umid_is_random = is_random;
-@@ -54,7 +55,7 @@
- static int __init set_umid_arg(char *name, int *add)
- {
--      return(set_umid(name, 0));
-+      return(set_umid(name, 0, printf));
- }
- __uml_setup("umid=", set_umid_arg,
-@@ -67,7 +68,7 @@
- {
-       int n;
--      if(!umid_inited && make_umid()) return(-1);
-+      if(!umid_inited && make_umid(printk)) return(-1);
-       n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
-       if(n > len){
-@@ -92,14 +93,14 @@
-       fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
-                         0644);
-       if(fd < 0){
--              printk("Open of machine pid file \"%s\" failed - "
-+              printf("Open of machine pid file \"%s\" failed - "
-                      "errno = %d\n", file, -fd);
-               return 0;
-       }
-       sprintf(pid, "%d\n", os_getpid());
-       if(write(fd, pid, strlen(pid)) != strlen(pid))
--              printk("Write of pid file failed - errno = %d\n", errno);
-+              printf("Write of pid file failed - errno = %d\n", errno);
-       close(fd);
-       return 0;
- }
-@@ -197,7 +198,7 @@
-       if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
-               uml_dir = malloc(strlen(name) + 1);
-               if(uml_dir == NULL){
--                      printk("Failed to malloc uml_dir - error = %d\n",
-+                      printf("Failed to malloc uml_dir - error = %d\n",
-                              errno);
-                       uml_dir = name;
-                       return(0);
-@@ -217,7 +218,7 @@
-               char *home = getenv("HOME");
-               if(home == NULL){
--                      printk("make_uml_dir : no value in environment for "
-+                      printf("make_uml_dir : no value in environment for "
-                              "$HOME\n");
-                       exit(1);
-               }
-@@ -239,25 +240,25 @@
-       strcpy(uml_dir, dir);
-       
-       if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
--              printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
-+              printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
-               return(-1);
-       }
-       return 0;
- }
--static int __init make_umid(void)
-+static int __init make_umid(int (*printer)(const char *fmt, ...))
- {
-       int fd, err;
-       char tmp[strlen(uml_dir) + UMID_LEN + 1];
-       strlcpy(tmp, uml_dir, sizeof(tmp));
--      if(*umid == 0){
-+      if(!umid_inited){
-               strcat(tmp, "XXXXXX");
-               fd = mkstemp(tmp);
-               if(fd < 0){
--                      printk("make_umid - mkstemp failed, errno = %d\n",
--                             errno);
-+                      (*printer)("make_umid - mkstemp failed, errno = %d\n",
-+                                 errno);
-                       return(1);
-               }
-@@ -267,7 +268,7 @@
-                * for directories.
-                */
-               unlink(tmp);
--              set_umid(&tmp[strlen(uml_dir)], 1);
-+              set_umid(&tmp[strlen(uml_dir)], 1, printer);
-       }
-       
-       sprintf(tmp, "%s%s", uml_dir, umid);
-@@ -275,14 +276,14 @@
-       if((err = mkdir(tmp, 0777)) < 0){
-               if(errno == EEXIST){
-                       if(not_dead_yet(tmp)){
--                              printk("umid '%s' is in use\n", umid);
-+                              (*printer)("umid '%s' is in use\n", umid);
-                               return(-1);
-                       }
-                       err = mkdir(tmp, 0777);
-               }
-       }
-       if(err < 0){
--              printk("Failed to create %s - errno = %d\n", umid, errno);
-+              (*printer)("Failed to create %s - errno = %d\n", umid, errno);
-               return(-1);
-       }
-@@ -295,7 +296,13 @@
- );
- __uml_postsetup(make_uml_dir);
--__uml_postsetup(make_umid);
-+
-+static int __init make_umid_setup(void)
-+{
-+      return(make_umid(printf));
-+}
-+
-+__uml_postsetup(make_umid_setup);
- __uml_postsetup(create_pid_file);
- /*
-diff -Naur a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
---- a/arch/um/kernel/user_util.c       Fri Aug 15 15:04:48 2003
-+++ b/arch/um/kernel/user_util.c       Fri Aug 15 15:10:41 2003
-@@ -119,17 +119,6 @@
-       }
- }
--int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
--{
--      int pid;
--
--      pid = clone(fn, sp, flags, arg);
--      if(pid < 0) return(-1);
--      wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
--      ptrace(PTRACE_CONT, pid, 0, 0);
--      return(pid);
--}
--
- int raw(int fd, int complain)
- {
-       struct termios tt;
-diff -Naur a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
---- a/arch/um/os-Linux/drivers/tuntap_user.c   Fri Aug 15 15:09:23 2003
-+++ b/arch/um/os-Linux/drivers/tuntap_user.c   Fri Aug 15 15:14:02 2003
-@@ -142,7 +142,7 @@
-                       return(-errno);
-               }
-               memset(&ifr, 0, sizeof(ifr));
--              ifr.ifr_flags = IFF_TAP;
-+              ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-               strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
-               if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
-                       printk("TUNSETIFF failed, errno = %d", errno);
-diff -Naur a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
---- a/arch/um/os-Linux/file.c  Fri Aug 15 15:09:15 2003
-+++ b/arch/um/os-Linux/file.c  Fri Aug 15 15:13:54 2003
-@@ -315,7 +315,7 @@
-       return(new);
- }
--int create_unix_socket(char *file, int len)
-+int create_unix_socket(char *file, int len, int close_on_exec)
- {
-       struct sockaddr_un addr;
-       int sock, err;
-@@ -327,6 +327,10 @@
-               return(-errno);
-       }
-+      if(close_on_exec && fcntl(sock, F_SETFD, 1) < 0)
-+              printk("create_unix_socket : Setting FD_CLOEXEC failed, "
-+                     "errno = %d", errno);
-+
-       addr.sun_family = AF_UNIX;
-       /* XXX Be more careful about overflow */
-@@ -342,6 +346,37 @@
-       return(sock);
- }
-+void os_flush_stdout(void)
-+{
-+      fflush(stdout);
-+}
-+
-+int os_lock_file(int fd, int excl)
-+{
-+      int type = excl ? F_WRLCK : F_RDLCK;
-+      struct flock lock = ((struct flock) { .l_type   = type,
-+                                            .l_whence = SEEK_SET,
-+                                            .l_start  = 0,
-+                                            .l_len    = 0 } );
-+      int err, save;
-+
-+      err = fcntl(fd, F_SETLK, &lock);
-+      if(!err)
-+              goto out;
-+
-+      save = -errno;
-+      err = fcntl(fd, F_GETLK, &lock);
-+      if(err){
-+              err = -errno;
-+              goto out;
-+      }
-+      
-+      printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
-+      err = save;
-+ out:
-+      return(err);
-+}
-+
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
-diff -Naur a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
---- a/arch/um/sys-i386/Makefile        Fri Aug 15 15:04:47 2003
-+++ b/arch/um/sys-i386/Makefile        Fri Aug 15 15:10:35 2003
-@@ -1,7 +1,8 @@
--obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
--      ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
-+obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
-+      ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
- obj-$(CONFIG_HIGHMEM) += highmem.o
-+obj-$(CONFIG_MODULES) += module.o
- USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
- USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-@@ -9,6 +10,8 @@
- SYMLINKS = semaphore.c highmem.c module.c
- SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
-+clean-files := $(SYMLINKS)
-+
- semaphore.c-dir = kernel
- highmem.c-dir = mm
- module.c-dir = kernel
-@@ -24,8 +27,7 @@
- $(SYMLINKS): 
-       $(call make_link,$@)
--clean:
--      $(MAKE) -C util clean
-+subdir- := util
- fastdep:
-diff -Naur a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
---- a/arch/um/sys-i386/bugs.c  Fri Aug 15 15:07:41 2003
-+++ b/arch/um/sys-i386/bugs.c  Fri Aug 15 15:13:14 2003
-@@ -8,6 +8,7 @@
- #include <errno.h>
- #include <string.h>
- #include <sys/signal.h>
-+#include <asm/ldt.h>
- #include "kern_util.h"
- #include "user.h"
- #include "sysdep/ptrace.h"
-@@ -16,8 +17,8 @@
- #define MAXTOKEN 64
- /* Set during early boot */
--int cpu_has_cmov = 1;
--int cpu_has_xmm = 0;
-+int host_has_cmov = 1;
-+int host_has_xmm = 0;
- static char token(int fd, char *buf, int len, char stop)
- {
-@@ -104,6 +105,25 @@
-       return(1);
- }
-+static void disable_lcall(void)
-+{
-+      struct modify_ldt_ldt_s ldt;
-+      int err;
-+
-+      bzero(&ldt, sizeof(ldt));
-+      ldt.entry_number = 7;
-+      ldt.base_addr = 0;
-+      ldt.limit = 0;
-+      err = modify_ldt(1, &ldt, sizeof(ldt));
-+      if(err)
-+              printk("Failed to disable lcall7 - errno = %d\n", errno);
-+}
-+
-+void arch_init_thread(void)
-+{
-+      disable_lcall();
-+}
-+
- void arch_check_bugs(void)
- {
-       int have_it;
-@@ -113,8 +133,8 @@
-                      "checks\n");
-               return;
-       }
--      if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
--      if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
-+      if(check_cpu_feature("cmov", &have_it)) host_has_cmov = have_it;
-+      if(check_cpu_feature("xmm", &have_it)) host_has_xmm = have_it;
- }
- int arch_handle_signal(int sig, union uml_pt_regs *regs)
-@@ -130,18 +150,18 @@
-       if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
-               return(0);
--      if(cpu_has_cmov == 0)
-+      if(host_has_cmov == 0)
-               panic("SIGILL caused by cmov, which this processor doesn't "
-                     "implement, boot a filesystem compiled for older "
-                     "processors");
--      else if(cpu_has_cmov == 1)
-+      else if(host_has_cmov == 1)
-               panic("SIGILL caused by cmov, which this processor claims to "
-                     "implement");
--      else if(cpu_has_cmov == -1)
-+      else if(host_has_cmov == -1)
-               panic("SIGILL caused by cmov, couldn't tell if this processor "
-                     "implements it, boot a filesystem compiled for older "
-                     "processors");
--      else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
-+      else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
-       return(0);
- }
-diff -Naur a/arch/um/uml.lds.S b/arch/um/uml.lds.S
---- a/arch/um/uml.lds.S        Fri Aug 15 15:05:37 2003
-+++ b/arch/um/uml.lds.S        Fri Aug 15 15:11:48 2003
-@@ -26,7 +26,11 @@
-   . = ALIGN(4096);            /* Init code and data */
-   _stext = .;
-   __init_begin = .;
--  .text.init : { *(.text.init) }
-+  .init.text : { 
-+      _sinittext = .;
-+      *(.init.text)
-+      _einittext = .;
-+  }
-   . = ALIGN(4096);
-   .text      :
-   {
-@@ -38,7 +42,7 @@
-   #include "asm/common.lds.S"
--  .data.init : { *(.data.init) }
-+  init.data : { *(init.data) }
-   .data    :
-   {
-     . = ALIGN(KERNEL_STACK_SIZE);             /* init_task */
-diff -Naur a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
---- a/arch/um/util/mk_constants_kern.c Fri Aug 15 15:04:15 2003
-+++ b/arch/um/util/mk_constants_kern.c Fri Aug 15 15:10:27 2003
-@@ -1,5 +1,6 @@
- #include "linux/kernel.h"
- #include "linux/stringify.h"
-+#include "linux/time.h"
- #include "asm/page.h"
- extern void print_head(void);
-@@ -11,6 +12,7 @@
- {
-   print_head();
-   print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
-+
-   print_constant_str("UM_KERN_EMERG", KERN_EMERG);
-   print_constant_str("UM_KERN_ALERT", KERN_ALERT);
-   print_constant_str("UM_KERN_CRIT", KERN_CRIT);
-@@ -19,6 +21,8 @@
-   print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
-   print_constant_str("UM_KERN_INFO", KERN_INFO);
-   print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
-+
-+  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
-   print_tail();
-   return(0);
- }
-diff -Naur a/fs/Makefile b/fs/Makefile
---- a/fs/Makefile      Fri Aug 15 15:06:45 2003
-+++ b/fs/Makefile      Fri Aug 15 15:12:41 2003
-@@ -91,3 +91,5 @@
- obj-$(CONFIG_XFS_FS)          += xfs/
- obj-$(CONFIG_AFS_FS)          += afs/
- obj-$(CONFIG_BEFS_FS)         += befs/
-+obj-$(CONFIG_HOSTFS)          += hostfs/
-+obj-$(CONFIG_HPPFS)           += hppfs/
-diff -Naur a/fs/hostfs/Makefile b/fs/hostfs/Makefile
---- a/fs/hostfs/Makefile       Wed Dec 31 19:00:00 1969
-+++ b/fs/hostfs/Makefile       Fri Aug 15 15:10:07 2003
-@@ -0,0 +1,36 @@
-+# 
-+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
-+# Licensed under the GPL
-+#
-+
-+# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
-+# to __st_ino.  It stayed in the same place, so as long as the correct name
-+# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
-+
-+STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
-+                              echo __)st_ino
-+
-+hostfs-objs := hostfs_kern.o hostfs_user.o
-+
-+obj-y = 
-+obj-$(CONFIG_HOSTFS) += hostfs.o
-+
-+SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
-+
-+USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
-+USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-+
-+USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
-+
-+$(USER_OBJS) : %.o: %.c
-+      $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
-+
-+clean:
-+
-+modules:
-+
-+fastdep:
-+
-+dep:
-+
-+archmrproper: clean
-diff -Naur a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
---- a/fs/hostfs/hostfs.h       Wed Dec 31 19:00:00 1969
-+++ b/fs/hostfs/hostfs.h       Fri Aug 15 15:10:06 2003
-@@ -0,0 +1,79 @@
-+#ifndef __UM_FS_HOSTFS
-+#define __UM_FS_HOSTFS
-+
-+#include "os.h"
-+
-+/* These are exactly the same definitions as in fs.h, but the names are 
-+ * changed so that this file can be included in both kernel and user files.
-+ */
-+
-+#define HOSTFS_ATTR_MODE      1
-+#define HOSTFS_ATTR_UID       2
-+#define HOSTFS_ATTR_GID       4
-+#define HOSTFS_ATTR_SIZE      8
-+#define HOSTFS_ATTR_ATIME     16
-+#define HOSTFS_ATTR_MTIME     32
-+#define HOSTFS_ATTR_CTIME     64
-+#define HOSTFS_ATTR_ATIME_SET 128
-+#define HOSTFS_ATTR_MTIME_SET 256
-+#define HOSTFS_ATTR_FORCE     512     /* Not a change, but a change it */
-+#define HOSTFS_ATTR_ATTR_FLAG 1024
-+
-+struct hostfs_iattr {
-+      unsigned int    ia_valid;
-+      mode_t          ia_mode;
-+      uid_t           ia_uid;
-+      gid_t           ia_gid;
-+      loff_t          ia_size;
-+      struct timespec ia_atime;
-+      struct timespec ia_mtime;
-+      struct timespec ia_ctime;
-+      unsigned int    ia_attr_flags;
-+};
-+
-+extern int stat_file(const char *path, unsigned long long *inode_out, 
-+                   int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
-+                   unsigned long long *size_out, struct timespec *atime_out, 
-+                   struct timespec *mtime_out, struct timespec *ctime_out, 
-+                   int *blksize_out, unsigned long long *blocks_out);
-+extern int access_file(char *path, int r, int w, int x);
-+extern int open_file(char *path, int r, int w, int append);
-+extern int file_type(const char *path, int *rdev);
-+extern void *open_dir(char *path, int *err_out);
-+extern char *read_dir(void *stream, unsigned long long *pos, 
-+                    unsigned long long *ino_out, int *len_out);
-+extern void close_file(void *stream);
-+extern void close_dir(void *stream);
-+extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
-+extern int write_file(int fd, unsigned long long *offset, const char *buf,
-+                    int len);
-+extern int lseek_file(int fd, long long offset, int whence);
-+extern int file_create(char *name, int ur, int uw, int ux, int gr, 
-+                     int gw, int gx, int or, int ow, int ox);
-+extern int set_attr(const char *file, struct hostfs_iattr *attrs);
-+extern int make_symlink(const char *from, const char *to);
-+extern int unlink_file(const char *file);
-+extern int do_mkdir(const char *file, int mode);
-+extern int do_rmdir(const char *file);
-+extern int do_mknod(const char *file, int mode, int dev);
-+extern int link_file(const char *from, const char *to);
-+extern int do_readlink(char *file, char *buf, int size);
-+extern int rename_file(char *from, char *to);
-+extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
-+                   long long *bfree_out, long long *bavail_out, 
-+                   long long *files_out, long long *ffree_out, 
-+                   void *fsid_out, int fsid_size, long *namelen_out, 
-+                   long *spare_out);
-+
-+#endif
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
---- a/fs/hostfs/hostfs_kern.c  Wed Dec 31 19:00:00 1969
-+++ b/fs/hostfs/hostfs_kern.c  Fri Aug 15 15:10:12 2003
-@@ -0,0 +1,1010 @@
-+/* 
-+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
-+ * Licensed under the GPL
-+ *
-+ * Ported the filesystem routines to 2.5.
-+ * 2003-02-10 Petr Baudis <pasky@ucw.cz>
-+ */
-+
-+#include <linux/stddef.h>
-+#include <linux/fs.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
-+#include <linux/blkdev.h>
-+#include <linux/list.h>
-+#include <linux/buffer_head.h>
-+#include <linux/root_dev.h>
-+#include <linux/statfs.h>
-+#include <asm/uaccess.h>
-+#include "hostfs.h"
-+#include "kern_util.h"
-+#include "kern.h"
-+#include "user_util.h"
-+#include "2_5compat.h"
-+#include "init.h"
-+
-+struct hostfs_inode_info {
-+      char *host_filename;
-+      int fd;
-+      int mode;
-+      struct inode vfs_inode;
-+};
-+
-+static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
-+{
-+      return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
-+}
-+
-+#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
-+
-+int hostfs_d_delete(struct dentry *dentry)
-+{
-+      return(1);
-+}
-+
-+struct dentry_operations hostfs_dentry_ops = {
-+      .d_delete               = hostfs_d_delete,
-+};
-+
-+/* Changed in hostfs_args before the kernel starts running */
-+static char *root_ino = "/";
-+static int append = 0;
-+
-+#define HOSTFS_SUPER_MAGIC 0x00c0ffee
-+
-+static struct inode_operations hostfs_iops;
-+static struct inode_operations hostfs_dir_iops;
-+static struct address_space_operations hostfs_link_aops;
-+
-+static int __init hostfs_args(char *options, int *add)
-+{
-+      char *ptr;
-+
-+      ptr = strchr(options, ',');
-+      if(ptr != NULL)
-+              *ptr++ = '\0';
-+      if(*options != '\0')
-+              root_ino = options;
-+
-+      options = ptr;
-+      while(options){
-+              ptr = strchr(options, ',');
-+              if(ptr != NULL)
-+                      *ptr++ = '\0';
-+              if(*options != '\0'){
-+                      if(!strcmp(options, "append"))
-+                              append = 1;
-+                      else printf("hostfs_args - unsupported option - %s\n",
-+                                  options);
-+              }
-+              options = ptr;
-+      }
-+      return(0);
-+}
-+
-+__uml_setup("hostfs=", hostfs_args,
-+"hostfs=<root dir>,<flags>,...\n"
-+"    This is used to set hostfs parameters.  The root directory argument\n"
-+"    is used to confine all hostfs mounts to within the specified directory\n"
-+"    tree on the host.  If this isn't specified, then a user inside UML can\n"
-+"    mount anything on the host that's accessible to the user that's running\n"
-+"    it.\n"
-+"    The only flag currently supported is 'append', which specifies that all\n"
-+"    files opened by hostfs will be opened in append mode.\n\n"
-+);
-+
-+static char *dentry_name(struct dentry *dentry, int extra)
-+{
-+      struct dentry *parent;
-+      char *root, *name;
-+      int len;
-+
-+      len = 0;
-+      parent = dentry;
-+      while(parent->d_parent != parent){
-+              len += parent->d_name.len + 1;
-+              parent = parent->d_parent;
-+      }
-+      
-+      root = HOSTFS_I(parent->d_inode)->host_filename;
-+      len += strlen(root);
-+      name = kmalloc(len + extra + 1, GFP_KERNEL);
-+      if(name == NULL) return(NULL);
-+
-+      name[len] = '\0';
-+      parent = dentry;
-+      while(parent->d_parent != parent){
-+              len -= parent->d_name.len + 1;
-+              name[len] = '/';
-+              strncpy(&name[len + 1], parent->d_name.name, 
-+                      parent->d_name.len);
-+              parent = parent->d_parent;
-+      }
-+      strncpy(name, root, strlen(root));
-+      return(name);
-+}
-+
-+static char *inode_name(struct inode *ino, int extra)
-+{
-+      struct dentry *dentry;
-+
-+      dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
-+      return(dentry_name(dentry, extra));
-+}
-+
-+static int read_name(struct inode *ino, char *name)
-+{
-+      /* The non-int inode fields are copied into ints by stat_file and
-+       * then copied into the inode because passing the actual pointers
-+       * in and having them treated as int * breaks on big-endian machines
-+       */
-+      int err;
-+      int i_mode, i_nlink, i_blksize;
-+      unsigned long long i_size;
-+      unsigned long long i_ino;
-+      unsigned long long i_blocks;
-+
-+      err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, 
-+                      &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, 
-+                      &ino->i_ctime, &i_blksize, &i_blocks);
-+      if(err) 
-+              return(err);
-+
-+      ino->i_ino = i_ino;
-+      ino->i_mode = i_mode;
-+      ino->i_nlink = i_nlink;
-+      ino->i_size = i_size;
-+      ino->i_blksize = i_blksize;
-+      ino->i_blocks = i_blocks;
-+      if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
-+              ino->i_uid = 0;
-+      return(0);
-+}
-+
-+static char *follow_link(char *link)
-+{
-+      int len, n;
-+      char *name, *resolved, *end;
-+
-+      len = 64;
-+      while(1){
-+              n = -ENOMEM;
-+              name = kmalloc(len, GFP_KERNEL);
-+              if(name == NULL)
-+                      goto out;
-+
-+              n = do_readlink(link, name, len);
-+              if(n < len)
-+                      break;
-+              len *= 2;
-+              kfree(name);
-+      }
-+      if(n < 0)
-+              goto out_free;
-+
-+      if(*name == '/')
-+              return(name);
-+
-+      end = strrchr(link, '/');
-+      if(end == NULL)
-+              return(name);
-+
-+      *(end + 1) = '\0';
-+      len = strlen(link) + strlen(name) + 1;
-+
-+      resolved = kmalloc(len, GFP_KERNEL);
-+      if(resolved == NULL){
-+              n = -ENOMEM;
-+              goto out_free;
-+      }
-+
-+      sprintf(resolved, "%s%s", link, name);
-+      kfree(name);
-+      kfree(link);
-+      return(resolved);
-+
-+ out_free:
-+      kfree(name);
-+ out:
-+      return(ERR_PTR(n));
-+}
-+
-+static int read_inode(struct inode *ino)
-+{
-+      char *name;
-+      int err = 0;
-+
-+      /* Unfortunately, we are called from iget() when we don't have a dentry
-+       * allocated yet.
-+       */
-+      if(list_empty(&ino->i_dentry))
-+              goto out;
-+ 
-+      err = -ENOMEM;
-+      name = inode_name(ino, 0);
-+      if(name == NULL) 
-+              goto out;
-+
-+      if(file_type(name, NULL) == OS_TYPE_SYMLINK){
-+              name = follow_link(name);
-+              if(IS_ERR(name)){
-+                      err = PTR_ERR(name);
-+                      goto out;
-+              }
-+      }
-+      
-+      err = read_name(ino, name);
-+      kfree(name);
-+ out:
-+      return(err);
-+}
-+
-+int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
-+{
-+      /* do_statfs uses struct statfs64 internally, but the linux kernel
-+       * struct statfs still has 32-bit versions for most of these fields,
-+       * so we convert them here
-+       */
-+      int err;
-+      long long f_blocks;
-+      long long f_bfree;
-+      long long f_bavail;
-+      long long f_files;
-+      long long f_ffree;
-+
-+      err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
-+                      &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
-+                      &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
-+                      &sf->f_namelen, sf->f_spare);
-+      if(err) return(err);
-+      sf->f_blocks = f_blocks;
-+      sf->f_bfree = f_bfree;
-+      sf->f_bavail = f_bavail;
-+      sf->f_files = f_files;
-+      sf->f_ffree = f_ffree;
-+      sf->f_type = HOSTFS_SUPER_MAGIC;
-+      return(0);
-+}
-+
-+static struct inode *hostfs_alloc_inode(struct super_block *sb)
-+{
-+      struct hostfs_inode_info *hi;
-+
-+      hi = kmalloc(sizeof(*hi), GFP_KERNEL);
-+      if(hi == NULL) 
-+              return(NULL);
-+
-+      *hi = ((struct hostfs_inode_info) { .host_filename      = NULL,
-+                                          .fd                 = -1,
-+                                          .mode               = 0 });
-+      inode_init_once(&hi->vfs_inode);
-+      return(&hi->vfs_inode);
-+}
-+
-+static void hostfs_destroy_inode(struct inode *inode)
-+{
-+      if(HOSTFS_I(inode)->host_filename) 
-+              kfree(HOSTFS_I(inode)->host_filename);
-+
-+      if(HOSTFS_I(inode)->fd != -1) 
-+              close_file(&HOSTFS_I(inode)->fd);
-+
-+      kfree(HOSTFS_I(inode));
-+}
-+
-+static void hostfs_read_inode(struct inode *inode)
-+{
-+      read_inode(inode);
-+}
-+
-+static struct super_operations hostfs_sbops = { 
-+      .alloc_inode    = hostfs_alloc_inode,
-+      .destroy_inode  = hostfs_destroy_inode,
-+      .read_inode     = hostfs_read_inode,
-+      .statfs         = hostfs_statfs,
-+};
-+
-+int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
-+{
-+      void *dir;
-+      char *name;
-+      unsigned long long next, ino;
-+      int error, len;
-+
-+      name = dentry_name(file->f_dentry, 0);
-+      if(name == NULL) return(-ENOMEM);
-+      dir = open_dir(name, &error);
-+      kfree(name);
-+      if(dir == NULL) return(-error);
-+      next = file->f_pos;
-+      while((name = read_dir(dir, &next, &ino, &len)) != NULL){
-+              error = (*filldir)(ent, name, len, file->f_pos, 
-+                                 ino, DT_UNKNOWN);
-+              if(error) break;
-+              file->f_pos = next;
-+      }
-+      close_dir(dir);
-+      return(0);
-+}
-+
-+int hostfs_file_open(struct inode *ino, struct file *file)
-+{
-+      char *name;
-+      int mode = 0, r = 0, w = 0, fd;
-+
-+      mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
-+      if((mode & HOSTFS_I(ino)->mode) == mode)
-+              return(0);
-+
-+      /* The file may already have been opened, but with the wrong access,
-+       * so this resets things and reopens the file with the new access.
-+       */
-+      if(HOSTFS_I(ino)->fd != -1){
-+              close_file(&HOSTFS_I(ino)->fd);
-+              HOSTFS_I(ino)->fd = -1;
-+      }
-+
-+      HOSTFS_I(ino)->mode |= mode;
-+      if(HOSTFS_I(ino)->mode & FMODE_READ) 
-+              r = 1;
-+      if(HOSTFS_I(ino)->mode & FMODE_WRITE) 
-+              w = 1;
-+      if(w) 
-+              r = 1;
-+
-+      name = dentry_name(file->f_dentry, 0);
-+      if(name == NULL) 
-+              return(-ENOMEM);
-+
-+      fd = open_file(name, r, w, append);
-+      kfree(name);
-+      if(fd < 0) return(fd);
-+      FILE_HOSTFS_I(file)->fd = fd;
-+
-+      return(0);
-+}
-+
-+int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
-+{
-+      return(0);
-+}
-+
-+static struct file_operations hostfs_file_fops = {
-+      .llseek         = generic_file_llseek,
-+      .read           = generic_file_read,
-+      .write          = generic_file_write,
-+      .mmap           = generic_file_mmap,
-+      .open           = hostfs_file_open,
-+      .release        = NULL,
-+      .fsync          = hostfs_fsync,
-+};
-+
-+static struct file_operations hostfs_dir_fops = {
-+      .readdir        = hostfs_readdir,
-+      .read           = generic_read_dir,
-+};
-+
-+int hostfs_writepage(struct page *page, struct writeback_control *wbc)
-+{
-+      struct address_space *mapping = page->mapping;
-+      struct inode *inode = mapping->host;
-+      char *buffer;
-+      unsigned long long base;
-+      int count = PAGE_CACHE_SIZE;
-+      int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
-+      int err;
-+
-+      if (page->index >= end_index)
-+              count = inode->i_size & (PAGE_CACHE_SIZE-1);
-+
-+      buffer = kmap(page);
-+      base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
-+
-+      err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
-+      if(err != count){
-+              ClearPageUptodate(page);
-+              goto out;
-+      }
-+
-+      if (base > inode->i_size)
-+              inode->i_size = base;
-+
-+      if (PageError(page))
-+              ClearPageError(page);   
-+      err = 0;
-+
-+ out: 
-+      kunmap(page);
-+
-+      unlock_page(page);
-+      return err; 
-+}
-+
-+int hostfs_readpage(struct file *file, struct page *page)
-+{
-+      char *buffer;
-+      long long start;
-+      int err = 0;
-+
-+      start = (long long) page->index << PAGE_CACHE_SHIFT;
-+      buffer = kmap(page);
-+      err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
-+                      PAGE_CACHE_SIZE);
-+      if(err < 0) goto out;
-+
-+      memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
-+
-+      flush_dcache_page(page);
-+      SetPageUptodate(page);
-+      if (PageError(page)) ClearPageError(page);
-+      err = 0;
-+ out:
-+      kunmap(page);
-+      unlock_page(page);
-+      return(err);
-+}
-+
-+int hostfs_prepare_write(struct file *file, struct page *page, 
-+                       unsigned int from, unsigned int to)
-+{
-+      char *buffer;
-+      long long start, tmp;
-+      int err;
-+
-+      start = (long long) page->index << PAGE_CACHE_SHIFT;
-+      buffer = kmap(page);
-+      if(from != 0){
-+              tmp = start;
-+              err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
-+                              from);
-+              if(err < 0) goto out;
-+      }
-+      if(to != PAGE_CACHE_SIZE){
-+              start += to;
-+              err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
-+                              PAGE_CACHE_SIZE - to);
-+              if(err < 0) goto out;           
-+      }
-+      err = 0;
-+ out:
-+      kunmap(page);
-+      return(err);
-+}
-+
-+int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
-+               unsigned to)
-+{
-+      struct address_space *mapping = page->mapping;
-+      struct inode *inode = mapping->host;
-+      char *buffer;
-+      long long start;
-+      int err = 0;
-+
-+      start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
-+      buffer = kmap(page);
-+      err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, 
-+                       to - from);
-+      if(err > 0) err = 0;
-+      if(!err && (start > inode->i_size))
-+              inode->i_size = start;
-+
-+      kunmap(page);
-+      return(err);
-+}
-+
-+static struct address_space_operations hostfs_aops = {
-+      .writepage      = hostfs_writepage,
-+      .readpage       = hostfs_readpage,
-+/*    .set_page_dirty = __set_page_dirty_nobuffers, */
-+      .prepare_write  = hostfs_prepare_write,
-+      .commit_write   = hostfs_commit_write
-+};
-+
-+static int init_inode(struct inode *inode, struct dentry *dentry)
-+{
-+      char *name;
-+      int type, err = -ENOMEM, rdev;
-+
-+      if(dentry){
-+              name = dentry_name(dentry, 0);
-+              if(name == NULL)
-+                      goto out;
-+              type = file_type(name, &rdev);
-+              kfree(name);
-+      }
-+      else type = OS_TYPE_DIR;
-+
-+      err = 0;
-+      if(type == OS_TYPE_SYMLINK)
-+              inode->i_op = &page_symlink_inode_operations;
-+      else if(type == OS_TYPE_DIR)
-+              inode->i_op = &hostfs_dir_iops;
-+      else inode->i_op = &hostfs_iops;
-+
-+      if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
-+      else inode->i_fop = &hostfs_file_fops;
-+
-+      if(type == OS_TYPE_SYMLINK) 
-+              inode->i_mapping->a_ops = &hostfs_link_aops;
-+      else inode->i_mapping->a_ops = &hostfs_aops;
-+
-+      switch (type) {
-+      case OS_TYPE_CHARDEV:
-+              init_special_inode(inode, S_IFCHR, rdev);
-+              break;
-+      case OS_TYPE_BLOCKDEV:
-+              init_special_inode(inode, S_IFBLK, rdev);
-+              break;
-+      case OS_TYPE_FIFO:
-+              init_special_inode(inode, S_IFIFO, 0);
-+              break;
-+      case OS_TYPE_SOCK:
-+              init_special_inode(inode, S_IFSOCK, 0);
-+              break;
-+      }
-+ out:
-+      return(err);
-+}
-+
-+int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 
-+                 struct nameidata *nd)
-+{
-+      struct inode *inode;
-+      char *name;
-+      int error, fd;
-+
-+      error = -ENOMEM;
-+      inode = iget(dir->i_sb, 0);
-+      if(inode == NULL) goto out;
-+
-+      error = init_inode(inode, dentry);
-+      if(error) 
-+              goto out_put;
-+      
-+      error = -ENOMEM;
-+      name = dentry_name(dentry, 0);
-+      if(name == NULL)
-+              goto out_put;
-+
-+      fd = file_create(name, 
-+                       mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
-+                       mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
-+                       mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
-+      if(fd < 0) 
-+              error = fd;
-+      else error = read_name(inode, name);
-+
-+      kfree(name);
-+      if(error)
-+              goto out_put;
-+
-+      HOSTFS_I(inode)->fd = fd;
-+      HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
-+      d_instantiate(dentry, inode);
-+      return(0);
-+
-+ out_free:
-+      kfree(name);
-+ out_put:
-+      iput(inode);
-+ out:
-+      return(error);
-+}
-+
-+struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 
-+                            struct nameidata *nd)
-+{
-+      struct inode *inode;
-+      char *name;
-+      int err;
-+
-+      err = -ENOMEM;
-+      inode = iget(ino->i_sb, 0);
-+      if(inode == NULL) 
-+              goto out;
-+ 
-+      err = init_inode(inode, dentry);
-+      if(err) 
-+              goto out_put;
-+
-+      err = -ENOMEM;
-+      name = dentry_name(dentry, 0);
-+      if(name == NULL)
-+              goto out_put;
-+
-+      err = read_name(inode, name);
-+      kfree(name);
-+      if(err == -ENOENT){
-+              iput(inode);
-+              inode = NULL;
-+      }
-+      else if(err)
-+              goto out_put;
-+
-+      d_add(dentry, inode);
-+      dentry->d_op = &hostfs_dentry_ops;
-+      return(NULL);
-+
-+ out_put:
-+      iput(inode);
-+ out:
-+      return(ERR_PTR(err));
-+}
-+
-+static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
-+{
-+        char *file;
-+      int len;
-+
-+      file = inode_name(ino, dentry->d_name.len + 1);
-+      if(file == NULL) return(NULL);
-+        strcat(file, "/");
-+      len = strlen(file);
-+        strncat(file, dentry->d_name.name, dentry->d_name.len);
-+      file[len + dentry->d_name.len] = '\0';
-+        return(file);
-+}
-+
-+int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
-+{
-+        char *from_name, *to_name;
-+        int err;
-+
-+        if((from_name = inode_dentry_name(ino, from)) == NULL) 
-+                return(-ENOMEM);
-+        to_name = dentry_name(to, 0);
-+      if(to_name == NULL){
-+              kfree(from_name);
-+              return(-ENOMEM);
-+      }
-+        err = link_file(to_name, from_name);
-+        kfree(from_name);
-+        kfree(to_name);
-+        return(err);
-+}
-+
-+int hostfs_unlink(struct inode *ino, struct dentry *dentry)
-+{
-+      char *file;
-+      int err;
-+
-+      if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-+      if(append)
-+              return(-EPERM);
-+
-+      err = unlink_file(file);
-+      kfree(file);
-+      return(err);
-+}
-+
-+int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
-+{
-+      char *file;
-+      int err;
-+
-+      if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-+      err = make_symlink(file, to);
-+      kfree(file);
-+      return(err);
-+}
-+
-+int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
-+{
-+      char *file;
-+      int err;
-+
-+      if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-+      err = do_mkdir(file, mode);
-+      kfree(file);
-+      return(err);
-+}
-+
-+int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
-+{
-+      char *file;
-+      int err;
-+
-+      if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-+      err = do_rmdir(file);
-+      kfree(file);
-+      return(err);
-+}
-+
-+int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-+{
-+      struct inode *inode;
-+      char *name;
-+      int err = -ENOMEM;
-+ 
-+      inode = iget(dir->i_sb, 0);
-+      if(inode == NULL) 
-+              goto out;
-+
-+      err = init_inode(inode, dentry);
-+      if(err) 
-+              goto out_put;
-+
-+      err = -ENOMEM;
-+      name = dentry_name(dentry, 0);
-+      if(name == NULL)
-+              goto out_put;
-+
-+      init_special_inode(inode, mode, dev);
-+      err = do_mknod(name, mode, dev);
-+      if(err)
-+              goto out_free;
-+
-+      err = read_name(inode, name);
-+      kfree(name);
-+      if(err)
-+              goto out_put;
-+
-+      d_instantiate(dentry, inode);
-+      return(0);
-+
-+ out_free:
-+      kfree(name);
-+ out_put:
-+      iput(inode);
-+ out:
-+      return(err);
-+}
-+
-+int hostfs_rename(struct inode *from_ino, struct dentry *from,
-+                struct inode *to_ino, struct dentry *to)
-+{
-+      char *from_name, *to_name;
-+      int err;
-+
-+      if((from_name = inode_dentry_name(from_ino, from)) == NULL)
-+              return(-ENOMEM);
-+      if((to_name = inode_dentry_name(to_ino, to)) == NULL){
-+              kfree(from_name);
-+              return(-ENOMEM);
-+      }
-+      err = rename_file(from_name, to_name);
-+      kfree(from_name);
-+      kfree(to_name);
-+      return(err);
-+}
-+
-+void hostfs_truncate(struct inode *ino)
-+{
-+      not_implemented();
-+}
-+
-+int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
-+{
-+      char *name;
-+      int r = 0, w = 0, x = 0, err;
-+
-+      if(desired & MAY_READ) r = 1;
-+      if(desired & MAY_WRITE) w = 1;
-+      if(desired & MAY_EXEC) x = 1;
-+      name = inode_name(ino, 0);
-+      if(name == NULL) return(-ENOMEM);
-+      err = access_file(name, r, w, x);
-+      kfree(name);
-+      if(!err) err = vfs_permission(ino, desired);
-+      return(err);
-+}
-+
-+int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
-+{
-+      struct hostfs_iattr attrs;
-+      char *name;
-+      int err;
-+      
-+      if(append) 
-+              attr->ia_valid &= ~ATTR_SIZE;
-+
-+      attrs.ia_valid = 0;
-+      if(attr->ia_valid & ATTR_MODE){
-+              attrs.ia_valid |= HOSTFS_ATTR_MODE;
-+              attrs.ia_mode = attr->ia_mode;
-+      }
-+      if(attr->ia_valid & ATTR_UID){
-+              if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
-+                 (attr->ia_uid == 0))
-+                      attr->ia_uid = getuid();
-+              attrs.ia_valid |= HOSTFS_ATTR_UID;
-+              attrs.ia_uid = attr->ia_uid;
-+      }
-+      if(attr->ia_valid & ATTR_GID){
-+              if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
-+                 (attr->ia_gid == 0))
-+                      attr->ia_gid = getuid();
-+              attrs.ia_valid |= HOSTFS_ATTR_GID;
-+              attrs.ia_gid = attr->ia_gid;
-+      }
-+      if(attr->ia_valid & ATTR_SIZE){
-+              attrs.ia_valid |= HOSTFS_ATTR_SIZE;
-+              attrs.ia_size = attr->ia_size;
-+      }
-+      if(attr->ia_valid & ATTR_ATIME){
-+              attrs.ia_valid |= HOSTFS_ATTR_ATIME;
-+              attrs.ia_atime = attr->ia_atime;
-+      }
-+      if(attr->ia_valid & ATTR_MTIME){
-+              attrs.ia_valid |= HOSTFS_ATTR_MTIME;
-+              attrs.ia_mtime = attr->ia_mtime;
-+      }
-+      if(attr->ia_valid & ATTR_CTIME){
-+              attrs.ia_valid |= HOSTFS_ATTR_CTIME;
-+              attrs.ia_ctime = attr->ia_ctime;
-+      }
-+      if(attr->ia_valid & ATTR_ATIME_SET){
-+              attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
-+      }
-+      if(attr->ia_valid & ATTR_MTIME_SET){
-+              attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
-+      }
-+      name = dentry_name(dentry, 0);
-+      if(name == NULL) return(-ENOMEM);
-+      err = set_attr(name, &attrs);
-+      kfree(name);
-+      if(err)
-+              return(err);
-+
-+      return(inode_setattr(dentry->d_inode, attr));
-+}
-+
-+int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 
-+         struct kstat *stat)
-+{
-+      generic_fillattr(dentry->d_inode, stat);
-+      return(0);
-+}
-+
-+static struct inode_operations hostfs_iops = {
-+      .create         = hostfs_create,
-+      .link           = hostfs_link,
-+      .unlink         = hostfs_unlink,
-+      .symlink        = hostfs_symlink,
-+      .mkdir          = hostfs_mkdir,
-+      .rmdir          = hostfs_rmdir,
-+      .mknod          = hostfs_mknod,
-+      .rename         = hostfs_rename,
-+      .truncate       = hostfs_truncate,
-+      .permission     = hostfs_permission,
-+      .setattr        = hostfs_setattr,
-+      .getattr        = hostfs_getattr,
-+};
-+
-+static struct inode_operations hostfs_dir_iops = {
-+      .create         = hostfs_create,
-+      .lookup         = hostfs_lookup,
-+      .link           = hostfs_link,
-+      .unlink         = hostfs_unlink,
-+      .symlink        = hostfs_symlink,
-+      .mkdir          = hostfs_mkdir,
-+      .rmdir          = hostfs_rmdir,
-+      .mknod          = hostfs_mknod,
-+      .rename         = hostfs_rename,
-+      .truncate       = hostfs_truncate,
-+      .permission     = hostfs_permission,
-+      .setattr        = hostfs_setattr,
-+      .getattr        = hostfs_getattr,
-+};
-+
-+int hostfs_link_readpage(struct file *file, struct page *page)
-+{
-+      char *buffer, *name;
-+      long long start;
-+      int err;
-+
-+      start = page->index << PAGE_CACHE_SHIFT;
-+      buffer = kmap(page);
-+      name = inode_name(page->mapping->host, 0);
-+      if(name == NULL) return(-ENOMEM);
-+      err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
-+      kfree(name);
-+      if(err == PAGE_CACHE_SIZE)
-+              err = -E2BIG;
-+      else if(err > 0){
-+              flush_dcache_page(page);
-+              SetPageUptodate(page);
-+              if (PageError(page)) ClearPageError(page);
-+              err = 0;
-+      }
-+      kunmap(page);
-+      unlock_page(page);
-+      return(err);
-+}
-+
-+static struct address_space_operations hostfs_link_aops = {
-+      .readpage       = hostfs_link_readpage,
-+};
-+
-+static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
-+{
-+      struct inode *root_inode;
-+      char *name, *data = d;
-+      int err;
-+
-+      sb->s_blocksize = 1024;
-+      sb->s_blocksize_bits = 10;
-+      sb->s_magic = HOSTFS_SUPER_MAGIC;
-+      sb->s_op = &hostfs_sbops;
-+
-+      if((data == NULL) || (*data == '\0')) 
-+              data = root_ino;
-+
-+      err = -ENOMEM;
-+      name = kmalloc(strlen(data) + 1, GFP_KERNEL);
-+      if(name == NULL) 
-+              goto out;
-+
-+      strcpy(name, data);
-+
-+      root_inode = iget(sb, 0);
-+      if(root_inode == NULL)
-+              goto out_free;
-+
-+      err = init_inode(root_inode, NULL);
-+      if(err)
-+              goto out_put;
-+
-+      HOSTFS_I(root_inode)->host_filename = name;
-+
-+      err = -ENOMEM;
-+      sb->s_root = d_alloc_root(root_inode);
-+      if(sb->s_root == NULL)
-+              goto out_put;
-+
-+      err = read_inode(root_inode);
-+      if(err)
-+              goto out_put;
-+
-+      return(0);
-+
-+ out_put:
-+      iput(root_inode);
-+ out_free:
-+      kfree(name);
-+ out:
-+      return(err);
-+}
-+
-+static struct super_block *hostfs_read_sb(struct file_system_type *type,
-+                                           int flags, const char *dev_name,
-+                                           void *data)
-+{
-+      return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
-+}
-+
-+static struct file_system_type hostfs_type = {
-+      .owner          = THIS_MODULE,
-+      .name           = "hostfs",
-+      .get_sb         = hostfs_read_sb,
-+      .kill_sb        = kill_anon_super,
-+      .fs_flags       = 0,
-+};
-+
-+static int __init init_hostfs(void)
-+{
-+      return(register_filesystem(&hostfs_type));
-+}
-+
-+static void __exit exit_hostfs(void)
-+{
-+      unregister_filesystem(&hostfs_type);
-+}
-+
-+module_init(init_hostfs)
-+module_exit(exit_hostfs)
-+MODULE_LICENSE("GPL");
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
---- a/fs/hostfs/hostfs_user.c  Wed Dec 31 19:00:00 1969
-+++ b/fs/hostfs/hostfs_user.c  Fri Aug 15 15:10:43 2003
-@@ -0,0 +1,361 @@
-+/* 
-+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <fcntl.h>
-+#include <dirent.h>
-+#include <errno.h>
-+#include <utime.h>
-+#include <string.h>
-+#include <sys/stat.h>
-+#include <sys/time.h>
-+#include <sys/vfs.h>
-+#include "hostfs.h"
-+#include "kern_util.h"
-+#include "user.h"
-+
-+int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
-+            int *nlink_out, int *uid_out, int *gid_out, 
-+            unsigned long long *size_out, struct timespec *atime_out,
-+            struct timespec *mtime_out, struct timespec *ctime_out,
-+            int *blksize_out, unsigned long long *blocks_out)
-+{
-+      struct stat64 buf;
-+
-+      if(lstat64(path, &buf) < 0) 
-+              return(-errno);
-+
-+      /* See the Makefile for why STAT64_INO_FIELD is passed in
-+       * by the build
-+       */
-+      if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
-+      if(mode_out != NULL) *mode_out = buf.st_mode;
-+      if(nlink_out != NULL) *nlink_out = buf.st_nlink;
-+      if(uid_out != NULL) *uid_out = buf.st_uid;
-+      if(gid_out != NULL) *gid_out = buf.st_gid;
-+      if(size_out != NULL) *size_out = buf.st_size;
-+      if(atime_out != NULL) {
-+              atime_out->tv_sec = buf.st_atime;
-+              atime_out->tv_nsec = 0;
-+      }
-+      if(mtime_out != NULL) {
-+              mtime_out->tv_sec = buf.st_mtime;
-+              mtime_out->tv_nsec = 0;
-+      }
-+      if(ctime_out != NULL) {
-+              ctime_out->tv_sec = buf.st_ctime;
-+              ctime_out->tv_nsec = 0;
-+      }
-+      if(blksize_out != NULL) *blksize_out = buf.st_blksize;
-+      if(blocks_out != NULL) *blocks_out = buf.st_blocks;
-+      return(0);
-+}
-+
-+int file_type(const char *path, int *rdev)
-+{
-+      struct stat64 buf;
-+
-+      if(lstat64(path, &buf) < 0) 
-+              return(-errno);
-+      if(rdev != NULL) 
-+              *rdev = buf.st_rdev;
-+
-+      if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
-+      else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
-+      else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
-+      else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
-+      else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
-+      else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
-+      else return(OS_TYPE_FILE);
-+}
-+
-+int access_file(char *path, int r, int w, int x)
-+{
-+      int mode = 0;
-+
-+      if(r) mode = R_OK;
-+      if(w) mode |= W_OK;
-+      if(x) mode |= X_OK;
-+      if(access(path, mode) != 0) return(-errno);
-+      else return(0);
-+}
-+
-+int open_file(char *path, int r, int w, int append)
-+{
-+      int mode = 0, fd;
-+
-+      if(r && !w) 
-+              mode = O_RDONLY;
-+      else if(!r && w) 
-+              mode = O_WRONLY;
-+      else if(r && w) 
-+              mode = O_RDWR;
-+      else panic("Impossible mode in open_file");
-+
-+      if(append)
-+              mode |= O_APPEND;
-+      fd = open64(path, mode);
-+      if(fd < 0) return(-errno);
-+      else return(fd);
-+}
-+
-+void *open_dir(char *path, int *err_out)
-+{
-+      DIR *dir;
-+
-+      dir = opendir(path);
-+      *err_out = errno;
-+      if(dir == NULL) return(NULL);
-+      return(dir);
-+}
-+
-+char *read_dir(void *stream, unsigned long long *pos, 
-+             unsigned long long *ino_out, int *len_out)
-+{
-+      DIR *dir = stream;
-+      struct dirent *ent;
-+
-+      seekdir(dir, *pos);
-+      ent = readdir(dir);
-+      if(ent == NULL) return(NULL);
-+      *len_out = strlen(ent->d_name);
-+      *ino_out = ent->d_ino;
-+      *pos = telldir(dir);
-+      return(ent->d_name);
-+}
-+
-+int read_file(int fd, unsigned long long *offset, char *buf, int len)
-+{
-+      int n;
-+
-+      n = pread64(fd, buf, len, *offset);
-+      if(n < 0) return(-errno);
-+      *offset += n;
-+      return(n);
-+}
-+
-+int write_file(int fd, unsigned long long *offset, const char *buf, int len)
-+{
-+      int n;
-+
-+      n = pwrite64(fd, buf, len, *offset);
-+      if(n < 0) return(-errno);
-+      *offset += n;
-+      return(n);
-+}
-+
-+int lseek_file(int fd, long long offset, int whence)
-+{
-+      int ret;
-+
-+      ret = lseek64(fd, offset, whence);
-+      if(ret < 0) return(-errno);
-+      return(0);
-+}
-+
-+void close_file(void *stream)
-+{
-+      close(*((int *) stream));
-+}
-+
-+void close_dir(void *stream)
-+{
-+      closedir(stream);
-+}
-+
-+int file_create(char *name, int ur, int uw, int ux, int gr, 
-+              int gw, int gx, int or, int ow, int ox)
-+{
-+      int mode, fd;
-+
-+      mode = 0;
-+      mode |= ur ? S_IRUSR : 0;
-+      mode |= uw ? S_IWUSR : 0;
-+      mode |= ux ? S_IXUSR : 0;
-+      mode |= gr ? S_IRGRP : 0;
-+      mode |= gw ? S_IWGRP : 0;
-+      mode |= gx ? S_IXGRP : 0;
-+      mode |= or ? S_IROTH : 0;
-+      mode |= ow ? S_IWOTH : 0;
-+      mode |= ox ? S_IXOTH : 0;
-+      fd = open64(name, O_CREAT | O_RDWR, mode);
-+      if(fd < 0) 
-+              return(-errno);
-+      return(fd);
-+}
-+
-+int set_attr(const char *file, struct hostfs_iattr *attrs)
-+{
-+      struct utimbuf buf;
-+      int err, ma;
-+
-+      if(attrs->ia_valid & HOSTFS_ATTR_MODE){
-+              if(chmod(file, attrs->ia_mode) != 0) return(-errno);
-+      }
-+      if(attrs->ia_valid & HOSTFS_ATTR_UID){
-+              if(chown(file, attrs->ia_uid, -1)) return(-errno);
-+      }
-+      if(attrs->ia_valid & HOSTFS_ATTR_GID){
-+              if(chown(file, -1, attrs->ia_gid)) return(-errno);
-+      }
-+      if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
-+              if(truncate(file, attrs->ia_size)) return(-errno);
-+      }
-+      ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
-+      if((attrs->ia_valid & ma) == ma){
-+              buf.actime = attrs->ia_atime.tv_sec;
-+              buf.modtime = attrs->ia_mtime.tv_sec;
-+              if(utime(file, &buf) != 0) return(-errno);
-+      }
-+      else {
-+              struct timespec ts;
-+
-+              if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
-+                      err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
-+                                      NULL, NULL, &ts, NULL, NULL, NULL);
-+                      if(err != 0) 
-+                              return(err);
-+                      buf.actime = attrs->ia_atime.tv_sec;
-+                      buf.modtime = ts.tv_sec;
-+                      if(utime(file, &buf) != 0) 
-+                              return(-errno);
-+              }
-+              if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
-+                      err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
-+                                      NULL, &ts, NULL, NULL, NULL, NULL);
-+                      if(err != 0) 
-+                              return(err);
-+                      buf.actime = ts.tv_sec;
-+                      buf.modtime = attrs->ia_mtime.tv_sec;
-+                      if(utime(file, &buf) != 0) 
-+                              return(-errno);
-+              }
-+      }
-+      if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
-+      if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
-+              err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 
-+                              &attrs->ia_atime, &attrs->ia_mtime, NULL, 
-+                              NULL, NULL);
-+              if(err != 0) return(err);
-+      }
-+      return(0);
-+}
-+
-+int make_symlink(const char *from, const char *to)
-+{
-+      int err;
-+
-+      err = symlink(to, from);
-+      if(err) return(-errno);
-+      return(0);
-+}
-+
-+int unlink_file(const char *file)
-+{
-+      int err;
-+
-+      err = unlink(file);
-+      if(err) return(-errno);
-+      return(0);
-+}
-+
-+int do_mkdir(const char *file, int mode)
-+{
-+      int err;
-+
-+      err = mkdir(file, mode);
-+      if(err) return(-errno);
-+      return(0);
-+}
-+
-+int do_rmdir(const char *file)
-+{
-+      int err;
-+
-+      err = rmdir(file);
-+      if(err) return(-errno);
-+      return(0);
-+}
-+
-+int do_mknod(const char *file, int mode, int dev)
-+{
-+      int err;
-+
-+      err = mknod(file, mode, dev);
-+      if(err) return(-errno);
-+      return(0);
-+}
-+
-+int link_file(const char *to, const char *from)
-+{
-+      int err;
-+
-+      err = link(to, from);
-+      if(err) return(-errno);
-+      return(0);
-+}
-+
-+int do_readlink(char *file, char *buf, int size)
-+{
-+      int n;
-+
-+      n = readlink(file, buf, size);
-+      if(n < 0) 
-+              return(-errno);
-+      if(n < size) 
-+              buf[n] = '\0';
-+      return(n);
-+}
-+
-+int rename_file(char *from, char *to)
-+{
-+      int err;
-+
-+      err = rename(from, to);
-+      if(err < 0) return(-errno);
-+      return(0);      
-+}
-+
-+int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
-+            long long *bfree_out, long long *bavail_out, 
-+            long long *files_out, long long *ffree_out,
-+            void *fsid_out, int fsid_size, long *namelen_out, 
-+            long *spare_out)
-+{
-+      struct statfs64 buf;
-+      int err;
-+
-+      err = statfs64(root, &buf);
-+      if(err < 0) return(-errno);
-+      *bsize_out = buf.f_bsize;
-+      *blocks_out = buf.f_blocks;
-+      *bfree_out = buf.f_bfree;
-+      *bavail_out = buf.f_bavail;
-+      *files_out = buf.f_files;
-+      *ffree_out = buf.f_ffree;
-+      memcpy(fsid_out, &buf.f_fsid, 
-+             sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
-+             sizeof(buf.f_fsid));
-+      *namelen_out = buf.f_namelen;
-+      spare_out[0] = buf.f_spare[0];
-+      spare_out[1] = buf.f_spare[1];
-+      spare_out[2] = buf.f_spare[2];
-+      spare_out[3] = buf.f_spare[3];
-+      spare_out[4] = buf.f_spare[4];
-+      spare_out[5] = buf.f_spare[5];
-+      return(0);
-+}
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/fs/hppfs/Makefile b/fs/hppfs/Makefile
---- a/fs/hppfs/Makefile        Wed Dec 31 19:00:00 1969
-+++ b/fs/hppfs/Makefile        Fri Aug 15 15:12:31 2003
-@@ -0,0 +1,19 @@
-+# 
-+# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
-+# Licensed under the GPL
-+#
-+
-+hppfs-objs := hppfs_kern.o
-+
-+obj-y = 
-+obj-$(CONFIG_HPPFS) += hppfs.o
-+
-+clean:
-+
-+modules:
-+
-+fastdep:
-+
-+dep:
-+
-+archmrproper: clean
-diff -Naur a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
---- a/fs/hppfs/hppfs_kern.c    Wed Dec 31 19:00:00 1969
-+++ b/fs/hppfs/hppfs_kern.c    Fri Aug 15 15:11:52 2003
-@@ -0,0 +1,811 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/list.h>
-+#include <linux/kernel.h>
-+#include <linux/ctype.h>
-+#include <linux/dcache.h>
-+#include <linux/statfs.h>
-+#include <asm/uaccess.h>
-+#include <asm/fcntl.h>
-+#include "os.h"
-+
-+static int init_inode(struct inode *inode, struct dentry *dentry);
-+
-+struct hppfs_data {
-+      struct list_head list;
-+      char contents[PAGE_SIZE - sizeof(struct list_head)];
-+};
-+
-+struct hppfs_private {
-+      struct file proc_file;
-+      int host_fd;
-+      loff_t len;
-+      struct hppfs_data *contents;
-+};
-+
-+struct hppfs_inode_info {
-+        struct dentry *proc_dentry;
-+      struct inode vfs_inode;
-+};
-+
-+static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
-+{
-+      return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
-+}
-+
-+#define HPPFS_SUPER_MAGIC 0xb00000ee
-+
-+static struct super_operations hppfs_sbops;
-+
-+static int is_pid(struct dentry *dentry)
-+{
-+      struct super_block *sb;
-+      int i;
-+
-+      sb = dentry->d_sb;
-+      if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
-+              return(0);
-+
-+      for(i = 0; i < dentry->d_name.len; i++){
-+              if(!isdigit(dentry->d_name.name[i]))
-+                      return(0);
-+      }
-+      return(1);
-+}
-+
-+static char *dentry_name(struct dentry *dentry, int extra)
-+{
-+      struct dentry *parent;
-+      char *root, *name;
-+      const char *seg_name;
-+      int len, seg_len;
-+
-+      len = 0;
-+      parent = dentry;
-+      while(parent->d_parent != parent){
-+              if(is_pid(parent))
-+                      len += strlen("pid") + 1;
-+              else len += parent->d_name.len + 1;
-+              parent = parent->d_parent;
-+      }
-+      
-+      root = "proc";
-+      len += strlen(root);
-+      name = kmalloc(len + extra + 1, GFP_KERNEL);
-+      if(name == NULL) return(NULL);
-+
-+      name[len] = '\0';
-+      parent = dentry;
-+      while(parent->d_parent != parent){
-+              if(is_pid(parent)){
-+                      seg_name = "pid";
-+                      seg_len = strlen("pid");
-+              }
-+              else {
-+                      seg_name = parent->d_name.name;
-+                      seg_len = parent->d_name.len;
-+              }
-+
-+              len -= seg_len + 1;
-+              name[len] = '/';
-+              strncpy(&name[len + 1], seg_name, seg_len);
-+              parent = parent->d_parent;
-+      }
-+      strncpy(name, root, strlen(root));
-+      return(name);
-+}
-+
-+struct dentry_operations hppfs_dentry_ops = {
-+};
-+
-+static int file_removed(struct dentry *dentry, const char *file)
-+{
-+      char *host_file;
-+      int extra, fd;
-+
-+      extra = 0;
-+      if(file != NULL) extra += strlen(file) + 1;
-+
-+      host_file = dentry_name(dentry, extra + strlen("/remove"));
-+      if(host_file == NULL){
-+              printk("file_removed : allocation failed\n");
-+              return(-ENOMEM);
-+      }
-+
-+      if(file != NULL){
-+              strcat(host_file, "/");
-+              strcat(host_file, file);
-+      }
-+      strcat(host_file, "/remove");
-+
-+      fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
-+      kfree(host_file);
-+      if(fd > 0){
-+              os_close_file(fd);
-+              return(1);
-+      }
-+      return(0);
-+}
-+
-+static void hppfs_read_inode(struct inode *ino)
-+{
-+      struct inode *proc_ino;
-+
-+      if(HPPFS_I(ino)->proc_dentry == NULL)
-+              return;
-+
-+      proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
-+      ino->i_uid = proc_ino->i_uid;
-+      ino->i_gid = proc_ino->i_gid;
-+      ino->i_atime = proc_ino->i_atime;
-+      ino->i_mtime = proc_ino->i_mtime;
-+      ino->i_ctime = proc_ino->i_ctime;
-+      ino->i_ino = proc_ino->i_ino;
-+      ino->i_mode = proc_ino->i_mode;
-+      ino->i_nlink = proc_ino->i_nlink;
-+      ino->i_size = proc_ino->i_size;
-+      ino->i_blksize = proc_ino->i_blksize;
-+      ino->i_blocks = proc_ino->i_blocks;
-+}
-+
-+static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 
-+                                  struct nameidata *nd)
-+{
-+      struct dentry *proc_dentry, *new, *parent;
-+      struct inode *inode;
-+      int err, deleted;
-+
-+      deleted = file_removed(dentry, NULL);
-+      if(deleted < 0)
-+              return(ERR_PTR(deleted));
-+      else if(deleted)
-+              return(ERR_PTR(-ENOENT));
-+
-+      err = -ENOMEM;
-+      parent = HPPFS_I(ino)->proc_dentry;
-+      down(&parent->d_inode->i_sem);
-+      proc_dentry = d_lookup(parent, &dentry->d_name);
-+      if(proc_dentry == NULL){
-+              proc_dentry = d_alloc(parent, &dentry->d_name);
-+              if(proc_dentry == NULL){
-+                      up(&parent->d_inode->i_sem);
-+                      goto out;
-+              }
-+              new = (*parent->d_inode->i_op->lookup)(parent->d_inode, 
-+                                                     proc_dentry, NULL);
-+              if(new){
-+                      dput(proc_dentry);
-+                      proc_dentry = new;
-+              }
-+      }
-+      up(&parent->d_inode->i_sem);
-+
-+      if(IS_ERR(proc_dentry))
-+              return(proc_dentry);
-+
-+      inode = iget(ino->i_sb, 0);
-+      if(inode == NULL) 
-+              goto out_dput;
-+
-+      err = init_inode(inode, proc_dentry);
-+      if(err) 
-+              goto out_put;
-+      
-+      hppfs_read_inode(inode);
-+
-+      d_add(dentry, inode);
-+      dentry->d_op = &hppfs_dentry_ops;
-+      return(NULL);
-+
-+ out_put:
-+      iput(inode);
-+ out_dput:
-+      dput(proc_dentry);
-+ out:
-+      return(ERR_PTR(err));
-+}
-+
-+static struct inode_operations hppfs_file_iops = {
-+};
-+
-+static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
-+                       loff_t *ppos, int is_user)
-+{
-+      ssize_t (*read)(struct file *, char *, size_t, loff_t *);
-+      ssize_t n;
-+
-+      read = file->f_dentry->d_inode->i_fop->read;
-+
-+      if(!is_user)
-+              set_fs(KERNEL_DS);
-+              
-+      n = (*read)(file, buf, count, &file->f_pos);
-+
-+      if(!is_user)
-+              set_fs(USER_DS);
-+
-+      if(ppos) *ppos = file->f_pos;
-+      return(n);
-+}
-+
-+static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
-+{
-+      ssize_t n;
-+      int cur, err;
-+      char *new_buf;
-+
-+      n = -ENOMEM;
-+      new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-+      if(new_buf == NULL){
-+              printk("hppfs_read_file : kmalloc failed\n");
-+              goto out;
-+      }
-+      n = 0;
-+      while(count > 0){
-+              cur = min_t(ssize_t, count, PAGE_SIZE);
-+              err = os_read_file(fd, new_buf, cur);
-+              if(err < 0){
-+                      printk("hppfs_read : read failed, errno = %d\n",
-+                             count);
-+                      n = err;
-+                      goto out_free;
-+              }
-+              else if(err == 0)
-+                      break;
-+
-+              if(copy_to_user(buf, new_buf, err)){
-+                      n = -EFAULT;
-+                      goto out_free;
-+              }
-+              n += err;
-+              count -= err;
-+      }
-+ out_free:
-+      kfree(new_buf);
-+ out:
-+      return(n);
-+}
-+
-+static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
-+                        loff_t *ppos)
-+{
-+      struct hppfs_private *hppfs = file->private_data;
-+      struct hppfs_data *data;
-+      loff_t off;
-+      int err;
-+
-+      if(hppfs->contents != NULL){
-+              if(*ppos >= hppfs->len) return(0);
-+
-+              data = hppfs->contents;
-+              off = *ppos;
-+              while(off >= sizeof(data->contents)){
-+                      data = list_entry(data->list.next, struct hppfs_data,
-+                                        list);
-+                      off -= sizeof(data->contents);
-+              }
-+
-+              if(off + count > hppfs->len)
-+                      count = hppfs->len - off;
-+              copy_to_user(buf, &data->contents[off], count);
-+              *ppos += count;
-+      }
-+      else if(hppfs->host_fd != -1){
-+              err = os_seek_file(hppfs->host_fd, *ppos);
-+              if(err){
-+                      printk("hppfs_read : seek failed, errno = %d\n", err);
-+                      return(err);
-+              }
-+              count = hppfs_read_file(hppfs->host_fd, buf, count);
-+              if(count > 0)
-+                      *ppos += count;
-+      }
-+      else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
-+
-+      return(count);
-+}
-+
-+static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
-+                         loff_t *ppos)
-+{
-+      struct hppfs_private *data = file->private_data;
-+      struct file *proc_file = &data->proc_file;
-+      ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
-+      int err;
-+
-+      write = proc_file->f_dentry->d_inode->i_fop->write;
-+
-+      proc_file->f_pos = file->f_pos;
-+      err = (*write)(proc_file, buf, len, &proc_file->f_pos);
-+      file->f_pos = proc_file->f_pos;
-+
-+      return(err);
-+}
-+
-+static int open_host_sock(char *host_file, int *filter_out)
-+{
-+      char *end;
-+      int fd;
-+
-+      end = &host_file[strlen(host_file)];
-+      strcpy(end, "/rw");
-+      *filter_out = 1;
-+      fd = os_connect_socket(host_file);
-+      if(fd > 0)
-+              return(fd);
-+
-+      strcpy(end, "/r");
-+      *filter_out = 0;
-+      fd = os_connect_socket(host_file);
-+      return(fd);
-+}
-+
-+static void free_contents(struct hppfs_data *head)
-+{
-+      struct hppfs_data *data;
-+      struct list_head *ele, *next;
-+
-+      if(head == NULL) return;
-+
-+      list_for_each_safe(ele, next, &head->list){
-+              data = list_entry(ele, struct hppfs_data, list);
-+              kfree(data);
-+      }
-+      kfree(head);
-+}
-+
-+static struct hppfs_data *hppfs_get_data(int fd, int filter, 
-+                                       struct file *proc_file, 
-+                                       struct file *hppfs_file, 
-+                                       loff_t *size_out)
-+{
-+      struct hppfs_data *data, *new, *head;
-+      int n, err;
-+
-+      err = -ENOMEM;
-+      data = kmalloc(sizeof(*data), GFP_KERNEL);
-+      if(data == NULL){
-+              printk("hppfs_get_data : head allocation failed\n");
-+              goto failed;
-+      }
-+
-+      INIT_LIST_HEAD(&data->list);
-+
-+      head = data;
-+      *size_out = 0;
-+
-+      if(filter){
-+              while((n = read_proc(proc_file, data->contents,
-+                                   sizeof(data->contents), NULL, 0)) > 0)
-+                      os_write_file(fd, data->contents, n);
-+              err = os_shutdown_socket(fd, 0, 1);
-+              if(err){
-+                      printk("hppfs_get_data : failed to shut down "
-+                             "socket\n");
-+                      goto failed_free;
-+              }
-+      }
-+      while(1){
-+              n = os_read_file(fd, data->contents, sizeof(data->contents));
-+              if(n < 0){
-+                      err = n;
-+                      printk("hppfs_get_data : read failed, errno = %d\n",
-+                             err);
-+                      goto failed_free;
-+              }
-+              else if(n == 0)
-+                      break;
-+
-+              *size_out += n;
-+
-+              if(n < sizeof(data->contents))
-+                      break;
-+
-+              new = kmalloc(sizeof(*data), GFP_KERNEL);
-+              if(new == 0){
-+                      printk("hppfs_get_data : data allocation failed\n");
-+                      err = -ENOMEM;
-+                      goto failed_free;
-+              }
-+      
-+              INIT_LIST_HEAD(&new->list);
-+              list_add(&new->list, &data->list);
-+              data = new;
-+      }
-+      return(head);
-+
-+ failed_free:
-+      free_contents(head);
-+ failed:              
-+      return(ERR_PTR(err));
-+}
-+
-+static struct hppfs_private *hppfs_data(void)
-+{
-+      struct hppfs_private *data;
-+
-+      data = kmalloc(sizeof(*data), GFP_KERNEL);
-+      if(data == NULL)
-+              return(data);
-+
-+      *data = ((struct hppfs_private ) { .host_fd             = -1,
-+                                         .len                 = -1,
-+                                         .contents            = NULL } );
-+      return(data);
-+}
-+
-+static int file_mode(int fmode)
-+{
-+      if(fmode == (FMODE_READ | FMODE_WRITE))
-+              return(O_RDWR);
-+      if(fmode == FMODE_READ)
-+              return(O_RDONLY);
-+      if(fmode == FMODE_WRITE)
-+              return(O_WRONLY);
-+      return(0);
-+}
-+
-+static int hppfs_open(struct inode *inode, struct file *file)
-+{
-+      struct hppfs_private *data;
-+      struct dentry *proc_dentry;
-+      char *host_file;
-+      int err, fd, type, filter;
-+
-+      err = -ENOMEM;
-+      data = hppfs_data();
-+      if(data == NULL)
-+              goto out;
-+
-+      host_file = dentry_name(file->f_dentry, strlen("/rw"));
-+      if(host_file == NULL)
-+              goto out_free2;
-+
-+      proc_dentry = HPPFS_I(inode)->proc_dentry;
-+
-+      /* XXX This isn't closed anywhere */
-+      err = open_private_file(&data->proc_file, proc_dentry, 
-+                              file_mode(file->f_mode));
-+      if(err)
-+              goto out_free1;
-+
-+      type = os_file_type(host_file);
-+      if(type == OS_TYPE_FILE){
-+              fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
-+              if(fd >= 0) 
-+                      data->host_fd = fd;
-+              else printk("hppfs_open : failed to open '%s', errno = %d\n",
-+                          host_file, -fd);
-+
-+              data->contents = NULL;
-+      }
-+      else if(type == OS_TYPE_DIR){
-+              fd = open_host_sock(host_file, &filter);
-+              if(fd > 0){
-+                      data->contents = hppfs_get_data(fd, filter, 
-+                                                      &data->proc_file, 
-+                                                      file, &data->len);
-+                      if(!IS_ERR(data->contents))
-+                              data->host_fd = fd;
-+              }
-+              else printk("hppfs_open : failed to open a socket in "
-+                          "'%s', errno = %d\n", host_file, -fd);
-+      }
-+      kfree(host_file);
-+
-+      file->private_data = data;
-+      return(0);
-+
-+ out_free1:
-+      kfree(host_file);
-+ out_free2:
-+      free_contents(data->contents);
-+      kfree(data);
-+ out:
-+      return(err);
-+}
-+
-+static int hppfs_dir_open(struct inode *inode, struct file *file)
-+{
-+      struct hppfs_private *data;
-+      struct dentry *proc_dentry;
-+      int err;
-+
-+      err = -ENOMEM;
-+      data = hppfs_data();
-+      if(data == NULL)
-+              goto out;
-+
-+      proc_dentry = HPPFS_I(inode)->proc_dentry;
-+      err = open_private_file(&data->proc_file, proc_dentry, 
-+                              file_mode(file->f_mode));
-+      if(err)
-+              goto out_free;
-+
-+      file->private_data = data;
-+      return(0);
-+
-+ out_free:
-+      kfree(data);
-+ out:
-+      return(err);
-+}
-+
-+static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
-+{
-+      struct hppfs_private *data = file->private_data;
-+      struct file *proc_file = &data->proc_file;
-+      loff_t (*llseek)(struct file *, loff_t, int);
-+      loff_t ret;
-+
-+      llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
-+      if(llseek != NULL){
-+              ret = (*llseek)(proc_file, off, where);
-+              if(ret < 0)
-+                      return(ret);
-+      }
-+
-+      return(default_llseek(file, off, where));
-+}
-+
-+static struct file_operations hppfs_file_fops = {
-+      .owner          = NULL,
-+      .llseek         = hppfs_llseek,
-+      .read           = hppfs_read,
-+      .write          = hppfs_write,
-+      .open           = hppfs_open,
-+};
-+
-+struct hppfs_dirent {
-+      void *vfs_dirent;
-+      filldir_t filldir;
-+      struct dentry *dentry;
-+};
-+
-+static int hppfs_filldir(void *d, const char *name, int size, 
-+                       loff_t offset, ino_t inode, unsigned int type)
-+{
-+      struct hppfs_dirent *dirent = d;
-+
-+      if(file_removed(dirent->dentry, name))
-+              return(0);
-+
-+      return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
-+                                inode, type));
-+}
-+
-+static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
-+{
-+      struct hppfs_private *data = file->private_data;
-+      struct file *proc_file = &data->proc_file;
-+      int (*readdir)(struct file *, void *, filldir_t);
-+      struct hppfs_dirent dirent = ((struct hppfs_dirent)
-+                                    { .vfs_dirent     = ent,
-+                                      .filldir        = filldir,
-+                                      .dentry         = file->f_dentry } );
-+      int err;
-+
-+      readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
-+
-+      proc_file->f_pos = file->f_pos;
-+      err = (*readdir)(proc_file, &dirent, hppfs_filldir);
-+      file->f_pos = proc_file->f_pos;
-+
-+      return(err);
-+}
-+
-+static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
-+{
-+      return(0);
-+}
-+
-+static struct file_operations hppfs_dir_fops = {
-+      .owner          = NULL,
-+      .readdir        = hppfs_readdir,
-+      .open           = hppfs_dir_open,
-+      .fsync          = hppfs_fsync,
-+};
-+
-+static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
-+{
-+      sf->f_blocks = 0;
-+      sf->f_bfree = 0;
-+      sf->f_bavail = 0;
-+      sf->f_files = 0;
-+      sf->f_ffree = 0;
-+      sf->f_type = HPPFS_SUPER_MAGIC;
-+      return(0);
-+}
-+
-+static struct inode *hppfs_alloc_inode(struct super_block *sb)
-+{
-+      struct hppfs_inode_info *hi;
-+
-+      hi = kmalloc(sizeof(*hi), GFP_KERNEL);
-+      if(hi == NULL) 
-+              return(NULL);
-+
-+      *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
-+      inode_init_once(&hi->vfs_inode);
-+      return(&hi->vfs_inode);
-+}
-+
-+void hppfs_delete_inode(struct inode *ino)
-+{
-+      clear_inode(ino);
-+}
-+
-+static void hppfs_destroy_inode(struct inode *inode)
-+{
-+      kfree(HPPFS_I(inode));
-+}
-+
-+static struct super_operations hppfs_sbops = { 
-+      .alloc_inode    = hppfs_alloc_inode,
-+      .destroy_inode  = hppfs_destroy_inode,
-+      .read_inode     = hppfs_read_inode,
-+      .delete_inode   = hppfs_delete_inode,
-+      .statfs         = hppfs_statfs,
-+};
-+
-+static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
-+{
-+      struct file proc_file;
-+      struct dentry *proc_dentry;
-+      int (*readlink)(struct dentry *, char *, int);
-+      int err, n;
-+
-+      proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-+      err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
-+      if(err) 
-+              return(err);
-+
-+      readlink = proc_dentry->d_inode->i_op->readlink;
-+      n = (*readlink)(proc_dentry, buffer, buflen);
-+
-+      close_private_file(&proc_file);
-+      
-+      return(n);
-+}
-+
-+static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
-+{
-+      struct file proc_file;
-+      struct dentry *proc_dentry;
-+      int (*follow_link)(struct dentry *, struct nameidata *);
-+      int err, n;
-+
-+      proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-+      err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
-+      if(err) 
-+              return(err);
-+
-+      follow_link = proc_dentry->d_inode->i_op->follow_link;
-+      n = (*follow_link)(proc_dentry, nd);
-+
-+      close_private_file(&proc_file);
-+      
-+      return(n);
-+}
-+
-+static struct inode_operations hppfs_dir_iops = {
-+      .lookup         = hppfs_lookup,
-+};
-+
-+static struct inode_operations hppfs_link_iops = {
-+      .readlink       = hppfs_readlink,
-+      .follow_link    = hppfs_follow_link,
-+};
-+
-+static int init_inode(struct inode *inode, struct dentry *dentry)
-+{
-+      if(S_ISDIR(dentry->d_inode->i_mode)){
-+              inode->i_op = &hppfs_dir_iops;
-+              inode->i_fop = &hppfs_dir_fops;
-+      }
-+      else if(S_ISLNK(dentry->d_inode->i_mode)){
-+              inode->i_op = &hppfs_link_iops;
-+              inode->i_fop = &hppfs_file_fops;
-+      }
-+      else {
-+              inode->i_op = &hppfs_file_iops;
-+              inode->i_fop = &hppfs_file_fops;
-+      }
-+
-+      HPPFS_I(inode)->proc_dentry = dentry;
-+
-+      return(0);
-+}
-+
-+static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
-+{
-+      struct inode *root_inode;
-+      struct file_system_type *procfs;
-+      struct super_block *proc_sb;
-+      int err;
-+
-+      err = -ENOENT;
-+      procfs = get_fs_type("proc");
-+      if(procfs == NULL) 
-+              goto out;
-+
-+      if(list_empty(&procfs->fs_supers))
-+              goto out;
-+
-+      proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
-+                           s_instances);
-+      
-+      sb->s_blocksize = 1024;
-+      sb->s_blocksize_bits = 10;
-+      sb->s_magic = HPPFS_SUPER_MAGIC;
-+      sb->s_op = &hppfs_sbops;
-+
-+      root_inode = iget(sb, 0);
-+      if(root_inode == NULL)
-+              goto out;
-+
-+      err = init_inode(root_inode, proc_sb->s_root);
-+      if(err)
-+              goto out_put;
-+
-+      err = -ENOMEM;
-+      sb->s_root = d_alloc_root(root_inode);
-+      if(sb->s_root == NULL)
-+              goto out_put;
-+
-+      hppfs_read_inode(root_inode);
-+
-+      return(0);
-+
-+ out_put:
-+      iput(root_inode);
-+ out:
-+      return(err);
-+}
-+
-+static struct super_block *hppfs_read_super(struct file_system_type *type,
-+                                           int flags, const char *dev_name,
-+                                           void *data)
-+{
-+      return(get_sb_nodev(type, flags, data, hppfs_fill_super));
-+}
-+
-+static struct file_system_type hppfs_type = {
-+      .owner          = THIS_MODULE,
-+      .name           = "hppfs",
-+      .get_sb         = hppfs_read_super,
-+      .kill_sb        = kill_anon_super,
-+      .fs_flags       = 0,
-+};
-+
-+static int __init init_hppfs(void)
-+{
-+      return(register_filesystem(&hppfs_type));
-+}
-+
-+static void __exit exit_hppfs(void)
-+{
-+      unregister_filesystem(&hppfs_type);
-+}
-+
-+module_init(init_hppfs)
-+module_exit(exit_hppfs)
-+MODULE_LICENSE("GPL");
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-diff -Naur a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
---- a/include/asm-um/archparam-i386.h  Fri Aug 15 15:07:52 2003
-+++ b/include/asm-um/archparam-i386.h  Fri Aug 15 15:13:17 2003
-@@ -56,6 +56,65 @@
-       pr_reg[16] = PT_REGS_SS(regs);          \
- } while(0);
-+#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
-+#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
-+#define VSYSCALL_ENTRY        ((unsigned long) &__kernel_vsyscall)
-+extern void *__kernel_vsyscall;
-+
-+/*
-+ * Architecture-neutral AT_ values in 0-17, leave some room
-+ * for more of them, start the x86-specific ones at 32.
-+ */
-+#define AT_SYSINFO            32
-+#define AT_SYSINFO_EHDR               33
-+
-+#define ARCH_DLINFO                                           \
-+do {                                                          \
-+              NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
-+              NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);    \
-+} while (0)
-+
-+/*
-+ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
-+ * extra segments containing the vsyscall DSO contents.  Dumping its
-+ * contents makes post-mortem fully interpretable later without matching up
-+ * the same kernel and hardware config to see what PC values meant.
-+ * Dumping its extra ELF program headers includes all the other information
-+ * a debugger needs to easily find how the vsyscall DSO was being used.
-+ */
-+#define ELF_CORE_EXTRA_PHDRS          (VSYSCALL_EHDR->e_phnum)
-+#define ELF_CORE_WRITE_EXTRA_PHDRS                                          \
-+do {                                                                        \
-+      const struct elf_phdr *const vsyscall_phdrs =                         \
-+              (const struct elf_phdr *) (VSYSCALL_BASE                      \
-+                                         + VSYSCALL_EHDR->e_phoff);         \
-+      int i;                                                                \
-+      Elf32_Off ofs = 0;                                                    \
-+      for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
-+              struct elf_phdr phdr = vsyscall_phdrs[i];                     \
-+              if (phdr.p_type == PT_LOAD) {                                 \
-+                      ofs = phdr.p_offset = offset;                         \
-+                      offset += phdr.p_filesz;                              \
-+              }                                                             \
-+              else                                                          \
-+                      phdr.p_offset += ofs;                                 \
-+              phdr.p_paddr = 0; /* match other core phdrs */                \
-+              DUMP_WRITE(&phdr, sizeof(phdr));                              \
-+      }                                                                     \
-+} while (0)
-+#define ELF_CORE_WRITE_EXTRA_DATA                                           \
-+do {                                                                        \
-+      const struct elf_phdr *const vsyscall_phdrs =                         \
-+              (const struct elf_phdr *) (VSYSCALL_BASE                      \
-+                                         + VSYSCALL_EHDR->e_phoff);         \
-+      int i;                                                                \
-+      for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
-+              if (vsyscall_phdrs[i].p_type == PT_LOAD)                      \
-+                      DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,        \
-+                                 vsyscall_phdrs[i].p_filesz);               \
-+      }                                                                     \
-+} while (0)
-+
- /********* Bits for asm-um/delay.h **********/
- typedef unsigned long um_udelay_t;
-diff -Naur a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
---- a/include/asm-um/common.lds.S      Fri Aug 15 15:04:49 2003
-+++ b/include/asm-um/common.lds.S      Fri Aug 15 15:10:46 2003
-@@ -1,3 +1,5 @@
-+#include <asm-generic/vmlinux.lds.h>
-+
-   .fini      : { *(.fini)    } =0x9090
-   _etext = .;
-   PROVIDE (etext = .);
-@@ -67,6 +69,10 @@
-   }
-   __initcall_end = .;
-+  __con_initcall_start = .;
-+  .con_initcall.init : { *(.con_initcall.init) }
-+  __con_initcall_end = .;
-+
-   __uml_initcall_start = .;
-   .uml.initcall.init : { *(.uml.initcall.init) }
-   __uml_initcall_end = .;
-@@ -80,7 +86,33 @@
-   .uml.exitcall : { *(.uml.exitcall.exit) }
-   __uml_exitcall_end = .;
--  . = ALIGN(4096);
-+  . = ALIGN(4);
-+  __alt_instructions = .;
-+  .altinstructions : { *(.altinstructions) } 
-+  __alt_instructions_end = .; 
-+  .altinstr_replacement : { *(.altinstr_replacement) } 
-+  /* .exit.text is discard at runtime, not link time, to deal with references
-+     from .altinstructions and .eh_frame */
-+  .exit.text : { *(.exit.text) }
-+  .exit.data : { *(.exit.data) }
-+ 
-+  __preinit_array_start = .;
-+  .preinit_array : { *(.preinit_array) }
-+  __preinit_array_end = .;
-+  __init_array_start = .;
-+  .init_array : { *(.init_array) }
-+  __init_array_end = .;
-+  __fini_array_start = .;
-+  .fini_array : { *(.fini_array) }
-+  __fini_array_end = .;
-+
-+   . = ALIGN(4096);
-   __initramfs_start = .;
-   .init.ramfs : { *(.init.ramfs) }
-   __initramfs_end = .;
-+
-+  /* Sections to be discarded */
-+  /DISCARD/ : {
-+      *(.exitcall.exit)
-+  }
-+ 
-diff -Naur a/include/asm-um/cpufeature.h b/include/asm-um/cpufeature.h
---- a/include/asm-um/cpufeature.h      Wed Dec 31 19:00:00 1969
-+++ b/include/asm-um/cpufeature.h      Fri Aug 15 15:10:07 2003
-@@ -0,0 +1,6 @@
-+#ifndef __UM_CPUFEATURE_H
-+#define __UM_CPUFEATURE_H
-+
-+#include "asm/arch/cpufeature.h"
-+
-+#endif
-diff -Naur a/include/asm-um/current.h b/include/asm-um/current.h
---- a/include/asm-um/current.h Fri Aug 15 15:04:11 2003
-+++ b/include/asm-um/current.h Fri Aug 15 15:10:19 2003
-@@ -16,8 +16,10 @@
- #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
-                               (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
--#define current ({ int dummy; \
--                   ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
-+#define current_thread \
-+      ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
-+
-+#define current (current_thread->task)
- #endif /* __ASSEMBLY__ */
-diff -Naur a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
---- a/include/asm-um/fixmap.h  Fri Aug 15 15:08:40 2003
-+++ b/include/asm-um/fixmap.h  Fri Aug 15 15:13:36 2003
-@@ -34,6 +34,7 @@
-       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
-       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
- #endif
-+      FIX_VSYSCALL,
-       __end_of_fixed_addresses
- };
-@@ -63,6 +64,13 @@
- #define __fix_to_virt(x)      (FIXADDR_TOP - ((x) << PAGE_SHIFT))
- #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
-+/*
-+ * This is the range that is readable by user mode, and things
-+ * acting like user mode such as get_user_pages.
-+ */
-+#define FIXADDR_USER_START    (__fix_to_virt(FIX_VSYSCALL))
-+#define FIXADDR_USER_END      (FIXADDR_USER_START + PAGE_SIZE)
-+
- extern void __this_fixmap_does_not_exist(void);
- /*
-diff -Naur a/include/asm-um/irq.h b/include/asm-um/irq.h
---- a/include/asm-um/irq.h     Fri Aug 15 15:09:15 2003
-+++ b/include/asm-um/irq.h     Fri Aug 15 15:13:51 2003
-@@ -1,15 +1,6 @@
- #ifndef __UM_IRQ_H
- #define __UM_IRQ_H
--/* The i386 irq.h has a struct task_struct in a prototype without including
-- * sched.h.  This forward declaration kills the resulting warning.
-- */
--struct task_struct;
--
--#include "asm/ptrace.h"
--
--#undef NR_IRQS
--
- #define TIMER_IRQ             0
- #define UMN_IRQ                       1
- #define CONSOLE_IRQ           2
-@@ -28,8 +19,4 @@
- #define LAST_IRQ XTERM_IRQ
- #define NR_IRQS (LAST_IRQ + 1)
--extern int um_request_irq(unsigned int irq, int fd, int type,
--                        void (*handler)(int, void *, struct pt_regs *),
--                        unsigned long irqflags,  const char * devname,
--                        void *dev_id);
- #endif
-diff -Naur a/include/asm-um/local.h b/include/asm-um/local.h
---- a/include/asm-um/local.h   Wed Dec 31 19:00:00 1969
-+++ b/include/asm-um/local.h   Fri Aug 15 15:12:46 2003
-@@ -0,0 +1,6 @@
-+#ifndef __UM_LOCAL_H
-+#define __UM_LOCAL_H
-+
-+#include "asm/arch/local.h"
-+
-+#endif
-diff -Naur a/include/asm-um/module-generic.h b/include/asm-um/module-generic.h
---- a/include/asm-um/module-generic.h  Wed Dec 31 19:00:00 1969
-+++ b/include/asm-um/module-generic.h  Fri Aug 15 15:12:38 2003
-@@ -0,0 +1,6 @@
-+#ifndef __UM_MODULE_GENERIC_H
-+#define __UM_MODULE_GENERIC_H
-+
-+#include "asm/arch/module.h"
-+
-+#endif
-diff -Naur a/include/asm-um/module-i386.h b/include/asm-um/module-i386.h
---- a/include/asm-um/module-i386.h     Wed Dec 31 19:00:00 1969
-+++ b/include/asm-um/module-i386.h     Fri Aug 15 15:12:37 2003
-@@ -0,0 +1,13 @@
-+#ifndef __UM_MODULE_I386_H
-+#define __UM_MODULE_I386_H
-+
-+/* UML is simple */
-+struct mod_arch_specific
-+{
-+};
-+
-+#define Elf_Shdr Elf32_Shdr
-+#define Elf_Sym Elf32_Sym
-+#define Elf_Ehdr Elf32_Ehdr
-+
-+#endif
-diff -Naur a/include/asm-um/page.h b/include/asm-um/page.h
---- a/include/asm-um/page.h    Fri Aug 15 15:06:42 2003
-+++ b/include/asm-um/page.h    Fri Aug 15 15:12:40 2003
-@@ -4,7 +4,6 @@
- struct page;
- #include "asm/arch/page.h"
--#include "asm/bug.h"
- #undef __pa
- #undef __va
-diff -Naur a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
---- a/include/asm-um/pgtable.h Fri Aug 15 15:09:25 2003
-+++ b/include/asm-um/pgtable.h Fri Aug 15 15:14:09 2003
-@@ -79,12 +79,13 @@
- #define _PAGE_PRESENT 0x001
- #define _PAGE_NEWPAGE 0x002
--#define _PAGE_PROTNONE        0x004   /* If not present */
--#define _PAGE_RW      0x008
--#define _PAGE_USER    0x010
--#define _PAGE_ACCESSED        0x020
--#define _PAGE_DIRTY   0x040
--#define _PAGE_NEWPROT   0x080
-+#define _PAGE_NEWPROT   0x004
-+#define _PAGE_FILE    0x008   /* set:pagecache unset:swap */
-+#define _PAGE_PROTNONE        0x010   /* If not present */
-+#define _PAGE_RW      0x020
-+#define _PAGE_USER    0x040
-+#define _PAGE_ACCESSED        0x080
-+#define _PAGE_DIRTY   0x100
- #define REGION_MASK   0xf0000000
- #define REGION_SHIFT  28
-@@ -203,6 +204,16 @@
- #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
- #define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
-+/*
-+ * Bits 0 through 3 are taken
-+ */
-+#define PTE_FILE_MAX_BITS     28
-+
-+#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
-+
-+#define pgoff_to_pte(off) \
-+      ((pte_t) { ((off) << 4) + _PAGE_FILE })
-+
- static inline pte_t pte_mknewprot(pte_t pte)
- {
-       pte_val(pte) |= _PAGE_NEWPROT;
-@@ -236,6 +247,12 @@
-  * The following only work if pte_present() is true.
-  * Undefined behaviour if not..
-  */
-+static inline int pte_user(pte_t pte)
-+{ 
-+      return((pte_val(pte) & _PAGE_USER) && 
-+             !(pte_val(pte) & _PAGE_PROTNONE));
-+}
-+
- static inline int pte_read(pte_t pte)
- { 
-       return((pte_val(pte) & _PAGE_USER) && 
-@@ -253,6 +270,14 @@
-              !(pte_val(pte) & _PAGE_PROTNONE));
- }
-+/*
-+ * The following only works if pte_present() is not true.
-+ */
-+static inline int pte_file(pte_t pte)
-+{ 
-+      return (pte).pte_low & _PAGE_FILE; 
-+}
-+
- static inline int pte_dirty(pte_t pte)        { return pte_val(pte) & _PAGE_DIRTY; }
- static inline int pte_young(pte_t pte)        { return pte_val(pte) & _PAGE_ACCESSED; }
- static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
-@@ -355,14 +380,26 @@
- #define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
-                      ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
--/* to find an entry in a page-table-directory. */
-+/*
-+ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
-+ *
-+ * this macro returns the index of the entry in the pgd page which would
-+ * control the given virtual address
-+ */
- #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
--/* to find an entry in a page-table-directory */
-+/*
-+ * pgd_offset() returns a (pgd_t *)
-+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
-+ */
- #define pgd_offset(mm, address) \
- ((mm)->pgd + ((address) >> PGDIR_SHIFT))
--/* to find an entry in a kernel page-table-directory */
-+
-+/*
-+ * a shortcut which implies the use of the kernel's pgd, instead
-+ * of a process's
-+ */
- #define pgd_offset_k(address) pgd_offset(&init_mm, address)
- #define pmd_index(address) \
-@@ -374,7 +411,12 @@
-       return (pmd_t *) dir;
- }
--/* Find an entry in the third-level page table.. */ 
-+/*
-+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
-+ *
-+ * this macro returns the index of the entry in the pte page which would
-+ * control the given virtual address
-+ */
- #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
- #define pte_offset_kernel(dir, address) \
-       ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
-@@ -400,11 +442,11 @@
- #define update_mmu_cache(vma,address,pte) do ; while (0)
- /* Encode and de-code a swap entry */
--#define __swp_type(x)                 (((x).val >> 3) & 0x7f)
--#define __swp_offset(x)                       ((x).val >> 10)
-+#define __swp_type(x)                 (((x).val >> 4) & 0x3f)
-+#define __swp_offset(x)                       ((x).val >> 11)
- #define __swp_entry(type, offset) \
--      ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
-+      ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
- #define __pte_to_swp_entry(pte) \
-       ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
- #define __swp_entry_to_pte(x)         ((pte_t) { (x).val })
-diff -Naur a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
---- a/include/asm-um/processor-generic.h       Fri Aug 15 15:04:48 2003
-+++ b/include/asm-um/processor-generic.h       Fri Aug 15 15:10:42 2003
-@@ -11,9 +11,7 @@
- struct task_struct;
- #include "linux/config.h"
--#include "linux/signal.h"
- #include "asm/ptrace.h"
--#include "asm/siginfo.h"
- #include "choose-mode.h"
- struct mm_struct;
-@@ -101,14 +99,19 @@
- } mm_segment_t;
- extern struct task_struct *alloc_task_struct(void);
--extern void free_task_struct(struct task_struct *task);
- extern void release_thread(struct task_struct *);
- extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
- extern void dump_thread(struct pt_regs *regs, struct user *u);
-+extern void prepare_to_copy(struct task_struct *tsk);
- extern unsigned long thread_saved_pc(struct task_struct *t);
-+static inline void mm_copy_segments(struct mm_struct *from_mm, 
-+                                  struct mm_struct *new_mm)
-+{
-+}
-+
- #define init_stack    (init_thread_union.stack)
- /*
-diff -Naur a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
---- a/include/asm-um/processor-i386.h  Fri Aug 15 15:04:00 2003
-+++ b/include/asm-um/processor-i386.h  Fri Aug 15 15:10:18 2003
-@@ -6,8 +6,8 @@
- #ifndef __UM_PROCESSOR_I386_H
- #define __UM_PROCESSOR_I386_H
--extern int cpu_has_xmm;
--extern int cpu_has_cmov;
-+extern int host_has_xmm;
-+extern int host_has_cmov;
- struct arch_thread {
-       unsigned long debugregs[8];
-diff -Naur a/include/asm-um/sections.h b/include/asm-um/sections.h
---- a/include/asm-um/sections.h        Wed Dec 31 19:00:00 1969
-+++ b/include/asm-um/sections.h        Fri Aug 15 15:12:54 2003
-@@ -0,0 +1,7 @@
-+#ifndef _UM_SECTIONS_H
-+#define _UM_SECTIONS_H
-+
-+/* nothing to see, move along */
-+#include <asm-generic/sections.h>
-+
-+#endif
-diff -Naur a/include/asm-um/smp.h b/include/asm-um/smp.h
---- a/include/asm-um/smp.h     Fri Aug 15 15:03:35 2003
-+++ b/include/asm-um/smp.h     Fri Aug 15 15:10:04 2003
-@@ -7,9 +7,10 @@
- #include "linux/config.h"
- #include "linux/bitops.h"
-+#include "linux/threads.h"
- #include "asm/current.h"
--#define smp_processor_id() (current->thread_info->cpu)
-+#define smp_processor_id() (current_thread->cpu)
- #define cpu_logical_map(n) (n)
- #define cpu_number_map(n) (n)
- #define PROC_CHANGE_PENALTY   15 /* Pick a number, any number */
-@@ -30,6 +31,13 @@
- {
- }
-+extern inline int any_online_cpu(unsigned int mask)
-+{
-+        if (mask & cpu_online_map)
-+                return __ffs(mask & cpu_online_map);
-+
-+        return -1;
-+}
- #endif
- #endif
-diff -Naur a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h
---- a/include/asm-um/system-generic.h  Fri Aug 15 15:09:22 2003
-+++ b/include/asm-um/system-generic.h  Fri Aug 15 15:14:01 2003
-@@ -23,8 +23,10 @@
- extern void block_signals(void);
- extern void unblock_signals(void);
--#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
--#define local_irq_restore(flags) do { set_signals(flags); } while(0)
-+#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
-+                                   (flags) = get_signals(); } while(0)
-+#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
-+                                    set_signals(flags); } while(0)
- #define local_irq_save(flags) do { local_save_flags(flags); \
-                                    local_irq_disable(); } while(0)
-diff -Naur a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
---- a/include/asm-um/thread_info.h     Fri Aug 15 15:05:00 2003
-+++ b/include/asm-um/thread_info.h     Fri Aug 15 15:11:11 2003
-@@ -9,6 +9,7 @@
- #ifndef __ASSEMBLY__
- #include <asm/processor.h>
-+#include <asm/types.h>
- struct thread_info {
-       struct task_struct      *task;          /* main task structure */
-@@ -43,15 +44,18 @@
- static inline struct thread_info *current_thread_info(void)
- {
-       struct thread_info *ti;
--      __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
-+      unsigned long mask = PAGE_SIZE * 
-+              (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
-+      __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
-       return ti;
- }
- /* thread information allocation */
--#define THREAD_SIZE (4*PAGE_SIZE)
--#define alloc_thread_info(tsk) ((struct thread_info *) \
--      __get_free_pages(GFP_KERNEL,2))
--#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
-+#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
-+#define alloc_thread_info(tsk) \
-+      ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
-+#define free_thread_info(ti) kfree(ti)
-+      
- #define get_thread_info(ti) get_task_struct((ti)->task)
- #define put_thread_info(ti) put_task_struct((ti)->task)
-@@ -65,11 +69,13 @@
- #define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling 
-                                        * TIF_NEED_RESCHED 
-                                        */
-+#define TIF_RESTART_BLOCK     4
- #define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
- #define _TIF_SIGPENDING               (1 << TIF_SIGPENDING)
- #define _TIF_NEED_RESCHED     (1 << TIF_NEED_RESCHED)
- #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
-+#define _TIF_RESTART_BLOCK    (1 << TIF_RESTART_BLOCK)
- #endif
-diff -Naur a/include/asm-um/timex.h b/include/asm-um/timex.h
---- a/include/asm-um/timex.h   Fri Aug 15 15:07:22 2003
-+++ b/include/asm-um/timex.h   Fri Aug 15 15:12:48 2003
-@@ -1,8 +1,6 @@
- #ifndef __UM_TIMEX_H
- #define __UM_TIMEX_H
--#include "linux/time.h"
--
- typedef unsigned long cycles_t;
- #define cacheflush_time (0)
-diff -Naur a/include/linux/mm.h b/include/linux/mm.h
---- a/include/linux/mm.h       Fri Aug 15 15:03:56 2003
-+++ b/include/linux/mm.h       Fri Aug 15 15:10:14 2003
-@@ -483,6 +483,9 @@
-       return __set_page_dirty_buffers(page);
- }
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
-+                      size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc_map() that does all
-@@ -513,9 +516,10 @@
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
--      unsigned long len, unsigned long prot,
--      unsigned long flag, unsigned long pgoff);
-+extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
-+                                 unsigned long addr, unsigned long len,
-+                                 unsigned long prot, unsigned long flag,
-+                                 unsigned long pgoff);
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
-       unsigned long len, unsigned long prot,
-@@ -525,7 +529,8 @@
-       if ((offset + PAGE_ALIGN(len)) < offset)
-               goto out;
-       if (!(offset & ~PAGE_MASK))
--              ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-+              ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
-+                                  offset >> PAGE_SHIFT);
- out:
-       return ret;
- }
-diff -Naur a/include/linux/proc_mm.h b/include/linux/proc_mm.h
---- a/include/linux/proc_mm.h  Wed Dec 31 19:00:00 1969
-+++ b/include/linux/proc_mm.h  Fri Aug 15 15:10:02 2003
-@@ -0,0 +1,48 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+      unsigned long addr;
-+      unsigned long len;
-+      unsigned long prot;
-+      unsigned long flags;
-+      unsigned long fd;
-+      unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+      unsigned long addr;
-+      unsigned long len;      
-+};
-+
-+struct mm_mprotect {
-+      unsigned long addr;
-+      unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+      int op;
-+      union {
-+              struct mm_mmap mmap;
-+              struct mm_munmap munmap;
-+              struct mm_mprotect mprotect;
-+              int copy_segments;
-+      } u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
-diff -Naur a/mm/Makefile b/mm/Makefile
---- a/mm/Makefile      Fri Aug 15 15:07:22 2003
-+++ b/mm/Makefile      Fri Aug 15 15:12:48 2003
-@@ -12,3 +12,5 @@
-                          slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y)
- obj-$(CONFIG_SWAP)    += page_io.o swap_state.o swapfile.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
-+
-diff -Naur a/mm/memory.c b/mm/memory.c
---- a/mm/memory.c      Fri Aug 15 15:05:37 2003
-+++ b/mm/memory.c      Fri Aug 15 15:11:48 2003
-@@ -45,6 +45,7 @@
- #include <linux/pagemap.h>
- #include <linux/vcache.h>
- #include <linux/rmap-locking.h>
-+#include <linux/init.h>
- #include <asm/pgalloc.h>
- #include <asm/rmap.h>
-@@ -669,6 +670,24 @@
- }
-+static struct vm_area_struct fixmap_vma = {
-+      /* Catch users - if there are any valid
-+         ones, we can make this be "&init_mm" or
-+         something.  */
-+      .vm_mm = NULL,
-+      .vm_page_prot = PAGE_READONLY,
-+      .vm_flags = VM_READ | VM_EXEC,
-+};
-+
-+static int init_fixmap_vma(void)
-+{
-+      fixmap_vma.vm_start = FIXADDR_START;
-+      fixmap_vma.vm_end = FIXADDR_TOP;
-+      return(0);
-+}
-+
-+__initcall(init_fixmap_vma);
-+
- int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
-               unsigned long start, int len, int write, int force,
-               struct page **pages, struct vm_area_struct **vmas)
-@@ -689,19 +708,8 @@
-               vma = find_extend_vma(mm, start);
--#ifdef FIXADDR_USER_START
--              if (!vma &&
--                  start >= FIXADDR_USER_START && start < FIXADDR_USER_END) {
--                      static struct vm_area_struct fixmap_vma = {
--                              /* Catch users - if there are any valid
--                                 ones, we can make this be "&init_mm" or
--                                 something.  */
--                              .vm_mm = NULL,
--                              .vm_start = FIXADDR_USER_START,
--                              .vm_end = FIXADDR_USER_END,
--                              .vm_page_prot = PAGE_READONLY,
--                              .vm_flags = VM_READ | VM_EXEC,
--                      };
-+#ifdef FIXADDR_START
-+              if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) {
-                       unsigned long pg = start & PAGE_MASK;
-                       pgd_t *pgd;
-                       pmd_t *pmd;
-diff -Naur a/mm/mmap.c b/mm/mmap.c
---- a/mm/mmap.c        Fri Aug 15 15:07:18 2003
-+++ b/mm/mmap.c        Fri Aug 15 15:12:45 2003
-@@ -457,11 +457,11 @@
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--                      unsigned long len, unsigned long prot,
--                      unsigned long flags, unsigned long pgoff)
-+unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
-+                          unsigned long addr, unsigned long len,
-+                          unsigned long prot, unsigned long flags,
-+                          unsigned long pgoff)
- {
--      struct mm_struct * mm = current->mm;
-       struct vm_area_struct * vma, * prev;
-       struct inode *inode;
-       unsigned int vm_flags;
-diff -Naur a/mm/mprotect.c b/mm/mprotect.c
---- a/mm/mprotect.c    Fri Aug 15 15:05:20 2003
-+++ b/mm/mprotect.c    Fri Aug 15 15:11:21 2003
-@@ -222,7 +222,8 @@
- }
- asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
-+           unsigned long prot)
- {
-       unsigned long nstart, end, tmp;
-       struct vm_area_struct * vma, * next, * prev;
-@@ -239,9 +240,9 @@
-       if (end == start)
-               return 0;
--      down_write(&current->mm->mmap_sem);
-+      down_write(&mm->mmap_sem);
--      vma = find_vma_prev(current->mm, start, &prev);
-+      vma = find_vma_prev(mm, start, &prev);
-       error = -ENOMEM;
-       if (!vma || vma->vm_start > start)
-               goto out;
-@@ -301,6 +302,11 @@
-               prev->vm_mm->map_count--;
-       }
- out:
--      up_write(&current->mm->mmap_sem);
-+      up_write(&mm->mmap_sem);
-       return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+        return(do_mprotect(current->mm, start, len, prot));
-+}
-diff -Naur a/mm/proc_mm.c b/mm/proc_mm.c
---- a/mm/proc_mm.c     Wed Dec 31 19:00:00 1969
-+++ b/mm/proc_mm.c     Fri Aug 15 15:11:44 2003
-@@ -0,0 +1,174 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+      struct mm_struct *ret = ERR_PTR(-EBADF);
-+      struct file *file;
-+
-+      file = fget(fd);
-+      if (!file)
-+              goto out;
-+
-+      ret = ERR_PTR(-EINVAL);
-+      if(file->f_op != &proc_mm_fops)
-+              goto out_fput;
-+
-+      ret = file->private_data;
-+ out_fput:
-+      fput(file);
-+ out:
-+      return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
-+                   unsigned long len, unsigned long prot, 
-+                   unsigned long flags, unsigned long fd,
-+                   unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+                           size_t count, loff_t *ppos)
-+{
-+      struct mm_struct *mm = file->private_data;
-+      struct proc_mm_op req;
-+      int n, ret;
-+
-+      if(count > sizeof(req))
-+              return(-EINVAL);
-+
-+      n = copy_from_user(&req, buffer, count);
-+      if(n != 0)
-+              return(-EFAULT);
-+
-+      ret = count;
-+      switch(req.op){
-+      case MM_MMAP: {
-+              struct mm_mmap *map = &req.u.mmap;
-+
-+              ret = do_mmap2(mm, map->addr, map->len, map->prot, 
-+                             map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+              if((ret & ~PAGE_MASK) == 0)
-+                      ret = count;
-+      
-+              break;
-+      }
-+      case MM_MUNMAP: {
-+              struct mm_munmap *unmap = &req.u.munmap;
-+
-+              down_write(&mm->mmap_sem);
-+              ret = do_munmap(mm, unmap->addr, unmap->len);
-+              up_write(&mm->mmap_sem);
-+
-+              if(ret == 0)
-+                      ret = count;
-+              break;
-+      }
-+      case MM_MPROTECT: {
-+              struct mm_mprotect *protect = &req.u.mprotect;
-+
-+              ret = do_mprotect(mm, protect->addr, protect->len, 
-+                                protect->prot);
-+              if(ret == 0)
-+                      ret = count;
-+              break;
-+      }
-+
-+      case MM_COPY_SEGMENTS: {
-+              struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+              if(IS_ERR(from)){
-+                      ret = PTR_ERR(from);
-+                      break;
-+              }
-+
-+              mm_copy_segments(from, mm);
-+              break;
-+      }
-+      default:
-+              ret = -EINVAL;
-+              break;
-+      }
-+
-+      return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+      struct mm_struct *mm = mm_alloc();
-+      int ret;
-+
-+      ret = -ENOMEM;
-+      if(mm == NULL)
-+              goto out_mem;
-+
-+      ret = init_new_context(current, mm);
-+      if(ret)
-+              goto out_free;
-+
-+      spin_lock(&mmlist_lock);
-+      list_add(&mm->mmlist, &current->mm->mmlist);
-+      mmlist_nr++;
-+      spin_unlock(&mmlist_lock);
-+
-+      file->private_data = mm;
-+
-+      return(0);
-+
-+ out_free:
-+      mmput(mm);
-+ out_mem:
-+      return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+      struct mm_struct *mm = file->private_data;
-+
-+      mmput(mm);
-+      return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+      .open           = open_proc_mm,
-+      .release        = release_proc_mm,
-+      .write          = write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+      struct proc_dir_entry *ent;
-+
-+      ent = create_proc_entry("mm", 0222, &proc_root);
-+      if(ent == NULL){
-+              printk("make_proc_mm : Failed to register /proc/mm\n");
-+              return(0);
-+      }
-+      ent->proc_fops = &proc_mm_fops;
-+
-+      return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
diff --git a/lustre/kernel_patches/pc/uml-patch-2.6.0-test3-1.pc b/lustre/kernel_patches/pc/uml-patch-2.6.0-test3-1.pc
deleted file mode 100644 (file)
index 9a32c9a..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-arch/um/config.release
-arch/um/defconfig
-arch/um/drivers/chan_kern.c
-arch/um/drivers/chan_user.c
-arch/um/drivers/cow.h
-arch/um/drivers/cow_kern.c
-arch/um/drivers/cow_sys.h
-arch/um/drivers/cow_user.c
-arch/um/drivers/hostaudio_kern.c
-arch/um/drivers/line.c
-arch/um/drivers/Makefile
-arch/um/drivers/mconsole_kern.c
-arch/um/drivers/mconsole_user.c
-arch/um/drivers/mmapper_kern.c
-arch/um/drivers/net_kern.c
-arch/um/drivers/port_kern.c
-arch/um/drivers/ssl.c
-arch/um/drivers/stdio_console.c
-arch/um/drivers/ubd_kern.c
-arch/um/drivers/ubd_user.c
-arch/um/drivers/xterm.c
-arch/um/drivers/xterm_kern.c
-arch/um/dyn.lds.S
-arch/um/include/irq_kern.h
-arch/um/include/kern_util.h
-arch/um/include/line.h
-arch/um/include/mconsole.h
-arch/um/include/mem.h
-arch/um/include/mem_user.h
-arch/um/include/os.h
-arch/um/include/sysdep-i386/sigcontext.h
-arch/um/include/ubd_user.h
-arch/um/include/user.h
-arch/um/include/user_util.h
-arch/um/Kconfig
-arch/um/Kconfig_block
-arch/um/Kconfig_net
-arch/um/kernel/config.c.in
-arch/um/kernel/exec_kern.c
-arch/um/kernel/init_task.c
-arch/um/kernel/irq.c
-arch/um/kernel/Makefile
-arch/um/kernel/mem.c
-arch/um/kernel/mem_user.c
-arch/um/kernel/process.c
-arch/um/kernel/process_kern.c
-arch/um/kernel/ptrace.c
-arch/um/kernel/sigio_kern.c
-arch/um/kernel/signal_kern.c
-arch/um/kernel/skas/include/mode.h
-arch/um/kernel/skas/include/uaccess.h
-arch/um/kernel/skas/Makefile
-arch/um/kernel/skas/process.c
-arch/um/kernel/skas/process_kern.c
-arch/um/kernel/skas/util/mk_ptregs.c
-arch/um/kernel/smp.c
-arch/um/kernel/syscall_kern.c
-arch/um/kernel/sys_call_table.c
-arch/um/kernel/sysrq.c
-arch/um/kernel/time.c
-arch/um/kernel/time_kern.c
-arch/um/kernel/trap_kern.c
-arch/um/kernel/trap_user.c
-arch/um/kernel/tt/include/uaccess.h
-arch/um/kernel/tt/process_kern.c
-arch/um/kernel/tt/ptproxy/proxy.c
-arch/um/kernel/tt/tracer.c
-arch/um/kernel/tt/uaccess_user.c
-arch/um/kernel/tty_log.c
-arch/um/kernel/um_arch.c
-arch/um/kernel/umid.c
-arch/um/kernel/user_util.c
-arch/um/Makefile
-arch/um/Makefile-i386
-arch/um/Makefile-skas
-arch/um/os-Linux/drivers/tuntap_user.c
-arch/um/os-Linux/file.c
-arch/um/sys-i386/bugs.c
-arch/um/sys-i386/Makefile
-arch/um/uml.lds.S
-arch/um/util/mk_constants_kern.c
-fs/hostfs/hostfs.h
-fs/hostfs/hostfs_kern.c
-fs/hostfs/hostfs_user.c
-fs/hostfs/Makefile
-fs/hppfs/hppfs_kern.c
-fs/hppfs/Makefile
-fs/Makefile
-include/asm-um/archparam-i386.h
-include/asm-um/common.lds.S
-include/asm-um/cpufeature.h
-include/asm-um/current.h
-include/asm-um/fixmap.h
-include/asm-um/irq.h
-include/asm-um/local.h
-include/asm-um/module-generic.h
-include/asm-um/module-i386.h
-include/asm-um/page.h
-include/asm-um/pgtable.h
-include/asm-um/processor-generic.h
-include/asm-um/processor-i386.h
-include/asm-um/sections.h
-include/asm-um/smp.h
-include/asm-um/system-generic.h
-include/asm-um/thread_info.h
-include/asm-um/timex.h
-include/linux/mm.h
-include/linux/proc_mm.h
-mm/Makefile
-mm/memory.c
-mm/mmap.c
-mm/mprotect.c
-mm/proc_mm.c