lkml.org 
[lkml]   [1997]   [Dec]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectupdated msdos patch for 2.1.72
I've made a couple of minor improvements to the msdos patch that should
more closely follow the old semantics with respect to invalid file
names.

Instead of returning an error from the d_hash operation for invalid file
names, the code now leaves the hash unchanged. This allows the dentry to
be created, and then the msdos fs operations can return the appropriate
error when the dentry is used. (I.e. ENOENT for searches, EINVAL for
creation.) The d_compare operation falls back to the standard compare to
avoid creating multiple copies of the dentry.

In addition to preserving error semantics, leaving the negative dentry
in place will speed up operations if for some reason the invalid name is
used a lot. This might be the case with certain wild-card names like
*.bak or whatever.

Regards,
Bill--- linux-2.1.72/fs/fat/inode.c.old Sun Nov 30 11:26:00 1997
+++ linux-2.1.72/fs/fat/inode.c Wed Dec 10 10:23:01 1997
@@ -117,6 +117,16 @@

void fat_delete_inode(struct inode *inode)
{
+ /*
+ * Make sure there are no active dependencies ...
+ */
+ if (MSDOS_I(inode)->i_old)
+ printk("fat_delete_inode: inode %ld, old=%p??\n",
+ inode->i_ino, MSDOS_I(inode)->i_old);
+ if (MSDOS_I(inode)->i_oldlink)
+ printk("fat_delete_inode: inode %ld, oldlink=%p??\n",
+ inode->i_ino, MSDOS_I(inode)->i_oldlink);
+
fat_cache_inval_inode(inode);
inode->i_size = 0;
fat_truncate(inode);
--- linux-2.1.72/fs/msdos/namei.c.old Sun Nov 30 11:26:00 1997
+++ linux-2.1.72/fs/msdos/namei.c Wed Dec 10 10:23:01 1997
@@ -173,56 +173,60 @@
return fat_scan(dir,msdos_name,bh,de,ino,scantype);
}

-
+/*
+ * Compute the hash for the msdos name corresponding to the dentry.
+ * Note: if the name is invalid, we leave the hash code unchanged so
+ * that the existing dentry can be used. The msdos fs routines will
+ * return ENOENT or EINVAL as appropriate.
+ */
static int msdos_hash(struct dentry *dentry, struct qstr *qstr)
{
- unsigned long hash;
- char msdos_name[MSDOS_NAME];
+ struct fat_mount_options *options = & (MSDOS_SB(dentry->d_sb)->options);
int error;
- int i;
- struct fat_mount_options *options =
- & (MSDOS_SB(dentry->d_inode->i_sb)->options);
+ char msdos_name[MSDOS_NAME];

- error = msdos_format_name(options->name_check,
- qstr->name, qstr->len, msdos_name,1,
- options->dotsOK);
- if(error)
- return error;
- hash = init_name_hash();
- for(i=0; i< MSDOS_NAME; i++)
- hash = partial_name_hash(msdos_name[i], hash);
- qstr->hash = end_name_hash(hash);
+ error = msdos_format_name(options->name_check, qstr->name, qstr->len,
+ msdos_name, 1, options->dotsOK);
+ if (!error)
+ qstr->hash = full_name_hash(msdos_name, MSDOS_NAME);
return 0;
}

-
-static int msdos_cmp(struct dentry *dentry,
- struct qstr *a, struct qstr *b)
+/*
+ * Compare two msdos names. If either of the names are invalid,
+ * we fall back to doing the standard name comparison.
+ */
+static int msdos_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b)
{
- char a_msdos_name[MSDOS_NAME],b_msdos_name[MSDOS_NAME];
+ struct fat_mount_options *options = & (MSDOS_SB(dentry->d_sb)->options);
int error;
- struct fat_mount_options *options =
- & (MSDOS_SB(dentry->d_inode->i_sb)->options);
+ char a_msdos_name[MSDOS_NAME], b_msdos_name[MSDOS_NAME];

- error = msdos_format_name(options->name_check,
- a->name, a->len, a_msdos_name,1,
- options->dotsOK);
- if(error)
- return error;
- error = msdos_format_name(options->name_check,
- b->name, b->len, b_msdos_name,1,
- options->dotsOK);
- if(error)
- return error;
-
- return memcmp(a_msdos_name, b_msdos_name, MSDOS_NAME);
+ error = msdos_format_name(options->name_check, a->name, a->len,
+ a_msdos_name, 1, options->dotsOK);
+ if (error)
+ goto old_compare;
+ error = msdos_format_name(options->name_check, b->name, b->len,
+ b_msdos_name, 1, options->dotsOK);
+ if (error)
+ goto old_compare;
+ error = memcmp(a_msdos_name, b_msdos_name, MSDOS_NAME);
+out:
+ return error;
+
+old_compare:
+ error = 1;
+ if (a->len == b->len)
+ error = memcmp(a->name, b->name, a->len);
+ goto out;
}


static struct dentry_operations msdos_dentry_operations = {
- 0, /* d_revalidate */
+ NULL, /* d_revalidate */
msdos_hash,
- msdos_cmp
+ msdos_cmp,
+ NULL /* d_delete */
};

struct super_block *msdos_read_super(struct super_block *sb,void *data, int silent)
@@ -233,14 +237,16 @@

MSDOS_SB(sb)->options.isvfat = 0;
sb->s_op = &msdos_sops;
- res = fat_read_super(sb, data, silent);
- if (res == NULL) {
- sb->s_dev = 0;
- MOD_DEC_USE_COUNT;
- return NULL;
- }
+ res = fat_read_super(sb, data, silent);
+ if (res == NULL)
+ goto out_fail;
sb->s_root->d_op = &msdos_dentry_operations;
return res;
+
+out_fail:
+ sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
+ return NULL;
}


@@ -290,11 +296,14 @@
PRINTK (("msdos_lookup 6\n"));
while (MSDOS_I(inode)->i_old) {
next = MSDOS_I(inode)->i_old;
+#ifdef MSDOS_PARANOIA
+printk("msdos_lookup: ino %ld, old ino=%ld\n", inode->i_ino, next->i_ino);
+if (MSDOS_I(next)->i_depend != inode)
+printk("msdos_lookup: depend=%p, inode=%p??\n", MSDOS_I(next)->i_depend, inode);
+#endif
+ next->i_count++;
iput(inode);
- if (!(inode = iget(next->i_sb,next->i_ino))) {
- fat_fs_panic(dir->i_sb,"msdos_lookup: Can't happen");
- return -ENOENT; /* N.B. Maybe ENOMEM is better? */
- }
+ inode = next;
}
PRINTK (("msdos_lookup 7\n"));
d_add(dentry, inode);
\
 
 \ /
  Last update: 2005-03-22 13:40    [W:0.050 / U:0.040 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site