patch-2.1.87 linux/fs/umsdos/rdir.c

Next file: linux/fs/umsdos/symlink.c
Previous file: linux/fs/umsdos/namei.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.86/linux/fs/umsdos/rdir.c linux/fs/umsdos/rdir.c
@@ -32,240 +32,270 @@
 
 static int rdir_filldir(
 	void * buf,
-	const char * name,
+	const char *name,
 	int name_len,
 	off_t offset,
 	ino_t ino)
 {
-	int ret = 0;
-	struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR*) buf;
-	if (d->real_root){
-		/* 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] == '.'){
+  int ret = 0;
+  struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR*) buf;
+  Printk ((KERN_DEBUG "rdir_filldir /mn/: entering\n"));
+  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);
-		}
-	}else{
-		/* Any DOS directory */
-		ret = d->filldir (d->dirbuf,name,name_len,offset,ino);
-	}
-	return ret;
+	ino = pseudo_root->i_ino;
+      }
+      ret = d->filldir (d->dirbuf,name,name_len,offset,ino);
+    }
+  }else{
+    /* Any DOS directory */
+    Printk ((KERN_DEBUG "rdir_filldir /mn/: calling d->filldir (%p) for %12s (%d)\n",d->filldir,name,ino));
+    ret = d->filldir (d->dirbuf,name,name_len,offset,ino);
+  }
+  return ret;
 }
 
 
 static int UMSDOS_rreaddir (
-	struct inode *dir,
 	struct file *filp,
-    void *dirbuf,
+	void *dirbuf,
 	filldir_t filldir)
 {
-	struct RDIR_FILLDIR bufk;
-	bufk.filldir = filldir;
-	bufk.dirbuf = dirbuf;
-	bufk.real_root = pseudo_root != NULL
-		&& dir == dir->i_sb->s_mounted
-		&& dir == pseudo_root->i_sb->s_mounted;
-	return fat_readdir(dir,filp,&bufk,rdir_filldir);
+  struct RDIR_FILLDIR bufk;
+  struct inode *dir = filp->f_dentry->d_inode;
+  
+  Printk ((KERN_DEBUG "UMSDOS_rreaddir /mn/: entering %p %p\n", filldir, dirbuf));
+
+  
+  bufk.filldir = filldir;
+  bufk.dirbuf = dirbuf;
+  bufk.real_root = pseudo_root
+    && dir == iget(dir->i_sb,UMSDOS_ROOT_INO)
+    && dir == iget(pseudo_root->i_sb,UMSDOS_ROOT_INO);
+  Printk ((KERN_DEBUG "UMSDOS_rreaddir /mn/: calling fat_readdir with filldir=%p and exiting\n",filldir));
+  return fat_readdir(filp, &bufk, rdir_filldir);
 }
 
+
 /*
-	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)).
+  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)).
 */
 int umsdos_rlookup_x(
-	struct inode *dir,
-	const char *name,
-	int len,
-	struct inode **result,	/* Will hold inode of the file, if successful */
-	int nopseudo)			/* Don't care about pseudo root mode */
-							/* so locating "linux" will work */
+   struct inode *dir,
+   struct dentry *dentry,
+   int nopseudo)   /* Don't care about pseudo root mode */
+     /* so locating "linux" will work */
 {
-	int ret;
-	if (pseudo_root != NULL
-		&& len == 2
-		&& name[0] == '.'
-		&& name[1] == '.'
-		&& dir == dir->i_sb->s_mounted
-		&& dir == pseudo_root->i_sb->s_mounted){
-		*result = pseudo_root;
-		atomic_inc(&pseudo_root->i_count);
-		ret = 0;
-		/* #Specification: pseudo root / DOS/..
-			In the real root directory (c:\), the directory ..
-			is the pseudo root (c:\linux).
-		*/
-	}else{
-		ret = umsdos_real_lookup (dir,name,len,result);
-		if (ret == 0){
-			struct inode *inode = *result;
-			if (inode == pseudo_root && !nopseudo){
-				/* #Specification: pseudo root / DOS/linux
-					Even in the real root directory (c:\), the directory
-					/linux won't show
-				*/
-				ret = -ENOENT;
-				iput (pseudo_root);
-				*result = NULL;
-			}else if (S_ISDIR(inode->i_mode)){
-				/* We must place the proper function table */
-				/* depending if this is a MsDOS directory or an UMSDOS directory */
-				umsdos_setup_dir_inode(inode);
-			}
-		}
-	}
-	iput (dir);
-	return ret;
+  int len = dentry->d_name.len;
+  const char *name = dentry->d_name.name;
+  struct inode *inode;
+  int ret;
+  if (pseudo_root
+      && len == 2
+      && name[0] == '.'
+      && name[1] == '.'
+      && dir == iget(dir->i_sb,UMSDOS_ROOT_INO)
+      && dir == iget(pseudo_root->i_sb,UMSDOS_ROOT_INO) ){
+    /*    *result = pseudo_root;*/
+    Printk (("umsdos_rlookup_x: we are at pseudo-root thingy?\n"));
+    pseudo_root->i_count++;
+    ret = 0;
+    /* #Specification: pseudo root / DOS/..
+       In the real root directory (c:\), the directory ..
+       is the pseudo root (c:\linux).
+    */
+  }else{
+    ret = umsdos_real_lookup (dir, dentry); inode=dentry->d_inode;
+    Printk ((KERN_DEBUG "umsdos_rlookup_x: umsdos_real_lookup for %s in %d returned %d\n", name, dir->i_ino, ret));
+    Printk ((KERN_DEBUG "umsdos_rlookup_x: umsdos_real_lookup: inode is %p resolving to ", inode));
+    if (inode) {	/* /mn/ FIXME: DEL_ME */
+        Printk ((KERN_DEBUG "i_ino=%d\n",inode->i_ino));
+    } else {
+        Printk ((KERN_DEBUG "NONE!\n"));
+    }
+    if ((ret == 0) && inode){
+      
+      if (pseudo_root && inode == pseudo_root && !nopseudo){
+      /* #Specification: pseudo root / DOS/linux
+	 Even in the real root directory (c:\), the directory
+	 /linux won't show
+      */
+        Printk (("umsdos_rlookup_x: do the pseudo-thingy...\n"));
+	ret = -ENOENT;
+	iput (pseudo_root);
+       
+      }else if (S_ISDIR(inode->i_mode)){
+	/* We must place the proper function table */
+	/* depending if this is a MsDOS directory or an UMSDOS directory */
+        Printk (("umsdos_rlookup_x: setting up setup_dir_inode %d...\n", inode->i_ino));
+	umsdos_setup_dir_inode (inode);
+      }
+    }
+  }
+  iput (dir);
+  Printk ((KERN_DEBUG "umsdos_rlookup_x: returning %d\n", ret));
+  return ret;
 }
+
+
 int UMSDOS_rlookup(
 	struct inode *dir,
-	const char *name,
-	int len,
-	struct inode **result)	/* Will hold inode of the file, if successful */
+	struct dentry *dentry
+	)
 {
-	return umsdos_rlookup_x(dir,name,len,result,0);
+  Printk ((KERN_DEBUG "UMSDOS_rlookup /mn/: executing umsdos_rlookup_x for ino=%d in %20s\n",dir->i_ino,dentry->d_name.name));
+  return umsdos_rlookup_x(dir,dentry,0);
 }
 
+
 static int UMSDOS_rrmdir (
 	struct inode *dir,
-	const char *name,
-	int len)
+	struct dentry *dentry)
 {
-	/* #Specification: dual mode / rmdir in a DOS directory
-		In a DOS (not EMD in it) directory, we use a reverse strategy
-		compared with an 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 make 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 subdirectory are also
-		Umsdos directory, so we check the EMD file first.
-	*/
-	int ret;
-	if (umsdos_is_pseudodos(dir,name,len)){
-		/* #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
-			MsDOS) is always possible.
-
-			EPERM is returned.
-		*/
-		ret = -EPERM;
+  /* #Specification: dual mode / rmdir in a DOS directory
+     In a DOS (not EMD in it) directory, we use a reverse strategy
+     compared with an 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 make 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 subdirectory are also
+     Umsdos directory, so we check the EMD file first.
+  */
+  int ret;
+  if (umsdos_is_pseudodos(dir,dentry)){
+    /* #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
+       MsDOS) is always possible.
+       
+       EPERM is returned.
+    */
+    ret = -EPERM;
+  }else{
+    umsdos_lockcreate (dir);
+    dir->i_count++;
+    ret = msdos_rmdir (dir,dentry);
+    if (ret == -ENOTEMPTY){
+      struct inode *sdir;
+      dir->i_count++;
+      
+      ret = UMSDOS_rlookup (dir,dentry);
+      sdir = dentry->d_inode;
+      PRINTK (("rrmdir lookup %d ",ret));
+      if (ret == 0){
+	int empty;
+	if ((empty = umsdos_isempty (sdir)) != 0){
+	  PRINTK (("isempty %d i_count %d ",empty,
+		   atomic_read(&sdir->i_count)));
+	  if (empty == 2){
+	    /*
+	      Not a Umsdos directory, so the previous msdos_rmdir
+	      was not lying :-)
+	    */
+	    ret = -ENOTEMPTY;
+	  }else if (empty == 1){
+	    /* We have to removed the EMD file */
+	    struct dentry *temp;
+	    temp = creat_dentry (UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN, NULL);
+	    ret = msdos_unlink(sdir, temp);
+	    sdir = NULL;
+	    if (ret == 0){
+	      dir->i_count++;
+	      ret = msdos_rmdir (dir,dentry);
+	    }
+	  }
 	}else{
-		umsdos_lockcreate (dir);
-		atomic_inc(&dir->i_count);
-		ret = msdos_rmdir (dir,name,len);
-		if (ret == -ENOTEMPTY){
-			struct inode *sdir;
-			atomic_inc(&dir->i_count);
-			ret = UMSDOS_rlookup (dir,name,len,&sdir);
-			PRINTK (("rrmdir lookup %d ",ret));
-			if (ret == 0){
-				int empty;
-				if ((empty = umsdos_isempty (sdir)) != 0){
-					PRINTK (("isempty %d i_count %d ",empty,
-						 atomic_read(&sdir->i_count)));
-					if (empty == 2){
-						/*
-							Not a Umsdos directory, so the previous msdos_rmdir
-							was not lying :-)
-						*/
-						ret = -ENOTEMPTY;
-					}else if (empty == 1){
-						/* We have to removed the EMD file */
-						ret = msdos_unlink(sdir,UMSDOS_EMD_FILE
-							,UMSDOS_EMD_NAMELEN);
-						sdir = NULL;
-						if (ret == 0){
-							atomic_inc(&dir->i_count);
-							ret = msdos_rmdir (dir,name,len);
-						}
-					}
-				}else{
-					ret = -ENOTEMPTY;
-				}
-				iput (sdir);
-			}
-		}
-		umsdos_unlockcreate (dir);
+	  ret = -ENOTEMPTY;
 	}
-	iput (dir);
-	return ret;
+	iput (sdir);
+      }
+    }
+    umsdos_unlockcreate (dir);
+  }
+  iput (dir);
+  return ret;
 }
 
 /* #Specification: dual mode / introduction
-	One goal of UMSDOS is to allow a practical and simple coexistence
-	between MsDOS and Linux in a single partition. Using the EMD file
-	in each directory, UMSDOS add Unix semantics and capabilities to
-	normal DOS file system. 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 MsDOS 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 semantic.
-	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
-	semantic 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 semantic.
+   One goal of UMSDOS is to allow a practical and simple coexistence
+   between MsDOS and Linux in a single partition. Using the EMD file
+   in each directory, UMSDOS add Unix semantics and capabilities to
+   normal DOS file system. 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 MsDOS 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 semantic.
+   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
+   semantic 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 semantic.
 */
 static struct file_operations umsdos_rdir_operations = {
-	NULL,				/* lseek - default */
-	UMSDOS_dir_read,	/* read */
-	NULL,				/* write - bad */
-	UMSDOS_rreaddir,	/* readdir */
-	NULL,				/* poll - default */
-	UMSDOS_ioctl_dir,	/* ioctl - default */
-	NULL,				/* mmap */
-	NULL,				/* no special open code */
-	NULL,				/* no special release code */
-	NULL				/* fsync */
+  NULL,				/* lseek - default */
+  UMSDOS_dir_read,		/* read */
+  NULL,				/* write - bad */
+  UMSDOS_rreaddir,		/* readdir */
+  NULL,				/* poll - default */
+  UMSDOS_ioctl_dir,		/* ioctl - default */
+  NULL,				/* mmap */
+  NULL,				/* no special open code */
+  NULL,				/* no special release code */
+  NULL				/* fsync */
 };
 
 struct inode_operations umsdos_rdir_inode_operations = {
-	&umsdos_rdir_operations,	/* default directory file-ops */
-	msdos_create,		/* create */
-	UMSDOS_rlookup,		/* lookup */
-	NULL,				/* link */
-	msdos_unlink,		/* unlink */
-	NULL,				/* symlink */
-	msdos_mkdir,		/* mkdir */
-	UMSDOS_rrmdir,		/* rmdir */
-	NULL,				/* mknod */
-	msdos_rename,		/* rename */
-	NULL,				/* readlink */
-	NULL,				/* readpage */
-	NULL,				/* writepage */
-	NULL,				/* bmap */
-	NULL,				/* truncate */
-	NULL				/* permission */
+  &umsdos_rdir_operations,	/* default directory file-ops */
+  msdos_create,			/* create */
+  UMSDOS_rlookup,		/* lookup */
+  NULL,				/* link */
+  msdos_unlink,			/* unlink */
+  NULL,				/* symlink */
+  msdos_mkdir,			/* mkdir */
+  UMSDOS_rrmdir,		/* rmdir */
+  NULL,				/* mknod */
+  msdos_rename,			/* rename */
+  NULL,				/* readlink */
+  NULL,				/* followlink */
+  NULL,				/* readpage */
+  NULL,				/* writepage */
+  NULL,				/* bmap */
+  NULL,				/* truncate */
+  NULL,				/* permission */
+  NULL,				/* smap */
+  NULL,				/* updatepage */
+  NULL,				/* revalidate */
 };
 
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov