
From: Christoph Hellwig <hch@lst.de>

UMSDOS has been non-function since early 2.5 and would need a major rewrite
to be resurrected (which I don't hope anyone plans as it's a really
horrible hack)

From: Adrian Bunk <bunk@stusta.de>

With umsdos gone, there's no longer a MAINTAINERS entry required.

Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 /dev/null                                  | 1097 ----------------------------
 25-akpm/Documentation/filesystems/00-INDEX |    2 
 25-akpm/MAINTAINERS                        |    7 
 25-akpm/fs/Kconfig                         |   46 -
 25-akpm/fs/Makefile                        |    1 
 25-akpm/fs/umsdos/Makefile                 |   13 
 25-akpm/fs/umsdos/README-WIP.txt           |  110 --
 25-akpm/fs/umsdos/dir.c                    |  810 --------------------
 25-akpm/fs/umsdos/inode.c                  |  483 ------------
 25-akpm/fs/umsdos/ioctl.c                  |  446 -----------
 25-akpm/fs/umsdos/mangle.c                 |  522 -------------
 25-akpm/fs/umsdos/namei.c                  | 1124 -----------------------------
 25-akpm/fs/umsdos/rdir.c                   |  248 ------
 25-akpm/fs/umsdos/specs                    |  289 -------
 14 files changed, 2 insertions(+), 5196 deletions(-)

diff -puN Documentation/filesystems/00-INDEX~remove-umsdos-from-tree Documentation/filesystems/00-INDEX
--- 25/Documentation/filesystems/00-INDEX~remove-umsdos-from-tree	2005-01-10 21:13:45.187826760 -0800
+++ 25-akpm/Documentation/filesystems/00-INDEX	2005-01-10 21:13:45.215822504 -0800
@@ -42,8 +42,6 @@ udf.txt
 	- info and mount options for the UDF filesystem.
 ufs.txt
 	- info on the ufs filesystem.
-umsdos.txt
-	- info on the umsdos extensions to the msdos filesystem.
 vfat.txt
 	- info on using the VFAT filesystem used in Windows NT and Windows 95
 vfs.txt
diff -L Documentation/filesystems/umsdos.txt -puN Documentation/filesystems/umsdos.txt~remove-umsdos-from-tree /dev/null
--- 25/Documentation/filesystems/umsdos.txt
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,100 +0,0 @@
-Firstly, let me say that UMSDOS is going through some major code changes,
-and has some KNOWN BUGS (and quite a few unknown :-). Please read
-fs/umsdos/README-WIP.txt for more information on current status. Thanks.
-
-----------------------------------------------------------------------------
-Very short explanation for the impatient!
-
-Umsdos is a file system driver that run on top the MSDOS fs driver.
-It is written by Jacques Gelinas (jacques@solucorp.qc.ca)
-and is currently maintained by Matija Nalis (mnalis@jagor.srce.hr)
-
-Umsdos is not a file system per se, but a twist to make a boring
-one into a useful one.
-
-It gives you:
-
-	long file names
-	Permissions and owners
-	Links
-	Special files (devices, pipes...)
-	All that is needed to be a linux root fs.
-
-There is plenty of documentation on it in the source. A formatted document
-made from those comments is available from
-sunsite.unc.edu:/pub/Linux/system/Filesystems/umsdos.
-
-You mount a DOS partition like this:
-
-mount -t umsdos /dev/hda3 /mnt
-         ^
----------|
-
-All options are passed to the msdos drivers. Option like uid,gid etc are
-given to msdos.
-
-The default behavior of Umsdos is to do the same thing as the msdos driver
-mostly passing commands to it without much processing. Again, this is
-the default. After doing the mount on a DOS partition, nothing special
-happens. This is why all mount options are passed to the msdos fs driver.
-
-Umsdos uses a special DOS file --linux-.--- to store the information
-which can't be handled by the normal MS-DOS filesystem. This is the trick.
-
---linux-.--- is optional. There is one per directory.
-
-**** If --linux-.--- is missing, then Umsdos process the directory the
-     same way the msdos driver does. Short file names, no goodies, default
-     owner and permissions. So each directory may have or not this
-     --linux-.---
-
-Now, how to get those --linux-.---.
-
-\begin joke_section
-
-	Well send me a directory content
-	and I will send you one customised for you.
-	$5 per directory. Add any applicable taxes.
-\end joke_section
-
-A utility umssync creates those. The kernel maintains them. It is available
-from the same directory above (sunsite) in the file umsdos_progs-0.7.tar.gz.
-A compiled version is available in umsdos_progs-0.7.bin.tar.gz.
-
-So in our example, after mounting mnt, we do
-
-	umssync .
-
-This will promote this directory (a recursive option is available) to full
-umsdos capabilities (long name, etc.).  However, an "ls -l" before and after
-won't show much difference.  The files which were there are still there, but
-now you can do all this:
-
-	chmod 644 *
-	chown you.your_group *
-	ls >THIS_IS.A.VERY.LONG.NAME
-	ln -s toto tata
-	ls -l
-
-Once a directory is promoted, all subdirectories created will inherit that
-promotion.
-
-What happens if you boot DOS and create files in those promoted directories ?
-Umsdos won't notice new files, but will signal removed files (it won't crash).
-Using umssync in /etc/rc will make sure the DOS directory is in sync with
-the --linux-.---.
-
-It is a good idea to put the following command in your RC file just
-after the "mount -a":
-
-	mount -a
-	/sbin/umssync -i+ -c+ -r99 /umsdos_mount_point
-
-	(You put one for each umsdos mount point in the fstab)
-
-This will ensure nice operation.  A umsdos.fsck is in the making,
-so you will be allowed to manage umsdos partitions in the same way
-other filesystems are, using the generic fsck front end.
-
-Hope this helps!
-
diff -puN fs/Kconfig~remove-umsdos-from-tree fs/Kconfig
--- 25/fs/Kconfig~remove-umsdos-from-tree	2005-01-10 21:13:45.190826304 -0800
+++ 25-akpm/fs/Kconfig	2005-01-10 21:13:45.218822048 -0800
@@ -578,9 +578,8 @@ config FAT_FS
 	tristate
 	select NLS
 	help
-	  If you want to use one of the FAT-based file systems (the MS-DOS,
-	  VFAT (Windows 95) and UMSDOS (used to run Linux on top of an
-	  ordinary DOS partition) file systems), then you must say Y or M here
+	  If you want to use one of the FAT-based file systems (the MS-DOS and
+	  VFAT (Windows 95) file systems), then you must say Y or M here
 	  to include FAT support. You will then be able to mount partitions or
 	  diskettes with FAT-based file systems and transparently access the
 	  files on them, i.e. MSDOS files will look and behave just like all
@@ -612,9 +611,6 @@ config FAT_FS
 	  fat.  Note that if you compile the FAT support as a module, you
 	  cannot compile any of the FAT-based file systems into the kernel
 	  -- they will have to be modules as well.
-	  The file system of your root partition (the one containing the
-	  directory /) cannot be a module, so don't say M here if you intend
-	  to use UMSDOS as your root file system.
 
 config MSDOS_FS
 	tristate "MSDOS fs support"
@@ -631,10 +627,6 @@ config MSDOS_FS
 	  transparent, i.e. the MSDOS files look and behave just like all
 	  other Unix files.
 
-	  If you want to use UMSDOS, the Unix-like file system on top of a
-	  DOS file system, which allows you to run Linux from within a DOS
-	  partition without repartitioning, you'll have to say Y or M here.
-
 	  If you have Windows 95 or Windows NT installed on your MSDOS
 	  partitions, you should use the VFAT file system (say Y to "VFAT fs
 	  support" below), or you will not be able to see the long filenames
@@ -654,11 +646,6 @@ config VFAT_FS
 	  used by Windows 95, Windows 98, Windows NT 4.0, and the Unix
 	  programs from the mtools package.
 
-	  You cannot use the VFAT file system for your Linux root partition
-	  (the one containing the directory /); use UMSDOS instead if you
-	  want to run Linux from within a DOS partition (i.e. say Y to
-	  "Unix like fs on top of std MSDOS fs", below).
-
 	  The VFAT support enlarges your kernel by about 10 KB and it only
 	  works if you said Y to the "DOS FAT fs support" above.  Please read
 	  the file <file:Documentation/filesystems/vfat.txt> for details.  If
@@ -689,35 +676,6 @@ config FAT_DEFAULT_IOCHARSET
 	  If unsure, you shouldn't set "utf8" here.
 	  See <file:Documentation/filesystems/vfat.txt> for more information.
 
-config UMSDOS_FS
-#dep_tristate '    UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
-# UMSDOS is temprory broken
-	bool
-	help
-	  Say Y here if you want to run Linux from within an existing DOS
-	  partition of your hard drive. The advantage of this is that you can
-	  get away without repartitioning your hard drive (which often implies
-	  backing everything up and restoring afterwards) and hence you're
-	  able to quickly try out Linux or show it to your friends; the
-	  disadvantage is that Linux becomes susceptible to DOS viruses and
-	  that UMSDOS is somewhat slower than ext2fs.  Another use of UMSDOS
-	  is to write files with long unix filenames to MSDOS floppies; it
-	  also allows Unix-style soft-links and owner/permissions of files on
-	  MSDOS floppies.  You will need a program called umssync in order to
-	  make use of UMSDOS; read
-	  <file:Documentation/filesystems/umsdos.txt>.
-
-	  To get utilities for initializing/checking UMSDOS file system, or
-	  latest patches and/or information, visit the UMSDOS home page at
-	  <http://www.voyager.hr/~mnalis/umsdos/>.
-
-	  This option enlarges your kernel by about 28 KB and it only works if
-	  you said Y to both "DOS FAT fs support" and "MSDOS fs support"
-	  above.  To compile this as a module, choose M here: the module will be
-	  called umsdos.  Note that the file system of your root partition
-	  (the one containing the directory /) cannot be a module, so saying M
-	  could be dangerous.  If unsure, say N.
-
 config NTFS_FS
 	tristate "NTFS file system support"
 	select NLS
diff -puN fs/umsdos/dir.c~remove-umsdos-from-tree fs/umsdos/dir.c
--- 25/fs/umsdos/dir.c~remove-umsdos-from-tree	2005-01-10 21:13:45.192826000 -0800
+++ 25-akpm/fs/umsdos/dir.c	2005-01-10 21:13:45.221821592 -0800
@@ -1,810 +0,0 @@
-/*
- *  linux/fs/umsdos/dir.c
- *
- *  Written 1993 by Jacques Gelinas
- *      Inspired from linux/fs/msdos/... : Werner Almesberger
- *
- *  Extended MS-DOS directory handling functions
- */
-
-#include <linux/time.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/errno.h>
-#include <linux/stat.h>
-#include <linux/limits.h>
-#include <linux/umsdos_fs.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
-
-#define UMSDOS_SPECIAL_DIRFPOS	3
-extern struct dentry *saved_root;
-extern struct inode *pseudo_root;
-
-/* #define UMSDOS_DEBUG_VERBOSE 1 */
-
-/*
- * Dentry operations routines
- */
-
-/* nothing for now ... */
-static int umsdos_dentry_validate(struct dentry *dentry, struct nameidata *nd)
-{
-	return 1;
-}
-
-/* for now, drop everything to force lookups ... */
-/* ITYM s/everything/& positive/... */
-static int umsdos_dentry_dput(struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	if (inode) {
-		return 1;
-	}
-	return 0;
-}
-
-struct dentry_operations umsdos_dentry_operations =
-{
-	.d_revalidate	= umsdos_dentry_validate,
-	.d_delete	= umsdos_dentry_dput,
-};
-
-struct UMSDOS_DIR_ONCE {
-	void *dirbuf;
-	filldir_t filldir;
-	int count;
-	int stop;
-};
-
-/*
- * Record a single entry the first call.
- * Return -EINVAL the next one.
- * NOTE: filldir DOES NOT use a dentry
- */
-
-static int umsdos_dir_once (	void *buf,
-				const char *name,
-				int len,
-				loff_t offset,
-				ino_t ino,
-				unsigned type)
-{
-	int ret = -EINVAL;
-	struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *) buf;
-
-	if (d->count == 0) {
-		PRINTK ((KERN_DEBUG "dir_once :%.*s: offset %Ld\n", 
-			len, name, offset));
-		ret = d->filldir (d->dirbuf, name, len, offset, ino, DT_UNKNOWN);
-		d->stop = ret < 0;
-		d->count = 1;
-	}
-	return ret;
-}
-
-
-/*
- * Read count directory entries from directory filp
- * Return a negative value from linux/errno.h.
- * Return > 0 if success (the number of bytes written by filldir).
- * 
- * This function is used by the normal readdir VFS entry point,
- * and in order to get the directory entry from a file's dentry.
- * See umsdos_dentry_to_entry() below.
- */
- 
-static int umsdos_readdir_x (struct inode *dir, struct file *filp,
-				void *dirbuf, struct umsdos_dirent *u_entry,
-				filldir_t filldir)
-{
-	struct dentry *demd;
-	off_t start_fpos;
-	int ret = 0;
-	loff_t pos;
-
-	umsdos_startlookup (dir);
-
-	if (filp->f_pos == UMSDOS_SPECIAL_DIRFPOS && dir == pseudo_root) {
-
-		/*
-		 * We don't need to simulate this pseudo directory
-		 * when umsdos_readdir_x is called for internal operation
-		 * of umsdos. This is why dirent_in_fs is tested
-		 */
-		/* #Specification: pseudo root / directory /DOS
-		 * When umsdos operates in pseudo root mode (C:\linux is the
-		 * linux root), it simulate a directory /DOS which points to
-		 * the real root of the file system.
-		 */
-
-		Printk ((KERN_WARNING "umsdos_readdir_x: pseudo_root thing UMSDOS_SPECIAL_DIRFPOS\n"));
-		if (filldir (dirbuf, "DOS", 3, 
-				UMSDOS_SPECIAL_DIRFPOS, UMSDOS_ROOT_INO, DT_DIR) == 0) {
-			filp->f_pos++;
-		}
-		goto out_end;
-	}
-
-	if (filp->f_pos < 2 || 
-	    (dir->i_ino != UMSDOS_ROOT_INO && filp->f_pos == 32)) {
-	
-		int last_f_pos = filp->f_pos;
-		struct UMSDOS_DIR_ONCE bufk;
-
-		Printk (("umsdos_readdir_x: . or .. /mn/?\n"));
-
-		bufk.dirbuf = dirbuf;
-		bufk.filldir = filldir;
-		bufk.count = 0;
-
-		ret = fat_readdir (filp, &bufk, umsdos_dir_once);
-		if (last_f_pos > 0 && filp->f_pos > last_f_pos)
-			filp->f_pos = UMSDOS_SPECIAL_DIRFPOS;
-		if (u_entry != NULL)
-			u_entry->flags = 0;
-		goto out_end;
-	}
-
-	Printk (("umsdos_readdir_x: normal file /mn/?\n"));
-
-	/* get the EMD dentry */
-	demd = umsdos_get_emd_dentry(filp->f_dentry);
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out_end;
-	ret = -EIO;
-	if (!demd->d_inode) {
-		printk(KERN_WARNING 
-			"umsdos_readir_x: EMD file %s/%s not found\n",
-			demd->d_parent->d_name.name, demd->d_name.name);
-		goto out_dput;
-	}
-
-	pos = filp->f_pos;
-	start_fpos = filp->f_pos;
-
-	if (pos <= UMSDOS_SPECIAL_DIRFPOS + 1)
-		pos = 0;
-	ret = 0;
-	while (pos < demd->d_inode->i_size) {
-		off_t cur_f_pos = pos;
-		struct dentry *dret;
-		struct inode *inode;
-		struct umsdos_dirent entry;
-		struct umsdos_info info;
-
-		ret = -EIO;
-		if (umsdos_emd_dir_readentry (demd, &pos, &entry) != 0)
-			break;
-		if (entry.name_len == 0)
-			continue;
-#ifdef UMSDOS_DEBUG_VERBOSE
-if (entry.flags & UMSDOS_HLINK)
-printk("umsdos_readdir_x: %s/%s is hardlink\n",
-filp->f_dentry->d_name.name, entry.name);
-#endif
-
-		umsdos_parse (entry.name, entry.name_len, &info);
-		info.f_pos = cur_f_pos;
-		umsdos_manglename (&info);
-		/*
-		 * Do a real lookup on the short name.
-		 */
-		dret = umsdos_covered(filp->f_dentry, info.fake.fname,
-						 info.fake.len);
-		ret = PTR_ERR(dret);
-		if (IS_ERR(dret))
-			break;
-		/*
-		 * If the file wasn't found, remove it from the EMD.
-		 */
-		inode = dret->d_inode;
-		if (!inode)
-			goto remove_name;
-#ifdef UMSDOS_DEBUG_VERBOSE
-if (UMSDOS_I(inode)->i_is_hlink)
-printk("umsdos_readdir_x: %s/%s already resolved, ino=%ld\n",
-dret->d_parent->d_name.name, dret->d_name.name, inode->i_ino);
-#endif
-
-Printk (("Found %s/%s, ino=%ld, flags=%x\n",
-dret->d_parent->d_name.name, info.fake.fname, dret->d_inode->i_ino,
-entry.flags));
-		/* check whether to resolve a hard-link */
-		if ((entry.flags & UMSDOS_HLINK) &&
-		    !UMSDOS_I(inode)->i_is_hlink) {
-			dret = umsdos_solve_hlink (dret);
-			ret = PTR_ERR(dret);
-			if (IS_ERR(dret))
-				break;
-			inode = dret->d_inode;
-			if (!inode) {
-printk("umsdos_readdir_x: %s/%s negative after link\n",
-dret->d_parent->d_name.name, dret->d_name.name);
-				goto clean_up;
-			}
-		}
-
-		/* #Specification:  pseudo root / reading real root
-		 * The pseudo root (/linux) is logically
-		 * erased from the real root.  This means that
-		 * ls /DOS, won't show "linux". This avoids
-		 * infinite recursion (/DOS/linux/DOS/linux/...) while
-		 * walking the file system.
-		 */
-		if (inode != pseudo_root && !(entry.flags & UMSDOS_HIDDEN)) {
-			if (filldir (dirbuf, entry.name, entry.name_len,
-				 cur_f_pos, inode->i_ino, DT_UNKNOWN) < 0) {
-				pos = cur_f_pos;
-			}
-Printk(("umsdos_readdir_x: got %s/%s, ino=%ld\n",
-dret->d_parent->d_name.name, dret->d_name.name, inode->i_ino));
-			if (u_entry != NULL)
-				*u_entry = entry;
-			dput(dret);
-			ret = 0;
-			break;
-		}
-	clean_up:
-		dput(dret);
-		continue;
-
-	remove_name:
-		/* #Specification:  umsdos / readdir / not in MSDOS
-		 * During a readdir operation, if the file is not
-		 * in the MS-DOS directory any more, the entry is
-		 * removed from the EMD file silently.
-		 */
-#ifdef UMSDOS_PARANOIA
-printk("umsdos_readdir_x: %s/%s out of sync, erasing\n",
-filp->f_dentry->d_name.name, info.entry.name);
-#endif
-		ret = umsdos_delentry(filp->f_dentry, &info, 
-					S_ISDIR(info.entry.mode));
-		if (ret)
-			printk(KERN_WARNING 
-				"umsdos_readdir_x: delentry %s, err=%d\n",
-				info.entry.name, ret);
-		goto clean_up;
-	}
-	/*
-	 * If the fillbuf has failed, f_pos is back to 0.
-	 * To avoid getting back into the . and .. state
-	 * (see comments at the beginning), we put back
-	 * the special offset.
-	 */
-	filp->f_pos = pos;
-	if (filp->f_pos == 0)
-		filp->f_pos = start_fpos;
-out_dput:
-	dput(demd);
-
-out_end:
-	umsdos_endlookup (dir);
-	
-	Printk ((KERN_DEBUG "read dir %p pos %Ld ret %d\n",
-		dir, filp->f_pos, ret));
-	return ret;
-}
-
-
-/*
- * Read count directory entries from directory filp.
- * Return a negative value from linux/errno.h.
- * Return 0 or positive if successful.
- */
- 
-static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
-{
-	struct inode *dir = filp->f_dentry->d_inode;
-	int ret = 0, count = 0;
-	struct UMSDOS_DIR_ONCE bufk;
-
-	lock_kernel();
-
-	bufk.dirbuf = dirbuf;
-	bufk.filldir = filldir;
-	bufk.stop = 0;
-
-	Printk (("UMSDOS_readdir in\n"));
-	while (ret == 0 && bufk.stop == 0) {
-		struct umsdos_dirent entry;
-
-		bufk.count = 0;
-		ret = umsdos_readdir_x (dir, filp, &bufk, &entry, 
-					umsdos_dir_once);
-		if (bufk.count == 0)
-			break;
-		count += bufk.count;
-	}
-	unlock_kernel();
-	Printk (("UMSDOS_readdir out %d count %d pos %Ld\n", 
-		ret, count, filp->f_pos));
-	return count ? : ret;
-}
-
-
-/*
- * Complete the inode content with info from the EMD file.
- *
- * This function modifies the state of a dir inode.  It decides
- * whether the dir is a UMSDOS or DOS directory.  This is done
- * deeper in umsdos_patch_inode() called at the end of this function.
- * 
- * Because it is does disk access, umsdos_patch_inode() may block.
- * At the same time, another process may get here to initialise
- * the same directory inode. There are three cases.
- * 
- * 1) The inode is already initialised.  We do nothing.
- * 2) The inode is not initialised.  We lock access and do it.
- * 3) Like 2 but another process has locked the inode, so we try
- * to lock it and check right afterward check whether
- * initialisation is still needed.
- * 
- * 
- * Thanks to the "mem" option of the kernel command line, it was
- * possible to consistently reproduce this problem by limiting
- * my memory to 4 MB and running X.
- *
- * Do this only if the inode is freshly read, because we will lose
- * the current (updated) content.
- *
- * A lookup of a mount point directory yield the inode into
- * the other fs, so we don't care about initialising it. iget()
- * does this automatically.
- */
-
-void umsdos_lookup_patch_new(struct dentry *dentry, struct umsdos_info *info)
-{
-	struct inode *inode = dentry->d_inode;
-	struct umsdos_dirent *entry = &info->entry;
-
-	/*
-	 * This part of the initialization depends only on i_patched.
-	 */
-	if (UMSDOS_I(inode)->i_patched)
-		goto out;
-	UMSDOS_I(inode)->i_patched = 1;
-	if (S_ISREG (entry->mode))
-		entry->mtime = inode->i_mtime;
-	inode->i_mode = entry->mode;
-	inode->i_rdev = to_kdev_t (entry->rdev);
-	inode->i_atime = entry->atime;
-	inode->i_ctime = entry->ctime;
-	inode->i_mtime = entry->mtime;
-	inode->i_uid = entry->uid;
-	inode->i_gid = entry->gid;
-
-	/* #Specification: umsdos / i_nlink
-	 * The nlink field of an inode is maintained by the MSDOS file system
-	 * for directory and by UMSDOS for other files.  The logic is that
-	 * MSDOS is already figuring out what to do for directories and
-	 * does nothing for other files.  For MSDOS, there are no hard links
-	 * so all file carry nlink==1.  UMSDOS use some info in the
-	 * EMD file to plug the correct value.
-	 */
-	if (!S_ISDIR (entry->mode)) {
-		if (entry->nlink > 0) {
-			inode->i_nlink = entry->nlink;
-		} else {
-			printk (KERN_ERR 
-				"UMSDOS:  lookup_patch entry->nlink < 1 ???\n");
-		}
-	}
-	/*
-	 * The mode may have changed, so patch the inode again.
-	 */
-	umsdos_patch_dentry_inode(dentry, info->f_pos);
-	umsdos_set_dirinfo_new(dentry, info->f_pos);
-
-out:
-	return;
-}
-
-
-/*
- * Return != 0 if an entry is the pseudo DOS entry in the pseudo root.
- */
-
-int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry)
-{
-	/* #Specification: pseudo root / DOS hard coded
-	 * The pseudo sub-directory DOS in the pseudo root is hard coded.
-	 * The name is DOS. This is done this way to help standardised
-	 * the umsdos layout. The idea is that from now on /DOS is
-	 * a reserved path and nobody will think of using such a path
-	 * for a package.
-	 */
-	return dir == pseudo_root
-	    && dentry->d_name.len == 3
-	    && dentry->d_name.name[0] == 'D'
-	    && dentry->d_name.name[1] == 'O'
-	    && dentry->d_name.name[2] == 'S';
-}
-
-
-/*
- * Check whether a file exists in the current directory.
- * Return 0 if OK, negative error code if not (ex: -ENOENT).
- *
- * fills dentry->d_inode with found inode, and increments its count.
- * if not found, return -ENOENT.
- */
-/* #Specification: umsdos / lookup
- * A lookup for a file is done in two steps.  First, we
- * locate the file in the EMD file.  If not present, we
- * return an error code (-ENOENT).  If it is there, we
- * repeat the operation on the msdos file system. If
- * this fails, it means that the file system is not in
- * sync with the EMD file.   We silently remove this
- * entry from the EMD file, and return ENOENT.
- */
-
-struct dentry *umsdos_lookup_x (struct inode *dir, struct dentry *dentry, int nopseudo)
-{				
-	struct dentry *dret = NULL;
-	struct inode *inode;
-	int ret = -ENOENT;
-	struct umsdos_info info;
-
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk("umsdos_lookup_x: looking for %s/%s\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
-
-	umsdos_startlookup (dir);
-	if (umsdos_is_pseudodos (dir, dentry)) {
-		/* #Specification: pseudo root / lookup(DOS)
-		 * A lookup of DOS in the pseudo root will always succeed
-		 * and return the inode of the real root.
-		 */
-		Printk ((KERN_DEBUG "umsdos_lookup_x: following /DOS\n"));
-		inode = saved_root->d_inode;
-		goto out_add;
-	}
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret) {
-printk("umsdos_lookup_x: %s/%s parse failed, ret=%d\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out;
-	}
-
-	ret = umsdos_findentry (dentry->d_parent, &info, 0);
-	if (ret) {
-if (ret != -ENOENT)
-printk("umsdos_lookup_x: %s/%s findentry failed, ret=%d\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out;
-	}
-Printk (("lookup %.*s pos %lu ret %d len %d ", 
-info.fake.len, info.fake.fname, info.f_pos, ret, info.fake.len));
-
-	/* do a real lookup to get the short name ... */
-	dret = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(dret);
-	if (IS_ERR(dret)) {
-printk("umsdos_lookup_x: %s/%s real lookup failed, ret=%d\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out;
-	}
-	inode = dret->d_inode;
-	if (!inode)
-		goto out_remove;
-	umsdos_lookup_patch_new(dret, &info);
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk("umsdos_lookup_x: found %s/%s, ino=%ld\n", 
-dret->d_parent->d_name.name, dret->d_name.name, dret->d_inode->i_ino);
-#endif
-
-	/* Check for a hard link */
-	if ((info.entry.flags & UMSDOS_HLINK) &&
-	    !UMSDOS_I(inode)->i_is_hlink) {
-		dret = umsdos_solve_hlink (dret);
-		ret = PTR_ERR(dret);
-		if (IS_ERR(dret))
-			goto out;
-		ret = -ENOENT;
-		inode = dret->d_inode;
-		if (!inode) {
-printk("umsdos_lookup_x: %s/%s negative after link\n", 
-dret->d_parent->d_name.name, dret->d_name.name);
-			goto out_dput;
-		}
-	}
-
-	if (inode == pseudo_root && !nopseudo) {
-		/* #Specification: pseudo root / dir lookup
-		 * For the same reason as readdir, a lookup in /DOS for
-		 * the pseudo root directory (linux) will fail.
-		 */
-		/*
-		 * This has to be allowed for resolving hard links
-		 * which are recorded independently of the pseudo-root
-		 * mode.
-		 */
-printk("umsdos_lookup_x: skipping DOS/linux\n");
-		ret = -ENOENT;
-		goto out_dput;
-	}
-
-	/*
-	 * We've found it OK.  Now hash the dentry with the inode.
-	 */
-out_add:
-	atomic_inc(&inode->i_count);
-	d_add (dentry, inode);
-	dentry->d_op = &umsdos_dentry_operations;
-	ret = 0;
-
-out_dput:
-	if (dret && dret != dentry)
-		d_drop(dret);
-	dput(dret);
-out:
-	umsdos_endlookup (dir);
-	return ERR_PTR(ret);
-
-out_remove:
-	printk(KERN_WARNING "UMSDOS:  entry %s/%s out of sync, erased\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name);
-	umsdos_delentry (dentry->d_parent, &info, S_ISDIR (info.entry.mode));
-	ret = -ENOENT;
-	goto out_dput;
-}
-
-
-/*
- * Check whether a file exists in the current directory.
- * Return 0 if OK, negative error code if not (ex: -ENOENT).
- * 
- * Called by VFS; should fill dentry->d_inode via d_add.
- */
-
-struct dentry *UMSDOS_lookup (struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-	struct dentry *ret;
-
-	ret = umsdos_lookup_x (dir, dentry, 0);
-
-	/* Create negative dentry if not found. */
-	if (ret == ERR_PTR(-ENOENT)) {
-		Printk ((KERN_DEBUG 
-			"UMSDOS_lookup: converting -ENOENT to negative\n"));
-		d_add (dentry, NULL);
-		dentry->d_op = &umsdos_dentry_operations;
-		ret = NULL;
-	}
-	return ret;
-}
-
-struct dentry *umsdos_covered(struct dentry *parent, char *name, int len)
-{
-	struct dentry *result, *dentry;
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len  = len;
-	qstr.hash = full_name_hash(name, len);
-	result = ERR_PTR(-ENOMEM);
-	dentry = d_alloc(parent, &qstr);
-	if (dentry) {
-		/* XXXXXXXXXXXXXXXXXXX Race alert! */
-		result = UMSDOS_rlookup(parent->d_inode, dentry);
-		d_drop(dentry);
-		if (result)
-			goto out_fail;
-		return dentry;
-	}
-out:
-	return result;
-
-out_fail:
-	dput(dentry);
-	goto out;
-}
-
-/*
- * Lookup or create a dentry from within the filesystem.
- *
- * We need to use this instead of lookup_dentry, as the 
- * directory semaphore lock is already held.
- */
-struct dentry *umsdos_lookup_dentry(struct dentry *parent, char *name, int len,
-					int real)
-{
-	struct dentry *result, *dentry;
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len  = len;
-	qstr.hash = full_name_hash(name, len);
-	result = d_lookup(parent, &qstr);
-	if (!result) {
-		result = ERR_PTR(-ENOMEM);
-		dentry = d_alloc(parent, &qstr);
-		if (dentry) {
-			result = real ?
-				UMSDOS_rlookup(parent->d_inode, dentry) :
-				UMSDOS_lookup(parent->d_inode, dentry);
-			if (result)
-				goto out_fail;
-			return dentry;
-		}
-	}
-out:
-	return result;
-
-out_fail:
-	dput(dentry);
-	goto out;
-}
-
-/*
- * Return a path relative to our root.
- */
-char * umsdos_d_path(struct dentry *dentry, char * buffer, int len)
-{
-	struct dentry * old_root;
-	char * path;
-
-	read_lock(&current->fs->lock);
-	old_root = dget(current->fs->root);
-	read_unlock(&current->fs->lock);
-	spin_lock(&dcache_lock);
-	path = __d_path(dentry, current->fs->rootmnt, dentry->d_sb->s_root, current->fs->rootmnt, buffer, len); /* FIXME: current->fs->rootmnt */
-	spin_unlock(&dcache_lock);
-
-	if (*path == '/')
-		path++; /* skip leading '/' */
-
-	if (current->fs->root->d_inode == pseudo_root)
-	{
-		*(path-1) = '/';
-		path -= (UMSDOS_PSDROOT_LEN+1);
-		memcpy(path, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN);
-	}
-	dput(old_root);
-
-	return path;
-}
-
-/*
- * Return the dentry which points to a pseudo-hardlink.
- *
- * it should try to find file it points to
- * if file is found, return new dentry/inode
- * The resolved inode will have i_is_hlink set.
- *
- * Note: the original dentry is always dput(), even if an error occurs.
- */
-
-struct dentry *umsdos_solve_hlink (struct dentry *hlink)
-{
-	/* root is our root for resolving pseudo-hardlink */
-	struct dentry *base = hlink->d_sb->s_root;
-	struct dentry *dentry_dst;
-	char *path, *pt;
-	int len;
-	struct address_space *mapping = hlink->d_inode->i_mapping;
-	struct page *page;
-
-	page=read_cache_page(mapping,0,(filler_t *)mapping->a_ops->readpage,NULL);
-	dentry_dst=(struct dentry *)page;
-	if (IS_ERR(page))
-		goto out;
-	wait_on_page_locked(page);
-	if (!PageUptodate(page))
-		goto async_fail;
-
-	dentry_dst = ERR_PTR(-ENOMEM);
-	path = (char *) kmalloc (PATH_MAX, GFP_KERNEL);
-	if (path == NULL)
-		goto out_release;
-	memcpy(path, kmap(page), hlink->d_inode->i_size);
-	kunmap(page);
-	page_cache_release(page);
-
-	len = hlink->d_inode->i_size;
-
-	/* start at root dentry */
-	dentry_dst = dget(base);
-	path[len] = '\0';
-	
-	pt = path;
-	if (*path == '/')
-		pt++; /* skip leading '/' */
-	
-	if (base->d_inode == pseudo_root)
-		pt += (UMSDOS_PSDROOT_LEN + 1);
-	
-	while (1) {
-		struct dentry *dir = dentry_dst, *demd;
-		char *start = pt;
-		int real;
-
-		while (*pt != '\0' && *pt != '/') pt++;
-		len = (int) (pt - start);
-		if (*pt == '/') *pt++ = '\0';
-
-		real = 1;
-		demd = umsdos_get_emd_dentry(dir);
-		if (!IS_ERR(demd)) {
-			if (demd->d_inode)
-				real = 0;
-			dput(demd);
-		}
-
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk ("umsdos_solve_hlink: dir %s/%s, name=%s, real=%d\n",
-dir->d_parent->d_name.name, dir->d_name.name, start, real);
-#endif
-		dentry_dst = umsdos_lookup_dentry(dir, start, len, real);
-/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
-		if (real)
-			d_drop(dir);
-		dput (dir);
-		if (IS_ERR(dentry_dst))
-			break;
-		/* not found? stop search ... */
-		if (!dentry_dst->d_inode) {
-			break;
-		}
-		if (*pt == '\0')	/* we're finished! */
-			break;
-	} /* end while */
-
-	if (!IS_ERR(dentry_dst)) {
-		struct inode *inode = dentry_dst->d_inode;
-		if (inode) {
-			UMSDOS_I(inode)->i_is_hlink = 1;
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk ("umsdos_solve_hlink: resolved link %s/%s, ino=%ld\n",
-dentry_dst->d_parent->d_name.name, dentry_dst->d_name.name, inode->i_ino);
-#endif
-		} else {
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk ("umsdos_solve_hlink: resolved link %s/%s negative!\n",
-dentry_dst->d_parent->d_name.name, dentry_dst->d_name.name);
-#endif
-		}
-	} else
-		printk(KERN_WARNING
-			"umsdos_solve_hlink: err=%ld\n", PTR_ERR(dentry_dst));
-	kfree (path);
-
-out:
-	dput(hlink);	/* original hlink no longer needed */
-	return dentry_dst;
-
-async_fail:
-	dentry_dst = ERR_PTR(-EIO);
-out_release:
-	page_cache_release(page);
-	goto out;
-}	
-
-
-struct file_operations umsdos_dir_operations =
-{
-	.read		= generic_read_dir,
-	.readdir	= UMSDOS_readdir,
-	.ioctl		= UMSDOS_ioctl_dir,
-};
-
-struct inode_operations umsdos_dir_inode_operations =
-{
-	.create		= UMSDOS_create,
-	.lookup		= UMSDOS_lookup,
-	.link		= UMSDOS_link,
-	.unlink		= UMSDOS_unlink,
-	.symlink	= UMSDOS_symlink,
-	.mkdir		= UMSDOS_mkdir,
-	.rmdir		= UMSDOS_rmdir,
-	.mknod		= UMSDOS_mknod,
-	.rename		= UMSDOS_rename,
-	.setattr	= UMSDOS_notify_change,
-};
diff -L fs/umsdos/emd.c -puN fs/umsdos/emd.c~remove-umsdos-from-tree /dev/null
--- 25/fs/umsdos/emd.c
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,660 +0,0 @@
-/*
- *  linux/fs/umsdos/emd.c
- *
- *  Written 1993 by Jacques Gelinas
- *
- *  Extended MS-DOS directory handling functions
- */
-
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/msdos_fs.h>
-#include <linux/umsdos_fs.h>
-#include <linux/dcache.h>
-#include <linux/pagemap.h>
-#include <linux/delay.h>
-
-void put_entry (struct umsdos_dirent *p, struct umsdos_dirent *q)
-{
-	p->name_len = q->name_len;
-	p->flags = q->flags;
-	p->nlink = cpu_to_le16(q->nlink);
-	p->uid = cpu_to_le16(q->uid);
-	p->gid = cpu_to_le16(q->gid);
-	p->atime = cpu_to_le32(q->atime);
-	p->mtime = cpu_to_le32(q->mtime);
-	p->ctime = cpu_to_le32(q->ctime);
-	p->rdev = cpu_to_le16(q->rdev);
-	p->mode = cpu_to_le16(q->mode);
-}
-
-static void get_entry(struct umsdos_dirent *p, struct umsdos_dirent *q)
-{
-	p->name_len = q->name_len;
-	p->name[p->name_len]='\0';
-	p->flags = q->flags;
-	p->nlink = le16_to_cpu (q->nlink);
-	/* FIXME -- 32bit UID/GID issues */
-	p->uid = le16_to_cpu (q->uid);
-	p->gid = le16_to_cpu (q->gid);
-	p->atime = le32_to_cpu (q->atime);
-	p->mtime = le32_to_cpu (q->mtime);
-	p->ctime = le32_to_cpu (q->ctime);
-	p->rdev = le16_to_cpu (q->rdev);
-	p->mode = le16_to_cpu (q->mode);
-}
-
-/*
- * Lookup the EMD dentry for a directory.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-struct dentry *umsdos_get_emd_dentry(struct dentry *parent)
-{
-	struct dentry *demd;
-
-	demd = umsdos_lookup_dentry(parent, UMSDOS_EMD_FILE, 
-					UMSDOS_EMD_NAMELEN, 1);
-	return demd;
-}
-
-/*
- * Check whether a directory has an EMD file.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-int umsdos_have_emd(struct dentry *dir)
-{
-	struct dentry *demd = umsdos_get_emd_dentry (dir);
-	int found = 0;
-
-	if (!IS_ERR(demd)) {
-		if (demd->d_inode)
-			found = 1;
-		dput(demd);
-	}
-	return found;
-}
-
-/*
- * Create the EMD file for a directory if it doesn't
- * already exist. Returns 0 or an error code.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-int umsdos_make_emd(struct dentry *parent)
-{
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-	int err = PTR_ERR(demd);
-
-	if (IS_ERR(demd)) {
-		printk("umsdos_make_emd: can't get dentry in %s, err=%d\n",
-			parent->d_name.name, err);
-		goto out;
-	}
-
-	/* already created? */
-	err = 0;
-	if (demd->d_inode)
-		goto out_set;
-
-Printk(("umsdos_make_emd: creating EMD %s/%s\n",
-parent->d_name.name, demd->d_name.name));
-
-	err = msdos_create(parent->d_inode, demd, S_IFREG | 0777, NULL);
-	if (err) {
-		printk (KERN_WARNING
-			"umsdos_make_emd: create %s/%s failed, err=%d\n",
-			parent->d_name.name, demd->d_name.name, err);
-	}
-out_set:
-	dput(demd);
-out:
-	return err;
-}
-
-
-/*
- * Read an entry from the EMD file.
- * Support variable length record.
- * Return -EIO if error, 0 if OK.
- *
- * does not change {d,i}_count
- */
-
-int umsdos_emd_dir_readentry (struct dentry *demd, loff_t *pos, struct umsdos_dirent *entry)
-{
-	struct address_space *mapping = demd->d_inode->i_mapping;
-	struct page *page;
-	struct umsdos_dirent *p;
-	int offs = *pos & ~PAGE_CACHE_MASK;
-	int recsize;
-	int ret = 0;
-
-	page = read_cache_page(mapping, *pos>>PAGE_CACHE_SHIFT,
-			(filler_t*)mapping->a_ops->readpage, NULL);
-	if (IS_ERR(page))
-		goto sync_fail;
-	wait_on_page_locked(page);
-	if (!PageUptodate(page))
-		goto async_fail;
-	p = (struct umsdos_dirent*)(kmap(page)+offs);
-
-	/* if this is an invalid entry (invalid name length), ignore it */
-	if( p->name_len > UMSDOS_MAXNAME )
-	{
-		printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len);
-		p->name_len = 0; 
-		ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */
-		/* FIXME: does not work if we did 'ls -l' before 'udosctl uls' ?! */
-	}
-
-	recsize = umsdos_evalrecsize(p->name_len);
-	if (offs + recsize > PAGE_CACHE_SIZE) {
-		struct page *page2;
-		int part = (char *)(page_address(page) + PAGE_CACHE_SIZE) - p->spare;
-		page2 = read_cache_page(mapping, 1+(*pos>>PAGE_CACHE_SHIFT),
-				(filler_t*)mapping->a_ops->readpage, NULL);
-		if (IS_ERR(page2)) {
-			kunmap(page);
-			page_cache_release(page);
-			page = page2;
-			goto sync_fail;
-		}
-		wait_on_page_locked(page2);
-		if (!PageUptodate(page2)) {
-			kunmap(page);
-			page_cache_release(page2);
-			goto async_fail;
-		}
-		memcpy(entry->spare,p->spare,part);
-		memcpy(entry->spare+part,kmap(page2),
-				recsize+offs-PAGE_CACHE_SIZE);
-		kunmap(page2);
-		page_cache_release(page2);
-	} else
-		memcpy(entry->spare,p->spare,((char*)p+recsize)-p->spare);
-	get_entry(entry, p);
-	kunmap(page);
-	page_cache_release(page);
-	*pos += recsize;
-	return ret;
-async_fail:
-	page_cache_release(page);
-	page = ERR_PTR(-EIO);
-sync_fail:
-	return PTR_ERR(page);
-}
-
-
-/*
- * Write an entry in the EMD file.
- * Return 0 if OK, -EIO if some error.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
-				int free_entry)
-{
-	struct inode *dir = parent->d_inode;
-	struct umsdos_dirent *entry = &info->entry;
-	struct dentry *emd_dentry;
-	int ret;
-	struct umsdos_dirent entry0,*p;
-	struct address_space *mapping;
-	struct page *page, *page2 = NULL;
-	int offs;
-
-	emd_dentry = umsdos_get_emd_dentry(parent);
-	ret = PTR_ERR(emd_dentry);
-	if (IS_ERR(emd_dentry))
-		goto out;
-	/* make sure there's an EMD file */
-	ret = -EIO;
-	if (!emd_dentry->d_inode) {
-		printk(KERN_WARNING
-			"umsdos_writeentry: no EMD file in %s/%s\n",
-			parent->d_parent->d_name.name, parent->d_name.name);
-		goto out_dput;
-	}
-
-	if (free_entry) {
-		/* #Specification: EMD file / empty entries
-		 * Unused entries in the EMD file are identified
-		 * by the name_len field equal to 0. However to
-		 * help future extension (or bug correction :-( ),
-		 * empty entries are filled with 0.
-		 */
-		memset (&entry0, 0, sizeof (entry0));
-		entry = &entry0;
-	} else if (entry->name_len > 0) {
-		memset (entry->name + entry->name_len, '\0', 
-			sizeof (entry->name) - entry->name_len);
-		/* #Specification: EMD file / spare bytes
-		 * 10 bytes are unused in each record of the EMD. They
-		 * are set to 0 all the time, so it will be possible
-		 * to do new stuff and rely on the state of those
-		 * bytes in old EMD files.
-		 */
-		memset (entry->spare, 0, sizeof (entry->spare));
-	}
-
-	/* write the entry and update the parent timestamps */
-	mapping = emd_dentry->d_inode->i_mapping;
-	offs = info->f_pos & ~PAGE_CACHE_MASK;
-	ret = -ENOMEM;
-	page = grab_cache_page(mapping, info->f_pos>>PAGE_CACHE_SHIFT);
-	if (!page)
-		goto out_dput;
-	p = (struct umsdos_dirent *) (page_address(page) + offs);
-	if (offs + info->recsize > PAGE_CACHE_SIZE) {
-		ret = mapping->a_ops->prepare_write(NULL,page,offs,
-					PAGE_CACHE_SIZE);
-		if (ret)
-			goto out_unlock;
-		page2 = grab_cache_page(mapping,
-					(info->f_pos>>PAGE_CACHE_SHIFT)+1);
-		if (!page2)
-			goto out_unlock2;
-		ret = mapping->a_ops->prepare_write(NULL,page2,0,
-					offs+info->recsize-PAGE_CACHE_SIZE);
-		if (ret)
-			goto out_unlock3;
-		put_entry (p, entry);
-		memcpy(p->spare,entry->spare,
-			(char *)(page_address(page) + PAGE_CACHE_SIZE) - p->spare);
-		memcpy(page_address(page2),
-				((char*)entry)+PAGE_CACHE_SIZE-offs,
-				offs+info->recsize-PAGE_CACHE_SIZE);
-		ret = mapping->a_ops->commit_write(NULL,page2,0,
-					offs+info->recsize-PAGE_CACHE_SIZE);
-		if (ret)
-			goto out_unlock3;
-		ret = mapping->a_ops->commit_write(NULL,page,offs,
-					PAGE_CACHE_SIZE);
-		unlock_page(page2);
-		page_cache_release(page2);
-		if (ret)
-			goto out_unlock;
-	} else {
-		ret = mapping->a_ops->prepare_write(NULL,page,offs,
-					offs + info->recsize);
-		if (ret)
-			goto out_unlock;
-		put_entry (p, entry);
-		memcpy(p->spare,entry->spare,((char*)p+info->recsize)-p->spare);
-		ret = mapping->a_ops->commit_write(NULL,page,offs,
-					offs + info->recsize);
-		if (ret)
-			goto out_unlock;
-	}
-	unlock_page(page);
-	page_cache_release(page);
-		
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
-	mark_inode_dirty(dir);
-
-out_dput:
-	dput(emd_dentry);
-out:
-	Printk (("umsdos_writeentry /mn/: returning %d...\n", ret));
-	return ret;
-out_unlock3:
-	unlock_page(page2);
-	page_cache_release(page2);
-out_unlock2:
-	ClearPageUptodate(page);
-	kunmap(page);
-out_unlock:
-	unlock_page(page);
-	page_cache_release(page);
-	printk ("UMSDOS:  problem with EMD file:  can't write\n");
-	goto out_dput;
-}
-
-/*
- * General search, locate a name in the EMD file or an empty slot to
- * store it. if info->entry.name_len == 0, search the first empty
- * slot (of the proper size).
- * 
- * Return 0 if found, -ENOENT if not found, another error code if
- * other problem.
- * 
- * So this routine is used to either find an existing entry or to
- * create a new one, while making sure it is a new one. After you
- * get -ENOENT, you make sure the entry is stuffed correctly and
- * call umsdos_writeentry().
- * 
- * To delete an entry, you find it, zero out the entry (memset)
- * and call umsdos_writeentry().
- * 
- * All this to say that umsdos_writeentry must be called after this
- * function since it relies on the f_pos field of info.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-/* #Specification: EMD file structure
- * The EMD file uses a fairly simple layout.  It is made of records
- * (UMSDOS_REC_SIZE == 64).  When a name can't be written in a single
- * record, multiple contiguous records are allocated.
- */
-
-static int umsdos_find (struct dentry *demd, struct umsdos_info *info)
-{
-	struct umsdos_dirent *entry = &info->entry;
-	int recsize = info->recsize;
-	struct inode *emd_dir;
-	int ret = -ENOENT;
-	struct {
-		off_t posok;	/* Position available to store the entry */
-		off_t one;	/* One empty position -> maybe <- large enough */
-	} empty;
-	int found = 0;
-	int empty_size = 0;
-	struct address_space *mapping;
-	filler_t *readpage;
-	struct page *page = NULL;
-	int index = -1;
-	int offs = PAGE_CACHE_SIZE,max_offs = PAGE_CACHE_SIZE;
-	char *p = NULL;
-	loff_t pos = 0;
-
-	/* make sure there's an EMD file ... */
-	ret = -ENOENT;
-	emd_dir = demd->d_inode;
-	if (!emd_dir)
-		goto out_dput;
-	mapping = emd_dir->i_mapping;
-	readpage = (filler_t*)mapping->a_ops->readpage;
-
-	empty.posok = emd_dir->i_size;
-	while (1) {
-		struct umsdos_dirent *rentry;
-		int entry_size;
-
-		if (offs >= max_offs) {
-			if (page) {
-				kunmap(page);
-				page_cache_release(page);
-				page = NULL;
-			}
-			if (pos >= emd_dir->i_size) {
-				info->f_pos = empty.posok;
-				break;
-			}
-			if (++index == (emd_dir->i_size>>PAGE_CACHE_SHIFT))
-				max_offs = emd_dir->i_size & ~PAGE_CACHE_MASK;
-			offs -= PAGE_CACHE_SIZE;
-			page = read_cache_page(mapping,index,readpage,NULL);
-			if (IS_ERR(page))
-				goto sync_fail;
-			wait_on_page_locked(page);
-			if (!PageUptodate(page))
-				goto async_fail;
-			p = kmap(page);
-		}
-
-		rentry = (struct umsdos_dirent *)(p+offs);
-
-		if (rentry->name_len == 0) {
-			/* We are looking for an empty section at least */
-			/* as large as recsize. */
-			if (entry->name_len == 0) {
-				info->f_pos = pos;
-				ret = 0;
-				break;
-			}
-			offs += UMSDOS_REC_SIZE;
-			pos += UMSDOS_REC_SIZE;
-			if (found)
-				continue;
-			if (!empty_size)
-				empty.one = pos-UMSDOS_REC_SIZE;
-			empty_size += UMSDOS_REC_SIZE;
-			if (empty_size == recsize) {
-				/* Here is a large enough section. */
-				empty.posok = empty.one;
-				found = 1;
-			}
-			continue;
-		}
-
-		entry_size = umsdos_evalrecsize(rentry->name_len);
-		if (entry_size > PAGE_CACHE_SIZE)
-			goto async_fail;
-		empty_size = 0;
-		if (entry->name_len != rentry->name_len)
-			goto skip_it;
-
-		if (entry_size + offs > PAGE_CACHE_SIZE) {
-			/* Sucker spans the page boundary */
-			int len = (p+PAGE_CACHE_SIZE)-rentry->name;
-			struct page *next_page;
-			char *q;
-			next_page = read_cache_page(mapping,index+1,readpage,NULL);
-			if (IS_ERR(next_page)) {
-				page_cache_release(page);
-				page = next_page;
-				goto sync_fail;
-			}
-			wait_on_page_locked(next_page);
-			if (!PageUptodate(next_page)) {
-				page_cache_release(page);
-				page = next_page;
-				goto async_fail;
-			}
-			q = kmap(next_page);
-			if (memcmp(entry->name, rentry->name, len) ||
-			    memcmp(entry->name+len, q, entry->name_len-len)) {
-				kunmap(next_page);
-				page_cache_release(next_page);
-				goto skip_it;
-			}
-			kunmap(next_page);
-			page_cache_release(next_page);
-		} else if (memcmp (entry->name, rentry->name, entry->name_len))
-			goto skip_it;
-
-		info->f_pos = pos;
-		get_entry(entry, rentry);
-		ret = 0;
-		break;
-skip_it:
-		offs+=entry_size;
-		pos+=entry_size;
-	}
-	if (page) {
-		kunmap(page);
-		page_cache_release(page);
-	}
-	umsdos_manglename (info);
-
-out_dput:
-	dput(demd);
-	return ret;
-
-async_fail:
-	page_cache_release(page);
-	page = ERR_PTR(-EIO);
-sync_fail:
-	return PTR_ERR(page);
-}
-
-
-/*
- * Add a new entry in the EMD file.
- * Return 0 if OK or a negative error code.
- * Return -EEXIST if the entry already exists.
- *
- * Complete the information missing in info.
- * 
- * N.B. What if the EMD file doesn't exist?
- */
-
-int umsdos_newentry (struct dentry *parent, struct umsdos_info *info)
-{
-	int err, ret = -EEXIST;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	err = umsdos_find (demd, info);
-	if (err && err == -ENOENT) {
-		ret = umsdos_writeentry (parent, info, 0);
-		Printk (("umsdos_writeentry EMD ret = %d\n", ret));
-	}
-out:
-	return ret;
-}
-
-
-/*
- * Create a new hidden link.
- * Return 0 if OK, an error code if not.
- */
-
-/* #Specification: hard link / hidden name
- * When a hard link is created, the original file is renamed
- * to a hidden name. The name is "..LINKNNN" where NNN is a
- * number define from the entry offset in the EMD file.
- */
-int umsdos_newhidden (struct dentry *parent, struct umsdos_info *info)
-{
-	int ret;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-
-	umsdos_parse ("..LINK", 6, info);
-	info->entry.name_len = 0;
-	ret = umsdos_find (demd, info);
-	if (ret == -ENOENT || ret == 0) {
-		info->entry.name_len = sprintf (info->entry.name,
-						"..LINK%ld", info->f_pos);
-		ret = 0;
-	}
-out:
-	return ret;
-}
-
-
-/*
- * Remove an entry from the EMD file.
- * Return 0 if OK, a negative error code otherwise.
- * 
- * Complete the information missing in info.
- */
-
-int umsdos_delentry (struct dentry *parent, struct umsdos_info *info, int isdir)
-{
-	int ret;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	ret = umsdos_find (demd, info);
-	if (ret)
-		goto out;
-	if (info->entry.name_len == 0)
-		goto out;
-
-	if ((isdir != 0) != (S_ISDIR (info->entry.mode) != 0)) {
-		if (S_ISDIR (info->entry.mode)) {
-			ret = -EISDIR;
-		} else {
-			ret = -ENOTDIR;
-		}
-		goto out;
-	}
-	ret = umsdos_writeentry (parent, info, 1);
-
-out:
-	return ret;
-}
-
-
-/*
- * Verify that an EMD directory is empty.
- * Return: 
- * 0 if not empty,
- * 1 if empty (except for EMD file),
- * 2 if empty or no EMD file.
- */
-
-int umsdos_isempty (struct dentry *dentry)
-{
-	struct dentry *demd;
-	int ret = 2;
-	loff_t pos = 0;
-
-	demd = umsdos_get_emd_dentry(dentry);
-	if (IS_ERR(demd))
-		goto out;
-	/* If the EMD file does not exist, it is certainly empty. :-) */
-	if (!demd->d_inode)
-		goto out_dput;
-
-	ret = 1;
-	while (pos < demd->d_inode->i_size) {
-		struct umsdos_dirent entry;
-
-		if (umsdos_emd_dir_readentry (demd, &pos, &entry) != 0) {
-			ret = 0;
-			break;
-		}
-		if (entry.name_len != 0) {
-			ret = 0;
-			break;
-		}
-	}
-
-out_dput:
-	dput(demd);
-out:
-	return ret;
-}
-
-/*
- * Locate an entry in a EMD directory.
- * Return 0 if OK, error code if not, generally -ENOENT.
- *
- * expect argument:
- * 	0: anything
- * 	1: file
- * 	2: directory
- */
-
-int umsdos_findentry (struct dentry *parent, struct umsdos_info *info,
-			int expect)
-{		
-	int ret;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	ret = umsdos_find (demd, info);
-	if (ret)
-		goto out;
-
-	switch (expect) {
-	case 1:
-		if (S_ISDIR (info->entry.mode))
-			ret = -EISDIR;
-		break;
-	case 2:
-		if (!S_ISDIR (info->entry.mode))
-			ret = -ENOTDIR;
-	}
-
-out:
-	Printk (("umsdos_findentry: returning %d\n", ret));
-	return ret;
-}
diff -puN fs/umsdos/inode.c~remove-umsdos-from-tree fs/umsdos/inode.c
--- 25/fs/umsdos/inode.c~remove-umsdos-from-tree	2005-01-10 21:13:45.195825544 -0800
+++ 25-akpm/fs/umsdos/inode.c	2005-01-10 21:13:45.227820680 -0800
@@ -1,483 +0,0 @@
-/*
- *  linux/fs/umsdos/inode.c
- *
- *      Written 1993 by Jacques Gelinas
- *      Inspired from linux/fs/msdos/... by Werner Almesberger
- */
-
-#include <linux/module.h>
-
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <asm/uaccess.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/umsdos_fs.h>
-#include <linux/list.h>
-#include <linux/pagemap.h>
-
-extern struct dentry_operations umsdos_dentry_operations;
-
-struct dentry *saved_root;	/* Original root if changed */
-struct inode *pseudo_root;	/* Useful to simulate the pseudo DOS */
-					/* directory. See UMSDOS_readdir_x() */
-
-static struct dentry *check_pseudo_root(struct super_block *);
-
-
-void UMSDOS_put_inode (struct inode *inode)
-{
-	PRINTK ((KERN_DEBUG 
-		"put inode %p (%lu) pos %lu count=%d\n"
-		 ,inode, inode->i_ino
-		 ,UMSDOS_I(inode)->pos
-		 ,atomic_read(&inode->i_count)));
-
-	if (inode == pseudo_root) {
-		Printk ((KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, atomic_read(&inode->i_count)));
-	}
-
-	if (atomic_read(&inode->i_count) == 1)
-		UMSDOS_I(inode)->i_patched = 0;
-}
-
-
-void UMSDOS_put_super (struct super_block *sb)
-{
-	Printk ((KERN_DEBUG "UMSDOS_put_super: entering\n"));
-	if (saved_root && pseudo_root && kdev_same(sb->s_dev, ROOT_DEV)) {
-		shrink_dcache_parent(saved_root);
-		dput(saved_root);
-		saved_root = NULL;
-		pseudo_root = NULL;
-	}
-	fat_put_super (sb);
-}
-
-
-/*
- * Complete the setup of a directory dentry based on its
- * EMD/non-EMD status.  If it has an EMD, then plug the
- * umsdos function table. If not, use the msdos one.
- */
-void umsdos_setup_dir(struct dentry *dir)
-{
-	struct inode *inode = dir->d_inode;
-	struct umsdos_inode_info *ui = UMSDOS_I(inode);
-
-	if (!S_ISDIR(inode->i_mode))
-		printk(KERN_ERR "umsdos_setup_dir: %s/%s not a dir!\n",
-			dir->d_parent->d_name.name, dir->d_name.name);
-
-	init_waitqueue_head (&ui->dir_info.p);
-	ui->dir_info.looking = 0;
-	ui->dir_info.creating = 0;
-	ui->dir_info.pid = 0;
-
-	inode->i_op = &umsdos_rdir_inode_operations;
-	inode->i_fop = &umsdos_rdir_operations;
-	if (umsdos_have_emd(dir)) {
-Printk((KERN_DEBUG "umsdos_setup_dir: %s/%s using EMD\n",
-dir->d_parent->d_name.name, dir->d_name.name));
-		inode->i_op = &umsdos_dir_inode_operations;
-		inode->i_fop = &umsdos_dir_operations;
-	}
-}
-
-
-/*
- * Add some info into an inode so it can find its owner quickly
- */
-void umsdos_set_dirinfo_new (struct dentry *dentry, off_t f_pos)
-{
-	struct inode *inode = dentry->d_inode;
-	struct dentry *demd;
-
-	UMSDOS_I(inode)->pos = f_pos;
-
-	/* now check the EMD file */
-	demd = umsdos_get_emd_dentry(dentry->d_parent);
-	if (!IS_ERR(demd)) {
-		dput(demd);
-	}
-	return;
-}
-
-static struct inode_operations umsdos_file_inode_operations = {
-	.truncate	= fat_truncate,
-	.setattr	= UMSDOS_notify_change,
-};
-
-static struct inode_operations umsdos_symlink_inode_operations = {
-	.readlink	= page_readlink,
-	.follow_link	= page_follow_link,
-	.setattr	= UMSDOS_notify_change,
-};
-
-/*
- * Connect the proper tables in the inode and add some info.
- */
-/* #Specification: inode / umsdos info
- * The first time an inode is seen (inode->i_count == 1),
- * the inode number of the EMD file which controls this inode
- * is tagged to this inode. It allows operations such as
- * notify_change to be handled.
- */
-void umsdos_patch_dentry_inode(struct dentry *dentry, off_t f_pos)
-{
-	struct inode *inode = dentry->d_inode;
-
-PRINTK (("umsdos_patch_dentry_inode: inode=%lu\n", inode->i_ino));
-
-	/*
-	 * Classify the inode based on EMD/non-EMD status.
-	 */
-PRINTK (("umsdos_patch_inode: call umsdos_set_dirinfo_new(%p,%lu)\n",
-dentry, f_pos));
-	umsdos_set_dirinfo_new(dentry, f_pos);
-
-	inode->i_op = &umsdos_file_inode_operations;
-	if (S_ISREG (inode->i_mode)) {
-		/* address_space operations already set */
-	} else if (S_ISDIR (inode->i_mode)) {
-		umsdos_setup_dir(dentry);
-	} else if (S_ISLNK (inode->i_mode)) {
-		/* address_space operations already set */
-		inode->i_op = &umsdos_symlink_inode_operations;
-	} else
-		init_special_inode(inode, inode->i_mode,
-					kdev_t_to_nr(inode->i_rdev));
-}
-
-
-/*
- * lock the parent dir before starting ...
- * also handles hardlink converting
- */
-int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *dir, *inode;
-	struct umsdos_info info;
-	struct dentry *temp, *old_dentry = NULL;
-	int ret;
-
-	lock_kernel();
-
-	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;
-	inode = dentry->d_inode;
-
-	ret = inode_change_ok (inode, attr);
-	if (ret)
-		goto out;
-
-	ret = umsdos_notify_change_locked(dentry, attr);
-	if (ret == 0)
-		ret = inode_setattr (inode, attr);
-out:
-	if (old_dentry)
-		dput (dentry);	/* if we had to use fake dentry for hardlinks, dput() it now */
-	unlock_kernel();
-	return ret;
-}
-
-
-/*
- * Must be called with the parent lock held.
- */
-int umsdos_notify_change_locked(struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *inode = dentry->d_inode;
-	struct dentry *demd;
-	struct address_space *mapping;
-	struct page *page;
-	int ret = 0;
-	struct umsdos_dirent *entry;
-	int offs;
-
-Printk(("UMSDOS_notify_change: entering for %s/%s (%d)\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, UMSDOS_I(inode)->i_patched));
-
-	if (inode->i_nlink == 0)
-		goto out;
-	if (inode->i_ino == UMSDOS_ROOT_INO)
-		goto out;
-
-	/* get the EMD file dentry */
-	demd = umsdos_get_emd_dentry(dentry->d_parent);
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	ret = 0;
-	/* don't do anything if directory is not promoted to umsdos yet */
-	if (!demd->d_inode) { 
-		Printk((KERN_DEBUG
-			"UMSDOS_notify_change: no EMD file %s/%s\n",
-			demd->d_parent->d_name.name, demd->d_name.name));
-		goto out_dput;
-	}
-
-	/* don't do anything if this is the EMD itself */
-	if (inode == demd->d_inode)
-		goto out_dput;
-
-	/* This inode is not a EMD file nor an inode used internally
-	 * by MSDOS, so we can update its status.
-	 * See emd.c
-	 */
-
-	/* Read only the start of the entry since we don't touch the name */
-	mapping = demd->d_inode->i_mapping;
-	offs = UMSDOS_I(inode)->pos & ~PAGE_CACHE_MASK;
-	ret = -ENOMEM;
-	page=grab_cache_page(mapping,UMSDOS_I(inode)->pos>>PAGE_CACHE_SHIFT);
-	if (!page)
-		goto out_dput;
-	ret=mapping->a_ops->prepare_write(NULL,page,offs,offs+UMSDOS_REC_SIZE);
-	if (ret)
-		goto out_unlock;
-	entry = (struct umsdos_dirent *) (page_address(page) + offs);
-	if (attr->ia_valid & ATTR_UID)
-		entry->uid = cpu_to_le16(attr->ia_uid);
-	if (attr->ia_valid & ATTR_GID)
-		entry->gid = cpu_to_le16(attr->ia_gid);
-	if (attr->ia_valid & ATTR_MODE)
-		entry->mode = cpu_to_le16(attr->ia_mode);
-	if (attr->ia_valid & ATTR_ATIME)
-		entry->atime = cpu_to_le32(attr->ia_atime);
-	if (attr->ia_valid & ATTR_MTIME)
-		entry->mtime = cpu_to_le32(attr->ia_mtime);
-	if (attr->ia_valid & ATTR_CTIME)
-		entry->ctime = cpu_to_le32(attr->ia_ctime);
-	entry->nlink = cpu_to_le16(inode->i_nlink);
-	ret=mapping->a_ops->commit_write(NULL,page,offs,offs+UMSDOS_REC_SIZE);
-	if (ret)
-		printk(KERN_WARNING
-			"umsdos_notify_change: %s/%s EMD write error, ret=%d\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,ret);
-
-	/* #Specification: notify_change / msdos fs
-	 * notify_change operation are done only on the
-	 * EMD file. The msdos fs is not even called.
-	 */
-out_unlock:
-	unlock_page(page);
-	page_cache_release(page);
-out_dput:
-	dput(demd);
-out:
-	return ret;
-}
-
-
-/*
- * Update the disk with the inode content
- */
-int UMSDOS_write_inode (struct inode *inode, int wait)
-{
-	struct iattr newattrs;
-	int ret;
-
-	ret = fat_write_inode (inode, wait);
-	newattrs.ia_mtime = inode->i_mtime;
-	newattrs.ia_atime = inode->i_atime;
-	newattrs.ia_ctime = inode->i_ctime;
-	newattrs.ia_valid = ATTR_MTIME | ATTR_ATIME | ATTR_CTIME;
-	/*
-	 * UMSDOS_notify_change is convenient to call here
-	 * to update the EMD entry associated with this inode.
-	 * But it has the side effect to re"dirt" the inode.
-	 */
-/*      
- * UMSDOS_notify_change (inode, &newattrs);
-
- * inode->i_state &= ~I_DIRTY; / * FIXME: this doesn't work.  We need to remove ourselves from list on dirty inodes. /mn/ */
-	return ret;
-}
-
-
-static struct super_operations umsdos_sops =
-{
-	.write_inode	= UMSDOS_write_inode,
-	.put_inode	= UMSDOS_put_inode,
-	.delete_inode	= fat_delete_inode,
-	.put_super	= UMSDOS_put_super,
-	.statfs		= UMSDOS_statfs,
-	.clear_inode	= fat_clear_inode,
-};
-
-int UMSDOS_statfs(struct super_block *sb,struct statfs *buf)
-{
-	int ret;
-	ret = fat_statfs (sb, buf);
-	if (!ret)	
-		buf->f_namelen = UMSDOS_MAXNAME;
-	return ret;
-}
-
-/*
- * Read the super block of an Extended MS-DOS FS.
- */
-struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
-				      int silent)
-{
-	struct super_block *res;
-	struct dentry *new_root;
-
-	/*
-	 * Call msdos-fs to mount the disk.
-	 * Note: this returns res == sb or NULL
-	 */
-	MSDOS_SB(sb)->options.isvfat = 0;
-	res = fat_read_super(sb, data, silent, &umsdos_rdir_inode_operations);
-
-	if (IS_ERR(res))
-		return NULL;
-	if (res == NULL) {
-		if (!silent)
-			printk(KERN_INFO "VFS: Can't find a valid "
-			       "UMSDOS filesystem on dev %s.\n", sb->s_id);
-		return NULL;
-	}
-
-	printk (KERN_INFO "UMSDOS 0.86k "
-		"(compatibility level %d.%d, fast msdos)\n", 
-		UMSDOS_VERSION, UMSDOS_RELEASE);
-
-	sb->s_op = &umsdos_sops;
-	MSDOS_SB(sb)->options.dotsOK = 0;	/* disable hidden==dotfile */
-
-	/* install our dentry operations ... */
-	sb->s_root->d_op = &umsdos_dentry_operations;
-
-	umsdos_patch_dentry_inode(sb->s_root, 0);
-
-	/* Check whether to change to the /linux root */
-	new_root = check_pseudo_root(sb);
-
-	if (new_root) {
-		/* sanity check */
-		if (new_root->d_op != &umsdos_dentry_operations)
-			printk("umsdos_read_super: pseudo-root wrong ops!\n");
-
-		pseudo_root = new_root->d_inode;
-		saved_root = sb->s_root;
-		printk(KERN_INFO "UMSDOS: changed to alternate root\n");
-		dget (sb->s_root); sb->s_root = dget(new_root);
-	}
-	return sb;
-}
-
-/*
- * Check for an alternate root if we're the root device.
- */
-
-extern kdev_t ROOT_DEV;
-static struct dentry *check_pseudo_root(struct super_block *sb)
-{
-	struct dentry *root, *sbin, *init;
-
-	/*
-	 * Check whether we're mounted as the root device.
-	 * must check like this, because we can be used with initrd
-	 */
-		
-	if (!kdev_same(sb->s_dev, ROOT_DEV))
-		goto out_noroot;
-
-	/* 
-	 * lookup_dentry needs a (so far non-existent) root. 
-	 */
-	printk(KERN_INFO "check_pseudo_root: mounted as root\n");
-	root = lookup_one_len(UMSDOS_PSDROOT_NAME, sb->s_root,UMSDOS_PSDROOT_LEN); 
-	if (IS_ERR(root))
-		goto out_noroot;
-		
-	if (!root->d_inode || !S_ISDIR(root->d_inode->i_mode))
-		goto out_dput;
-
-printk(KERN_INFO "check_pseudo_root: found %s/%s\n",
-root->d_parent->d_name.name, root->d_name.name);
-
-	/* look for /sbin/init */
-	sbin = lookup_one_len("sbin", root, 4);
-	if (IS_ERR(sbin))
-		goto out_dput;
-	if (!sbin->d_inode || !S_ISDIR(sbin->d_inode->i_mode))
-		goto out_dput_sbin;
-	init = lookup_one_len("init", sbin, 4);
-	if (IS_ERR(init))
-		goto out_dput_sbin;
-	if (!init->d_inode)
-		goto out_dput_init;
-	printk(KERN_INFO "check_pseudo_root: found %s/%s, enabling pseudo-root\n", init->d_parent->d_name.name, init->d_name.name);
-	dput(sbin);
-	dput(init);
-	return root;
-
-	/* Alternate root not found ... */
-out_dput_init:
-	dput(init);
-out_dput_sbin:
-	dput(sbin);
-out_dput:
-	dput(root);
-out_noroot:
-	return NULL;
-}
-
-
-static DECLARE_FSTYPE_DEV(umsdos_fs_type, "umsdos", UMSDOS_read_super);
-
-static int __init init_umsdos_fs (void)
-{
-	return register_filesystem (&umsdos_fs_type);
-}
-
-static void __exit exit_umsdos_fs (void)
-{
-	unregister_filesystem (&umsdos_fs_type);
-}
-
-module_init(init_umsdos_fs)
-module_exit(exit_umsdos_fs)
-MODULE_LICENSE("GPL");
diff -puN fs/umsdos/ioctl.c~remove-umsdos-from-tree fs/umsdos/ioctl.c
--- 25/fs/umsdos/ioctl.c~remove-umsdos-from-tree	2005-01-10 21:13:45.196825392 -0800
+++ 25-akpm/fs/umsdos/ioctl.c	2005-01-10 21:13:45.229820376 -0800
@@ -1,446 +0,0 @@
-/*
- *  linux/fs/umsdos/ioctl.c
- *
- *  Written 1993 by Jacques Gelinas
- *
- *  Extended MS-DOS ioctl directory handling functions
- *
- *  Changes:
- *  11/07/2003      Daniele Bellucci <bellucda@tiscali.it>
- *                  - audit copy_to_user/put_user in umsdos_ioctl_fill.
- */
-
-#include <asm/uaccess.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/umsdos_fs.h>
-
-struct UMSDOS_DIR_ONCE {
-	struct dirent *ent;
-	int count;
-};
-
-/*
- * Record a single entry the first call.
- * Return -EINVAL the next one.
- */
-static int umsdos_ioctl_fill (
-				     void *buf,
-				     const char *name,
-				     int name_len,
-				     loff_t offset,
-				     ino_t ino,
-				     unsigned type)
-{
-	int ret = -EINVAL;
-	struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *) buf;
-
-	if (d->count == 0) {
-		if (copy_to_user (d->ent->d_name, name, name_len) ||
-		    put_user ('\0', d->ent->d_name + name_len) ||
-		    put_user (name_len, &d->ent->d_reclen) ||
-		    put_user (ino, &d->ent->d_ino) ||
-		    put_user (offset, &d->ent->d_off))
-			return -EFAULT;
-		d->count = 1;
-		ret = 0;
-	}
-	return ret;
-}
-
-
-/*
- * Perform special function on a directory
- */
-/* #Specification: ioctl / prototypes
- * The official prototype for the umsdos ioctl on directory
- * is:
- * 
- * int ioctl (
- * int fd,          // File handle of the directory
- * int cmd, // command
- * struct umsdos_ioctl *data)
- * 
- * The struct and the commands are defined in linux/umsdos_fs.h.
- * 
- * umsdos_progs/umsdosio.c provide an interface in C++ to all
- * these ioctl. umsdos_progs/udosctl is a small utility showing
- * all this.
- * 
- * These ioctl generally allow one to work on the EMD or the
- * DOS directory independently. These are essential to implement
- * the synchronise.
- */
-int UMSDOS_ioctl_dir(struct inode *dir, struct file *filp, unsigned int cmd,
-			unsigned long data_ptr)
-{
-	struct dentry *dentry = filp->f_dentry;
-	struct umsdos_ioctl *idata = (struct umsdos_ioctl *) data_ptr;
-	int ret;
-	struct umsdos_ioctl data;
-
-Printk(("UMSDOS_ioctl_dir: %s/%s, cmd=%d, data=%08lx\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, cmd, data_ptr));
-
-	/* forward non-umsdos ioctls - this hopefully doesn't cause conflicts */
-	if (cmd != UMSDOS_GETVERSION
-	    && cmd != UMSDOS_READDIR_DOS
-	    && cmd != UMSDOS_READDIR_EMD
-	    && cmd != UMSDOS_INIT_EMD
-	    && cmd != UMSDOS_CREAT_EMD
-	    && cmd != UMSDOS_RENAME_DOS
-	    && cmd != UMSDOS_UNLINK_EMD
-	    && cmd != UMSDOS_UNLINK_DOS
-	    && cmd != UMSDOS_RMDIR_DOS
-	    && cmd != UMSDOS_STAT_DOS
-	    && cmd != UMSDOS_DOS_SETUP)
-		return fat_dir_ioctl (dir, filp, cmd, data_ptr);
-
-	/* #Specification: ioctl / access
-	 * Only root (effective id) is allowed to do IOCTL on directory
-	 * in UMSDOS. EPERM is returned for other user.
-	 */
-	/*
-	 * Well, not all cases require write access, but it simplifies
-	 * the code, and let's face it, there is only one client (umssync)
-	 * for all this.
-	 */
-	ret = verify_area (VERIFY_WRITE, (void *) data_ptr, 
-				sizeof (struct umsdos_ioctl));
-	if (ret < 0)
-		goto out;
-
-	ret = -EPERM;
-	if (current->euid != 0 && cmd != UMSDOS_GETVERSION)
-		goto out;
-
-	ret = -EINVAL;
-	if (cmd == UMSDOS_GETVERSION) {
-		/* #Specification: ioctl / UMSDOS_GETVERSION
-		 * The field version and release of the structure
-		 * umsdos_ioctl are filled with the version and release
-		 * number of the fs code in the kernel. This will allow
-		 * some form of checking. Users won't be able to run
-		 * incompatible utility such as the synchroniser (umssync).
-		 * umsdos_progs/umsdosio.c enforce this checking.
-		 * 
-		 * Return always 0.
-		 */
-		put_user (UMSDOS_VERSION, &idata->version);
-		put_user (UMSDOS_RELEASE, &idata->release);
-		ret = 0;
-		goto out;
-	}
-	if (cmd == UMSDOS_READDIR_DOS) {
-		/* #Specification: ioctl / UMSDOS_READDIR_DOS
-		 * One entry is read from the DOS directory at the current
-		 * file position. The entry is put as is in the dos_dirent
-		 * field of struct umsdos_ioctl.
-		 * 
-		 * Return > 0 if success.
-		 */
-		struct UMSDOS_DIR_ONCE bufk;
-
-		bufk.count = 0;
-		bufk.ent = &idata->dos_dirent;
-
-		fat_readdir (filp, &bufk, umsdos_ioctl_fill);
-
-		ret = bufk.count == 1 ? 1 : 0;
-		goto out;
-	}
-	if (cmd == UMSDOS_READDIR_EMD) {
-		/* #Specification: ioctl / UMSDOS_READDIR_EMD
-		 * One entry is read from the EMD at the current
-		 * file position. The entry is put as is in the umsdos_dirent
-		 * field of struct umsdos_ioctl. The corresponding mangled
-		 * DOS entry name is put in the dos_dirent field.
-		 * 
-		 * All entries are read including hidden links. Blank
-		 * entries are skipped.
-		 * 
-		 * Return > 0 if success.
-		 */
-		struct dentry *demd;
-		loff_t pos = filp->f_pos;
-
-		/* The absence of the EMD is simply seen as an EOF */
-		demd = umsdos_get_emd_dentry(dentry);
-		ret = PTR_ERR(demd);
-		if (IS_ERR(demd))
-			goto out;
-		ret = 0;
-		if (!demd->d_inode)
-			goto read_dput;
-
-		while (pos < demd->d_inode->i_size) {
-			off_t f_pos = pos;
-			struct umsdos_dirent entry;
-			struct umsdos_info info;
-
-			ret = umsdos_emd_dir_readentry (demd, &pos, &entry);
-
-			if (ret == -ENAMETOOLONG) {
-				printk (KERN_INFO "Fixing EMD entry with invalid size -- zeroing out\n");
-				memset (&info, 0, sizeof (info));
-				info.f_pos = f_pos;
-				info.recsize = UMSDOS_REC_SIZE;
-				ret = umsdos_writeentry (dentry, &info, 1);
-				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);
-			ret = -EFAULT;
-			if (copy_to_user (&idata->umsdos_dirent, &entry,
-							sizeof (entry)))
-				break;
-			if (copy_to_user (&idata->dos_dirent.d_name,
-							info.fake.fname,
-				 			info.fake.len + 1))
-				break;
-			ret = entry.name_len;
-			break;
-		}
-		/* update the original f_pos */
-		filp->f_pos = pos;
-	read_dput:
-		d_drop(demd);
-		dput(demd);
-		goto out;
-	}
-	if (cmd == UMSDOS_INIT_EMD) {
-		/* #Specification: ioctl / UMSDOS_INIT_EMD
-		 * The UMSDOS_INIT_EMD command makes sure the EMD
-		 * exists for a directory. If it does not, it is
-		 * created. Also, it makes sure the directory function
-		 * table (struct inode_operations) is set to the UMSDOS
-		 * semantic. This mean that umssync may be applied to
-		 * an "opened" msdos directory, and it will change behavior
-		 * on the fly.
-		 * 
-		 * Return 0 if success.
-		 */
-
-		ret = umsdos_make_emd(dentry);
-Printk(("UMSDOS_ioctl_dir: INIT_EMD %s/%s, ret=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ret));
-		umsdos_setup_dir (dentry);
-		goto out;
-	}
-
-	ret = -EFAULT;
-	if (copy_from_user (&data, idata, sizeof (data)))
-		goto out;
-
-	if (cmd == UMSDOS_CREAT_EMD) {
-		/* #Specification: ioctl / UMSDOS_CREAT_EMD
-		 * The umsdos_dirent field of the struct umsdos_ioctl is used
-		 * as is to create a new entry in the EMD of the directory.
-		 * The DOS directory is not modified.
-		 * No validation is done (yet).
-		 * 
-		 * Return 0 if success.
-		 */
-		struct umsdos_info info;
-
-		/* This makes sure info.entry and info in general
-		 * is correctly initialised
-		 */
-		memcpy (&info.entry, &data.umsdos_dirent,
-			sizeof (data.umsdos_dirent));
-		umsdos_parse (data.umsdos_dirent.name
-		    ,data.umsdos_dirent.name_len, &info);
-		ret = umsdos_newentry (dentry, &info);
-		goto out;
-	}
-	else if (cmd == UMSDOS_RENAME_DOS) {
-		struct dentry *old_dentry, *new_dentry;		/* FIXME */
-
-		/* #Specification: ioctl / UMSDOS_RENAME_DOS
-		 * A file or directory is renamed in a DOS directory
-		 * (not moved across directory). The source name
-		 * is in the dos_dirent.name field and the destination
-		 * is in umsdos_dirent.name field.
-		 * 
-		 * This ioctl allows umssync to rename a mangled file
-		 * name before syncing it back in the EMD.
-		 */
-		old_dentry = umsdos_lookup_dentry (dentry, 
-						data.dos_dirent.d_name,
-						data.dos_dirent.d_reclen ,1);
-		ret = PTR_ERR(old_dentry);
-		if (IS_ERR(old_dentry))
-			goto out;
-		new_dentry = umsdos_lookup_dentry (dentry,
-						data.umsdos_dirent.name,
-						data.umsdos_dirent.name_len, 1);
-		ret = PTR_ERR(new_dentry);
-		if (!IS_ERR(new_dentry)) {
-printk("umsdos_ioctl: renaming %s/%s to %s/%s\n",
-old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
-new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
-			ret = msdos_rename (dir, old_dentry, dir, new_dentry);
-			d_drop(new_dentry);
-			d_drop(old_dentry);
-			dput(new_dentry);
-		}
-		dput(old_dentry);
-		goto out;
-	}
-	else if (cmd == UMSDOS_UNLINK_EMD) {
-		/* #Specification: ioctl / UMSDOS_UNLINK_EMD
-		 * The umsdos_dirent field of the struct umsdos_ioctl is used
-		 * as is to remove an entry from the EMD of the directory.
-		 * No validation is done (yet). The mode field is used
-		 * to validate S_ISDIR or S_ISREG.
-		 * 
-		 * Return 0 if success.
-		 */
-		struct umsdos_info info;
-
-		/* This makes sure info.entry and info in general
-		 * is correctly initialised
-		 */
-		memcpy (&info.entry, &data.umsdos_dirent,
-			sizeof (data.umsdos_dirent));
-		umsdos_parse (data.umsdos_dirent.name,
-				data.umsdos_dirent.name_len, &info);
-		ret = umsdos_delentry (dentry, &info,
-				S_ISDIR (data.umsdos_dirent.mode));
-		if (ret) {
-			printk(KERN_WARNING
-				"umsdos_ioctl: delentry %s/%s failed, ret=%d\n",
-				dentry->d_name.name, info.entry.name, ret);
-		}
-		goto out;
-	}
-	else if (cmd == UMSDOS_UNLINK_DOS) {
-		struct dentry *temp;
-
-		/* #Specification: ioctl / UMSDOS_UNLINK_DOS
-		 * The dos_dirent field of the struct umsdos_ioctl is used to
-		 * execute a msdos_unlink operation. The d_name and d_reclen
-		 * fields are used.
-		 * 
-		 * Return 0 if success.
-		 */
-		temp = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name,
-						data.dos_dirent.d_reclen, 1);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out;
-		ret = -ENOENT;
-		if (temp->d_inode) {
-			ret = -EISDIR;
-			if (!S_ISDIR(temp->d_inode->i_mode))
-				ret = msdos_unlink (dir, temp);
-			if (!ret)
-				d_delete(temp);
-		}
-		dput (temp);
-		goto out;
-	}
-	else if (cmd == UMSDOS_RMDIR_DOS) {
-		struct dentry *temp;
-
-		/* #Specification: ioctl / UMSDOS_RMDIR_DOS
-		 * The dos_dirent field of the struct umsdos_ioctl is used to
-		 * execute a msdos_rmdir operation. The d_name and d_reclen
-		 * fields are used.
-		 * 
-		 * Return 0 if success.
-		 */
-		temp = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name,
-					    data.dos_dirent.d_reclen, 1);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out;
-		ret = -ENOENT;
-		if (temp->d_inode) {
-			ret = -ENOTDIR;
-			if (S_ISDIR(temp->d_inode->i_mode))
-				ret = msdos_rmdir (dir, temp);
-			if (!ret)
-				d_delete(temp);
-		}
-		dput (temp);
-		goto out;
-
-	} else if (cmd == UMSDOS_STAT_DOS) {
-		/* #Specification: ioctl / UMSDOS_STAT_DOS
-		 * The dos_dirent field of the struct umsdos_ioctl is
-		 * used to execute a stat operation in the DOS directory.
-		 * The d_name and d_reclen fields are used.
-		 * 
-		 * The following field of umsdos_ioctl.stat are filled.
-		 * 
-		 * st_ino,st_mode,st_size,st_atime,st_mtime,st_ctime,
-		 * Return 0 if success.
-		 */
-		struct dentry *dret;
-		struct inode *inode;
-
-		dret = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name,
-					    data.dos_dirent.d_reclen, 1);
-		ret = PTR_ERR(dret);
-		if (IS_ERR(dret))
-			goto out;
-		ret = -ENOENT;
-		inode = dret->d_inode;
-		if (inode) {
-			data.stat.st_ino = inode->i_ino;
-			data.stat.st_mode = inode->i_mode;
-			data.stat.st_size = inode->i_size;
-			data.stat.st_atime = inode->i_atime;
-			data.stat.st_ctime = inode->i_ctime;
-			data.stat.st_mtime = inode->i_mtime;
-			ret = -EFAULT;
-			if (!copy_to_user (&idata->stat, &data.stat, 
-						sizeof (data.stat)))
-				ret = 0;
-		}
-		dput(dret);
-		goto out;
-	}
-	else if (cmd == UMSDOS_DOS_SETUP) {
-		/* #Specification: ioctl / UMSDOS_DOS_SETUP
-		 * The UMSDOS_DOS_SETUP ioctl allow changing the
-		 * default permission of the MS-DOS filesystem driver
-		 * on the fly.  The MS-DOS driver applies global permissions
-		 * to every file and directory. Normally these permissions
-		 * are controlled by a mount option. This is not
-		 * available for root partition, so a special utility
-		 * (umssetup) is provided to do this, normally in
-		 * /etc/rc.local.
-		 * 
-		 * Be aware that this applies ONLY to MS-DOS directories
-		 * (those without EMD --linux-.---). Umsdos directory
-		 * have independent (standard) permission for each
-		 * and every file.
-		 * 
-		 * The field umsdos_dirent provide the information needed.
-		 * umsdos_dirent.uid and gid sets the owner and group.
-		 * umsdos_dirent.mode set the permissions flags.
-		 */
-		dir->i_sb->u.msdos_sb.options.fs_uid = data.umsdos_dirent.uid;
-		dir->i_sb->u.msdos_sb.options.fs_gid = data.umsdos_dirent.gid;
-		dir->i_sb->u.msdos_sb.options.fs_fmask =
-			dir->i_sb->u.msdos_sb.options.fs_dmask =
-				data.umsdos_dirent.mode;
-		ret = 0;
-	}
-out:
-	Printk (("ioctl %d, returning %d\n", cmd, ret));
-	return ret;
-}
diff -puN fs/umsdos/Makefile~remove-umsdos-from-tree fs/umsdos/Makefile
--- 25/fs/umsdos/Makefile~remove-umsdos-from-tree	2005-01-10 21:13:45.198825088 -0800
+++ 25-akpm/fs/umsdos/Makefile	2005-01-10 21:13:45.229820376 -0800
@@ -1,13 +0,0 @@
-#
-# Makefile for the umsdos Unix-like filesystem routines.
-#
-
-obj-$(CONFIG_UMSDOS) += umsdos.o
-
-umsdos-objs := dir.o  inode.o ioctl.o mangle.o namei.o rdir.o emd.o
-
-p:
-	proto *.c >/usr/include/linux/umsdos_fs.p
-
-doc:
-	nadoc -i -p umsdos.doc - /tmp/umsdos.mpg
diff -puN fs/umsdos/mangle.c~remove-umsdos-from-tree fs/umsdos/mangle.c
--- 25/fs/umsdos/mangle.c~remove-umsdos-from-tree	2005-01-10 21:13:45.199824936 -0800
+++ 25-akpm/fs/umsdos/mangle.c	2005-01-10 21:13:45.232819920 -0800
@@ -1,522 +0,0 @@
-/*
- *  linux/fs/umsdos/mangle.c
- *
- *      Written 1993 by Jacques Gelinas 
- *
- * Control the mangling of file name to fit msdos name space.
- * Many optimisations by GLU == dglaude@is1.vub.ac.be (Glaude David)
- */
-
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/umsdos_fs.h>
-
-/* (This file is used outside of the kernel) */
-#ifndef __KERNEL__
-#define KERN_WARNING
-#endif
-
-/*
- * Complete the mangling of the MSDOS fake name
- * based on the position of the entry in the EMD file.
- * 
- * Simply complete the job of umsdos_parse; fill the extension.
- * 
- * Beware that info->f_pos must be set.
- */
-void umsdos_manglename (struct umsdos_info *info)
-{
-	if (info->msdos_reject) {
-		/* #Specification: file name / non MSDOS conforming / mangling
-		 * Each non MSDOS conforming file has a special extension
-		 * build from the entry position in the EMD file.
-		 * 
-		 * This number is then transform in a base 32 number, where
-		 * each digit is expressed like hexadecimal number, using
-		 * digit and letter, except it uses 22 letters from 'a' to 'v'.
-		 * The number 32 comes from 2**5. It is faster to split a binary
-		 * number using a base which is a power of two. And I was 32
-		 * when I started this project. Pick your answer :-) .
-		 * 
-		 * If the result is '0', it is replace with '_', simply
-		 * to make it odd.
-		 * 
-		 * This is true for the first two character of the extension.
-		 * The last one is taken from a list of odd character, which
-		 * are:
-		 * 
-		 * { } ( ) ! ` ^ & @
-		 * 
-		 * With this scheme, we can produce 9216 ( 9* 32 * 32)
-		 * different extensions which should not clash with any useful
-		 * extension already popular or meaningful. Since most directory
-		 * have much less than 32 * 32 files in it, the first character
-		 * of the extension of any mangled name will be {.
-		 * 
-		 * Here are the reason to do this (this kind of mangling).
-		 * 
-		 * -The mangling is deterministic. Just by the extension, we
-		 * are able to locate the entry in the EMD file.
-		 * 
-		 * -By keeping to beginning of the file name almost unchanged,
-		 * we are helping the MSDOS user.
-		 * 
-		 * -The mangling produces names not too ugly, so an msdos user
-		 * may live with it (remember it, type it, etc...).
-		 * 
-		 * -The mangling produces names ugly enough so no one will
-		 * ever think of using such a name in real life. This is not
-		 * fool proof. I don't think there is a total solution to this.
-		 */
-		int entry_num;
-		char *pt = info->fake.fname + info->fake.len;
-		/* lookup for encoding the last character of the extension 
-		 * It contains valid character after the ugly one to make sure 
-		 * even if someone overflows the 32 * 32 * 9 limit, it still 
-		 * does something 
-		 */
-#define SPECIAL_MANGLING '{','}','(',')','!','`','^','&','@'
-		static char lookup3[] =
-		{
-			SPECIAL_MANGLING,
-		/* This is the start of lookup12 */
-			'_', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-			'p', 'q', 'r', 's', 't', 'u', 'v'
-		};
-
-#define lookup12 (lookup3+9)
-		entry_num = info->f_pos / UMSDOS_REC_SIZE;
-		if (entry_num > (9* 32 * 32)){
-			printk (KERN_WARNING "UMSDOS: more than 9216 files in a directory.\n"
-				"This may break the mangling strategy.\n"
-				"Not a killer problem. See doc.\n");
-		}
-		*pt++ = '.';
-		*pt++ = lookup3 [(entry_num >> 10) & 31];
-		*pt++ = lookup12[(entry_num >> 5) & 31];
-		*pt++ = lookup12[entry_num & 31];
-		*pt = '\0';		/* help doing printk */	
-		info->fake.len += 4;
-		info->msdos_reject = 0;		/* Avoid mangling twice */
-	}
-}
-
-/*
- * Evaluate the record size needed to store of name of len character.
- * The value returned is a multiple of UMSDOS_REC_SIZE.
- */
-int umsdos_evalrecsize (int len)
-{
-	struct umsdos_dirent dirent;
-	int nbrec = 1 + ((len - 1 + (dirent.name - (char *) &dirent))
-			 / UMSDOS_REC_SIZE);
-
-	return nbrec * UMSDOS_REC_SIZE;
-	/*
-	 * GLU        This should be inlined or something to speed it up to the max.
-	 * GLU        nbrec is absolutely not needed to return the value.
-	 */
-}
-#ifdef TEST
-int umsdos_evalrecsize_old (int len)
-{
-	struct umsdos_dirent dirent;
-	int size = len + (dirent.name - (char *) &dirent);
-	int nbrec = size / UMSDOS_REC_SIZE;
-	int extra = size % UMSDOS_REC_SIZE;
-
-	if (extra > 0)
-		nbrec++;
-	return nbrec * UMSDOS_REC_SIZE;
-}
-#endif
-
-
-/*
- * Fill the struct info with the full and msdos name of a file
- * Return 0 if all is OK, a negative error code otherwise.
- */
-int umsdos_parse (
-			 const char *fname,
-			 int len,
-			 struct umsdos_info *info)
-{
-	int ret = -ENAMETOOLONG;
-
-	/* #Specification: file name / too long
-	 * If a file name exceed UMSDOS maxima, the file name is silently
-	 * truncated. This makes it conformant with the other file system
-	 * of Linux (minix and ext2 at least).
-	 */
-	if (len > UMSDOS_MAXNAME)
-		len = UMSDOS_MAXNAME;
-	{
-		const char *firstpt = NULL;	/* First place we saw a "." in fname */
-
-		/* #Specification: file name / non MSDOS conforming / base length 0
-		 * file names beginning with a period '.' are invalid for MS-DOS.
-		 * It needs absolutely a base name. So the file name is mangled
-		 */
-		int ivldchar = fname[0] == '.';		/* At least one invalid character */
-		int msdos_len = len;
-		int base_len;
-
-		/*
-		 * cardinal_per_size tells if there exists at least one
-		 * DOS pseudo device on length n.  See the test below.
-		 */
-		static const char cardinal_per_size[9] =
-		{
-			0, 0, 0, 1, 1, 0, 1, 0, 1
-		};
-
-		/*
-		 * lkp translate all character to acceptable character (for DOS).
-		 * When lkp[n] == n, it means also it is an acceptable one.
-		 * So it serves both as a flag and as a translator.
-		 */
-		static char lkp[256];
-		static char is_init;
-
-		if (!is_init) {
-			/*
-			 * Initialisation of the array is easier and less error
-                         * prone like this.
-			 */
-			int i;
-			static const char *spc = "\"*+,/:;<=>?[\\]|~";
-
-			is_init = 1;
-			for (i = 0; i <= 32; i++)
-				lkp[i] = '#';
-			for (i = 33; i < 'A'; i++)
-				lkp[i] = (char) i;
-			for (i = 'A'; i <= 'Z'; i++)
-				lkp[i] = (char) (i + ('a' - 'A'));
-			for (i = 'Z' + 1; i < 127; i++)
-				lkp[i] = (char) i;
-			for (i = 128; i < 256; i++)
-				lkp[i] = '#';
-
-			lkp['.'] = '_';
-			while (*spc != '\0')
-				lkp[(unsigned char) (*spc++)] = '#';
-		}
-		/*  GLU
-		 * File names longer than 8+'.'+3 are invalid for MS-DOS,
-		 * so the file name is to be mangled--no further test is needed.
-		 * This speeds up handling of long names.
-		 * The position of the last point is no more necessary anyway.
-		 */
-		if (len <= (8 + 1 + 3)) {
-			const char *pt = fname;
-			const char *endpt = fname + len;
-
-			while (pt < endpt) {
-				if (*pt == '.') {
-					if (firstpt != NULL) {
-						/* 2 . in a file name. Reject */
-						ivldchar = 1;
-						break;
-					} else {
-						int extlen = (int) (endpt - pt);
-
-						firstpt = pt;
-						if (firstpt - fname > 8) {
-							/* base name longer than 8: reject */
-							ivldchar = 1;
-							break;
-						} else if (extlen > 4) {
-							/* Extension longer than 4 (including .): reject */
-							ivldchar = 1;
-							break;
-						} else if (extlen == 1) {
-							/* #Specification: file name / non MSDOS conforming / last char == .
-							 * If the last character of a file name is
-							 * a period, mangling is applied. MS-DOS does
-							 * not support those file names.
-							 */
-							ivldchar = 1;
-							break;
-						} else if (extlen == 4) {
-							/* #Specification: file name / non MSDOS conforming / mangling clash
-							 * To avoid clash with    the umsdos mangling, any file
-							 * with a special character as the first character
-							 * of the extension will be mangled. This solves the
-							 * following problem:
-							 * 
-							 * #
-							 * touch FILE
-							 * # FILE is invalid for DOS, so mangling is applied
-							 * # file.{_1 is created in the DOS directory
-							 * touch file.{_1
-							 * # To UMSDOS file point to a single DOS entry.
-							 * # So file.{_1 has to be mangled.
-							 * #
-							 */
-							static char special[] =
-							{
-								SPECIAL_MANGLING, '\0'
-							};
-
-							if (strchr (special, firstpt[1]) != NULL) {
-								ivldchar = 1;
-								break;
-							}
-						}
-					}
-				} else if (lkp[(unsigned char) (*pt)] != *pt) {
-					ivldchar = 1;
-					break;
-				}
-				pt++;
-			}
-		} else {
-			ivldchar = 1;
-		}
-		if (ivldchar
-		    || (firstpt == NULL && len > 8)
-		    || (len == UMSDOS_EMD_NAMELEN
-			&& memcmp (fname, UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN) == 0)) {
-			/* #Specification: file name / --linux-.---
-			 * The name of the EMD file --linux-.--- is map to a mangled
-			 * name. So UMSDOS does not restrict its use.
-			 */
-			/* #Specification: file name / non MSDOS conforming / mangling
-			 * Non MSDOS conforming file names must use some alias to fit
-			 * in the MSDOS name space.
-			 * 
-			 * The strategy is simple. The name is simply truncated to
-			 * 8 char. points are replace with underscore and a
-			 * number is given as an extension. This number correspond
-			 * to the entry number in the EMD file. The EMD file
-			 * only need to carry the real name.
-			 * 
-			 * Upper case is also converted to lower case.
-			 * Control character are converted to #.
-			 * Spaces are converted to #.
-			 * The following characters are also converted to #.
-			 * #
-			 * " * + , / : ; < = > ? [ \ ] | ~
-			 * #
-			 * 
-			 * Sometimes the problem is not in MS-DOS itself but in
-			 * command.com.
-			 */
-			int i;
-			char *pt = info->fake.fname;
-
-			base_len = msdos_len = (msdos_len > 8) ? 8 : msdos_len;
-			/*
-			 * There is no '.' any more so we know for a fact that
-			 * the base length is the length.
-			 */
-			memcpy (info->fake.fname, fname, msdos_len);
-			for (i = 0; i < msdos_len; i++, pt++)
-				*pt = lkp[(unsigned char) (*pt)];
-			*pt = '\0';	/* GLU  We force null termination. */
-			info->msdos_reject = 1;
-			/*
-			 * The numeric extension is added only when we know
-			 * the position in the EMD file, in umsdos_newentry(),
-			 * umsdos_delentry(), and umsdos_findentry().
-			 * See umsdos_manglename().
-			 */
-		} else {
-			/* Conforming MSDOS file name */
-			strncpy (info->fake.fname, fname, len);
-			info->msdos_reject = 0;
-			base_len = firstpt != NULL ? (int) (firstpt - fname) : len;
-		}
-		if (cardinal_per_size[base_len]) {
-			/* #Specification: file name / MSDOS devices / mangling
-			 * To avoid unreachable file from MS-DOS, any MS-DOS conforming
-			 * file with a basename equal to one of the MS-DOS pseudo
-			 * devices will be mangled.
-			 * 
-			 * If a file such as "prn" was created, it would be unreachable
-			 * under MS-DOS because "prn" is assumed to be the printer, even
-			 * if the file does have an extension.
-			 * 
-			 * Since the extension is unimportant to MS-DOS, we must patch
-			 * the basename also. We simply insert a minus '-'. To avoid
-			 * conflict with valid file with a minus in front (such as
-			 * "-prn"), we add an mangled extension like any other
-			 * mangled file name.
-			 * 
-			 * Here is the list of DOS pseudo devices:
-			 * 
-			 * #
-			 * "prn","con","aux","nul",
-			 * "lpt1","lpt2","lpt3","lpt4",
-			 * "com1","com2","com3","com4",
-			 * "clock$"
-			 * #
-			 * 
-			 * and some standard ones for common DOS programs
-			 * 
-			 * "emmxxxx0","xmsxxxx0","setverxx"
-			 * 
-			 * (Thanks to Chris Hall <cah17@phoenix.cambridge.ac.uk>
-			 * for pointing these out to me).
-			 * 
-			 * Is there one missing?
-			 */
-			/* This table must be ordered by length */
-			static const char *tbdev[] =
-			{
-				"prn", "con", "aux", "nul",
-				"lpt1", "lpt2", "lpt3", "lpt4",
-				"com1", "com2", "com3", "com4",
-				"clock$",
-				"emmxxxx0", "xmsxxxx0", "setverxx"
-			};
-
-			/* Tell where to find in tbdev[], the first name of */
-			/* a certain length */
-			static const char start_ind_dev[9] =
-			{
-				0, 0, 0, 4, 12, 12, 13, 13, 16
-			};
-			char basen[9];
-			int i;
-
-			for (i = start_ind_dev[base_len - 1]; i < start_ind_dev[base_len]; i++) {
-				if (memcmp (info->fake.fname, tbdev[i], base_len) == 0) {
-					memcpy (basen, info->fake.fname, base_len);
-					basen[base_len] = '\0';		/* GLU  We force null termination. */
-					/*
-					 * GLU        We do that only if necessary; we try to do the
-					 * GLU        simple thing in the usual circumstance. 
-					 */
-					info->fake.fname[0] = '-';
-					strcpy (info->fake.fname + 1, basen);	/* GLU  We already guaranteed a null would be at the end. */
-					msdos_len = (base_len == 8) ? 8 : base_len + 1;
-					info->msdos_reject = 1;
-					break;
-				}
-			}
-		}
-		info->fake.fname[msdos_len] = '\0';	/* Help doing printk */
-		/* GLU      This zero should (always?) be there already. */
-		info->fake.len = msdos_len;
-		/* Why not use info->fake.len everywhere? Is it longer?
-                 */
-		memcpy (info->entry.name, fname, len);
-		info->entry.name[len] = '\0';	/* for printk */
-		info->entry.name_len = len;
-		ret = 0;
-	}
-	/*
-	 * Evaluate how many records are needed to store this entry.
-	 */
-	info->recsize = umsdos_evalrecsize (len);
-	return ret;
-}
-
-#ifdef TEST
-
-struct MANG_TEST {
-	char *fname;		/* Name to validate */
-	int msdos_reject;	/* Expected msdos_reject flag */
-	char *msname;		/* Expected msdos name */
-};
-
-struct MANG_TEST tb[] =
-{
-	"hello", 0, "hello",
-	"hello.1", 0, "hello.1",
-	"hello.1_", 0, "hello.1_",
-	"prm", 0, "prm",
-
-#ifdef PROPOSITION
-	"HELLO", 1, "hello",
-	"Hello.1", 1, "hello.1",
-	"Hello.c", 1, "hello.c",
-#else
-/*
- * I find the three examples below very unfortunate.  I propose to
- * convert them to lower case in a quick preliminary pass, then test
- * whether there are other troublesome characters.  I have not made
- * this change, because it is not easy, but I wanted to mention the 
- * principle.  Obviously something like that would increase the chance
- * of collisions, for example between "HELLO" and "Hello", but these
- * can be treated elsewhere along with the other collisions.
- */
-
-	"HELLO", 1, "hello",
-	"Hello.1", 1, "hello_1",
-	"Hello.c", 1, "hello_c",
-#endif
-
-	"hello.{_1", 1, "hello_{_",
-	"hello\t", 1, "hello#",
-	"hello.1.1", 1, "hello_1_",
-	"hel,lo", 1, "hel#lo",
-	"Salut.Tu.vas.bien?", 1, "salut_tu",
-	".profile", 1, "_profile",
-	".xv", 1, "_xv",
-	"toto.", 1, "toto_",
-	"clock$.x", 1, "-clock$",
-	"emmxxxx0", 1, "-emmxxxx",
-	"emmxxxx0.abcd", 1, "-emmxxxx",
-	"aux", 1, "-aux",
-	"prn", 1, "-prn",
-	"prn.abc", 1, "-prn",
-	"PRN", 1, "-prn",
-  /* 
-   * GLU        WARNING:  the results of these are different with my version
-   * GLU        of mangling compared to the original one.
-   * GLU        CAUSE:  the manner of calculating the baselen variable.
-   * GLU                For you they are always 3.
-   * GLU                For me they are respectively 7, 8, and 8.
-
-   */
-	"PRN.abc", 1, "prn_abc",
-	"Prn.abcd", 1, "prn_abcd",
-	"prn.abcd", 1, "prn_abcd",
-	"Prn.abcdefghij", 1, "prn_abcd"
-};
-
-int main (int argc, char *argv[])
-{
-	int i, rold, rnew;
-
-	printf ("Testing the umsdos_parse.\n");
-	for (i = 0; i < sizeof (tb) / sizeof (tb[0]); i++) {
-		struct MANG_TEST *pttb = tb + i;
-		struct umsdos_info info;
-		int ok = umsdos_parse (pttb->fname, strlen (pttb->fname), &info);
-
-		if (strcmp (info.fake.fname, pttb->msname) != 0) {
-			printf ("**** %s -> ", pttb->fname);
-			printf ("%s <> %s\n", info.fake.fname, pttb->msname);
-		} else if (info.msdos_reject != pttb->msdos_reject) {
-			printf ("**** %s -> %s ", pttb->fname, pttb->msname);
-			printf ("%d <> %d\n", info.msdos_reject, pttb->msdos_reject);
-		} else {
-			printf ("     %s -> %s %d\n", pttb->fname, pttb->msname
-				,pttb->msdos_reject);
-		}
-	}
-	printf ("Testing the new umsdos_evalrecsize.");
-	for (i = 0; i < UMSDOS_MAXNAME; i++) {
-		rnew = umsdos_evalrecsize (i);
-		rold = umsdos_evalrecsize_old (i);
-		if (!(i % UMSDOS_REC_SIZE)) {
-			printf ("\n%d:\t", i);
-		}
-		if (rnew != rold) {
-			printf ("**** %d newres: %d != %d \n", i, rnew, rold);
-		} else {
-			printf (".");
-		}
-	}
-	printf ("\nEnd of Testing.\n");
-
-	return 0;
-}
-
-#endif
diff -puN fs/umsdos/namei.c~remove-umsdos-from-tree fs/umsdos/namei.c
--- 25/fs/umsdos/namei.c~remove-umsdos-from-tree	2005-01-10 21:13:45.201824632 -0800
+++ 25-akpm/fs/umsdos/namei.c	2005-01-10 21:13:45.237819160 -0800
@@ -1,1124 +0,0 @@
-/*
- *  linux/fs/umsdos/namei.c
- *
- *      Written 1993 by Jacques Gelinas 
- *      Inspired from linux/fs/msdos/... by Werner Almesberger
- *
- * Maintain and access the --linux alternate directory file.
- */
- /*
-  * You are in the maze of twisted functions - half of them shouldn't
-  * be here...
-  */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/msdos_fs.h>
-#include <linux/umsdos_fs.h>
-#include <linux/slab.h>
-
-#define UMSDOS_DIR_LOCK
-
-#ifdef UMSDOS_DIR_LOCK
-
-static inline void u_sleep_on (struct inode *dir)
-{
-	sleep_on (&UMSDOS_I(dir)->dir_info.p);
-}
-
-static inline void u_wake_up (struct inode *dir)
-{
-    	wake_up (&UMSDOS_I(dir)->dir_info.p);
-}
-
-/*
- * Wait for creation exclusivity.
- * Return 0 if the dir was already available.
- * Return 1 if a wait was necessary.
- * When 1 is return, it means a wait was done. It does not
- * mean the directory is available.
- */
-static int umsdos_waitcreate (struct inode *dir)
-{
-	int ret = 0;
-
-	if (UMSDOS_I(dir)->dir_info.creating
-	    && UMSDOS_I(dir)->dir_info.pid != current->pid) {
-	    	PRINTK (("creating && dir_info.pid=%lu, current->pid=%u\n", UMSDOS_I(dir)->dir_info.pid, current->pid));
-	    	u_sleep_on (dir);
-		ret = 1;
-	}
-	return ret;
-}
-
-/*
- * Wait for any lookup process to finish
- */
-static void umsdos_waitlookup (struct inode *dir)
-{
-	while (UMSDOS_I(dir)->dir_info.looking) {
-	    	u_sleep_on (dir);
-	}
-}
-
-/*
- * Lock all other process out of this directory.
- */
-/* #Specification: file creation / not atomic
- * File creation is a two step process. First we create (allocate)
- * an entry in the EMD file and then (using the entry offset) we
- * build a unique name for MSDOS. We create this name in the msdos
- * space.
- * 
- * We have to use semaphore (sleep_on/wake_up) to prevent lookup
- * into a directory when we create a file or directory and to
- * prevent creation while a lookup is going on. Since many lookup
- * may happen at the same time, the semaphore is a counter.
- * 
- * Only one creation is allowed at the same time. This protection
- * may not be necessary. The problem arise mainly when a lookup
- * or a readdir is done while a file is partially created. The
- * lookup process see that as a "normal" problem and silently
- * erase the file from the EMD file. Normal because a file
- * may be erased during a MSDOS session, but not removed from
- * the EMD file.
- * 
- * The locking is done on a directory per directory basis. Each
- * directory inode has its wait_queue.
- * 
- * For some operation like hard link, things even get worse. Many
- * creation must occur at once (atomic). To simplify the design
- * a process is allowed to recursively lock the directory for
- * creation. The pid of the locking process is kept along with
- * a counter so a second level of locking is granted or not.
- */
-void umsdos_lockcreate (struct inode *dir)
-{
-	/*
-	 * Wait for any creation process to finish except
-	 * if we (the process) own the lock
-	 */
-	while (umsdos_waitcreate (dir) != 0);
-	UMSDOS_I(dir)->dir_info.creating++;
-	UMSDOS_I(dir)->dir_info.pid = current->pid;
-	umsdos_waitlookup (dir);
-}
-
-/*
- * Lock all other process out of those two directories.
- */
-static void umsdos_lockcreate2 (struct inode *dir1, struct inode *dir2)
-{
-	/*
-	 * We must check that both directory are available before
-	 * locking anyone of them. This is to avoid some deadlock.
-	 * Thanks to dglaude@is1.vub.ac.be (GLAUDE DAVID) for pointing
-	 * this to me.
-	 */
-	while (1) {
-		if (umsdos_waitcreate (dir1) == 0
-		    && umsdos_waitcreate (dir2) == 0) {
-			/* We own both now */
-			UMSDOS_I(dir1)->dir_info.creating++;
-			UMSDOS_I(dir1)->dir_info.pid = current->pid;
-			UMSDOS_I(dir2)->dir_info.creating++;
-			UMSDOS_I(dir2)->dir_info.pid = current->pid;
-			break;
-		}
-	}
-	umsdos_waitlookup (dir1);
-	umsdos_waitlookup (dir2);
-}
-
-/*
- * Wait until creation is finish in this directory.
- */
-void umsdos_startlookup (struct inode *dir)
-{
-	while (umsdos_waitcreate (dir) != 0);
-	UMSDOS_I(dir)->dir_info.looking++;
-}
-
-/*
- * Unlock the directory.
- */
-void umsdos_unlockcreate (struct inode *dir)
-{
-	UMSDOS_I(dir)->dir_info.creating--;
-	if (UMSDOS_I(dir)->dir_info.creating < 0) {
-		printk ("UMSDOS: UMSDOS_I(dir)->dir_info.creating < 0: %d"
-			,UMSDOS_I(dir)->dir_info.creating);
-	}
-    	u_wake_up (dir);
-}
-
-/*
- * Tell directory lookup is over.
- */
-void umsdos_endlookup (struct inode *dir)
-{
-	UMSDOS_I(dir)->dir_info.looking--;
-	if (UMSDOS_I(dir)->dir_info.looking < 0) {
-		printk ("UMSDOS: UMSDOS_I(dir)->dir_info.looking < 0: %d"
-			,UMSDOS_I(dir)->dir_info.looking);
-	}
-    	u_wake_up (dir);
-}
-
-#else
-static void umsdos_lockcreate (struct inode *dir)
-{
-}
-static void umsdos_lockcreate2 (struct inode *dir1, struct inode *dir2)
-{
-}
-void umsdos_startlookup (struct inode *dir)
-{
-}
-static void umsdos_unlockcreate (struct inode *dir)
-{
-}
-void umsdos_endlookup (struct inode *dir)
-{
-}
-
-#endif
-
-static int umsdos_nevercreat (struct inode *dir, struct dentry *dentry,
-				int errcod)
-{
-	int ret = 0;
-
-	if (umsdos_is_pseudodos (dir, dentry)) {
-		/* #Specification: pseudo root / any file creation /DOS
-		 * The pseudo sub-directory /DOS can't be created!
-		 * EEXIST is returned.
-		 * 
-		 * The pseudo sub-directory /DOS can't be removed!
-		 * EPERM is returned.
-		 */
-		ret = errcod;
-	}
-	return ret;
-}
-
-/*
- * Add a new file (ordinary or special) into the alternate directory.
- * The file is added to the real MSDOS directory. If successful, it
- * is then added to the EMD file.
- * 
- * Return the status of the operation. 0 mean success.
- *
- * #Specification: create / file exists in DOS
- * Here is a situation: we are trying to create a file with
- * UMSDOS. The file is unknown to UMSDOS but already
- * exists in the DOS directory.
- * 
- * Here is what we are NOT doing:
- * 
- * We could silently assume that everything is fine
- * and allows the creation to succeed.
- * 
- * It is possible not all files in the partition
- * are meant to be visible from linux. By trying to create
- * those file in some directory, one user may get access
- * to those file without proper permissions. Looks like
- * a security hole to me. Off course sharing a file system
- * with DOS is some kind of security hole :-)
- * 
- * So ?
- * 
- * We return EEXIST in this case.
- * The same is true for directory creation.
- */
-static int umsdos_create_any (struct inode *dir, struct dentry *dentry,
-				int mode, dev_t rdev, char flags)
-{
-	struct dentry *fake;
-	struct inode *inode;
-	int ret;
-	struct umsdos_info info;
-
-	ret = umsdos_nevercreat (dir, dentry, -EEXIST);
-	if (ret)
-		goto out;
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret)
-		goto out;
-
-	info.entry.mode = mode;
-	info.entry.rdev = rdev;
-	info.entry.flags = flags;
-	info.entry.uid = current->fsuid;
-	info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	info.entry.ctime = info.entry.atime = info.entry.mtime = get_seconds();
-	info.entry.nlink = 1;
-	ret = umsdos_newentry (dentry->d_parent, &info);
-	if (ret)
-		goto out;
-
-	/* do a real lookup to get the short name dentry */
-	fake = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(fake);
-	if (IS_ERR(fake))
-		goto out_remove;
-
-	/* should not exist yet ... */
-	ret = -EEXIST;
-	if (fake->d_inode)
-		goto out_remove_dput;
-
-	ret = msdos_create (dir, fake, S_IFREG | 0777, NULL);
-	if (ret)
-		goto out_remove_dput;
-
-	inode = fake->d_inode;
-	atomic_inc(&inode->i_count);
-	d_instantiate (dentry, inode);
-	dput(fake);
-	if (atomic_read(&inode->i_count) > 1) {
-		printk(KERN_WARNING
-			"umsdos_create_any: %s/%s, ino=%ld, icount=%d??\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
-			inode->i_ino, atomic_read(&inode->i_count));
-	}
-	umsdos_lookup_patch_new(dentry, &info);
-
-out:
-	return ret;
-
-	/* Creation failed ... remove the EMD entry */
-out_remove_dput:
-	dput(fake);
-out_remove:
-	if (ret == -EEXIST)
-		printk(KERN_WARNING "UMSDOS: out of sync, deleting %s/%s\n",
-			dentry->d_parent->d_name.name, info.fake.fname);
-	umsdos_delentry (dentry->d_parent, &info, S_ISDIR (info.entry.mode));
-	goto out;
-}
-
-/*
- * Add a new file into the alternate directory.
- * The file is added to the real MSDOS directory. If successful, it
- * is then added to the EMD file.
- * 
- * Return the status of the operation. 0 mean success.
- */
-int UMSDOS_create (struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
-{
-	return umsdos_create_any (dir, dentry, mode, 0, 0);
-}
-
-
-/*
- * Initialise the new_entry from the old for a rename operation.
- * (Only useful for umsdos_rename_f() below).
- */
-static void umsdos_ren_init (struct umsdos_info *new_info,
-			     struct umsdos_info *old_info)
-{
-	new_info->entry.mode = old_info->entry.mode;
-	new_info->entry.rdev = old_info->entry.rdev;
-	new_info->entry.uid = old_info->entry.uid;
-	new_info->entry.gid = old_info->entry.gid;
-	new_info->entry.ctime = old_info->entry.ctime;
-	new_info->entry.atime = old_info->entry.atime;
-	new_info->entry.mtime = old_info->entry.mtime;
-	new_info->entry.flags = old_info->entry.flags;
-	new_info->entry.nlink = old_info->entry.nlink;
-}
-
-/*
- * Rename a file (move) in the file system.
- */
- 
-static int umsdos_rename_f (struct inode *old_dir, struct dentry *old_dentry,
-			    struct inode *new_dir, struct dentry *new_dentry,
-			    int flags)
-{
-	struct inode *old_inode = old_dentry->d_inode;
-	struct dentry *old, *new, *old_emd;
-	int err, ret;
-	struct umsdos_info old_info;
-	struct umsdos_info new_info;
-
- 	ret = -EPERM;
-	err = umsdos_parse (old_dentry->d_name.name,
-				old_dentry->d_name.len, &old_info);
-	if (err)
-		goto out;
-	err = umsdos_parse (new_dentry->d_name.name,
-				new_dentry->d_name.len, &new_info);
-	if (err)
-		goto out;
-
-	/* Get the EMD dentry for the old parent */
-	old_emd = umsdos_get_emd_dentry(old_dentry->d_parent);
-	ret = PTR_ERR(old_emd);
-	if (IS_ERR(old_emd))
-		goto out;
-
-	umsdos_lockcreate2 (old_dir, new_dir);
-
-	ret = umsdos_findentry(old_emd->d_parent, &old_info, 0);
-	if (ret)
-		goto out_unlock;
-
-	err = umsdos_findentry(new_dentry->d_parent, &new_info, 0);
-	if (err == 0) {
-		/* check whether it _really_ exists ... */
-		ret = -EEXIST;
-		if (new_dentry->d_inode)
-			goto out_unlock;
-
-		/* bogus lookup? complain and fix up the EMD ... */
-		printk(KERN_WARNING
-			"umsdos_rename_f: entry %s/%s exists, inode NULL??\n",
-			new_dentry->d_parent->d_name.name, new_info.entry.name);
-		err = umsdos_delentry(new_dentry->d_parent, &new_info,
-					S_ISDIR(new_info.entry.mode));
-	}
-
-	umsdos_ren_init (&new_info, &old_info);
-	if (flags)
-		new_info.entry.flags = flags;
-	ret = umsdos_newentry (new_dentry->d_parent, &new_info);
-	if (ret)
-		goto out_unlock;
-
-	/* If we're moving a hardlink, drop it first */
-	if (old_info.entry.flags & UMSDOS_HLINK) {
-		d_drop(old_dentry);
-	}
-
-	old = umsdos_covered(old_dentry->d_parent, old_info.fake.fname, 
-					old_info.fake.len);
-	ret = PTR_ERR(old);
-	if (IS_ERR(old))
-		goto out_unlock;
-	/* make sure it's the same inode! */
-	ret = -ENOENT;
-	/*
-	 * 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);
-	ret = PTR_ERR(new);
-	if (IS_ERR(new))
-		goto out_dput;
-
-	/* Do the msdos-level rename */
-	ret = msdos_rename (old_dir, old, new_dir, new);
-
-	dput(new);
-
-	/* If the rename failed, remove the new EMD entry */
-	if (ret != 0) {
-		umsdos_delentry (new_dentry->d_parent, &new_info,
-				 S_ISDIR (new_info.entry.mode));
-		goto out_dput;
-	}
-
-	/*
-	 * Rename successful ... remove the old name from the EMD.
-	 * Note that we use the EMD parent here, as the old dentry
-	 * may have moved to a new parent ...
-	 */
-	err = umsdos_delentry (old_emd->d_parent, &old_info,
-				S_ISDIR (old_info.entry.mode));
-	if (err) {
-		/* Failed? Complain a bit, but don't fail the operation */
-		printk(KERN_WARNING 
-			"umsdos_rename_f: delentry %s/%s failed, error=%d\n",
-			old_emd->d_parent->d_name.name, old_info.entry.name,
-			err);
-	}
-
-	/*
-	 * Update f_pos so notify_change will succeed
-	 * if the file was already in use.
-	 */
-	umsdos_set_dirinfo_new(old_dentry, new_info.f_pos);
-
-	/* dput() the dentry if we haven't already */
-out_dput:
-	dput(old);
-
-out_unlock:
-	dput(old_emd);
-	umsdos_unlockcreate (old_dir);
-	umsdos_unlockcreate (new_dir);
-
-out:
-	Printk ((" _ret=%d\n", ret));
-	return ret;
-}
-
-/*
- * Setup a Symbolic link or a (pseudo) hard link
- * Return a negative error code or 0 if OK.
- */
-/* #Specification: symbolic links / strategy
- * A symbolic link is simply a file which holds a path. It is
- * implemented as a normal MSDOS file (not very space efficient :-()
- * 
- * I see two different ways to do this: One is to place the link data
- * in unused entries of the EMD file; the other is to have a separate
- * file dedicated to hold all symbolic links data.
- * 
- * Let's go for simplicity...
- */
-
-/*
- * AV. Should be called with dir->i_sem down.
- */
-static int umsdos_symlink_x (struct inode *dir, struct dentry *dentry,
-			const char *symname, int mode, char flags)
-{
-	int ret, len;
-
-	ret = umsdos_create_any (dir, dentry, mode, 0, flags);
-	if (ret) {
-		printk(KERN_WARNING
-			"umsdos_symlink: create failed, ret=%d\n", ret);
-		goto out;
-	}
-
-	len = strlen (symname) + 1;
-	ret = page_symlink(dentry->d_inode, symname, len);
-	if (ret < 0)
-		goto out_unlink;
-out:
-	return ret;
-
-out_unlink:
-	printk(KERN_WARNING "umsdos_symlink: write failed, unlinking\n");
-	UMSDOS_unlink (dir, dentry);
-	d_drop(dentry);
-	goto out;
-}
-
-/*
- * Setup a Symbolic link.
- * Return a negative error code or 0 if OK.
- */
-int UMSDOS_symlink ( struct inode *dir, struct dentry *dentry,
-		 const char *symname)
-{
-	return umsdos_symlink_x (dir, dentry, symname, S_IFLNK | 0777, 0);
-}
-
-/*
- * Add a link to an inode in a directory
- */
-int UMSDOS_link (struct dentry *olddentry, struct inode *dir,
-		 struct dentry *dentry)
-{
-	struct inode *oldinode = olddentry->d_inode;
-	struct inode *olddir = olddentry->d_parent->d_inode;
-	struct dentry *temp;
-	char *path;
-	unsigned long buffer;
-	int ret;
-	struct umsdos_info old_info;
-	struct umsdos_info hid_info;
-
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk("umsdos_link: new %s/%s -> %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, 
-olddentry->d_parent->d_name.name, olddentry->d_name.name);
-#endif
- 
-	ret = -EPERM;
-	if (S_ISDIR (oldinode->i_mode))
-		goto out;
-
-	ret = umsdos_nevercreat (dir, dentry, -EPERM);
-	if (ret)
-		goto out;
-
-	ret = -ENOMEM;
-	buffer = get_zeroed_page(GFP_KERNEL);
-	if (!buffer)
-		goto out;
-
-	/*
-	 * Lock the link parent if it's not the same directory.
-	 */
-	ret = -EDEADLOCK;
-	if (olddir != dir) {
-		if (atomic_read(&olddir->i_sem.count) < 1)
-			goto out_free;
-		down(&olddir->i_sem);
-	}
-
-	/*
-	 * Parse the name and get the visible directory entry.
-	 */
-	ret = umsdos_parse (olddentry->d_name.name, olddentry->d_name.len,
-				&old_info);
-	if (ret)
-		goto out_unlock;
-	ret = umsdos_findentry (olddentry->d_parent, &old_info, 1);
-	if (ret) {
-printk("UMSDOS_link: %s/%s not in EMD, ret=%d\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name, ret);
-		goto out_unlock;
-	}
-
-	/*
-	 * If the visible dentry is a pseudo-hardlink, the original
-	 * file must be already hidden.
-	 */
-	if (!(old_info.entry.flags & UMSDOS_HLINK)) {
-		int err;
-
-		/* create a hidden link name */
-		ret = umsdos_newhidden (olddentry->d_parent, &hid_info);
-		if (ret) {
-printk("umsdos_link: can't make hidden %s/%s, ret=%d\n",
-olddentry->d_parent->d_name.name, hid_info.entry.name, ret);
-			goto out_unlock;
-		}
-
-		/*
-		 * Make a dentry and rename the original file ...
-		 */
-		temp = umsdos_lookup_dentry(olddentry->d_parent,
-						hid_info.entry.name,
-						hid_info.entry.name_len, 0); 
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp)) {
-printk("umsdos_link: lookup %s/%s failed, ret=%d\n",
-dentry->d_parent->d_name.name, hid_info.entry.name, ret);
-			goto cleanup;
-		}
-		/* rename the link to the hidden location ... */
-		ret = umsdos_rename_f(olddir, olddentry, olddir, temp,
-					UMSDOS_HIDDEN);
-		d_move(olddentry, temp);
-		dput(temp);
-		if (ret) {
-printk("umsdos_link: rename to %s/%s failed, ret=%d\n",
-temp->d_parent->d_name.name, temp->d_name.name, ret);
-			goto cleanup;
-		}
-		/* mark the inode as a hardlink */
-		UMSDOS_I(oldinode)->i_is_hlink = 1;
-
-		/*
-		 * Capture the path to the hidden link.
-		 */
-		path = umsdos_d_path(olddentry, (char *) buffer, PAGE_SIZE);
-Printk(("umsdos_link: hidden link path=%s\n", path));
-
-		/*
-		 * Recreate a dentry for the original name and symlink it,
-		 * then symlink the new dentry. Don't give up if one fails,
-		 * or we'll lose the file completely!
-		 *
-		 * Note: this counts as the "original" reference, so we 
-		 * don't increment i_nlink for this one.
-		 */ 
-		temp = umsdos_lookup_dentry(olddentry->d_parent,
-						old_info.entry.name,
-						old_info.entry.name_len, 0); 
-		ret = PTR_ERR(temp);
-		if (!IS_ERR(temp)) {
-			ret = umsdos_symlink_x (olddir, temp, path, 
-						S_IFREG | 0777, UMSDOS_HLINK);
-			dput(temp);
-		}
-
-		/* This symlink increments i_nlink (see below.) */
-		err = umsdos_symlink_x (dir, dentry, path,
-					S_IFREG | 0777, UMSDOS_HLINK);
-		/* fold the two errors */
-		if (!ret)
-			ret = err;
-		goto out_unlock;
-
-		/* creation failed ... remove the link entry */
-	cleanup:
-printk("umsdos_link: link failed, ret=%d, removing %s/%s\n",
-ret, olddentry->d_parent->d_name.name, hid_info.entry.name);
-		err = umsdos_delentry(olddentry->d_parent, &hid_info, 0);
-		goto out_unlock;
-	}
-
-Printk(("UMSDOS_link: %s/%s already hidden\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name));
-	/*
-	 * The original file is already hidden, and we need to get 
-	 * the dentry for its real name, not the visible name.
-	 * N.B. make sure it's the hidden inode ...
-	 */
-	if (!UMSDOS_I(oldinode)->i_is_hlink)
-		printk("UMSDOS_link: %s/%s hidden, ino=%ld not hlink??\n",
-			olddentry->d_parent->d_name.name,
-			olddentry->d_name.name, oldinode->i_ino);
-
-	/*
-	 * In order to get the correct (real) inode, we just drop
-	 * the original dentry.
-	 */ 
-	d_drop(olddentry);
-Printk(("UMSDOS_link: hard link %s/%s, fake=%s\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name, old_info.fake.fname));
-
-	/* 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_unlock;
-
-	/* now resolve the link ... */
-	temp = umsdos_solve_hlink(temp);
-	ret = PTR_ERR(temp);
-	if (IS_ERR(temp))
-		goto out_unlock;
-	path = umsdos_d_path(temp, (char *) buffer, PAGE_SIZE);
-	dput(temp);
-Printk(("umsdos_link: %s/%s already hidden, path=%s\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name, path));
-
-	/* finally we can symlink it ... */
-	ret = umsdos_symlink_x (dir, dentry, path, S_IFREG | 0777,UMSDOS_HLINK);
-
-out_unlock:
-	/* remain locked for the call to notify_change ... */
-	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 (!UMSDOS_I(oldinode)->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
-		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(temp, &newattrs);
- 		if (ret == 0)
-			mark_inode_dirty(temp->d_inode);
-		dput(temp);
-out_unlock2:	
-		if (ret == 0)
-			mark_inode_dirty(olddentry->d_inode);
-	}
-	if (olddir != dir)
-		up(&olddir->i_sem);
-
-out_free:
-	free_page(buffer);
-out:
-	Printk (("umsdos_link %d\n", ret));
-	return ret;
-}
-
-
-/*
- * Add a sub-directory in a directory
- */
-/* #Specification: mkdir / Directory already exist in DOS
- * We do the same thing as for file creation.
- * For all user it is an error.
- */
-/* #Specification: mkdir / umsdos directory / create EMD
- * When we created a new sub-directory in a UMSDOS
- * directory (one with full UMSDOS semantics), we
- * create immediately an EMD file in the new
- * sub-directory so it inherits UMSDOS semantics.
- */
-int UMSDOS_mkdir (struct inode *dir, struct dentry *dentry, int mode)
-{
-	struct dentry *temp;
-	struct inode *inode;
-	int ret, err;
-	struct umsdos_info info;
-
-	ret = umsdos_nevercreat (dir, dentry, -EEXIST);
-	if (ret)
-		goto out;
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret)
-		goto out;
-
-	info.entry.mode = mode | S_IFDIR;
-	info.entry.rdev = 0;
-	info.entry.uid = current->fsuid;
-	info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	info.entry.ctime = info.entry.atime = info.entry.mtime = get_seconds();
-	info.entry.flags = 0;
-	info.entry.nlink = 1;
-	ret = umsdos_newentry (dentry->d_parent, &info);
-	if (ret)
-		goto out;
-
-	/* lookup 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_remove;
-
-	/* Make sure the short name doesn't exist */
-	ret = -EEXIST;
-	if (temp->d_inode) {
-printk("umsdos_mkdir: short name %s/%s exists\n",
-dentry->d_parent->d_name.name, info.fake.fname);
-		goto out_remove_dput;
-	}
-
-	ret = msdos_mkdir (dir, temp, mode);
-	if (ret)
-		goto out_remove_dput;
-
-	/*
-	 * Lock the inode to protect the EMD creation ...
-	 */
-	inode = temp->d_inode;
-	down(&inode->i_sem);
-
-	atomic_inc(&inode->i_count);
-	d_instantiate(dentry, inode);
-
-	/* N.B. this should have an option to create the EMD ... */
-	umsdos_lookup_patch_new(dentry, &info);
-
-	/* 
-	 * Create the EMD file, and set up the dir so it is
-	 * promoted to EMD with the EMD file invisible.
-	 *
-	 * N.B. error return if EMD fails?
-	 */
-	err = umsdos_make_emd(dentry);
-	umsdos_setup_dir(dentry);
-
-	up(&inode->i_sem);
-	dput(temp);
-
-out:
-	Printk(("umsdos_mkdir: %s/%s, ret=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name, ret));
-	return ret;
-
-	/* an error occurred ... remove EMD entry. */
-out_remove_dput:
-	dput(temp);
-out_remove:
-	umsdos_delentry (dentry->d_parent, &info, 1);
-	goto out;
-}
-
-/*
- * Add a new device special file into a directory.
- *
- * #Specification: Special files / strategy
- * Device special file, pipes, etc ... are created like normal
- * file in the msdos file system. Of course they remain empty.
- * 
- * One strategy was to create those files only in the EMD file
- * since they were not important for MSDOS. The problem with
- * that, is that there were not getting inode number allocated.
- * The MSDOS filesystems is playing a nice game to fake inode
- * number, so why not use it.
- * 
- * The absence of inode number compatible with those allocated
- * for ordinary files was causing major trouble with hard link
- * in particular and other parts of the kernel I guess.
- */
-int UMSDOS_mknod (struct inode *dir, struct dentry *dentry,
-		 int mode, dev_t rdev)
-{
-	return umsdos_create_any (dir, dentry, mode, rdev, 0);
-}
-
-/*
- * Remove a sub-directory.
- */
-int UMSDOS_rmdir (struct inode *dir, struct dentry *dentry)
-{
-	struct dentry *temp;
-	int ret, err, empty;
-	struct umsdos_info info;
-
-	ret = umsdos_nevercreat (dir, dentry, -EPERM);
-	if (ret)
-		goto out;
-
-	ret = -EBUSY;
-	if (!d_unhashed(dentry))
-		goto out;
-
-	/* check whether the EMD is empty */
-	ret = -ENOTEMPTY;
-	empty = umsdos_isempty (dentry);
-
-	/* Have to remove the EMD file? */
-	if (empty == 1) {
-		struct dentry *demd;
-
-		demd = umsdos_get_emd_dentry(dentry);
-		if (!IS_ERR(demd)) {
-			err = -ENOENT;
-			if (demd->d_inode)
-				err = msdos_unlink (dentry->d_inode, demd);
-Printk (("UMSDOS_rmdir: unlinking empty EMD err=%d", err));
-#ifdef UMSDOS_PARANOIA
-if (err)
-printk("umsdos_rmdir: EMD %s/%s unlink failed, err=%d\n",
-demd->d_parent->d_name.name, demd->d_name.name, err);
-#endif
-			if (!err) {
-				d_delete(demd);
-				ret = 0;
-			}
-			dput(demd);
-		}
-	} else if (empty == 2)
-		ret = 0;
-	if (ret)
-		goto out;
-
-	umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	/* Call findentry to complete the mangling */
-	umsdos_findentry (dentry->d_parent, &info, 2);
-	temp = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(temp);
-	if (IS_ERR(temp))
-		goto out;
-	/*
-	 * Attempt to remove the msdos name.
-	 */
-	ret = msdos_rmdir (dir, temp);
-	if (ret && ret != -ENOENT)
-		goto out_dput;
-
-	d_delete(temp);
-	/* OK so far ... remove the name from the EMD */
-	ret = umsdos_delentry (dentry->d_parent, &info, 1);
-#ifdef UMSDOS_PARANOIA
-if (ret)
-printk("umsdos_rmdir: delentry %s failed, ret=%d\n", info.entry.name, ret);
-#endif
-
-	/* dput() temp if we didn't do it above */
-out_dput:
-	dput(temp);
-
-out:
-	Printk (("umsdos_rmdir %d\n", ret));
-	return ret;
-}
-
-
-/*
- * Remove a file from the directory.
- *
- * #Specification: hard link / deleting a link
- * When we delete a file and this file is a link,
- * we must subtract 1 from the nlink field of the
- * hidden link.
- * 
- * If the count goes to 0, we delete this hidden
- * link too.
- */
-int UMSDOS_unlink (struct inode *dir, struct dentry *dentry)
-{
-	struct dentry *temp, *link = NULL;
-	struct inode *inode;
-	int ret;
-	struct umsdos_info info;
-
-Printk(("UMSDOS_unlink: entering %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name));
-
-	ret = umsdos_nevercreat (dir, dentry, -EPERM);
-	if (ret)
-		goto out;
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret)
-		goto out;
-
-	umsdos_lockcreate (dir);
-	ret = umsdos_findentry (dentry->d_parent, &info, 1);
-	if (ret) {
-printk("UMSDOS_unlink: %s/%s not in EMD, ret=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out_unlock;
-	}
-
-Printk (("UMSDOS_unlink %.*s ", info.fake.len, info.fake.fname));
-
-	/*
-	 * Note! If this is a hardlink and the names are aliased,
-	 * the short-name lookup will return the hardlink dentry.
-	 * In order to get the correct (real) inode, we just drop
-	 * the original dentry.
-	 */ 
-	if (info.entry.flags & UMSDOS_HLINK) {
-		d_drop(dentry);
-	}
-
-	/* 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_unlock;
-
-	/*
-	 * Resolve hardlinks now, but defer processing until later.
-	 */
-	if (info.entry.flags & UMSDOS_HLINK) {
-		link = umsdos_solve_hlink(dget(temp));
-	}
-
-	/* Delete the EMD entry */
-	ret = umsdos_delentry (dentry->d_parent, &info, 0);
-	if (ret && ret != -ENOENT) {
-		printk(KERN_WARNING "UMSDOS_unlink: delentry %s, error=%d\n",
-			info.entry.name, ret);
-		goto out_dput;
-	}
-
-	ret = msdos_unlink(dir, temp);
-	if (!ret)
-		d_delete(temp);
-#ifdef UMSDOS_PARANOIA
-if (ret)
-printk("umsdos_unlink: %s/%s unlink failed, ret=%d\n",
-temp->d_parent->d_name.name, temp->d_name.name, ret);
-#endif
-
-	/* dput() temp if we didn't do it above */
-out_dput:
-	dput(temp);
-
-out_unlock:
-	umsdos_unlockcreate (dir);
-
-	/*
-	 * Now check for deferred handling of a hardlink.
-	 */
-	if (!link)
-		goto out;
-
-	if (IS_ERR(link)) {
-printk("umsdos_unlink: failed to resolve %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-		if (!ret)
-			ret = PTR_ERR(link);
-		goto out;
-	}
-
-Printk(("umsdos_unlink: link %s/%s deferred, pending ret=%d\n",
-link->d_parent->d_name.name, link->d_name.name, ret));
-
-	/* already have an error? */
-	if (ret)
-		goto out_cleanup;
-
-	/* make sure the link exists ... */
-	inode = link->d_inode;
-	if (!inode) {
-		printk(KERN_WARNING "umsdos_unlink: hard link not found\n");
-		goto out_cleanup;
-	}
-
-	/*
-	 * If this was the last linked reference, delete it now.
-	 *
-	 * N.B. Deadlock problem? We should be holding the lock
-	 * for the hardlink's parent, but another process might
-	 * be holding that lock waiting for us to finish ...
-	 */
-	if (inode->i_nlink <= 1) {
-		ret = UMSDOS_unlink (link->d_parent->d_inode, link);
-		if (ret) {
-			printk(KERN_WARNING
-				"umsdos_unlink: link removal failed, ret=%d\n",
-				 ret);
-		} else
-			d_delete(link);
-	} else {
-		struct iattr newattrs;
-		inode->i_nlink--;
-		newattrs.ia_valid = 0;
-		ret = umsdos_notify_change_locked(link, &newattrs);
-		if (!ret)
-			mark_inode_dirty(link->d_inode);
-	}
-
-out_cleanup:
-	d_drop(link);
-	dput(link);
-
-out:
-	Printk (("umsdos_unlink %d\n", ret));
-	return ret;
-}
-
-/*
- * Rename (move) a file.
- */
-int UMSDOS_rename (struct inode *old_dir, struct dentry *old_dentry,
-		   struct inode *new_dir, struct dentry *new_dentry)
-{
-	int ret;
-
-	ret = umsdos_nevercreat (new_dir, new_dentry, -EEXIST);
-	if (ret)
-		return ret;
-
-		/*
-		 * If the target already exists, delete it first.
-		 */
-	if (new_dentry->d_inode) {
-		dget(new_dentry);
-		if (S_ISDIR(old_dentry->d_inode->i_mode))
-			ret = UMSDOS_rmdir (new_dir, new_dentry);
-		else
-			ret = UMSDOS_unlink (new_dir, new_dentry);
-		if (!ret)
-			d_drop(new_dentry);
-		dput(new_dentry);
-		if (ret)
-			return ret;
-	}
-	ret = umsdos_rename_f(old_dir, old_dentry, new_dir, new_dentry, 0);
-	return ret;
-}
diff -puN fs/umsdos/rdir.c~remove-umsdos-from-tree fs/umsdos/rdir.c
--- 25/fs/umsdos/rdir.c~remove-umsdos-from-tree	2005-01-10 21:13:45.202824480 -0800
+++ 25-akpm/fs/umsdos/rdir.c	2005-01-10 21:13:45.238819008 -0800
@@ -1,248 +0,0 @@
-/*
- *  linux/fs/umsdos/rdir.c
- *
- *  Written 1994 by Jacques Gelinas
- *
- *  Extended MS-DOS directory pure MS-DOS handling functions
- *  (For directory without EMD file).
- */
-
-#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/errno.h>
-#include <linux/stat.h>
-#include <linux/limits.h>
-#include <linux/umsdos_fs.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-
-#include <asm/uaccess.h>
-
-
-extern struct dentry *saved_root;
-extern struct inode *pseudo_root;
-extern struct dentry_operations umsdos_dentry_operations;
-
-struct RDIR_FILLDIR {
-	void *dirbuf;
-	filldir_t filldir;
-	int real_root;
-};
-
-static int rdir_filldir (	void *buf,
-				const char *name,
-				int name_len,
-				loff_t offset,
-				ino_t ino,
-				unsigned int d_type)
-{
-	int ret = 0;
-	struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR *) buf;
-
-	if (d->real_root) {
-		PRINTK ((KERN_DEBUG "rdir_filldir /mn/: real root!\n"));
-		/* real root of a pseudo_rooted partition */
-		if (name_len != UMSDOS_PSDROOT_LEN
-		    || memcmp (name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN) != 0) {
-			/* So it is not the /linux directory */
-			if (name_len == 2 && name[0] == '.' && name[1] == '.') {
-				/* Make sure the .. entry points back to the pseudo_root */
-				ino = pseudo_root->i_ino;
-			}
-			ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN);
-		}
-	} else {
-		/* Any DOS directory */
-		ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN);
-	}
-	return ret;
-}
-
-
-static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir)
-{
-	struct inode *dir = filp->f_dentry->d_inode;
-	struct RDIR_FILLDIR bufk;
-	int ret;
-
-	lock_kernel();
-	bufk.filldir = filldir;
-	bufk.dirbuf = dirbuf;
-	bufk.real_root = pseudo_root && (dir == saved_root->d_inode);
-	ret = fat_readdir (filp, &bufk, rdir_filldir);
-	unlock_kernel();
-	return ret;
-}
-
-
-/*
- * Lookup into a non promoted directory.
- * If the result is a directory, make sure we find out if it is
- * a promoted one or not (calling umsdos_setup_dir_inode(inode)).
- */
-/* #Specification: pseudo root / DOS/..
- * In the real root directory (c:\), the directory ..
- * is the pseudo root (c:\linux).
- */
-struct dentry *umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo)
-{
-	struct dentry *ret;
-
-	if (saved_root && dir == saved_root->d_inode && !nopseudo &&
-	    dentry->d_name.len == UMSDOS_PSDROOT_LEN &&
-	    memcmp (dentry->d_name.name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN) == 0) {
-		/* #Specification: pseudo root / DOS/linux
-		 * Even in the real root directory (c:\), the directory
-		 * /linux won't show
-		 */
-		 
-		ret = ERR_PTR(-ENOENT);
-		goto out;
-	}
-
-	ret = msdos_lookup (dir, dentry, NULL);
-	if (ret) {
-		printk(KERN_WARNING
-			"umsdos_rlookup_x: %s/%s failed, ret=%ld\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
-			PTR_ERR(ret));
-		goto out;
-	}
-	if (dentry->d_inode) {
-		/* We must install the proper function table
-		 * depending on whether this is an MS-DOS or 
-		 * a UMSDOS directory
-		 */
-Printk ((KERN_DEBUG "umsdos_rlookup_x: patch_dentry_inode %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name));
-/* only patch if needed (because we get called even for lookup
-   (not only rlookup) stuff sometimes, like in umsdos_covered() */
-		if (UMSDOS_I(dentry->d_inode)->i_patched == 0)	
-		umsdos_patch_dentry_inode(dentry, 0);
-
-	}
-out:
-	/* always install our dentry ops ... */
-	dentry->d_op = &umsdos_dentry_operations;
-	return ret;
-}
-
-
-struct dentry *UMSDOS_rlookup ( struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-	return umsdos_rlookup_x (dir, dentry, 0);
-}
-
-
-/* #Specification: dual mode / rmdir in a DOS directory
- * In a DOS (not EMD in it) directory, we use a reverse strategy
- * compared with a UMSDOS directory. We assume that a subdirectory
- * of a DOS directory is also a DOS directory. This is not always
- * true (umssync may be used anywhere), but makes sense.
- * 
- * So we call msdos_rmdir() directly. If it failed with a -ENOTEMPTY
- * then we check if it is a Umsdos directory. We check if it is
- * really empty (only . .. and --linux-.--- in it). If it is true
- * we remove the EMD and do a msdos_rmdir() again.
- * 
- * In a Umsdos directory, we assume all subdirectories are also
- * Umsdos directories, so we check the EMD file first.
- */
-/* #Specification: pseudo root / rmdir /DOS
- * The pseudo sub-directory /DOS can't be removed!
- * This is done even if the pseudo root is not a Umsdos
- * directory anymore (very unlikely), but an accident (under
- * MS-DOS) is always possible.
- * 
- * EPERM is returned.
- */
-static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry)
-{
-	int ret, empty;
-
-	ret = -EPERM;
-	if (umsdos_is_pseudodos (dir, dentry))
-		goto out;
-
-	ret = -EBUSY;
-	if (!d_unhashed(dentry))
-		goto out;
-
-	ret = msdos_rmdir (dir, dentry);
-	if (ret != -ENOTEMPTY)
-		goto out;
-
-	empty = umsdos_isempty (dentry);
-	if (empty == 1) {
-		struct dentry *demd;
-		/* We have to remove the EMD file. */
-		demd = umsdos_get_emd_dentry(dentry);
-		ret = PTR_ERR(demd);
-		if (!IS_ERR(demd)) {
-			ret = 0;
-			if (demd->d_inode)
-				ret = msdos_unlink (dentry->d_inode, demd);
-			if (!ret)
-				d_delete(demd);
-			dput(demd);
-		}
-	}
-	if (ret)
-		goto out;
-
-	/* now retry the original ... */
-	ret = msdos_rmdir (dir, dentry);
-
-out:
-	return ret;
-}
-
-/* #Specification: dual mode / introduction
- * One goal of UMSDOS is to allow a practical and simple coexistence
- * between MS-DOS and Linux in a single partition. Using the EMD file
- * in each directory, UMSDOS adds Unix semantics and capabilities to
- * a normal DOS filesystem. To help and simplify coexistence, here is
- * the logic related to the EMD file.
- * 
- * If it is missing, then the directory is managed by the MS-DOS driver.
- * The names are limited to DOS limits (8.3). No links, no device special
- * and pipe and so on.
- * 
- * If it is there, it is the directory. If it is there but empty, then
- * the directory looks empty. The utility umssync allows synchronisation
- * of the real DOS directory and the EMD.
- * 
- * Whenever umssync is applied to a directory without EMD, one is
- * created on the fly.  The directory is promoted to full Unix semantics.
- * Of course, the ls command will show exactly the same content as before
- * the umssync session.
- * 
- * It is believed that the user/admin will promote directories to Unix
- * semantics as needed.
- * 
- * The strategy to implement this is to use two function table (struct
- * inode_operations). One for true UMSDOS directory and one for directory
- * with missing EMD.
- * 
- * Functions related to the DOS semantic (but aware of UMSDOS) generally
- * have a "r" prefix (r for real) such as UMSDOS_rlookup, to differentiate
- * from the one with full UMSDOS semantics.
- */
-struct file_operations umsdos_rdir_operations =
-{
-	.read		= generic_read_dir,
-	.readdir	= UMSDOS_rreaddir,
-	.ioctl		= UMSDOS_ioctl_dir,
-};
-
-struct inode_operations umsdos_rdir_inode_operations =
-{
-	.create		= msdos_create,
-	.lookup		= UMSDOS_rlookup,
-	.unlink		= msdos_unlink,
-	.mkdir		= msdos_mkdir,
-	.rmdir		= UMSDOS_rrmdir,
-	.rename		= msdos_rename,
-	.setattr	= UMSDOS_notify_change,
-};
diff -puN fs/umsdos/README-WIP.txt~remove-umsdos-from-tree fs/umsdos/README-WIP.txt
--- 25/fs/umsdos/README-WIP.txt~remove-umsdos-from-tree	2005-01-10 21:13:45.203824328 -0800
+++ 25-akpm/fs/umsdos/README-WIP.txt	2005-01-10 21:13:45.239818856 -0800
@@ -1,114 +0,0 @@
-Changes by Matija Nalis (mnalis@jagor.srce.hr) on umsdos dentry fixing
-(started by Peter T. Waltenberg <peterw@karaka.chch.cri.nz>)
-(Final conversion to dentries Bill Hawes <whawes@star.net>)
-
-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.
-
-Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
-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/
-
-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.
-
-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 (010125) - UMSDOS 0.86j:
-
-(1) pure MSDOS (no --linux-.--- EMD file):
-
-READ:
-+ readdir			- works
-+ lookup			- works
-+ read file			- works
-
-WRITE:
-+ creat file			- works
-+ unlink file			- works
-+ write file			- works
-+ rename file (same dir)	- works
-+ rename file (dif. dir)	- works
-+ rename dir (same dir)		- works
-+ rename dir (dif. dir)		- works
-+ mkdir				- works
-+ rmdir 			- works
-
-
-(2) umsdos (with --linux-.--- EMD file):
-
-READ:
-+ readdir			- works
-+ lookup 			- works
-+ permissions/owners stuff	- works
-+ long file names		- works
-+ read file			- works
-+ switching MSDOS/UMSDOS	- works
-+ switching UMSDOS/MSDOS	- works
-- pseudo root things		- works mostly. See notes below.
-+ resolve symlink		- works
-+ dereference symlink		- works
-+ dangling symlink		- works
-+ hard links			- works
-+ special files (block/char devices, FIFOs, sockets...)	- works
-+ various umsdos ioctls		- works
-
-
-WRITE:
-+ create symlink		- works
-+ 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)	- works, but see notes below.
-+ rename symlink (same dir)	- works
-+ rename symlink (dif. dir)	- works
-+ rename dir (same dir)		- works
-+ rename dir (dif. dir)		- works
-+ unlink file			- works
-+ notify_change (chown,perms)	- works
-+ notify_change for hardlinks	- works
-+ unlink hardlink		- works
-+ mkdir				- works
-+ rmdir 			- works
-+ umssyncing (many ioctls)	- works
-
-
-- CVF-FAT stuff (compressed DOS filesystem) - there is some support from Frank
-  Gockel <gockel@sent13.uni-duisburg.de> to use it even under umsdosfs, but I
-  have no way of testing it -- please let me know if there are problems specific
-  to umsdos (for instance, it works under msdosfs, but not under umsdosfs).
-
-
-Some current notes:
-
-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 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.
-See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade
-procedure if you used broken versions...
-
-------------------------------------------------------------------------------
-
-Some general notes:
-
-Good idea when running development kernels is to have SysRq support compiled
-in kernel, and use Sync/Emergency-remount-RO if you bump into problems (like
-not being able to umount(2) umsdosfs, and because of it root partition also,
-or panics which force you to reboot etc.)
-
-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.
diff -puN fs/umsdos/specs~remove-umsdos-from-tree fs/umsdos/specs
--- 25/fs/umsdos/specs~remove-umsdos-from-tree	2005-01-10 21:13:45.205824024 -0800
+++ 25-akpm/fs/umsdos/specs	2005-01-10 21:13:45.241818552 -0800
@@ -1,289 +0,0 @@
-/* #Specification: umsdos / readdir
- * umsdos_readdir() should fill a struct dirent with
- * an inode number. The cheap way to get it is to
- * do a lookup in the MSDOS directory for each
- * entry processed by the readdir() function.
- * This is not very efficient, but very simple. The
- * other way around is to maintain a copy of the inode
- * number in the EMD file. This is a problem because
- * this has to be maintained in sync using tricks.
- * Remember that MSDOS (the OS) does not update the
- * modification time (mtime) of a directory. There is
- * no easy way to tell that a directory was modified
- * during a DOS session and synchronise the EMD file.
- */
-		/* #Specification: readdir / . and ..
-		 * The msdos filesystem manages the . and .. entry properly
-		 * so the EMD file won't hold any info about it.
-		 * 
-		 * In readdir, we assume that for the root directory
-		 * the read position will be 0 for ".", 1 for "..". For
-		 * a non root directory, the read position will be 0 for "."
-		 * and 32 for "..".
-		 */
-		/*
-		 * This is a trick used by the msdos file system (fs/msdos/dir.c)
-		 * to manage . and .. for the root directory of a file system.
-		 * Since there is no such entry in the root, fs/msdos/dir.c
-		 * use the following:
-		 * 
-		 * if f_pos == 0, return ".".
-		 * if f_pos == 1, return "..".
-		 * 
-		 * So let msdos handle it
-		 * 
-		 * Since umsdos entries are much larger, we share the same f_pos.
-		 * if f_pos is 0 or 1 or 32, we are clearly looking at . and
-		 * ..
-		 * 
-		 * As soon as we get f_pos == 2 or f_pos == 64, then back to
-		 * 0, but this time we are reading the EMD file.
-		 * 
-		 * Well, not so true. The problem, is that UMSDOS_REC_SIZE is
-		 * also 64, so as soon as we read the first record in the
-		 * EMD, we are back at offset 64. So we set the offset
-		 * to UMSDOS_SPECIAL_DIRFPOS(3) as soon as we have read the
-		 * .. entry from msdos.
-		 * 
-		 * Now (linux 1.3), umsdos_readdir can read more than one
-		 * entry even if we limit (umsdos_dir_once) to only one:
-		 * It skips over hidden file. So we switch to
-		 * UMSDOS_SPECIAL_DIRFPOS as soon as we have read successfully
-		 * the .. entry.
-		 */
-			/* #Specification: umsdos / lookup / inode info
-			 * After successfully reading an inode from the MSDOS
-			 * filesystem, we use the EMD file to complete it.
-			 * We update the following field.
-			 * 
-			 * uid, gid, atime, ctime, mtime, mode.
-			 * 
-			 * We rely on MSDOS for mtime. If the file
-			 * was modified during an MSDOS session, at least
-			 * mtime will be meaningful. We do this only for regular
-			 * file.
-			 * 
-			 * We don't rely on MS-DOS for mtime for directories
-			 * because the MS-DOS date on a directory is its
-			 * creation time (strange MSDOS behavior) which
-			 * corresponds to none of the three Unix time stamps.
-			 */
-	/* #Specification: umsdos / conversion mode
-	 * The msdos filesystem can do some inline conversion
-	 * of the data of a file.  It can translate silently
-	 * from the MS-DOS text file format to the Unix one
-	 * (CRLF -> LF) while reading, and the reverse
-	 * while writing. This is activated using the mount
-	 * option conv=....
-	 * 
-	 * This is not useful for Linux files in a promoted
-	 * directory.  It can even be harmful.  For this
-	 * reason, the binary (no conversion) mode is
-	 * always activated.
-	 */
-	/* #Specification: umsdos / conversion mode / todo
-	 * A flag could be added to file and directories
-	 * forcing an automatic conversion mode (as
-	 * done with the msdos filesystem).
-	 * 
-	 * This flag could be setup on a directory basis
-	 * (instead of file) and all files in it would
-	 * logically inherit it.  If the conversion mode
-	 * is active (conv=) then the i_binary flag would
-	 * be left untouched in those directories.
-	 * 
-	 * It was proposed that the sticky bit be used to set
-	 * this.  A problem with that is that new files would
-	 * be written incorrectly.  The other problem is that
-	 * the sticky bit has a meaning for directories. So
-	 * another bit should be used (there is some space
-	 * in the EMD file for it) and a special utility
-	 * would be used to assign the flag to a directory).
-	 * I don't think it is useful to assign this flag
-	 * on a single file.
-	 */
- * #Specification: weakness / rename
- * There is a case where UMSDOS rename has a different behavior
- * than a normal Unix file system.  Renaming an open file across
- * directory boundary does not work.  Renaming an open file within
- * a directory does work, however.
- * 
- * The problem may is in Linux VFS driver for msdos.
- * I believe this is not a bug but a design feature, because
- * an inode number represents some sort of directory address
- * in the MSDOS directory structure, so moving the file into
- * another directory does not preserve the inode number.
- */
-/* #Specification: rename / new name exist
- * If the destination name already exists, it will
- * silently be removed.  EXT2 does it this way
- * and this is the spec of SunOS.  So does UMSDOS.
- * 
- * If the destination is an empty directory it will
- * also be removed.
- */
-/* #Specification: rename / new name exist / possible flaw
- * The code to handle the deletion of the target (file
- * and directory) use to be in umsdos_rename_f, surrounded
- * by proper directory locking.  This was ensuring that only
- * one process could achieve a rename (modification) operation
- * in the source and destination directory.  This was also
- * ensuring the operation was "atomic".
- * 
- * This has been changed because this was creating a
- * stack overflow (the stack is only 4 kB) in the kernel.  To avoid
- * the code doing the deletion of the target (if exist) has
- * been moved to a upper layer. umsdos_rename_f is tried
- * once and if it fails with EEXIST, the target is removed
- * and umsdos_rename_f is done again.
- * 
- * This makes the code cleaner and may solve a
- * deadlock problem one tester was experiencing.
- * 
- * The point is to mention that possibly, the semantic of
- * "rename" may be wrong. Anyone dare to check that :-)
- * Be aware that IF it is wrong, to produce the problem you
- * will need two process trying to rename a file to the
- * same target at the same time. Again, I am not sure it
- * is a problem at all.
- */
-
-/* #Specification: hard link / strategy
- * Hard links are difficult to implement on top of an MS-DOS FAT file
- * system. Unlike Unix file systems, there are no inodes. A directory
- * entry holds the functionality of the inode and the entry.
- * 
- * We will used the same strategy as a normal Unix file system
- * (with inodes) except we will do it symbolically (using paths).
- * 
- * Because anything can happen during a DOS session (defragment,
- * directory sorting, etc.), we can't rely on an MS-DOS pseudo
- * inode number to record the link. For this reason, the link
- * will be done using hidden symbolic links. The following
- * scenario illustrates how it works.
- * 
- * Given a file /foo/file
- * 
- * #
- * ln /foo/file /tmp/file2
- * 
- * become internally
- * 
- * mv /foo/file /foo/-LINK1
- * ln -s /foo/-LINK1 /foo/file
- * ln -s /foo/-LINK1 /tmp/file2
- * #
- * 
- * Using this strategy, we can operate on /foo/file or /foo/file2.
- * We can remove one and keep the other, like a normal Unix hard link.
- * We can rename /foo/file or /tmp/file2 independently.
- * 
- * The entry -LINK1 will be hidden. It will hold a link count.
- * When all link are erased, the hidden file is erased too.
- */
-
-/* #Specification: weakness / hard link
- * The strategy for hard link introduces a side effect that
- * may or may not be acceptable. Here is the sequence
- * 
- * #
- * mkdir subdir1
- * touch subdir1/file
- * mkdir subdir2
- * ln    subdir1/file subdir2/file
- * rm    subdir1/file
- * rmdir subdir1
- * rmdir: subdir1: Directory not empty
- * #
- * 
- * This happen because there is an invisible file (--link) in
- * subdir1 which is referenced by subdir2/file.
- * 
- * Any idea ?
- */
-/* #Specification: weakness / hard link / rename directory
- * Another weakness of hard link come from the fact that
- * it is based on hidden symbolic links. Here is an example.
- * 
- * #
- * mkdir /subdir1
- * touch /subdir1/file
- * mkdir /subdir2
- * ln    /subdir1/file subdir2/file
- * mv    /subdir1 subdir3
- * ls -l /subdir2/file
- * #
- * 
- * Since /subdir2/file is a hidden symbolic link
- * to /subdir1/..hlinkNNN, accessing it will fail since
- * /subdir1 does not exist anymore (has been renamed).
- */
-/* #Specification: hard link / directory
- * A hard link can't be made on a directory. EPERM is returned
- * in this case.
- */
-/* #Specification: hard link / first hard link
- * The first time a hard link is done on a file, this
- * file must be renamed and hidden. Then an internal
- * symbolic link must be done on the hidden file.
- * 
- * The second link is done after on this hidden file.
- * 
- * It is expected that the Linux MSDOS file system
- * keeps the same pseudo inode when a rename operation
- * is done on a file in the same directory.
- */
-/* #Specification: function name / convention
- * A simple convention for function names has been used in
- * the UMSDOS filesystem. First, all functions use the prefix
- * umsdos_ to avoid name clashes with other parts of the kernel.
- * 
- * Standard VFS entry points use the prefix UMSDOS (upper case)
- * so it's easier to tell them apart.
- * N.B. (FIXME) PTW, the order and contents of this struct changed.
- */
-
-/* #Specification: mount / options
- * Umsdos run on top of msdos. Currently, it supports no
- * mount option, but happily pass all option received to
- * the msdos driver. I am not sure if all msdos mount option
- * make sense with Umsdos. Here are at least those who
- * are useful.
- * uid=
- * gid=
- * 
- * These options affect the operation of umsdos in directories
- * which do not have an EMD file. They behave like normal
- * msdos directory, with all limitation of msdos.
- */
-
-/* #Specification: pseudo root / mount
- * When a umsdos fs is mounted, a special handling is done
- * if it is the root partition. We check for the presence
- * of the file /linux/etc/init or /linux/etc/rc or
- * /linux/sbin/init. If one is there, we do a chroot("/linux").
- * 
- * We check both because (see init/main.c) the kernel
- * try to exec init at different place and if it fails
- * it tries /bin/sh /etc/rc. To be consistent with
- * init/main.c, many more test would have to be done
- * to locate init. Any complain ?
- * 
- * The chroot is done manually in init/main.c but the
- * info (the inode) is located at mount time and store
- * in a global variable (pseudo_root) which is used at
- * different place in the umsdos driver. There is no
- * need to store this variable elsewhere because it
- * will always be one, not one per mount.
- * 
- * This feature allows the installation
- * of a linux system within a DOS system in a subdirectory.
- * 
- * A user may install its linux stuff in c:\linux
- * avoiding any clash with existing DOS file and subdirectory.
- * When linux boots, it hides this fact, showing a normal
- * root directory with /etc /bin /tmp ...
- * 
- * The word "linux" is hardcoded in /usr/include/linux/umsdos_fs.h
- * in the macro UMSDOS_PSDROOT_NAME.
- */
diff -L include/linux/umsdos_fs.h -puN include/linux/umsdos_fs.h~remove-umsdos-from-tree /dev/null
--- 25/include/linux/umsdos_fs.h
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,182 +0,0 @@
-#ifndef LINUX_UMSDOS_FS_H
-#define LINUX_UMSDOS_FS_H
-
-
-/*#define UMS_DEBUG 1	// define for check_* functions */
-/*#define UMSDOS_DEBUG 1*/
-#define UMSDOS_PARANOIA 1
-
-#define UMSDOS_VERSION	0
-#define UMSDOS_RELEASE	4
-
-#define UMSDOS_ROOT_INO 1
-
-/* This is the file acting as a directory extension */
-#define UMSDOS_EMD_FILE		"--linux-.---"
-#define UMSDOS_EMD_NAMELEN	12
-#define UMSDOS_PSDROOT_NAME	"linux"
-#define UMSDOS_PSDROOT_LEN	5
-
-#ifndef _LINUX_TYPES_H
-#include <linux/types.h>
-#endif
-#ifndef _LINUX_LIMITS_H
-#include <linux/limits.h>
-#endif
-#ifndef _LINUX_DIRENT_H
-#include <linux/dirent.h>
-#endif
-#ifndef _LINUX_IOCTL_H
-#include <linux/ioctl.h>
-#endif
-
-
-#ifdef __KERNEL__
-/* #Specification: convention / PRINTK Printk and printk
- * Here is the convention for the use of printk inside fs/umsdos
- * 
- * printk carry important message (error or status).
- * Printk is for debugging (it is a macro defined at the beginning of
- * most source.
- * PRINTK is a nulled Printk macro.
- * 
- * This convention makes the source easier to read, and Printk easier
- * to shut off.
- */
-#	define PRINTK(x)
-#	ifdef UMSDOS_DEBUG
-#		define Printk(x) printk x
-#	else
-#		define Printk(x)
-#	endif
-#endif	/* __KERNEL__ */
-
-
-struct umsdos_fake_info {
-	char fname[13];
-	int len;
-};
-
-#define UMSDOS_MAXNAME	220
-/* This structure is 256 bytes large, depending on the name, only part */
-/* of it is written to disk */
-/* nice though it would be, I can't change this and preserve backward compatibility */
-struct umsdos_dirent {
-	unsigned char name_len;	/* if == 0, then this entry is not used */
-	unsigned char flags;	/* UMSDOS_xxxx */
-	unsigned short nlink;	/* How many hard links point to this entry */
-	__kernel_uid_t uid;	/* Owner user id */
-	__kernel_gid_t gid;	/* Group id */
-	time_t atime;		/* Access time */
-	time_t mtime;		/* Last modification time */
-	time_t ctime;		/* Creation time */
-	unsigned short rdev;	/* major and minor of a device special file */
-	umode_t mode;		/* Standard UNIX permissions bits + type of */
-	char spare[12];		/* unused bytes for future extensions */
-				/* file, see linux/stat.h */
-	char name[UMSDOS_MAXNAME];	/* Not '\0' terminated */
-				/* but '\0' padded, so it will allow */
-				/* for adding news fields in this record */
-				/* by reducing the size of name[] */
-};
-
-#define UMSDOS_HIDDEN	1	/* Never show this entry in directory search */
-#define UMSDOS_HLINK	2	/* It is a (pseudo) hard link */
-
-/* #Specification: EMD file / record size
- * Entry are 64 bytes wide in the EMD file. It allows for a 30 characters
- * name. If a name is longer, contiguous entries are allocated. So a
- * umsdos_dirent may span multiple records.
- */
- 
-#define UMSDOS_REC_SIZE		64
-
-/* Translation between MSDOS name and UMSDOS name */
-
-struct umsdos_info {
-	int msdos_reject;	/* Tell if the file name is invalid for MSDOS */
-				/* See umsdos_parse */
-	struct umsdos_fake_info fake;
-	struct umsdos_dirent entry;
-	off_t f_pos;		/* offset of the entry in the EMD file
-				 * or offset where the entry may be store
-				 * if it is a new entry
-				 */
-	int recsize;		/* Record size needed to store entry */
-};
-
-/* Definitions for ioctl (number randomly chosen)
- * The next ioctl commands operate only on the DOS directory
- * The file umsdos_progs/umsdosio.c contain a string table
- * based on the order of those definition. Keep it in sync
- */
-#define UMSDOS_READDIR_DOS _IO(0x04,210)	/* Do a readdir of the DOS directory */
-#define UMSDOS_UNLINK_DOS  _IO(0x04,211)	/* Erase in the DOS directory only */
-#define UMSDOS_RMDIR_DOS   _IO(0x04,212)	/* rmdir in the DOS directory only */
-#define UMSDOS_STAT_DOS    _IO(0x04,213)	/* Get info about a file */
-
-/* The next ioctl commands operate only on the EMD file */
-#define UMSDOS_CREAT_EMD   _IO(0x04,214)	/* Create a file */
-#define UMSDOS_UNLINK_EMD  _IO(0x04,215)	/* unlink (rmdir) a file */
-#define UMSDOS_READDIR_EMD _IO(0x04,216)	/* read the EMD file only. */
-#define UMSDOS_GETVERSION  _IO(0x04,217)	/* Get the release number of UMSDOS */
-#define UMSDOS_INIT_EMD    _IO(0x04,218)	/* Create the EMD file if not there */
-#define UMSDOS_DOS_SETUP   _IO(0x04,219)	/* Set the defaults of the MS-DOS driver. */
-
-#define UMSDOS_RENAME_DOS  _IO(0x04,220)	/* rename a file/directory in the DOS
-						 * directory only */
-struct umsdos_ioctl {
-	struct dirent dos_dirent;
-	struct umsdos_dirent umsdos_dirent;
-	/* The following structure is used to exchange some data with
-	 * utilities (umsdos_progs/util/umsdosio.c). The first releases
-	 * were using struct stat from "sys/stat.h". This was causing
-	 * some problem for cross compilation of the kernel.
-	 * Since I am not really using the structure stat, but only
-	 * some fields of it, I have decided to replicate the structure
-	 * here for compatibility with the binaries out there.
-	 * FIXME PTW 1998, this has probably changed
-	 */
-	
-	struct {
-		unsigned long st_dev;
-		ino_t st_ino;			/* used */
-		umode_t st_mode;		/* used */
-		nlink_t st_nlink;
-		__kernel_uid_t st_uid;
-		__kernel_gid_t st_gid;
-		unsigned long st_rdev;
-		off_t st_size;			/* used */
-		unsigned long st_blksize;
-		unsigned long st_blocks;
-		time_t st_atime;		/* used */
-		unsigned long __unused1;
-		time_t st_mtime;		/* used */
-		unsigned long __unused2;
-		time_t st_ctime;		/* used */
-		unsigned long __unused3;
-		uid_t st_uid32;
-		gid_t st_gid32;
-	} stat;
-	char version, release;
-};
-
-/* Different macros to access struct umsdos_dirent */
-#define EDM_ENTRY_ISUSED(e) ((e)->name_len!=0)
-
-#ifdef __KERNEL__
-
-#ifndef LINUX_FS_H
-#include <linux/fs.h>
-#endif
-
-extern struct inode_operations umsdos_dir_inode_operations;
-extern struct inode_operations umsdos_rdir_inode_operations;
-extern struct file_operations umsdos_dir_operations;
-extern struct file_operations umsdos_rdir_operations;
-
-#include <linux/umsdos_fs.p>
-
-#endif				/* __KERNEL__ */
-
-#endif
diff -L include/linux/umsdos_fs_i.h -puN include/linux/umsdos_fs_i.h~remove-umsdos-from-tree /dev/null
--- 25/include/linux/umsdos_fs_i.h
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,58 +0,0 @@
-#ifndef UMSDOS_FS_I_H
-#define UMSDOS_FS_I_H
-
-#ifndef _LINUX_TYPES_H
-#include <linux/types.h>
-#endif
-
-#include <linux/msdos_fs_i.h>
-#include <linux/pipe_fs_i.h>
-
-/* #Specification: strategy / in memory inode
- * Here is the information specific to the inode of the UMSDOS file
- * system. This information is added to the end of the standard struct
- * inode. Each file system has its own extension to struct inode,
- * so do the umsdos file system.
- * 
- * The strategy is to have the umsdos_inode_info as a superset of
- * the msdos_inode_info, since most of the time the job is done
- * by the msdos fs code.
- * 
- * So we duplicate the msdos_inode_info, and add our own info at the
- * end.
- * 
- * The offset in this EMD file of the entry: pos
- * 
- * For directory, we have dir_locking_info to help synchronise
- * file creation and file lookup. See also msdos_fs_i.h for more 
- * information about msdos_inode_info.
- * 
- * Special file and fifo do have an inode which correspond to an
- * empty MSDOS file.
- * 
- * symlink are processed mostly like regular file. The content is the
- * link.
- * 
- * The UMSDOS specific extension is placed after the union.
- */
-
-struct dir_locking_info {
-	wait_queue_head_t p;
-	short int looking;	/* How many process doing a lookup */
-	short int creating;	/* Is there any creation going on here
-				 *  Only one at a time, although one
-				 *  may recursively lock, so it is a counter
-				 */
-	long pid;		/* pid of the process owning the creation
-				 * lock */
-};
-
-struct umsdos_inode_info {
-	struct msdos_inode_info msdos_info;
-	struct dir_locking_info dir_info;
-	int i_patched;		/* Inode has been patched */
-	int i_is_hlink;		/* Resolved hardlink inode? */
-	off_t pos;		/* Entry offset in the emd_owner file */
-};
-
-#endif
diff -L include/linux/umsdos_fs.p -puN include/linux/umsdos_fs.p~remove-umsdos-from-tree /dev/null
--- 25/include/linux/umsdos_fs.p
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,100 +0,0 @@
-/* check.c 23/01/95 03.38.30 */
-void check_page_tables (void);
-
-/* dir.c 22/06/95 00.22.12 */
-int  dummy_dir_read ( struct file *filp,
-	 char *buf,
-	 size_t size,
-	 loff_t *count);
-char * umsdos_d_path(struct dentry *, char *, int);
-void umsdos_lookup_patch_new(struct dentry *, struct umsdos_info *);
-int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry);
-struct dentry *umsdos_lookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo);
-struct dentry *UMSDOS_lookup(struct inode *, struct dentry *, struct nameidata *);
-struct dentry *umsdos_lookup_dentry(struct dentry *, char *, int, int);
-struct dentry *umsdos_covered(struct dentry *, char *, int);
-
-struct dentry *umsdos_solve_hlink (struct dentry *hlink);
-
-/* emd.c 22/06/95 00.22.04 */
-struct dentry *umsdos_get_emd_dentry(struct dentry *);
-int umsdos_have_emd(struct dentry *);
-int umsdos_make_emd(struct dentry *);
-int umsdos_emd_dir_readentry (struct dentry *, loff_t *, struct umsdos_dirent *);
-int umsdos_newentry (struct dentry *, struct umsdos_info *);
-int umsdos_newhidden (struct dentry *, struct umsdos_info *);
-int umsdos_delentry (struct dentry *, struct umsdos_info *, int);
-int umsdos_findentry (struct dentry *, struct umsdos_info *, int);
-int umsdos_isempty (struct dentry *);
-int umsdos_writeentry (struct dentry *, struct umsdos_info *, int);
-
-/* file.c 25/01/95 02.25.38 */
-
-/* inode.c 12/06/95 09.49.40 */
-void fill_new_filp (struct file *filp, struct dentry *dentry);
-void UMSDOS_read_inode (struct inode *);
-void UMSDOS_write_inode (struct inode *, int);
-int UMSDOS_notify_change (struct dentry *, struct iattr *attr);
-int umsdos_notify_change_locked(struct dentry *, struct iattr *attr);
-void UMSDOS_put_inode (struct inode *);
-int UMSDOS_statfs (struct super_block *, struct statfs *);
-struct super_block *UMSDOS_read_super (struct super_block *, void *, int);
-void UMSDOS_put_super (struct super_block *);
-
-void umsdos_setup_dir(struct dentry *);
-void umsdos_set_dirinfo_new(struct dentry *, off_t);
-void umsdos_patch_dentry_inode (struct dentry *, off_t);
-int umsdos_get_dirowner (struct inode *inode, struct inode **result);
-
-/* ioctl.c 22/06/95 00.22.08 */
-int UMSDOS_ioctl_dir (struct inode *dir,
-	 struct file *filp,
-	 unsigned int cmd,
-	 unsigned long data);
-
-/* mangle.c 25/01/95 02.25.38 */
-void umsdos_manglename (struct umsdos_info *info);
-int umsdos_evalrecsize (int len);
-int umsdos_parse (const char *name,int len, struct umsdos_info *info);
-
-/* namei.c 25/01/95 02.25.38 */
-void umsdos_lockcreate (struct inode *dir);
-void umsdos_startlookup (struct inode *dir);
-void umsdos_unlockcreate (struct inode *dir);
-void umsdos_endlookup (struct inode *dir);
-
-int umsdos_readlink_x (	     struct dentry *dentry,
-			     char *buffer,
-			     int bufsiz);
-int UMSDOS_symlink (struct inode *dir,
-		    struct dentry *dentry,
-		    const char *symname);
-int UMSDOS_link (struct dentry *olddentry,
-		 struct inode *dir,
-		 struct dentry *dentry);
-int UMSDOS_create (struct inode *dir,
-		   struct dentry *dentry,
-		   int mode);
-
-int UMSDOS_mkdir (struct inode *dir,
-		  struct dentry *dentry,
-		  int mode);
-int UMSDOS_mknod (struct inode *dir,
-		  struct dentry *dentry,
-		  int mode,
-		  dev_t rdev);
-int UMSDOS_rmdir (struct inode *dir,struct dentry *dentry);
-int UMSDOS_unlink (struct inode *dir, struct dentry *dentry);
-int UMSDOS_rename (struct inode *old_dir,
-		   struct dentry *old_dentry,
-		   struct inode *new_dir,
-		   struct dentry *new_dentry);
-
-/* rdir.c 22/03/95 03.31.42 */
-struct dentry *umsdos_rlookup_x (struct inode *dir, struct dentry *dentry, int nopseudo);
-struct dentry *UMSDOS_rlookup (struct inode *dir, struct dentry *dentry, struct nameidata *nd);
-
-static inline struct umsdos_inode_info *UMSDOS_I(struct inode *inode)
-{
-	return &inode->u.umsdos_i;
-}
diff -puN fs/Makefile~remove-umsdos-from-tree fs/Makefile
--- 25/fs/Makefile~remove-umsdos-from-tree	2005-01-10 21:13:45.210823264 -0800
+++ 25-akpm/fs/Makefile	2005-01-10 21:13:45.243818248 -0800
@@ -57,7 +57,6 @@ obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
 obj-$(CONFIG_CODA_FS)		+= coda/
 obj-$(CONFIG_MINIX_FS)		+= minix/
 obj-$(CONFIG_FAT_FS)		+= fat/
-obj-$(CONFIG_UMSDOS_FS)		+= umsdos/
 obj-$(CONFIG_MSDOS_FS)		+= msdos/
 obj-$(CONFIG_VFAT_FS)		+= vfat/
 obj-$(CONFIG_BFS_FS)		+= bfs/
diff -puN MAINTAINERS~remove-umsdos-from-tree MAINTAINERS
--- 25/MAINTAINERS~remove-umsdos-from-tree	2005-01-10 21:13:45.211823112 -0800
+++ 25-akpm/MAINTAINERS	2005-01-10 21:13:45.245817944 -0800
@@ -2244,13 +2244,6 @@ L:	linux_udf@hpesjro.fc.hp.com
 W:	http://linux-udf.sourceforge.net
 S:	Maintained
 
-UMSDOS FILESYSTEM
-P:	Matija Nalis
-M:	Matija Nalis <mnalis-umsdos@voyager.hr>
-L:	linux-kernel@vger.kernel.org
-W:	http://linux.voyager.hr/umsdos/
-S:	Maintained
-
 UNIFORM CDROM DRIVER
 P:	Jens Axboe
 M:	axboe@suse.de
_
