diff -ur linux-2.2.16/MAINTAINERS linux-2.2.16-my/MAINTAINERS
--- linux-2.2.16/MAINTAINERS	Mon Jul 24 16:49:35 2000
+++ linux-2.2.16-my/MAINTAINERS	Mon Jul 24 16:50:38 2000
@@ -888,7 +888,7 @@
 
 UMSDOS FILESYSTEM
 P:	Matija Nalis
-M:	mnalis@jagor.srce.hr
+M:	mnalis-umsdos@voyager.hr
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
diff -ur linux/fs/umsdos.org.2.2.16/README-WIP.txt linux/fs/umsdos/README-WIP.txt
--- linux/fs/umsdos.org.2.2.16/README-WIP.txt	Sun Jul 23 18:16:13 2000
+++ linux/fs/umsdos/README-WIP.txt	Sat Jul 29 21:08:18 2000
@@ -5,20 +5,16 @@
 There is no warning any more.
 Both read-only and read-write stuff is fixed, both in
 msdos-compatibile mode, and in umsdos EMD mode, and it seems stable.
-There are still few hardlink nuisances, but those are not fatal.
-
-I'd call it pre-release, and ask for as many people as possible to
-come and test it! See notes below for some more information, or if
-you are trying to use UMSDOS as root partition.
 
 Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
-will compile and work on 2.2.x kernels and glibc based systems may be found
-at http://cvs.linux.hr/
+will compile and work on 2.2.x+ kernels and glibc based systems, as well as
+kernel patches and other umsdos related information may be found at
+http://linux.voyager.hr/umsdos/
 
 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 (000123) - UMSDOS 0.85g:
+Current status (000729) - UMSDOS 0.85i:
 
 (1) pure MSDOS (no --linux-.--- EMD file):
 
@@ -29,7 +25,7 @@
 
 WRITE:
 + creat file			- works
-+ delete file			- works
++ unlink file			- works
 + write file			- works
 + rename file (same dir)	- works
 + rename file (dif. dir)	- works
@@ -49,7 +45,7 @@
 + read file			- works
 + switching MSDOS/UMSDOS	- works
 + switching UMSDOS/MSDOS	- works
-- pseudo root things		- works mostly. See notes below.
+- pseudo root things		- works. See notes below.
 + resolve symlink		- works
 + dereference symlink		- works
 + dangling symlink		- works
@@ -60,21 +56,21 @@
 
 WRITE:
 + create symlink		- works
-- create hardlink		- works for same DIR (see notes)
++ create hardlink		- works
 + 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)	- works
-- rename hardlink (dif. dir)	-
++ rename hardlink (dif. dir)	- works
 + rename symlink (same dir)	- works
 + rename symlink (dif. dir)	- works
 + rename dir (same dir)		- works
 + rename dir (dif. dir)		- works
 + delete file			- works
 + notify_change (chown,perms)	- works
-- delete hardlink		- works for same DIR (see notes)
++ delete hardlink		- works
 + mkdir				- works
 + rmdir 			- works
 + umssyncing (many ioctls)	- works
@@ -91,26 +87,13 @@
 Note: creating and using pseudo-hardlinks is always non-perfect, especially
 in filesystems that might be externally modified like umsdos. There is
 example is specs file about it. Specifically, moving directory which
-contains hardlinks will break them.
-
-Note: (about pseudoroot) If you are currently trying to use UMSDOS as root
-partition (with linux installed in c:\linux) it will boot, but there may be
-some problems. Volunteers ready to test pseudoroot are needed (preferably
-ones with working backups or unimportant data).  For example, '/DOS' pseudo
-directory is only partially re-implemented and buggy. It works most of the
-time, though. Update: should work ok in 0.84, although it still does not
-work correctly in combination with initrd featere. Working on this!
+contains hardlinks will break them in some cases.
 
 Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in
 pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice
 versa. Thanks to Sorin Iordachescu <sorin@rodae.ro> for providing fix.
-
-Warning: (about hardlinks) - modifying hardlinks (esp. if they are in
-different directories) are currently somewhat broken, I'm working on it.
-Problem seems to be that code uses and updates EMD of directory where 'real
-hardlink' is stored, not EMD of directory where our pseudo-hardlink is
-located! I'm looking for ideas how to work around this in clean way, since
-without it modifying hardlinks in any but most simple ways is broken!
+See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade
+procedure if you used broken versions...
 
 ------------------------------------------------------------------------------
 
@@ -124,6 +107,5 @@
 I'm unfortunately somewhat out of time to read linux-kernel@vger, but I do
 check for messages having "UMSDOS" in the subject, and read them.  I might
 miss some in all that volume, though.  I should reply to any direct e-mail
-in few days.  If I don't, probably I never got your message.  You can try
-mnalis-umsdos@voyager.hr; however mnalis@jagor.srce.hr is preferable.
+in few days.  If I don't, probably I never got your message.
 
diff -ur linux/fs/umsdos.org.2.2.16/emd.c linux/fs/umsdos/emd.c
--- linux/fs/umsdos.org.2.2.16/emd.c	Sun Jul 23 18:16:13 2000
+++ linux/fs/umsdos/emd.c	Sat Jul 29 20:52:55 2000
@@ -273,6 +273,16 @@
 	Printk ((KERN_DEBUG "umsdos_emd_dir_readentry /mn/: entering.\n"));
 
 	ret = umsdos_emd_dir_read (filp, (char *) entry, UMSDOS_REC_SIZE);
+
+	/* if this is an invalid entry (invalid name length), ignore it */
+	if( entry->name_len > UMSDOS_MAXNAME )
+	{
+		printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len);
+		entry->name_len = 0; 
+		ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */
+	}
+
+
 	if (ret == 0) {	/* if no error */
 		/* Variable size record. Maybe, we have to read some more */
 		int recsize = umsdos_evalrecsize (entry->name_len);
diff -ur linux/fs/umsdos.org.2.2.16/inode.c linux/fs/umsdos/inode.c
--- linux/fs/umsdos.org.2.2.16/inode.c	Sun Jul 23 18:16:13 2000
+++ linux/fs/umsdos/inode.c	Thu Jul 27 20:26:44 2000
@@ -56,8 +56,7 @@
 		 ,inode->i_count));
 
 	if (inode == pseudo_root) {
-		printk (KERN_ERR "Umsdos: Oops releasing pseudo_root."
-			" Notify jacques@solucorp.qc.ca\n");
+		printk (KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, inode->i_count);
 	}
 
 	if (inode->i_count == 1)
@@ -180,21 +179,6 @@
 }
 
 
-int umsdos_notify_change_locked(struct dentry *, struct iattr *);
-/*
- * lock the parent dir before starting ...
- */
-int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *dir = dentry->d_parent->d_inode;
-	int ret;
-
-	down(&dir->i_sem);
-	ret = umsdos_notify_change_locked(dentry, attr);
-	up(&dir->i_sem);
-	return ret;
-}
-
 /*
  * Must be called with the parent lock held.
  */
@@ -300,6 +284,65 @@
 
 
 /*
+ * lock the parent dir before starting ...
+ * also handles hardlink converting
+ */
+int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *dir;
+	struct umsdos_info info;
+	struct dentry *temp, *old_dentry = NULL;
+	int ret;
+
+	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
+				&info);
+	if (ret)
+		goto out;
+	ret = umsdos_findentry (dentry->d_parent, &info, 0);
+	if (ret) {
+printk("UMSDOS_notify_change: %s/%s not in EMD, ret=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, ret);
+		goto out;
+	}
+
+	if (info.entry.flags & UMSDOS_HLINK) {
+		/*
+		 * In order to get the correct (real) inode, we just drop
+		 * the original dentry.
+		 */ 
+		d_drop(dentry);
+Printk(("UMSDOS_notify_change: hard link %s/%s, fake=%s\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
+	
+		/* Do a real lookup to get the short name dentry */
+		temp = umsdos_covered(dentry->d_parent, info.fake.fname,
+						info.fake.len);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out;
+	
+		/* now resolve the link ... */
+		temp = umsdos_solve_hlink(temp);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out;
+		old_dentry = dentry;
+		dentry = temp;	/* so umsdos_notify_change_locked will operate on that */
+	}
+
+	dir = dentry->d_parent->d_inode;
+
+	down(&dir->i_sem);
+	ret = umsdos_notify_change_locked(dentry, attr);
+	up(&dir->i_sem);
+out:
+	if (old_dentry)
+		dput (dentry);	/* if we had to use fake dentry for hardlinks, dput() it now */
+	return ret;
+}
+
+
+/*
  * Update the disk with the inode content
  */
 void UMSDOS_write_inode (struct inode *inode)
@@ -332,11 +375,28 @@
 	UMSDOS_notify_change,	/* notify_change */
 	UMSDOS_put_super,	/* put_super */
 	NULL,			/* write_super */
-	fat_statfs,		/* statfs */
+	UMSDOS_statfs,		/* statfs */
 	NULL,			/* remount_fs */
 	fat_clear_inode,	/* clear_inode */
 };
 
+
+int UMSDOS_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
+{
+	int ret;
+	struct statfs tmp;
+	
+	ret = fat_statfs (sb, buf, bufsiz);
+	copy_from_user (&tmp, buf, bufsiz);
+	if (!ret) {
+		copy_from_user (&tmp, buf, bufsiz);
+		tmp.f_namelen = UMSDOS_MAXNAME;
+		copy_to_user (buf, &tmp, bufsiz);
+	}
+	return ret;
+}
+
+
 /*
  * Read the super block of an Extended MS-DOS FS.
  */
@@ -356,7 +416,7 @@
 	if (!res)
 		goto out_fail;
 
-	printk (KERN_INFO "UMSDOS 0.85g "
+	printk (KERN_INFO "UMSDOS 0.85i "
 		"(compatibility level %d.%d, fast msdos)\n", 
 		UMSDOS_VERSION, UMSDOS_RELEASE);
 
diff -ur linux/fs/umsdos.org.2.2.16/ioctl.c linux/fs/umsdos/ioctl.c
--- linux/fs/umsdos.org.2.2.16/ioctl.c	Sun Jul 23 18:16:13 2000
+++ linux/fs/umsdos/ioctl.c	Sat Jul 29 21:08:53 2000
@@ -179,11 +179,22 @@
 			struct umsdos_info info;
 
 			ret = umsdos_emd_dir_readentry (&new_filp, &entry);
+
+			if (ret == -ENAMETOOLONG) {
+				printk (KERN_INFO "Fixing EMD entry with invalid size -- zeroing out\n");
+				fill_new_filp (&new_filp, demd);
+				new_filp.f_pos = f_pos;
+				new_filp.f_reada = 0;
+				memset (&entry, 0, sizeof (entry));
+				ret = umsdos_emd_dir_write (&new_filp, (char *) &entry, UMSDOS_REC_SIZE);
+				continue;
+			}
+
 			if (ret)
 				break;
 			if (entry.name_len <= 0)
 				continue;
-
+
 			umsdos_parse (entry.name, entry.name_len, &info);
 			info.f_pos = f_pos;
 			umsdos_manglename (&info);
diff -ur linux/fs/umsdos.org.2.2.16/namei.c linux/fs/umsdos/namei.c
--- linux/fs/umsdos.org.2.2.16/namei.c	Sun Jul 23 18:16:13 2000
+++ linux/fs/umsdos/namei.c	Sun Jul 23 20:16:05 2000
@@ -715,17 +715,35 @@
 	if (ret == 0) {
 		struct iattr newattrs;
 
+		/* Do a real lookup to get the short name dentry */
+		temp = umsdos_covered(olddentry->d_parent,
+					old_info.fake.fname,
+					old_info.fake.len);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out_unlock2;
+
+		/* now resolve the link ... */
+		temp = umsdos_solve_hlink(temp);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out_unlock2;
+
 #ifdef UMSDOS_PARANOIA
 if (!oldinode->u.umsdos_i.i_is_hlink)
 printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino);
 #endif
-		oldinode->i_nlink++;
+		temp->d_inode->i_nlink++;
 Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name,
 oldinode->i_ino, oldinode->i_nlink));
 		newattrs.ia_valid = 0;
-		ret = umsdos_notify_change_locked(olddentry, &newattrs);
+		ret = umsdos_notify_change_locked(temp, &newattrs);
+ 		if (ret == 0)
+			mark_inode_dirty(temp->d_inode);
+		dput(temp);
+out_unlock2:	
 	}
 	if (olddir != dir)
 		up(&olddir->i_sem);
