diff -ur linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/README-WIP.txt linux/fs/umsdos/README-WIP.txt
--- linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/README-WIP.txt	Sun Jan 16 20:22:51 2000
+++ linux/fs/umsdos/README-WIP.txt	Sun Jan 23 19:35:05 2000
@@ -18,7 +18,7 @@
 Legend: those lines marked with '+' on the beggining of line indicates it
 passed all of my tests, and performed perfect in all of them.
 
-Current status (990202) - UMSDOS 0.85:
+Current status (000123) - UMSDOS 0.85g:
 
 (1) pure MSDOS (no --linux-.--- EMD file):
 
@@ -60,13 +60,13 @@
 
 WRITE:
 + create symlink		- works
-- create hardlink		- works
+- create hardlink		- works for same DIR (see notes)
 + create file			- works
 + create special file		- works
 + write to file			- works
 + rename file (same dir)	- works
 + rename file (dif. dir)	- works
-- rename hardlink (same dir)	-
++ rename hardlink (same dir)	- works
 - rename hardlink (dif. dir)	-
 + rename symlink (same dir)	- works
 + rename symlink (dif. dir)	- works
@@ -74,7 +74,7 @@
 + rename dir (dif. dir)		- works
 + delete file			- works
 + notify_change (chown,perms)	- works
-+ delete hardlink		- works
+- delete hardlink		- works for same DIR (see notes)
 + mkdir				- works
 + rmdir 			- works
 + umssyncing (many ioctls)	- works
diff -ur linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/check.c linux/fs/umsdos/check.c
--- linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/check.c	Sun Jan 16 20:21:52 2000
+++ linux/fs/umsdos/check.c	Mon Jan 10 03:00:35 2000
@@ -81,11 +81,11 @@
 void check_inode (struct inode *inode)
 {
 	if (inode) {
-		printk (KERN_DEBUG "*   inode is %lu (i_count=%d)",
-			 inode->i_ino, inode->i_count);
+		printk (KERN_DEBUG "*   inode is %lu (i_count=%d, pos=%lu)",
+			 inode->i_ino, inode->i_count, inode->u.umsdos_i.pos);
 		check_sb (inode->i_sb, 'i');
 		
-		if (inode->i_dentry.next) {	/* FIXME: does this work ? */
+		if (!list_empty(&inode->i_dentry)) {
 			printk (" (has i_dentry)");
 		} else {
 			printk (" (NO i_dentry)");
diff -ur linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/dir.c linux/fs/umsdos/dir.c
--- linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/dir.c	Sun Jan 16 20:21:52 2000
+++ linux/fs/umsdos/dir.c	Sun Jan 23 15:33:52 2000
@@ -597,6 +597,13 @@
 	return ret;
 }
 
+/*
+ * looks up REAL DOS filename and returns result dentry
+ *
+ * NOTE: since it is looked via UMSDOS_rlookup, it will not have i_patched,
+ * umsdos_i.pos and other EMD-related stuff ! Moreover, it will destroy them
+ * if such dentry was pre-existant.
+ */
 struct dentry *umsdos_covered(struct dentry *parent, char *name, int len)
 {
 	struct dentry *result, *dentry;
@@ -674,7 +681,7 @@
 	if (*path == '/')
 		path++; /* skip leading '/' */
 
-	if (old_root->d_inode == pseudo_root)
+	if (current->fs->root->d_inode == pseudo_root)
 	{
 		*(path-1) = '/';
 		path -= (UMSDOS_PSDROOT_LEN+1);
@@ -718,6 +725,7 @@
 	filp.f_flags = O_RDONLY;
 
 	len = umsdos_file_read_kmem (&filp, path, hlink->d_inode->i_size);
+	if ((len > 0) && (len < PATH_MAX)) path[len] = '\0';
 	if (len != hlink->d_inode->i_size)
 		goto out_noread;
 #ifdef UMSDOS_DEBUG_VERBOSE
diff -ur linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/emd.c linux/fs/umsdos/emd.c
--- linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/emd.c	Sun Jan 16 20:21:52 2000
+++ linux/fs/umsdos/emd.c	Thu Jan 20 01:31:52 2000
@@ -287,6 +287,7 @@
 	}
 	Printk (("umsdos_emd_dir_readentry /mn/: ret=%d.\n", ret));
 	if (entry && ret == 0) {
+		entry->name[entry->name_len]='\0';
 Printk (("umsdos_emd_dir_readentry /mn/: returning len=%d,name=%.*s\n",
 (int) entry->name_len, (int) entry->name_len, entry->name));
 	}
diff -ur linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/inode.c linux/fs/umsdos/inode.c
--- linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/inode.c	Sun Jan 16 20:22:51 2000
+++ linux/fs/umsdos/inode.c	Sun Jan 23 19:28:39 2000
@@ -68,7 +68,7 @@
 void UMSDOS_put_super (struct super_block *sb)
 {
 	Printk ((KERN_DEBUG "UMSDOS_put_super: entering\n"));
-	if (saved_root) {
+	if (saved_root && pseudo_root && sb->s_dev == ROOT_DEV) {
 		shrink_dcache_parent(saved_root);
 printk("UMSDOS_put_super: freeing saved root, d_count=%d\n",
 saved_root->d_count);
@@ -356,7 +356,7 @@
 	if (!res)
 		goto out_fail;
 
-	printk (KERN_INFO "UMSDOS 0.85b "
+	printk (KERN_INFO "UMSDOS 0.85g "
 		"(compatibility level %d.%d, fast msdos)\n", 
 		UMSDOS_VERSION, UMSDOS_RELEASE);
 
diff -ur linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/namei.c linux/fs/umsdos/namei.c
--- linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/namei.c	Sun Jan 16 20:21:52 2000
+++ linux/fs/umsdos/namei.c	Sun Jan 23 19:34:20 2000
@@ -404,8 +404,15 @@
 		goto out_unlock;
 	/* make sure it's the same inode! */
 	ret = -ENOENT;
-	if (old->d_inode != old_inode)
-		goto out_dput;
+	/*
+	 * note: for hardlinks they will be different!
+	 *  old_inode will contain inode of .LINKxxx file containing data, and
+	 *  old->d_inode will contain inode of file containing path to .LINKxxx file
+	 */
+	if (!(old_info.entry.flags & UMSDOS_HLINK)) {
+		if (old->d_inode != old_inode)
+			goto out_dput;
+	}
 
 	new = umsdos_covered(new_dentry->d_parent, new_info.fake.fname, 
 					new_info.fake.len);
diff -ur linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/rdir.c linux/fs/umsdos/rdir.c
--- linux-2.2.13-ext3-clean-with-umsdos-as-2.2.14/fs/umsdos/rdir.c	Sun Jan 16 20:21:52 2000
+++ linux/fs/umsdos/rdir.c	Mon Jan 10 04:49:39 2000
@@ -110,7 +110,10 @@
 		 */
 Printk ((KERN_DEBUG "umsdos_rlookup_x: patch_dentry_inode %s/%s\n",
 dentry->d_parent->d_name.name, dentry->d_name.name));
-		umsdos_patch_dentry_inode(dentry, 0);
+/* only patch if needed (because we get called even for lookup
+   (not only rlookup) stuff sometimes, like in umsdos_covered() */
+		if (dentry->d_inode->u.umsdos_i.i_patched == 0)	
+			umsdos_patch_dentry_inode(dentry, 0);
 
 	}
 out:

