diff -ur linux-2.3.41.orig/fs/umsdos/README-WIP.txt linux-2.3.x-my/fs/umsdos/README-WIP.txt
--- linux-2.3.41.orig/fs/umsdos/README-WIP.txt	Mon Jan 31 23:52:39 2000
+++ linux-2.3.x-my/fs/umsdos/README-WIP.txt	Tue Feb  1 22:08:15 2000
@@ -16,7 +16,7 @@
 at http://cvs.linux.hr/
 
 Also look at the quick-hack "homepage" for umsdos filesystem at 
-http://www.voyager.hr/~mnalis/umsdos
+http://www.voyager.hr/~mnalis/umsdos/
 
 Information below is getting outdated slowly -- I'll fix it one day when I
 get enough time - there are more important things to fix right now.
@@ -24,7 +24,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 (000201) - UMSDOS 0.86g:
 
 (1) pure MSDOS (no --linux-.--- EMD file):
 
@@ -66,13 +66,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
@@ -80,7 +80,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.3.41.orig/fs/umsdos/check.c linux-2.3.x-my/fs/umsdos/check.c
--- linux-2.3.41.orig/fs/umsdos/check.c	Mon Jan 31 23:52:39 2000
+++ linux-2.3.x-my/fs/umsdos/check.c	Tue Feb  1 22:06:40 2000
@@ -89,11 +89,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.3.41.orig/fs/umsdos/dir.c linux-2.3.x-my/fs/umsdos/dir.c
--- linux-2.3.41.orig/fs/umsdos/dir.c	Mon Jan 31 23:52:39 2000
+++ linux-2.3.x-my/fs/umsdos/dir.c	Tue Feb  1 22:06:40 2000
@@ -594,6 +594,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;
@@ -671,7 +678,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);
@@ -715,6 +722,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.3.41.orig/fs/umsdos/emd.c linux-2.3.x-my/fs/umsdos/emd.c
--- linux-2.3.41.orig/fs/umsdos/emd.c	Mon Jan 31 23:52:39 2000
+++ linux-2.3.x-my/fs/umsdos/emd.c	Tue Feb  1 22:06:40 2000
@@ -277,6 +277,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.3.41.orig/fs/umsdos/inode.c linux-2.3.x-my/fs/umsdos/inode.c
--- linux-2.3.41.orig/fs/umsdos/inode.c	Mon Jan 31 23:52:39 2000
+++ linux-2.3.x-my/fs/umsdos/inode.c	Tue Feb  1 22:07:10 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);
@@ -338,7 +338,7 @@
 	if (!res)
 		goto out_fail;
 
-	printk (KERN_INFO "UMSDOS 0.86 "
+	printk (KERN_INFO "UMSDOS 0.86g "
 		"(compatibility level %d.%d, fast msdos)\n", 
 		UMSDOS_VERSION, UMSDOS_RELEASE);
 
diff -ur linux-2.3.41.orig/fs/umsdos/namei.c linux-2.3.x-my/fs/umsdos/namei.c
--- linux-2.3.41.orig/fs/umsdos/namei.c	Mon Jan 31 23:52:39 2000
+++ linux-2.3.x-my/fs/umsdos/namei.c	Tue Feb  1 22:06:40 2000
@@ -418,8 +418,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.3.41.orig/fs/umsdos/rdir.c linux-2.3.x-my/fs/umsdos/rdir.c
--- linux-2.3.41.orig/fs/umsdos/rdir.c	Mon Jan 31 23:52:39 2000
+++ linux-2.3.x-my/fs/umsdos/rdir.c	Tue Feb  1 22:06:40 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:
