patch-2.1.123 linux/fs/umsdos/dir.c
Next file: linux/fs/umsdos/emd.c
Previous file: linux/fs/ufs/symlink.c
Back to the patch index
Back to the overall index
- Lines: 306
- Date:
Fri Sep 25 16:30:07 1998
- Orig file:
v2.1.122/linux/fs/umsdos/dir.c
- Orig date:
Thu Sep 17 17:53:38 1998
diff -u --recursive --new-file v2.1.122/linux/fs/umsdos/dir.c linux/fs/umsdos/dir.c
@@ -20,6 +20,7 @@
#include <asm/uaccess.h>
#define UMSDOS_SPECIAL_DIRFPOS 3
+extern struct dentry *saved_root;
extern struct inode *pseudo_root;
/* #define UMSDOS_DEBUG_VERBOSE 1 */
@@ -53,42 +54,6 @@
NULL,
};
-/*
- * This needs to have the parent dentry passed to it.
- * N.B. Try to get rid of this soon!
- */
-int compat_msdos_create (struct inode *dir, const char *name, int len,
- int mode, struct inode **inode)
-{
- int ret;
- struct dentry *dentry, *d_dir;
-
- check_inode (dir);
- ret = -ENOMEM;
- d_dir = geti_dentry (dir);
- if (!d_dir) {
-printk(KERN_ERR "compat_msdos_create: flaky i_dentry didn't work\n");
- goto out;
- }
- dget(d_dir);
- dentry = creat_dentry (name, len, NULL, d_dir);
- dput(d_dir);
- if (!dentry)
- goto out;
-
- check_dentry_path (dentry, "compat_msdos_create START");
- ret = msdos_create (dir, dentry, mode);
- check_dentry_path (dentry, "compat_msdos_create END");
- if (ret)
- goto out;
- if (inode != NULL)
- *inode = dentry->d_inode;
-
- check_inode (dir);
-out:
- return ret;
-}
-
/*
* So grep * doesn't complain in the presence of directories.
@@ -203,9 +168,11 @@
ret = PTR_ERR(demd);
if (IS_ERR(demd))
goto out_end;
- ret = 0;
+ ret = -EIO;
if (!demd->d_inode) {
-printk("no EMD file??\n");
+ 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;
}
@@ -404,18 +371,17 @@
* does this automatically.
*/
-void umsdos_lookup_patch (struct inode *dir, struct inode *inode,
- struct umsdos_dirent *entry, off_t emd_pos)
+void umsdos_lookup_patch_new(struct dentry *dentry, struct umsdos_info *info)
{
- if (inode->i_sb != dir->i_sb)
- goto out;
- if (umsdos_isinit (inode))
- goto out;
+ struct inode *inode = dentry->d_inode;
+ struct umsdos_dirent *entry = &info->entry;
- if (S_ISDIR (inode->i_mode))
- umsdos_lockcreate (inode);
- if (umsdos_isinit (inode))
- goto out_unlock;
+ /*
+ * This part of the initialization depends only on i_patched.
+ */
+ if (inode->u.umsdos_i.i_patched)
+ goto out;
+ inode->u.umsdos_i.i_patched = 1;
if (S_ISREG (entry->mode))
entry->mtime = inode->i_mtime;
@@ -444,150 +410,18 @@
"UMSDOS: lookup_patch entry->nlink < 1 ???\n");
}
}
- umsdos_patch_inode (inode, dir, emd_pos);
+ /*
+ * 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_unlock:
- if (S_ISDIR (inode->i_mode))
- umsdos_unlockcreate (inode);
- if (inode->u.umsdos_i.i_emd_owner == 0)
- printk (KERN_WARNING "UMSDOS: emd_owner still 0?\n");
out:
return;
}
/*
- * The preferred interface to the above routine ...
- */
-void umsdos_lookup_patch_new(struct dentry *dentry, struct umsdos_dirent *entry,
- off_t emd_pos)
-{
- umsdos_lookup_patch(dentry->d_parent->d_inode, dentry->d_inode, entry,
- emd_pos);
-}
-
-
-struct UMSDOS_DIRENT_K {
- off_t f_pos; /* will hold the offset of the entry in EMD */
- ino_t ino;
-};
-
-
-/*
- * Just to record the offset of one entry.
- */
-
-static int umsdos_filldir_k ( void *buf,
- const char *name,
- int len,
- off_t offset,
- ino_t ino)
-{
- struct UMSDOS_DIRENT_K *d = (struct UMSDOS_DIRENT_K *) buf;
-
- d->f_pos = offset;
- d->ino = ino;
- return 0;
-}
-
-struct UMSDOS_DIR_SEARCH {
- struct umsdos_dirent *entry;
- int found;
- ino_t search_ino;
-};
-
-static int umsdos_dir_search ( void *buf,
- const char *name,
- int len,
- off_t offset,
- ino_t ino)
-{
- int ret = 0;
- struct UMSDOS_DIR_SEARCH *d = (struct UMSDOS_DIR_SEARCH *) buf;
-
- if (d->search_ino == ino) {
- d->found = 1;
- memcpy (d->entry->name, name, len);
- d->entry->name[len] = '\0';
- d->entry->name_len = len;
- ret = 1; /* So fat_readdir will terminate */
- }
- return ret;
-}
-
-
-
-/*
- * Locate the directory entry for a dentry in its parent directory.
- * Return 0 or a negative error code.
- *
- * Normally, this function must succeed. It means a strange corruption
- * in the file system if not.
- */
-
-int umsdos_dentry_to_entry(struct dentry *dentry, struct umsdos_dirent *entry)
-{
- struct dentry *parent = dentry->d_parent;
- struct inode *inode = dentry->d_inode;
- int ret = -ENOENT, err;
- struct file filp;
- struct UMSDOS_DIR_SEARCH bufsrch;
- struct UMSDOS_DIRENT_K bufk;
-
- if (pseudo_root && inode == pseudo_root) {
- /*
- * Quick way to find the name.
- * Also umsdos_readdir_x won't show /linux anyway
- */
- memcpy (entry->name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN + 1);
- entry->name_len = UMSDOS_PSDROOT_LEN;
- ret = 0;
- goto out;
- }
-
- /* initialize the file */
- fill_new_filp (&filp, parent);
-
- if (!umsdos_have_emd(parent)) {
- /* This is a DOS directory. */
- filp.f_pos = 0;
- bufsrch.entry = entry;
- bufsrch.search_ino = inode->i_ino;
- fat_readdir (&filp, &bufsrch, umsdos_dir_search);
- if (bufsrch.found) {
- ret = 0;
- inode->u.umsdos_i.i_emd_owner = 0;
-if (!S_ISDIR(inode->i_mode))
-printk("UMSDOS: %s/%s not a directory!\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
- /* N.B. why call this? not always a dir ... */
- umsdos_setup_dir(dentry);
- }
- goto out;
- }
-
- /* skip . and .. see umsdos_readdir_x() */
- filp.f_pos = UMSDOS_SPECIAL_DIRFPOS;
- while (1) {
- err = umsdos_readdir_x (parent->d_inode, &filp, &bufk, 1,
- entry, 0, umsdos_filldir_k);
- if (err < 0) {
- printk ("umsdos_dentry_to_entry: ino=%ld, err=%d\n",
- inode->i_ino, err);
- break;
- }
- if (bufk.ino == inode->i_ino) {
- ret = 0;
- umsdos_lookup_patch_new(dentry, entry, bufk.f_pos);
- break;
- }
- }
-out:
- return ret;
-}
-
-
-/*
* Return != 0 if an entry is the pseudo DOS entry in the pseudo root.
*/
@@ -627,8 +461,6 @@
int umsdos_lookup_x (struct inode *dir, struct dentry *dentry, int nopseudo)
{
- const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
struct dentry *dret = NULL;
struct inode *inode;
int ret = -ENOENT;
@@ -640,28 +472,13 @@
#endif
umsdos_startlookup (dir);
- /* this shouldn't happen ... */
- if (len == 1 && name[0] == '.') {
- printk("umsdos_lookup_x: UMSDOS broken, please report!\n");
- goto out;
- }
-
- /* this shouldn't happen ... */
- if (len == 2 && name[0] == '.' && name[1] == '.') {
- printk("umsdos_lookup_x: UMSDOS broken, please report!\n");
- goto out;
- }
-
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.
*/
- inode = iget(dir->i_sb, UMSDOS_ROOT_INO);
- if (inode)
- goto out_add;
- ret = -ENOMEM;
- goto out;
+ inode = saved_root->d_inode;
+ goto out_add;
}
ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
@@ -693,7 +510,7 @@
inode = dret->d_inode;
if (!inode)
goto out_remove;
- umsdos_lookup_patch_new(dret, &info.entry, info.f_pos);
+ 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);
@@ -726,6 +543,7 @@
* mode.
*/
printk(KERN_WARNING "umsdos_lookup_x: untested, inode == Pseudo_root\n");
+ ret = -ENOENT;
goto out_dput;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov