patch-2.1.121 linux/fs/umsdos/rdir.c
Next file: linux/fs/umsdos/specs
Previous file: linux/fs/umsdos/namei.c
Back to the patch index
Back to the overall index
- Lines: 331
- Date:
Wed Sep 9 09:01:20 1998
- Orig file:
v2.1.120/linux/fs/umsdos/rdir.c
- Orig date:
Sat Sep 5 16:46:41 1998
diff -u --recursive --new-file v2.1.120/linux/fs/umsdos/rdir.c linux/fs/umsdos/rdir.c
@@ -18,9 +18,6 @@
#include <asm/uaccess.h>
-#define PRINTK(x)
-#define Printk(x) printk x
-
extern struct inode *pseudo_root;
@@ -39,16 +36,13 @@
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] == '.') {
+ if (name_len == 2 && name[0] == '.' && name[1] == '.') {
/* Make sure the .. entry points back to the pseudo_root */
ino = pseudo_root->i_ino;
}
@@ -56,30 +50,22 @@
}
} else {
/* Any DOS directory */
- PRINTK ((KERN_DEBUG "rdir_filldir /mn/: calling d->filldir (%p) for %.*s (%lu)\n", d->filldir, name_len, name, ino));
ret = d->filldir (d->dirbuf, name, name_len, offset, ino);
}
return ret;
}
-static int UMSDOS_rreaddir (
- struct file *filp,
- void *dirbuf,
- filldir_t filldir)
+static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t 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));
-
+ struct RDIR_FILLDIR bufk;
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));
+ bufk.real_root = pseudo_root &&
+ dir->i_ino == UMSDOS_ROOT_INO &&
+ dir->i_sb == pseudo_root->i_sb;
return fat_readdir (filp, &bufk, rdir_filldir);
}
@@ -89,157 +75,138 @@
* 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,
- struct dentry *dentry,
- int nopseudo)
-{ /* Don't care about pseudo root mode */
+/* #Specification: pseudo root / DOS/..
+ * In the real root directory (c:\), the directory ..
+ * is the pseudo root (c:\linux).
+ */
+int umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo)
+{
/* so locating "linux" will work */
- int len = dentry->d_name.len;
const char *name = dentry->d_name.name;
+ int len = dentry->d_name.len;
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 ((KERN_WARNING "umsdos_rlookup_x: we are at pseudo-root thingy?\n"));
- inc_count (pseudo_root);
+ if (pseudo_root && len == 2 && name[0] == '.' && name[1] == '.' &&
+ dir->i_ino == UMSDOS_ROOT_INO && dir->i_sb == pseudo_root->i_sb) {
+printk (KERN_WARNING "umsdos_rlookup_x: we are at pseudo-root thingy?\n");
+ pseudo_root->i_count++;
+ d_add(dentry, pseudo_root);
ret = 0;
- /* #Specification: pseudo root / DOS/..
- * In the real root directory (c:\), the directory ..
- * is the pseudo root (c:\linux).
- */
- } else {
- inc_count (dir);
- ret = umsdos_real_lookup (dir, dentry);
- inode = dentry->d_inode;
-
-#if 0
- Printk ((KERN_DEBUG "umsdos_rlookup_x: umsdos_real_lookup for %.*s in %lu returned %d\n", len, 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=%lu\n", inode->i_ino));
- } else {
- Printk ((KERN_DEBUG "NONE!\n"));
- }
-#endif
-
- if ((ret == 0) && inode) {
+ goto out;
+ }
- 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 ((KERN_WARNING "umsdos_rlookup_x: do the pseudo-thingy...\n"));
- ret = -ENOENT;
- iput (pseudo_root); /* FIXME? */
-
- } else if (S_ISDIR (inode->i_mode)) {
- /* We must place the proper function table */
- /* depending on whether this is an MS-DOS or a UMSDOS directory */
- Printk ((KERN_DEBUG "umsdos_rlookup_x: setting up setup_dir_inode %lu...\n", inode->i_ino));
- umsdos_setup_dir_inode (inode);
- }
+ ret = umsdos_real_lookup (dir, dentry);
+ inode = dentry->d_inode;
+ if ((ret == 0) && inode) {
+ if (inode == pseudo_root && !nopseudo) {
+ /* #Specification: pseudo root / DOS/linux
+ * Even in the real root directory (c:\), the directory
+ * /linux won't show
+ */
+printk(KERN_WARNING "umsdos_rlookup_x: do the pseudo-thingy...\n");
+ /* make the dentry negative */
+ d_delete(dentry);
+ }
+ else if (S_ISDIR (inode->i_mode)) {
+ /* We must place the proper function table
+ * depending on whether this is an MS-DOS or
+ * a UMSDOS directory
+ */
+Printk ((KERN_DEBUG "umsdos_rlookup_x: setting up setup_dir_inode %lu...\n",
+inode->i_ino));
+ umsdos_setup_dir(dentry);
}
- iput (dir);
}
+out:
PRINTK ((KERN_DEBUG "umsdos_rlookup_x: returning %d\n", ret));
return ret;
}
-int UMSDOS_rlookup (
- struct inode *dir,
- struct dentry *dentry
-)
+int UMSDOS_rlookup ( struct inode *dir, struct dentry *dentry)
{
- PRINTK ((KERN_DEBUG "UMSDOS_rlookup /mn/: executing umsdos_rlookup_x for ino=%lu in %.*s\n", dir->i_ino, (int) dentry->d_name.len, dentry->d_name.name));
return umsdos_rlookup_x (dir, dentry, 0);
}
-static int UMSDOS_rrmdir (
- struct inode *dir,
- 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 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)
{
- /* #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 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;
+ int ret, empty;
- 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
- * MS-DOS) is always possible.
- *
- * EPERM is returned.
- */
- ret = -EPERM;
- } else {
- umsdos_lockcreate (dir);
- inc_count (dir);
- ret = msdos_rmdir (dir, dentry);
- if (ret == -ENOTEMPTY) {
- struct inode *sdir;
-
- inc_count (dir);
-
- 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 remove the EMD file. */
- struct dentry *temp;
-
- Printk ((KERN_WARNING "UMSDOS_rmdir: hmmm... what about inode? FIXME\n"));
- temp = creat_dentry (UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN, NULL, NULL); /* FIXME: probably should fill inode part ? */
- ret = msdos_unlink (sdir, temp);
- sdir = NULL;
- if (ret == 0) {
- inc_count (dir);
- ret = msdos_rmdir (dir, dentry);
- }
- }
- } else {
- ret = -ENOTEMPTY;
- }
- /* iput (sdir); FIXME */
- }
+ ret = -EPERM;
+ if (umsdos_is_pseudodos (dir, dentry))
+ goto out;
+
+ umsdos_lockcreate (dir);
+ ret = -EBUSY;
+ if (dentry->d_count > 1) {
+ shrink_dcache_parent(dentry);
+ if (dentry->d_count > 1)
+ goto out_unlock;
+ }
+
+ ret = msdos_rmdir (dir, dentry);
+ if (ret != -ENOTEMPTY)
+ goto out_check;
+
+#if 0 /* why do this? we have the dentry ... */
+ ret = UMSDOS_rlookup (dir, dentry);
+ PRINTK (("rrmdir lookup %d ", ret));
+ if (ret)
+ goto out_unlock;
+ ret = -ENOTEMPTY;
+#endif
+
+ empty = umsdos_isempty (dentry);
+ if (empty == 1) {
+ struct dentry *temp;
+ /* We have to remove the EMD file. */
+ temp = umsdos_lookup_dentry(dentry, UMSDOS_EMD_FILE,
+ UMSDOS_EMD_NAMELEN);
+ ret = PTR_ERR(temp);
+ if (!IS_ERR(temp)) {
+ ret = 0;
+ if (temp->d_inode)
+ ret = msdos_unlink (dentry->d_inode, temp);
+ dput(temp);
}
- umsdos_unlockcreate (dir);
+ if (ret)
+ goto out_unlock;
}
- /* iput (dir); FIXME */
+ /* now retry the original ... */
+ ret = msdos_rmdir (dir, dentry);
+
+out_check:
+ /* Check whether we succeeded ... */
+ if (!ret)
+ d_delete(dentry);
+
+out_unlock:
+ umsdos_unlockcreate (dir);
+out:
check_inode (dir);
return ret;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov