diff -Naur -X exclude-files ac_cur/arch/um/fs/hostfs/Makefile ac/arch/um/fs/hostfs/Makefile
--- ac_cur/arch/um/fs/hostfs/Makefile	Sat Aug  4 22:01:03 2001
+++ ac/arch/um/fs/hostfs/Makefile	Sun Aug  5 12:53:31 2001
@@ -3,23 +3,35 @@
 # 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 := __st_ino
+
+HOST_VER := $(shell uname -r | sed 's/^\(2\.[0-9]\)\..*/\1/')
+
+ifeq ($(HOST_VER), 2.2)
+  STAT64_INO_FIELD := st_ino
+endif
+
 EXTRA_CFLAGS += -I../../include
 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS))
+USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) \
+	-DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
 
 O_TARGET :=
-obj-y   := 
+obj-y = 
+obj-m =
+
+CFLAGS_hostfs_kern.o := $(CFLAGS)
+CFLAGS_hostfs_user.o := $(USER_CFLAGS)
 
 ifneq ($(CONFIG_HOSTFS), n)
   O_TARGET := hostfs.o
-  obj-y := hostfs_kern.o hostfs_user.o
-  CFLAGS_hostfs_kern.o := $(CFLAGS)
-  CFLAGS_hostfs_user.o := $(USER_CFLAGS)
 endif
 
-ifeq ($(CONFIG_HOSTFS), m)
-  obj-m := $(O_TARGET)
-endif
+obj-$(CONFIG_HOSTFS) += hostfs_kern.o hostfs_user.o
 
 override CFLAGS =  
 
diff -Naur -X exclude-files ac_cur/arch/um/fs/hostfs/hostfs.h ac/arch/um/fs/hostfs/hostfs.h
--- ac_cur/arch/um/fs/hostfs/hostfs.h	Sat Aug  4 22:01:03 2001
+++ ac/arch/um/fs/hostfs/hostfs.h	Sun Aug  5 12:53:31 2001
@@ -47,7 +47,8 @@
 extern int open_file(char *path, int r, int w);
 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, int *len_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);
diff -Naur -X exclude-files ac_cur/arch/um/fs/hostfs/hostfs_kern.c ac/arch/um/fs/hostfs/hostfs_kern.c
--- ac_cur/arch/um/fs/hostfs/hostfs_kern.c	Sat Aug  4 22:01:03 2001
+++ ac/arch/um/fs/hostfs/hostfs_kern.c	Sun Aug  5 12:53:31 2001
@@ -17,6 +17,8 @@
 #include "kern.h"
 #include "user_util.h"
 
+#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
+
 int hostfs_d_delete(struct dentry *dentry)
 {
 	return(1);
@@ -45,7 +47,8 @@
 		len += parent->d_name.len + 1;
 		parent = parent->d_parent;
 	}
-	root = parent->d_inode->u.generic_ip;
+	
+	root = parent->d_inode->u.hostfs_i.host_filename;
 	len += strlen(root);
 	name = kmalloc(len + extra + 1, GFP_KERNEL);
 	if(name == NULL) return(NULL);
@@ -112,8 +115,10 @@
 
 void hostfs_delete_inode(struct inode *ino)
 {
-	if(ino->u.generic_ip) kfree(ino->u.generic_ip);
-	ino->u.generic_ip = NULL;
+	if(ino->u.hostfs_i.host_filename) kfree(ino->u.hostfs_i.host_filename);
+	ino->u.hostfs_i.host_filename = NULL;
+	if(ino->u.hostfs_i.fd != -1) close_file(&ino->u.hostfs_i.fd);
+	ino->u.hostfs_i.mode = 0;
 	clear_inode(ino);
 }
 
@@ -130,10 +135,10 @@
 	long long f_files;
 	long long f_ffree;
 
-	err = do_statfs(sb->s_root->d_inode->u.generic_ip, &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);
+	err = do_statfs(sb->s_root->d_inode->u.hostfs_i.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;
@@ -150,39 +155,11 @@
 	statfs:		hostfs_statfs,
 };
 
-ssize_t hostfs_write(struct file *file, const char *buf, size_t len, 
-		     loff_t *start)
-{
-	unsigned long page = __get_free_page(GFP_KERNEL);
-	int ret, one_len, n;
-
-	if(page == 0) return(-ENOMEM);
-	ret = 0;
-	while(len > 0){
-		one_len = (len < PAGE_SIZE) ? len : PAGE_SIZE;
-		if(copy_from_user((void *) page, &buf[ret], one_len)){
-			ret = -EFAULT;
-			break;
-		}		
-		n = write_file((int) file->private_data, start, (void *) page,
-			       one_len, file->f_flags & O_APPEND);
-		if(n < 0){
-			ret = n;
-			break;
-		}
-		ret += n;
-		len -= n;
-		if(n < one_len) break;
-	}
-	free_page(page);
-	return(ret);
-}
-
 int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
 {
 	void *dir;
 	char *name;
-	unsigned long long next;
+	unsigned long long next, ino;
 	int error, len;
 
 	name = dentry_name(file->f_dentry, 0);
@@ -191,10 +168,9 @@
 	kfree(name);
 	if(dir == NULL) return(-error);
 	next = file->f_pos;
-	while((name = read_dir(dir, &next, &len)) != NULL){
+	while((name = read_dir(dir, &next, &ino, &len)) != NULL){
 		error = (*filldir)(ent, name, len, file->f_pos, 
-				   file->f_dentry->d_inode->i_ino,
-				   DT_UNKNOWN);
+				   ino, DT_UNKNOWN);
 		if(error) break;
 		file->f_pos = next;
 	}
@@ -218,16 +194,25 @@
 int hostfs_file_open(struct inode *ino, struct file *file)
 {
 	char *name;
-	int r = 0, w = 0, fd;
+	int mode = 0, r = 0, w = 0, fd;
+
+	mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
+	if((mode & ino->u.hostfs_i.mode) == mode) return(0);
 
-	if(file->f_mode & FMODE_READ) r = 1;
-	if(file->f_mode & FMODE_WRITE) w = 1;
+	if(ino->u.hostfs_i.fd != -1){
+		close_file(&ino->u.hostfs_i.fd);
+		ino->u.hostfs_i.fd = -1;
+	}
+	ino->u.hostfs_i.mode |= mode;
+	if(ino->u.hostfs_i.mode & FMODE_READ) r = 1;
+	if(ino->u.hostfs_i.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);
 	kfree(name);
 	if(fd < 0) return(fd);
-	file->private_data = (void *) fd;
+	file_hostfs_i(file)->fd = fd;
 	return(0);
 }
 
@@ -236,12 +221,6 @@
 	return(0);	
 }
 
-int hostfs_file_release(struct inode *ino, struct file *file)
-{
-	close_file(file->private_data);
-	return(0);
-}
-
 int hostfs_dir_release(struct inode *ino, struct file *file)
 {
 	return(0);
@@ -258,14 +237,44 @@
 	return(-EINVAL);
 }
 
+#ifdef notdef
+ssize_t hostfs_write(struct file *file, const char *buf, size_t len, 
+                   loff_t *start)
+{
+	unsigned long page = __get_free_page(GFP_KERNEL);
+	int ret, one_len, n;
+
+	if(page == 0) return(-ENOMEM);
+	ret = 0;
+	while(len > 0){
+		one_len = (len < PAGE_SIZE) ? len : PAGE_SIZE;
+		if(copy_from_user((void *) page, &buf[ret], one_len)){
+			ret = -EFAULT;
+			break;
+		}
+		n = write_file(file_hostfs_i(file)->fd, start, (void *) page,
+			       one_len, file->f_flags & O_APPEND);
+		if(n < 0){
+			ret = n;
+			break;
+		}
+		ret += n;
+		len -= n;
+		if(n < one_len) break;
+	}
+	free_page(page);
+	return(ret);
+}
+#endif
+
 static struct file_operations hostfs_file_fops = {
 	owner:		NULL,
 	read:		generic_file_read,
-	write:		hostfs_write,
+	write:		generic_file_write,
 	poll:		hostfs_poll,
 	mmap:		generic_file_mmap,
 	open:		hostfs_file_open,
-	release:	hostfs_file_release,
+	release:	NULL,
 	fsync:		hostfs_fsync,
 	fasync:		hostfs_fasync
 };
@@ -283,8 +292,37 @@
 
 int hostfs_writepage(struct page *page)
 {
-	not_implemented();
-	return(-EINVAL);
+	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(inode->u.hostfs_i.fd, &base, buffer, count, 0);
+	if(err != count){
+		ClearPageUptodate(page);
+		goto out;
+	}
+
+	if (base > inode->i_size)
+		inode->i_size = base;
+
+	if (PageError(page))
+		ClearPageError(page);	
+
+ out:	
+	kunmap(page);
+
+	UnlockPage(page);
+	return err; 
 }
 
 int hostfs_readpage(struct file *file, struct page *page)
@@ -295,31 +333,65 @@
 
 	start = (long long) page->index << PAGE_CACHE_SHIFT;
 	buffer = kmap(page);
-	err = read_file((int) file->private_data, &start, buffer,
+	err = read_file(file_hostfs_i(file)->fd, &start, buffer,
 			PAGE_CACHE_SIZE);
-	if(err > 0){
-		flush_dcache_page(page);
-		SetPageUptodate(page);
-		if (PageError(page)) ClearPageError(page);
-		err = 0;
-	}
+	if(err < 0) goto out;
+
+	flush_dcache_page(page);
+	SetPageUptodate(page);
+	if (PageError(page)) ClearPageError(page);
+	err = 0;
+ out:
 	kunmap(page);
 	UnlockPage(page);
 	return(err);
 }
 
 int hostfs_prepare_write(struct file *file, struct page *page, unsigned from, 
-		  unsigned to)
+			 unsigned to)
 {
-	not_implemented();
-	return(-EINVAL);
+	char *buffer;
+	long long start;
+	int err;
+
+	start = (long long) page->index << PAGE_CACHE_SHIFT;
+	buffer = kmap(page);
+	if(from != 0){
+		err = read_file(file_hostfs_i(file)->fd, &start, 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)
 {
-	not_implemented();
-	return(-EINVAL);
+	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, 0);
+	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 = {
@@ -338,7 +410,9 @@
 
 	inode = get_empty_inode();
 	if(inode == NULL) return(NULL);
-	inode->u.generic_ip = NULL;
+	inode->u.hostfs_i.host_filename = NULL;
+	inode->u.hostfs_i.fd = -1;
+	inode->u.hostfs_i.mode = 0;
 	if(error) *error = 0;
 	insert_inode_hash(inode);
 	if(dentry){
@@ -675,7 +749,7 @@
 		kfree(name);
 		return(NULL);
 	}
-	root_inode->u.generic_ip = name;
+	root_inode->u.hostfs_i.host_filename = name;
 	sb->s_root = d_alloc_root(root_inode);
 	if(read_inode(root_inode)){
 		iput(root_inode);
diff -Naur -X exclude-files ac_cur/arch/um/fs/hostfs/hostfs_user.c ac/arch/um/fs/hostfs/hostfs_user.c
--- ac_cur/arch/um/fs/hostfs/hostfs_user.c	Sat Aug  4 22:01:03 2001
+++ ac/arch/um/fs/hostfs/hostfs_user.c	Sun Aug  5 12:53:31 2001
@@ -9,6 +9,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <utime.h>
+#include <string.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/vfs.h>
@@ -27,7 +28,11 @@
 	if(lstat64(path, &buf) < 0) 
 		return(-errno);
 	if(dev_out != NULL) *dev_out = buf.st_dev;
-	if(inode_out != NULL) *inode_out = buf.st_ino;
+
+	/* 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;
@@ -51,8 +56,9 @@
 	else if(S_ISLNK(buf.st_mode)) return(HOSTFS_SYMLINK);
 	else if(S_ISCHR(buf.st_mode)) return(HOSTFS_CHARDEV);
 	else if(S_ISBLK(buf.st_mode)) return(HOSTFS_BLOCDEV);
-	else if(S_ISFIFO(buf.st_mode)) return(HOSTFS_FIFO);
-	else if(S_ISSOCK(buf.st_mode)) return(HOSTFS_SOCK);
+	else if(S_ISFIFO(buf.st_mode))return(HOSTFS_FIFO);
+	else if(S_ISSOCK(buf.st_mode))return(HOSTFS_SOCK);
+
 	else return(HOSTFS_FILE);
 }
 
@@ -90,7 +96,8 @@
 	return(dir);
 }
 
-char *read_dir(void *stream, unsigned long long *pos, int *len_out)
+char *read_dir(void *stream, unsigned long long *pos, 
+	       unsigned long long *ino_out, int *len_out)
 {
 	DIR *dir = stream;
 	struct dirent *ent;
@@ -99,6 +106,7 @@
 	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);
 }
@@ -146,7 +154,7 @@
 
 void close_file(void *stream)
 {
-	close((int) stream);
+	close(*((int *) stream));
 }
 
 void close_dir(void *stream)
@@ -299,8 +307,9 @@
 	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,
+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)
 {
diff -Naur -X exclude-files ac_cur/include/linux/fs.h ac/include/linux/fs.h
--- ac_cur/include/linux/fs.h	Sat Aug  4 22:03:53 2001
+++ ac/include/linux/fs.h	Sun Aug  5 12:57:32 2001
@@ -324,6 +324,7 @@
 #include <linux/usbdev_fs_i.h>
 #include <linux/jffs2_fs_i.h>
 #include <linux/cramfs_fs_sb.h>
+#include <linux/hostfs_fs_i.h>
 
 /*
  * Attribute flags.  These should be or-ed together to figure out what
@@ -506,6 +507,7 @@
 		struct socket			socket_i;
 		struct usbdev_inode_info        usbdev_i;
 		struct jffs2_inode_info		jffs2_i;
+		struct hostfs_inode_info	hostfs_i;
 		void				*generic_ip;
 	} u;
 };
diff -Naur -X exclude-files ac_cur/include/linux/hostfs_fs_i.h ac/include/linux/hostfs_fs_i.h
--- ac_cur/include/linux/hostfs_fs_i.h	Wed Dec 31 19:00:00 1969
+++ ac/include/linux/hostfs_fs_i.h	Sun Aug  5 12:53:56 2001
@@ -0,0 +1,21 @@
+#ifndef _HOSTFS_FS_I
+#define _HOSTFS_FS_I
+
+struct hostfs_inode_info {
+	char *host_filename;
+	int fd;
+	int mode;
+};
+
+#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:
+ */