lkml.org 
[lkml]   [1999]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[RFC][PATCH] rename() on braindead filesystems
	Folks, I've produced something that pretends to fix the problems
with case-preserving & case-insensitive filesystems. In some respects it's
a gross hack. It seems to work and I'ld *really* like to hear some
feedback on the thing.
Nature of the problem: on case-insensitive but case-preserving
filesystems target of rename() should be treated in a special way.
Normally such filesystems treat names different only in capitalization as
synonims. Except for rename() target. We are using the same lookup() for
all cases and as the result lookups in rename("Foo","fOO"); bring us the
same dentry for source and target. With the obvious results. Another
related problem being that touch bar;mv foo Bar; is likely to rename foo
into bar. There is no really clean way to deal with that lossage -
semantics of rename() is incompatible with the case-braindamage exhibited
by those filesystems. Some approximation can be achieved in the following
way:
a) we are introducing new lookup flag: LOOKUP_TARGET (right thing
to do for completely unrelated reasons).
b) ->lookup() and ->d_compare() are getting the flags argument
(ditto). LOOKUP_TARGET reaches methods only on the last step of path.
c) filesystem may choose to implement stricter comparison in
d_compare() if LOOKUP_TARGET is passed.
d) in that case lookup() may do the following:
1) if we don't have a dentry for this object yet (even with the
different capitalization) - act as usual.
2) if we do - mark ->d_flags with DCACHE_VMS_LOSSAGE (sorry for
that name - AFAIK braindamage in question appeared in Vogon Made System),
set ->d_fsdata pointing to the existing alias, leave dentry unhashed and
return NULL.
e) for such filesystems ->rename() may get a dentry marked in
aforementioned way as a target. In that case we are guaranteed that it
bears the exact name we were asked for and ->d_fsdata points to the
normal dentry of the target (with a different capitalization).
I did ->lookup() and ->d_compare() type changes + required VFS
support + all changes needed to make it work in case of VFAT. Attached
patch is against the 2.2.9 + FAT patch (same as in 2.3.[23]). FAT patch
can be found on ftp.math.psu.edu/pub/firo/fat-patch-20.gz.

Why 2.2.9? Because for 2.3 I have a cleaner variant, but it
requires major dcache changes (needed for lots of other things anyway).
I'ld like to hear comments on the thing. I hate the idea of interface
changes in 2.2, but I *really* see no other way. If somebody have a
reasonable suggestion - you are more than welcome. I don't like the
proposed solution. Frankly, I'm sorely tempted to leave all this
case-perverted mess as is and to hell with mv Foo fOO; & Co. *If* it is
considered critical - well, solution is here.

Linus, decision belongs to you. Main changes are in fs/namei.c
(+ stuff in fs/vfat/namei.c, indeed). It's ugly, but I'm afraid that any
other fix will be even worse. Please, look it through.

Waiting for comments,
Al
diff -urN linux-bird.FAT/fs/adfs/namei.c linux-bird.BLETCH/fs/adfs/namei.c
--- linux-bird.FAT/fs/adfs/namei.c Thu May 13 07:02:55 1999
+++ linux-bird.BLETCH/fs/adfs/namei.c Tue May 25 07:53:42 1999
@@ -98,7 +98,7 @@
return 0;
}

-struct dentry *adfs_lookup (struct inode *dir, struct dentry *dentry)
+struct dentry *adfs_lookup (struct inode *dir, struct dentry *dentry, int flags)
{
struct inode *inode = NULL;
struct adfs_idir_entry de;
diff -urN linux-bird.FAT/fs/affs/namei.c linux-bird.BLETCH/fs/affs/namei.c
--- linux-bird.FAT/fs/affs/namei.c Thu May 13 07:02:55 1999
+++ linux-bird.BLETCH/fs/affs/namei.c Tue May 25 09:47:24 1999
@@ -40,7 +40,7 @@
}

static int affs_hash_dentry(struct dentry *, struct qstr *);
-static int affs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
+static int affs_compare_dentry(struct dentry *, struct qstr *, struct qstr *, int);
struct dentry_operations affs_dentry_operations = {
NULL, /* d_validate */
affs_hash_dentry, /* d_hash */
@@ -73,7 +73,7 @@
}

static int
-affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b, int flags)
{
unsigned int (*toupper)(unsigned int) = affs_toupper;
int alen = a->len;
@@ -202,7 +202,7 @@
}

struct dentry *
-affs_lookup(struct inode *dir, struct dentry *dentry)
+affs_lookup(struct inode *dir, struct dentry *dentry, int flags)
{
unsigned long ino;
struct buffer_head *bh;
diff -urN linux-bird.FAT/fs/autofs/dir.c linux-bird.BLETCH/fs/autofs/dir.c
--- linux-bird.FAT/fs/autofs/dir.c Thu May 13 07:02:56 1999
+++ linux-bird.BLETCH/fs/autofs/dir.c Tue May 25 07:54:37 1999
@@ -38,7 +38,8 @@
/*
* No entries except for "." and "..", both of which are handled by the VFS layer
*/
-static struct dentry *autofs_dir_lookup(struct inode *dir,struct dentry *dentry)
+static struct dentry *autofs_dir_lookup(struct inode *dir,struct dentry *dentry,
+int flags)
{
d_add(dentry, NULL);
return NULL;
diff -urN linux-bird.FAT/fs/autofs/root.c linux-bird.BLETCH/fs/autofs/root.c
--- linux-bird.FAT/fs/autofs/root.c Thu May 13 07:02:56 1999
+++ linux-bird.BLETCH/fs/autofs/root.c Tue May 25 07:55:12 1999
@@ -16,7 +16,7 @@
#include "autofs_i.h"

static int autofs_root_readdir(struct file *,void *,filldir_t);
-static struct dentry *autofs_root_lookup(struct inode *,struct dentry *);
+static struct dentry *autofs_root_lookup(struct inode *,struct dentry *,int);
static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
static int autofs_root_unlink(struct inode *,struct dentry *);
static int autofs_root_rmdir(struct inode *,struct dentry *);
@@ -209,7 +209,7 @@
NULL, /* d_compare */
};

-static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry,int flags)
{
struct autofs_sb_info *sbi;
int oz_mode;
diff -urN linux-bird.FAT/fs/coda/dir.c linux-bird.BLETCH/fs/coda/dir.c
--- linux-bird.FAT/fs/coda/dir.c Thu May 13 07:02:56 1999
+++ linux-bird.BLETCH/fs/coda/dir.c Tue May 25 07:56:44 1999
@@ -29,7 +29,8 @@
/* dir inode-ops */
static int coda_create(struct inode *dir, struct dentry *new, int mode);
static int coda_mknod(struct inode *dir, struct dentry *new, int mode, int rdev);
-static struct dentry *coda_lookup(struct inode *dir, struct dentry *target);
+static struct dentry *coda_lookup(struct inode *dir, struct dentry *target,
+ int flags);
static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
struct dentry *entry);
static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
@@ -107,7 +108,8 @@

/* inode operations for directories */
/* acces routines: lookup, readlink, permission */
-static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
+static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry,
+ int flags)
{
struct coda_inode_info *dircnp;
struct inode *res_inode = NULL;
diff -urN linux-bird.FAT/fs/dcache.c linux-bird.BLETCH/fs/dcache.c
--- linux-bird.FAT/fs/dcache.c Thu May 13 07:02:54 1999
+++ linux-bird.BLETCH/fs/dcache.c Tue May 25 06:39:48 1999
@@ -568,7 +568,7 @@
return dentry_hashtable + (hash & D_HASHMASK);
}

-struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
+struct dentry * d_lookup(struct dentry * parent, struct qstr * name, int flags)
{
unsigned int len = name->len;
unsigned int hash = name->hash;
@@ -586,7 +586,8 @@
if (dentry->d_parent != parent)
continue;
if (parent->d_op && parent->d_op->d_compare) {
- if (parent->d_op->d_compare(parent, &dentry->d_name, name))
+ if (parent->d_op->d_compare(parent, &dentry->d_name,
+ name, flags))
continue;
} else {
if (dentry->d_name.len != len)
@@ -889,7 +890,7 @@
goto out;
}

- dentry = d_lookup(dir, name);
+ dentry = d_lookup(dir, name, 0);
if (dentry)
{
if (dentry->d_inode)
diff -urN linux-bird.FAT/fs/devpts/root.c linux-bird.BLETCH/fs/devpts/root.c
--- linux-bird.FAT/fs/devpts/root.c Thu May 13 07:02:56 1999
+++ linux-bird.BLETCH/fs/devpts/root.c Tue May 25 07:57:23 1999
@@ -17,7 +17,7 @@
#include "devpts_i.h"

static int devpts_root_readdir(struct file *,void *,filldir_t);
-static struct dentry *devpts_root_lookup(struct inode *,struct dentry *);
+static struct dentry *devpts_root_lookup(struct inode *,struct dentry *,int);
static int devpts_revalidate(struct dentry *, int);

static struct file_operations devpts_root_operations = {
@@ -128,7 +128,8 @@
return ( sbi->inodes[dentry->d_inode->i_ino - 2] == dentry->d_inode );
}

-static struct dentry *devpts_root_lookup(struct inode * dir, struct dentry * dentry)
+static struct dentry *devpts_root_lookup(struct inode * dir,
+ struct dentry * dentry, int flags)
{
struct devpts_sb_info *sbi = SBI(dir->i_sb);
unsigned int entry;
diff -urN linux-bird.FAT/fs/ext2/namei.c linux-bird.BLETCH/fs/ext2/namei.c
--- linux-bird.FAT/fs/ext2/namei.c Thu May 13 07:02:56 1999
+++ linux-bird.BLETCH/fs/ext2/namei.c Tue May 25 07:57:54 1999
@@ -166,7 +166,7 @@
return NULL;
}

-struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, int flags)
{
struct inode * inode;
struct ext2_dir_entry_2 * de;
diff -urN linux-bird.FAT/fs/hfs/dir_cap.c linux-bird.BLETCH/fs/hfs/dir_cap.c
--- linux-bird.FAT/fs/hfs/dir_cap.c Thu May 13 07:02:58 1999
+++ linux-bird.BLETCH/fs/hfs/dir_cap.c Tue May 25 10:23:33 1999
@@ -27,7 +27,7 @@

/*================ Forward declarations ================*/

-static struct dentry *cap_lookup(struct inode *, struct dentry *);
+static struct dentry *cap_lookup(struct inode *, struct dentry *, int);
static int cap_readdir(struct file *, void *, filldir_t);

/*================ Global variables ================*/
@@ -147,7 +147,8 @@
* inode corresponding to an entry in a directory, given the inode for
* the directory and the name (and its length) of the entry.
*/
-static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry,
+ int flags)
{
ino_t dtype;
struct hfs_name cname;
diff -urN linux-bird.FAT/fs/hfs/dir_dbl.c linux-bird.BLETCH/fs/hfs/dir_dbl.c
--- linux-bird.FAT/fs/hfs/dir_dbl.c Thu May 13 07:02:58 1999
+++ linux-bird.BLETCH/fs/hfs/dir_dbl.c Tue May 25 13:38:06 1999
@@ -23,7 +23,7 @@

/*================ Forward declarations ================*/

-static struct dentry *dbl_lookup(struct inode *, struct dentry *);
+static struct dentry *dbl_lookup(struct inode *, struct dentry *, int);
static int dbl_readdir(struct file *, void *, filldir_t);
static int dbl_create(struct inode *, struct dentry *, int);
static int dbl_mkdir(struct inode *, struct dentry *, int);
@@ -130,7 +130,8 @@
* the inode for the directory and the name (and its length) of the
* entry.
*/
-static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry,
+ int flags)
{
struct hfs_name cname;
struct hfs_cat_entry *entry;
diff -urN linux-bird.FAT/fs/hfs/dir_nat.c linux-bird.BLETCH/fs/hfs/dir_nat.c
--- linux-bird.FAT/fs/hfs/dir_nat.c Thu May 13 07:02:58 1999
+++ linux-bird.BLETCH/fs/hfs/dir_nat.c Tue May 25 10:24:30 1999
@@ -29,7 +29,7 @@

/*================ Forward declarations ================*/

-static struct dentry *nat_lookup(struct inode *, struct dentry *);
+static struct dentry *nat_lookup(struct inode *, struct dentry *, int);
static int nat_readdir(struct file *, void *, filldir_t);
static int nat_rmdir(struct inode *, struct dentry *);
static int nat_hdr_unlink(struct inode *, struct dentry *);
@@ -136,7 +136,8 @@
* the inode corresponding to an entry in a directory, given the inode
* for the directory and the name (and its length) of the entry.
*/
-static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry,
+ int flags)
{
ino_t dtype;
struct hfs_name cname;
diff -urN linux-bird.FAT/fs/hfs/hfs.h linux-bird.BLETCH/fs/hfs/hfs.h
--- linux-bird.FAT/fs/hfs/hfs.h Thu May 13 22:16:13 1999
+++ linux-bird.BLETCH/fs/hfs/hfs.h Tue May 25 10:00:28 1999
@@ -519,7 +519,7 @@
this.len = len;
this.hash = hfs_strhash(name, len);

- return d_lookup(base, &this);
+ return d_lookup(base, &this, 0);
}

/* drop a dentry for one of the special directories.
diff -urN linux-bird.FAT/fs/hfs/sysdep.c linux-bird.BLETCH/fs/hfs/sysdep.c
--- linux-bird.FAT/fs/hfs/sysdep.c Thu May 13 07:02:58 1999
+++ linux-bird.BLETCH/fs/hfs/sysdep.c Tue May 25 10:25:27 1999
@@ -20,7 +20,7 @@

static int hfs_revalidate_dentry(struct dentry *, int);
static int hfs_hash_dentry(struct dentry *, struct qstr *);
-static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
+static int hfs_compare_dentry(struct dentry*, struct qstr*, struct qstr *, int);
static void hfs_dentry_iput(struct dentry *, struct inode *);
struct dentry_operations hfs_dentry_operations =
{
@@ -71,7 +71,7 @@

/* return 1 on failure and 0 on success */
static int hfs_compare_dentry(struct dentry *dentry, struct qstr *a,
- struct qstr *b)
+ struct qstr *b, int flags)
{
if (a->len != b->len) return 1;

diff -urN linux-bird.FAT/fs/hpfs/hpfs_fs.c linux-bird.BLETCH/fs/hpfs/hpfs_fs.c
--- linux-bird.FAT/fs/hpfs/hpfs_fs.c Thu May 13 07:02:58 1999
+++ linux-bird.BLETCH/fs/hpfs/hpfs_fs.c Tue May 25 09:44:56 1999
@@ -192,7 +192,7 @@
size_t count, loff_t *ppos);
static int hpfs_readdir(struct file *filp,
void *dirent, filldir_t filldir);
-static struct dentry *hpfs_lookup(struct inode *, struct dentry *);
+static struct dentry *hpfs_lookup(struct inode *, struct dentry *, int);

static const struct file_operations hpfs_dir_ops =
{
@@ -1119,7 +1119,8 @@
* the boondocks.)
*/

-static struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry,
+ int flags)
{
const char *name = dentry->d_name.name;
int len = dentry->d_name.len;
diff -urN linux-bird.FAT/fs/isofs/inode.c linux-bird.BLETCH/fs/isofs/inode.c
--- linux-bird.FAT/fs/isofs/inode.c Thu May 13 07:02:58 1999
+++ linux-bird.BLETCH/fs/isofs/inode.c Tue May 25 08:55:32 1999
@@ -44,14 +44,14 @@

static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
static int isofs_hash(struct dentry *parent, struct qstr *qstr);
-static int isofs_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int isofs_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
+static int isofs_cmpi(struct dentry *, struct qstr *, struct qstr *,int);
+static int isofs_cmp(struct dentry *, struct qstr *, struct qstr *,int);

#ifdef CONFIG_JOLIET
static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);
static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);
-static int isofs_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int isofs_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
+static int isofs_cmpi_ms(struct dentry *, struct qstr *, struct qstr *,int);
+static int isofs_cmp_ms(struct dentry *, struct qstr *, struct qstr *,int);
#endif

void isofs_put_super(struct super_block *sb)
@@ -238,13 +238,13 @@
}

static int
-isofs_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b,int flags)
{
return isofs_cmp_common(dentry, a, b, 0);
}

static int
-isofs_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b,int flags)
{
return isofs_cmpi_common(dentry, a, b, 0);
}
@@ -263,13 +263,13 @@
}

static int
-isofs_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b, int flags)
{
return isofs_cmp_common(dentry, a, b, 1);
}

static int
-isofs_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
+isofs_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b, int flags)
{
return isofs_cmpi_common(dentry, a, b, 1);
}
diff -urN linux-bird.FAT/fs/isofs/namei.c linux-bird.BLETCH/fs/isofs/namei.c
--- linux-bird.FAT/fs/isofs/namei.c Thu May 13 07:02:59 1999
+++ linux-bird.BLETCH/fs/isofs/namei.c Tue May 25 06:50:20 1999
@@ -46,7 +46,7 @@

qstr.name = compare;
qstr.len = dlen;
- return dentry->d_op->d_compare(dentry, &dentry->d_name, &qstr);
+ return dentry->d_op->d_compare(dentry, &dentry->d_name, &qstr, 0);
}

/*
@@ -227,7 +227,7 @@
return retval;
}

-struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry)
+struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, int flags)
{
unsigned long ino;
struct buffer_head * bh;
diff -urN linux-bird.FAT/fs/minix/namei.c linux-bird.BLETCH/fs/minix/namei.c
--- linux-bird.FAT/fs/minix/namei.c Thu May 13 07:03:00 1999
+++ linux-bird.BLETCH/fs/minix/namei.c Tue May 25 08:20:38 1999
@@ -116,7 +116,7 @@
0 /* compare */
};

-struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *minix_lookup(struct inode *dir, struct dentry *dentry, int flags)
{
struct inode * inode = NULL;
struct minix_dir_entry * de;
diff -urN linux-bird.FAT/fs/msdos/namei.c linux-bird.BLETCH/fs/msdos/namei.c
--- linux-bird.FAT/fs/msdos/namei.c Tue May 25 22:47:44 1999
+++ linux-bird.BLETCH/fs/msdos/namei.c Tue May 25 08:52:16 1999
@@ -174,7 +174,8 @@
* 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)
+static int msdos_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b,
+ int flag)
{
struct fat_mount_options *options = & (MSDOS_SB(dentry->d_sb)->options);
int error;
@@ -214,7 +215,7 @@
*/

/***** Get inode using directory and name */
-struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
+struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry, int flags)
{
struct super_block *sb = dir->i_sb;
struct inode *inode = NULL;
diff -urN linux-bird.FAT/fs/namei.c linux-bird.BLETCH/fs/namei.c
--- linux-bird.FAT/fs/namei.c Thu May 13 07:02:55 1999
+++ linux-bird.BLETCH/fs/namei.c Tue May 25 22:32:17 1999
@@ -215,7 +215,7 @@
*/
static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
{
- struct dentry * dentry = d_lookup(parent, name);
+ struct dentry * dentry = d_lookup(parent, name, flags);

if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
@@ -251,7 +251,7 @@
struct dentry * dentry = d_alloc(parent, name);
result = ERR_PTR(-ENOMEM);
if (dentry) {
- result = dir->i_op->lookup(dir, dentry);
+ result = dir->i_op->lookup(dir, dentry, flags);
if (result)
dput(dentry);
else
@@ -324,7 +324,8 @@
goto return_base;

inode = base->d_inode;
- lookup_flags &= LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK;
+ lookup_flags &= LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK |
+ LOOKUP_TARGET;

/* At this point we know we have a real path component. */
for(;;) {
@@ -360,8 +361,10 @@
do {
tmp = *++name;
} while (tmp == '/');
- if (tmp)
+ if (tmp) {
flags |= LOOKUP_CONTINUE;
+ flags &= ~LOOKUP_TARGET;
+ }
}

/*
@@ -1217,8 +1220,13 @@
{
int error;
int need_rehash = 0;
+ int norm_count = 1;
+ struct dentry *shadowed = new_dentry;

- if (old_dentry->d_inode == new_dentry->d_inode)
+ if (new_dentry->d_flags & DCACHE_VMS_LOSSAGE) {
+ shadowed = (struct dentry*)new_dentry->d_fsdata;
+ norm_count++;
+ } else if (old_dentry->d_inode == new_dentry->d_inode)
return 0;

error = may_delete(old_dir, old_dentry, 1);
@@ -1228,10 +1236,10 @@
if (new_dir->i_dev != old_dir->i_dev)
return -EXDEV;

- if (!new_dentry->d_inode)
- error = may_create(new_dir, new_dentry);
+ if (!shadowed->d_inode)
+ error = may_create(new_dir, shadowed);
else
- error = may_delete(new_dir, new_dentry, 1);
+ error = may_delete(new_dir, shadowed, 1);
if (error)
return error;

@@ -1254,17 +1262,21 @@
error = -EINVAL;
if (is_subdir(new_dentry, old_dentry))
goto out_unlock;
- if (new_dentry->d_inode) {
+ if (shadowed->d_inode && shadowed!=old_dentry) {
error = -EBUSY;
- if (d_invalidate(new_dentry)<0)
- goto out_unlock;
+ if (shadowed->d_count!=norm_count) {
+ shrink_dcache_parent(shadowed);
+ if (shadowed->d_count!=norm_count)
+ goto out_unlock;
+ }
+ d_drop(shadowed);
need_rehash = 1;
}
error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
if (need_rehash)
- d_rehash(new_dentry);
- if (!error)
- d_move(old_dentry,new_dentry);
+ d_rehash(shadowed);
+ if (!error && old_dentry!=shadowed)
+ d_move(old_dentry,shadowed);
out_unlock:
up(&old_dir->i_sb->s_vfs_rename_sem);
return error;
@@ -1274,8 +1286,11 @@
struct inode *new_dir, struct dentry *new_dentry)
{
int error;
+ struct dentry *shadowed = new_dentry;

- if (old_dentry->d_inode == new_dentry->d_inode)
+ if (new_dentry->d_flags & DCACHE_VMS_LOSSAGE)
+ shadowed = (struct dentry*)new_dentry->d_fsdata;
+ else if (old_dentry->d_inode == new_dentry->d_inode)
return 0;

error = may_delete(old_dir, old_dentry, 0);
@@ -1285,10 +1300,10 @@
if (new_dir->i_dev != old_dir->i_dev)
return -EXDEV;

- if (!new_dentry->d_inode)
- error = may_create(new_dir, new_dentry);
+ if (!shadowed->d_inode)
+ error = may_create(new_dir, shadowed);
else
- error = may_delete(new_dir, new_dentry, 0);
+ error = may_delete(new_dir, shadowed, 0);
if (error)
return error;

@@ -1302,7 +1317,8 @@
return error;
/* The following d_move() should become unconditional */
if (!(old_dir->i_sb->s_flags & MS_ODD_RENAME)) {
- d_move(old_dentry, new_dentry);
+ if (old_dentry!=shadowed)
+ d_move(old_dentry, shadowed);
}
return 0;
}
@@ -1320,7 +1336,7 @@
{
int error;
struct dentry * old_dir, * new_dir;
- struct dentry * old_dentry, *new_dentry;
+ struct dentry * old_dentry, *new_dentry, *shadowed = NULL;

old_dentry = lookup_dentry(oldname, NULL, 0);

@@ -1333,9 +1349,9 @@
goto exit_old;

{
- unsigned int flags = 0;
+ unsigned int flags = LOOKUP_TARGET;
if (S_ISDIR(old_dentry->d_inode->i_mode))
- flags = LOOKUP_SLASHOK;
+ flags = LOOKUP_SLASHOK | LOOKUP_TARGET;
new_dentry = lookup_dentry(newname, NULL, flags);
}

@@ -1345,16 +1361,21 @@

new_dir = get_parent(new_dentry);
old_dir = get_parent(old_dentry);
+ if (new_dentry->d_flags & DCACHE_VMS_LOSSAGE)
+ shadowed = (struct dentry*)new_dentry->d_fsdata;

double_lock(new_dir, old_dir);

error = -ENOENT;
- if (check_parent(old_dir, old_dentry) && check_parent(new_dir, new_dentry))
+ if (check_parent(old_dir, old_dentry) &&
+ check_parent(new_dir, (shadowed ? shadowed : new_dentry)))
error = vfs_rename(old_dir->d_inode, old_dentry,
new_dir->d_inode, new_dentry);

double_unlock(new_dir, old_dir);
dput(new_dentry);
+ if (shadowed)
+ dput(shadowed);
exit_old:
dput(old_dentry);
exit:
diff -urN linux-bird.FAT/fs/ncpfs/dir.c linux-bird.BLETCH/fs/ncpfs/dir.c
--- linux-bird.FAT/fs/ncpfs/dir.c Thu May 13 07:03:01 1999
+++ linux-bird.BLETCH/fs/ncpfs/dir.c Tue May 25 09:43:57 1999
@@ -50,7 +50,7 @@
static int ncp_readdir(struct file *, void *, filldir_t);

static int ncp_create(struct inode *, struct dentry *, int);
-static struct dentry *ncp_lookup(struct inode *, struct dentry *);
+static struct dentry *ncp_lookup(struct inode *, struct dentry *, int);
static int ncp_unlink(struct inode *, struct dentry *);
static int ncp_mkdir(struct inode *, struct dentry *, int);
static int ncp_rmdir(struct inode *, struct dentry *);
@@ -114,7 +114,7 @@
*/
static int ncp_lookup_validate(struct dentry *, int);
static int ncp_hash_dentry(struct dentry *, struct qstr *);
-static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *);
+static int ncp_compare_dentry(struct dentry *,struct qstr *,struct qstr *,int);
static void ncp_delete_dentry(struct dentry *);

struct dentry_operations ncp_dentry_operations =
@@ -152,7 +152,8 @@
}

static int
-ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b,
+ int flags)
{
int i;

@@ -739,7 +740,8 @@
return result;
}

-static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry,
+ int flags)
{
struct ncp_server *server;
struct inode *inode = NULL;
diff -urN linux-bird.FAT/fs/nfs/dir.c linux-bird.BLETCH/fs/nfs/dir.c
--- linux-bird.FAT/fs/nfs/dir.c Thu May 13 07:03:01 1999
+++ linux-bird.BLETCH/fs/nfs/dir.c Tue May 25 08:56:42 1999
@@ -53,7 +53,7 @@

static ssize_t nfs_dir_read(struct file *, char *, size_t, loff_t *);
static int nfs_readdir(struct file *, void *, filldir_t);
-static struct dentry *nfs_lookup(struct inode *, struct dentry *);
+static struct dentry *nfs_lookup(struct inode *, struct dentry *, int);
static int nfs_create(struct inode *, struct dentry *, int);
static int nfs_mkdir(struct inode *, struct dentry *, int);
static int nfs_rmdir(struct inode *, struct dentry *);
@@ -562,7 +562,8 @@
}
#endif

-static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
+static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry,
+ int flags)
{
struct inode *inode;
int error;
@@ -798,12 +799,12 @@
sqstr.name = silly;
sqstr.len = slen;
sqstr.hash = full_name_hash(silly, slen);
- sdentry = d_lookup(parent, &sqstr);
+ sdentry = d_lookup(parent, &sqstr, 0);
if (!sdentry) {
sdentry = d_alloc(parent, &sqstr);
if (sdentry == NULL)
return ERR_PTR(-ENOMEM);
- res = nfs_lookup(parent->d_inode, sdentry);
+ res = nfs_lookup(parent->d_inode, sdentry, 0);
if (res) {
dput(sdentry);
return res;
diff -urN linux-bird.FAT/fs/ntfs/fs.c linux-bird.BLETCH/fs/ntfs/fs.c
--- linux-bird.FAT/fs/ntfs/fs.c Thu May 13 07:03:03 1999
+++ linux-bird.BLETCH/fs/ntfs/fs.c Tue May 25 09:45:25 1999
@@ -372,7 +372,7 @@
return 0;
}

-static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
+static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d,int flags)
{
struct inode *res=0;
char *item=0;
diff -urN linux-bird.FAT/fs/proc/fd.c linux-bird.BLETCH/fs/proc/fd.c
--- linux-bird.FAT/fs/proc/fd.c Thu May 13 07:03:03 1999
+++ linux-bird.BLETCH/fs/proc/fd.c Tue May 25 08:53:17 1999
@@ -19,7 +19,7 @@
#include <asm/uaccess.h>

static int proc_readfd(struct file *, void *, filldir_t);
-static struct dentry *proc_lookupfd(struct inode *, struct dentry *);
+static struct dentry *proc_lookupfd(struct inode *, struct dentry *, int);

static struct file_operations proc_fd_operations = {
NULL, /* lseek - default */
@@ -67,7 +67,8 @@
*
* Thus just return -ENOENT instead.
*/
-static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
+static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
+ int flags)
{
unsigned int ino, pid, fd, c;
struct task_struct * p;
diff -urN linux-bird.FAT/fs/proc/root.c linux-bird.BLETCH/fs/proc/root.c
--- linux-bird.FAT/fs/proc/root.c Thu May 13 07:03:04 1999
+++ linux-bird.BLETCH/fs/proc/root.c Tue May 25 08:30:43 1999
@@ -28,7 +28,7 @@
#define FIRST_PROCESS_ENTRY 256

static int proc_root_readdir(struct file *, void *, filldir_t);
-static struct dentry *proc_root_lookup(struct inode *,struct dentry *);
+static struct dentry *proc_root_lookup(struct inode *,struct dentry *,int);
static int proc_unlink(struct inode *, struct dentry *);

static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
@@ -769,7 +769,7 @@
* Don't create negative dentries here, return -ENOENT by hand
* instead.
*/
-struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, int flags)
{
struct inode *inode;
struct proc_dir_entry * de;
@@ -801,7 +801,8 @@
return ERR_PTR(error);
}

-static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
+static struct dentry *proc_root_lookup(struct inode * dir,
+ struct dentry * dentry, int flags)
{
unsigned int pid, c;
struct task_struct *p;
@@ -820,7 +821,7 @@
read_unlock(&tasklist_lock);
}

- if (!proc_lookup(dir, dentry))
+ if (!proc_lookup(dir, dentry, flags))
return NULL;

pid = 0;
diff -urN linux-bird.FAT/fs/qnx4/namei.c linux-bird.BLETCH/fs/qnx4/namei.c
--- linux-bird.FAT/fs/qnx4/namei.c Thu May 13 07:03:04 1999
+++ linux-bird.BLETCH/fs/qnx4/namei.c Tue May 25 09:48:18 1999
@@ -104,7 +104,7 @@
return NULL;
}

-struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry)
+struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, int flags)
{
int ino;
struct qnx4_inode_entry *de;
diff -urN linux-bird.FAT/fs/romfs/inode.c linux-bird.BLETCH/fs/romfs/inode.c
--- linux-bird.FAT/fs/romfs/inode.c Thu May 13 07:03:04 1999
+++ linux-bird.BLETCH/fs/romfs/inode.c Tue May 25 09:47:56 1999
@@ -310,7 +310,7 @@
}

static struct dentry *
-romfs_lookup(struct inode *dir, struct dentry *dentry)
+romfs_lookup(struct inode *dir, struct dentry *dentry, int flags)
{
unsigned long offset, maxoff;
int fslen, res;
diff -urN linux-bird.FAT/fs/smbfs/dir.c linux-bird.BLETCH/fs/smbfs/dir.c
--- linux-bird.FAT/fs/smbfs/dir.c Thu May 13 07:03:04 1999
+++ linux-bird.BLETCH/fs/smbfs/dir.c Tue May 25 09:41:44 1999
@@ -22,7 +22,7 @@
static int smb_readdir(struct file *, void *, filldir_t);
static int smb_dir_open(struct inode *, struct file *);

-static struct dentry *smb_lookup(struct inode *, struct dentry *);
+static struct dentry *smb_lookup(struct inode *, struct dentry *, int);
static int smb_create(struct inode *, struct dentry *, int);
static int smb_mkdir(struct inode *, struct dentry *, int);
static int smb_rmdir(struct inode *, struct dentry *);
@@ -193,7 +193,7 @@
*/
static int smb_lookup_validate(struct dentry *, int);
static int smb_hash_dentry(struct dentry *, struct qstr *);
-static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
+static int smb_compare_dentry(struct dentry *,struct qstr *,struct qstr *,int);
static void smb_delete_dentry(struct dentry *);

static struct dentry_operations smbfs_dentry_operations =
@@ -267,7 +267,7 @@
}

static int
-smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b)
+smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b,int flags)
{
int i, result = 1;

@@ -325,7 +325,7 @@
}

static struct dentry *
-smb_lookup(struct inode *dir, struct dentry *dentry)
+smb_lookup(struct inode *dir, struct dentry *dentry, int flags)
{
struct smb_fattr finfo;
struct inode *inode;
diff -urN linux-bird.FAT/fs/sysv/namei.c linux-bird.BLETCH/fs/sysv/namei.c
--- linux-bird.FAT/fs/sysv/namei.c Thu May 13 07:03:05 1999
+++ linux-bird.BLETCH/fs/sysv/namei.c Tue May 25 09:39:35 1999
@@ -101,7 +101,7 @@
return NULL;
}

-struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry)
+struct dentry *sysv_lookup(struct inode *dir, struct dentry *dentry, int flags)
{
struct inode * inode = NULL;
struct sysv_dir_entry * de;
diff -urN linux-bird.FAT/fs/ufs/namei.c linux-bird.BLETCH/fs/ufs/namei.c
--- linux-bird.FAT/fs/ufs/namei.c Thu May 13 07:03:05 1999
+++ linux-bird.BLETCH/fs/ufs/namei.c Tue May 25 09:45:55 1999
@@ -183,7 +183,7 @@
return NULL;
}

-struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, int flags)
{
struct super_block * sb;
struct inode * inode;
diff -urN linux-bird.FAT/fs/umsdos/dir.c linux-bird.BLETCH/fs/umsdos/dir.c
--- linux-bird.FAT/fs/umsdos/dir.c Tue May 25 22:47:44 1999
+++ linux-bird.BLETCH/fs/umsdos/dir.c Tue May 25 09:16:23 1999
@@ -580,7 +580,7 @@
* Called by VFS; should fill dentry->d_inode via d_add.
*/

-struct dentry *UMSDOS_lookup (struct inode *dir, struct dentry *dentry)
+struct dentry *UMSDOS_lookup (struct inode *dir,struct dentry *dentry,int flags)
{
struct dentry *ret;

@@ -609,7 +609,7 @@
dentry = d_alloc(parent, &qstr);
if (dentry) {
/* XXXXXXXXXXXXXXXXXXX Race alert! */
- result = UMSDOS_rlookup(parent->d_inode, dentry);
+ result = UMSDOS_rlookup(parent->d_inode, dentry, 0);
d_drop(dentry);
if (result)
goto out_fail;
@@ -638,14 +638,14 @@
qstr.name = name;
qstr.len = len;
qstr.hash = full_name_hash(name, len);
- result = d_lookup(parent, &qstr);
+ result = d_lookup(parent, &qstr, 0);
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);
+ UMSDOS_rlookup(parent->d_inode, dentry, 0) :
+ UMSDOS_lookup(parent->d_inode, dentry, 0);
if (result)
goto out_fail;
return dentry;
diff -urN linux-bird.FAT/fs/umsdos/rdir.c linux-bird.BLETCH/fs/umsdos/rdir.c
--- linux-bird.FAT/fs/umsdos/rdir.c Thu May 13 07:03:06 1999
+++ linux-bird.BLETCH/fs/umsdos/rdir.c Tue May 25 08:58:57 1999
@@ -95,7 +95,7 @@
goto out;
}

- ret = msdos_lookup (dir, dentry);
+ ret = msdos_lookup (dir, dentry, 0);
if (ret) {
printk(KERN_WARNING
"umsdos_rlookup_x: %s/%s failed, ret=%ld\n",
@@ -120,7 +120,7 @@
}


-struct dentry *UMSDOS_rlookup ( struct inode *dir, struct dentry *dentry)
+struct dentry *UMSDOS_rlookup(struct inode *dir,struct dentry *dentry,int flags)
{
return umsdos_rlookup_x (dir, dentry, 0);
}
diff -urN linux-bird.FAT/fs/vfat/namei.c linux-bird.BLETCH/fs/vfat/namei.c
--- linux-bird.FAT/fs/vfat/namei.c Tue May 25 22:47:44 1999
+++ linux-bird.BLETCH/fs/vfat/namei.c Tue May 25 22:36:20 1999
@@ -51,8 +51,8 @@

static int vfat_hashi(struct dentry *parent, struct qstr *qstr);
static int vfat_hash(struct dentry *parent, struct qstr *qstr);
-static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
+static int vfat_cmpi(struct dentry*, struct qstr*, struct qstr*,int);
+static int vfat_cmp(struct dentry*, struct qstr*, struct qstr*,int);
static int vfat_revalidate(struct dentry *dentry, int);

static struct dentry_operations vfat_dentry_ops[4] = {
@@ -213,7 +213,8 @@
/*
* Case insensitive compare of two vfat names.
*/
-static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b)
+static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b,
+ int flags)
{
int alen, blen;

@@ -225,7 +226,10 @@
while (blen && b->name[blen-1] == '.')
blen--;
if (alen == blen) {
- if (strnicmp(a->name, b->name, alen) == 0)
+ if (flags & LOOKUP_TARGET) {
+ if (strncmp(a->name, b->name, alen) == 0)
+ return 0;
+ } else if (strnicmp(a->name, b->name, alen) == 0)
return 0;
}
return 1;
@@ -234,7 +238,8 @@
/*
* Case sensitive compare of two vfat names.
*/
-static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b)
+static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b,
+ int flags)
{
int alen, blen;

@@ -914,7 +919,7 @@
return NULL;
}

-struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry)
+struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry,int flags)
{
int res;
struct vfat_slot_info sinfo;
@@ -942,6 +947,19 @@
return ERR_PTR(res);
alias = find_alias(inode);
if (alias) {
+ /*
+ * Here the braindamage raises its ugly head.
+ * What a bloody pervert invented case-insensitive
+ * but case-preserving filesystems? May he rewrite
+ * VMS in JCL. Intuitive, my ass... COBOL is more
+ * intuitive than this misbegotten lossage.
+ */
+ if (flags & LOOKUP_TARGET) {
+ dentry->d_flags = DCACHE_VMS_LOSSAGE;
+ dentry->d_fsdata = (void*)alias;
+ iput(inode);
+ return NULL;
+ }
if (d_invalidate(alias)==0)
dput(alias);
else {
@@ -1143,10 +1161,19 @@
struct inode *old_inode, *new_inode;
int res, is_dir;
struct vfat_slot_info old_sinfo,sinfo;
+ int in_situ = 0;

old_bh = new_bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode;
- new_inode = new_dentry->d_inode;
+
+ if (new_dentry->d_flags & DCACHE_VMS_LOSSAGE) {
+ struct dentry *shadowed = (struct dentry*)new_dentry->d_fsdata;
+ if (shadowed == old_dentry)
+ in_situ = 1;
+ new_inode = shadowed->d_inode;
+ } else
+ new_inode = new_dentry->d_inode;
+
res = vfat_find(old_dir,&old_dentry->d_name,&old_sinfo,&old_bh,&old_de);
PRINTK3(("vfat_rename 2\n"));
if (res < 0) goto rename_done;
@@ -1157,7 +1184,7 @@
&dotdot_de,&dotdot_ino)) < 0)
goto rename_done;

- if (new_dentry->d_inode) {
+ if (new_inode) {
res = vfat_find(new_dir,&new_dentry->d_name,&sinfo,&new_bh,
&new_de);
if (res < 0 || MSDOS_I(new_inode)->i_location != sinfo.ino) {
@@ -1166,31 +1193,44 @@
goto rename_done;
}

- if (is_dir) {
+ if (is_dir && !in_situ) {
res = fat_dir_empty(new_inode);
if (res)
goto rename_done;
}
fat_detach(new_inode);
+ vfat_remove_entry(new_dir,&sinfo,new_bh,new_de);
+ res = vfat_add_entry(new_dir,&new_dentry->d_name,is_dir,
+ &sinfo,&new_bh,&new_de);
+ if (res < 0) {
+ /*
+ * We are *deep* in it. Thank you, user-friendliness
+ * theorists.
+ */
+ new_inode->i_nlink--;
+ goto rename_done;
+ }
} else {
- res = vfat_add_entry(new_dir,&new_dentry->d_name,is_dir,&sinfo,
- &new_bh,&new_de);
+ res = vfat_add_entry(new_dir,&new_dentry->d_name,is_dir,
+ &sinfo,&new_bh,&new_de);
if (res < 0) goto rename_done;
}

new_dir->i_version = ++event;

- /* releases old_bh */
- vfat_remove_entry(old_dir,&old_sinfo,old_bh,old_de);
- old_bh=NULL;
- fat_detach(old_inode);
+ if (!in_situ) {
+ /* releases old_bh */
+ vfat_remove_entry(old_dir,&old_sinfo,old_bh,old_de);
+ old_bh=NULL;
+ fat_detach(old_inode);
+ }
fat_attach(old_inode, sinfo.ino);
mark_inode_dirty(old_inode);

old_dir->i_version = ++event;
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(old_dir);
- if (new_inode) {
+ if (new_inode && !in_situ) {
new_inode->i_nlink--;
new_inode->i_ctime=CURRENT_TIME;
}
@@ -1202,7 +1242,7 @@
fat_mark_buffer_dirty(sb, dotdot_bh, 1);
old_dir->i_nlink--;
if (new_inode) {
- new_inode->i_nlink--;
+ if (!in_situ) new_inode->i_nlink--;
} else {
new_dir->i_nlink++;
mark_inode_dirty(new_dir);
diff -urN linux-bird.FAT/include/linux/adfs_fs.h linux-bird.BLETCH/include/linux/adfs_fs.h
--- linux-bird.FAT/include/linux/adfs_fs.h Thu May 13 07:03:21 1999
+++ linux-bird.BLETCH/include/linux/adfs_fs.h Tue May 25 09:38:44 1999
@@ -155,7 +155,7 @@
extern int adfs_map_lookup (struct super_block *sb, int frag_id, int offset);

/* namei.c */
-extern struct dentry *adfs_lookup (struct inode *dir, struct dentry *dentry);
+extern struct dentry *adfs_lookup (struct inode *dir,struct dentry *dentry,int);

/* super.c */
extern int init_adfs_fs (void);
diff -urN linux-bird.FAT/include/linux/affs_fs.h linux-bird.BLETCH/include/linux/affs_fs.h
--- linux-bird.FAT/include/linux/affs_fs.h Thu May 13 07:03:21 1999
+++ linux-bird.BLETCH/include/linux/affs_fs.h Tue May 25 08:32:34 1999
@@ -60,7 +60,7 @@
/* namei.c */

extern int affs_hash_name(const unsigned char *name, int len, int intl, int hashsize);
-extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry);
+extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry,int);
extern int affs_unlink(struct inode *dir, struct dentry *dentry);
extern int affs_create(struct inode *dir, struct dentry *dentry, int mode);
extern int affs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
diff -urN linux-bird.FAT/include/linux/dcache.h linux-bird.BLETCH/include/linux/dcache.h
--- linux-bird.FAT/include/linux/dcache.h Thu May 13 07:03:21 1999
+++ linux-bird.BLETCH/include/linux/dcache.h Tue May 25 06:36:48 1999
@@ -79,7 +79,7 @@
struct dentry_operations {
int (*d_revalidate)(struct dentry *, int);
int (*d_hash) (struct dentry *, struct qstr *);
- int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
+ int (*d_compare) (struct dentry *, struct qstr *, struct qstr *,int);
void (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
@@ -100,6 +100,14 @@
* renamed" and has to be
* deleted on the last dput()
*/
+#define DCACHE_VMS_LOSSAGE 0x0004 /* Case-preserving and case-insensitive
+ * is a brain-child of Vogons.
+ * Rename handling becomes especially
+ * interesting. This dentry is rename
+ * target that wants to change
+ * capitalization on a sucky
+ * filesystem.
+ */

/*
* d_drop() unhashes the entry from the parent
@@ -170,7 +178,7 @@
extern void d_move(struct dentry * entry, struct dentry * newdentry);

/* appendix may either be NULL or be used for transname suffixes */
-extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name);
+extern struct dentry * d_lookup(struct dentry *dir,struct qstr *name,int flags);

/* validate "insecure" dentry pointer */
extern int d_validate(struct dentry *dentry, struct dentry *dparent,
diff -urN linux-bird.FAT/include/linux/ext2_fs.h linux-bird.BLETCH/include/linux/ext2_fs.h
--- linux-bird.FAT/include/linux/ext2_fs.h Thu May 13 07:03:22 1999
+++ linux-bird.BLETCH/include/linux/ext2_fs.h Tue May 25 07:58:27 1999
@@ -572,7 +572,7 @@

/* namei.c */
extern void ext2_release (struct inode *, struct file *);
-extern struct dentry *ext2_lookup (struct inode *, struct dentry *);
+extern struct dentry *ext2_lookup (struct inode *, struct dentry *,int);
extern int ext2_create (struct inode *,struct dentry *,int);
extern int ext2_mkdir (struct inode *,struct dentry *,int);
extern int ext2_rmdir (struct inode *,struct dentry *);
diff -urN linux-bird.FAT/include/linux/fs.h linux-bird.BLETCH/include/linux/fs.h
--- linux-bird.FAT/include/linux/fs.h Tue May 25 22:47:44 1999
+++ linux-bird.BLETCH/include/linux/fs.h Tue May 25 14:53:35 1999
@@ -597,7 +597,7 @@
struct inode_operations {
struct file_operations * default_file_ops;
int (*create) (struct inode *,struct dentry *,int);
- struct dentry * (*lookup) (struct inode *,struct dentry *);
+ struct dentry * (*lookup) (struct inode *,struct dentry *,int);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -821,6 +821,7 @@
#define LOOKUP_DIRECTORY (2)
#define LOOKUP_SLASHOK (4)
#define LOOKUP_CONTINUE (8)
+#define LOOKUP_TARGET (16)

extern struct dentry * lookup_dentry(const char *, struct dentry *, unsigned int);
extern struct dentry * __namei(const char *, unsigned int);
diff -urN linux-bird.FAT/include/linux/iso_fs.h linux-bird.BLETCH/include/linux/iso_fs.h
--- linux-bird.FAT/include/linux/iso_fs.h Thu May 13 07:03:23 1999
+++ linux-bird.BLETCH/include/linux/iso_fs.h Tue May 25 07:20:46 1999
@@ -189,7 +189,7 @@

extern int isofs_open(struct inode * inode, struct file * filp);
extern void isofs_release(struct inode * inode, struct file * filp);
-extern struct dentry *isofs_lookup(struct inode * dir, struct dentry *);
+extern struct dentry *isofs_lookup(struct inode * dir, struct dentry *, int);
extern unsigned long isofs_count_free_inodes(struct super_block *sb);
extern int isofs_new_block(int dev);
extern int isofs_free_block(int dev, int block);
diff -urN linux-bird.FAT/include/linux/minix_fs.h linux-bird.BLETCH/include/linux/minix_fs.h
--- linux-bird.FAT/include/linux/minix_fs.h Thu May 13 07:03:23 1999
+++ linux-bird.BLETCH/include/linux/minix_fs.h Tue May 25 08:22:09 1999
@@ -89,7 +89,7 @@

#ifdef __KERNEL__

-extern struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry);
+extern struct dentry *minix_lookup(struct inode *, struct dentry *,int);
extern int minix_create(struct inode * dir, struct dentry *dentry, int mode);
extern int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode);
extern int minix_rmdir(struct inode * dir, struct dentry *dentry);
diff -urN linux-bird.FAT/include/linux/msdos_fs.h linux-bird.BLETCH/include/linux/msdos_fs.h
--- linux-bird.FAT/include/linux/msdos_fs.h Tue May 25 22:47:44 1999
+++ linux-bird.BLETCH/include/linux/msdos_fs.h Tue May 25 15:00:45 1999
@@ -288,7 +288,7 @@

/* msdos.c - these are for Umsdos */
extern void msdos_read_inode(struct inode *inode);
-extern struct dentry *msdos_lookup(struct inode *dir,struct dentry *);
+extern struct dentry *msdos_lookup(struct inode *dir,struct dentry *,int);
extern int msdos_create(struct inode *dir,struct dentry *dentry,int mode);
extern int msdos_rmdir(struct inode *dir,struct dentry *dentry);
extern int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode);
@@ -326,7 +326,7 @@
extern struct super_block *vfat_read_super(struct super_block *sb,void *data,
int silent);
extern void vfat_read_inode(struct inode *inode);
-extern struct dentry *vfat_lookup(struct inode *dir,struct dentry *);
+extern struct dentry *vfat_lookup(struct inode *dir,struct dentry *,int);

/* vfat/vfatfs_syms.c */
extern struct file_system_type vfat_fs_type;
diff -urN linux-bird.FAT/include/linux/proc_fs.h linux-bird.BLETCH/include/linux/proc_fs.h
--- linux-bird.FAT/include/linux/proc_fs.h Thu May 13 07:03:24 1999
+++ linux-bird.BLETCH/include/linux/proc_fs.h Tue May 25 14:53:49 1999
@@ -382,7 +382,7 @@
* of the /proc/<pid> subdirectories.
*/
extern int proc_readdir(struct file *, void *, filldir_t);
-extern struct dentry *proc_lookup(struct inode *, struct dentry *);
+extern struct dentry *proc_lookup(struct inode *, struct dentry *,int);

struct openpromfs_dev {
struct openpromfs_dev *next;
@@ -394,9 +394,9 @@
};
extern struct inode_operations *
proc_openprom_register(int (*readdir)(struct file *, void *, filldir_t),
- struct dentry * (*lookup)(struct inode *, struct dentry *),
- void (*use)(struct inode *, int),
- struct openpromfs_dev ***);
+ struct dentry * (*lookup)(struct inode *, struct dentry *,int),
+ void (*use)(struct inode *, int),
+ struct openpromfs_dev ***);
extern void proc_openprom_deregister(void);
extern void (*proc_openprom_use)(struct inode *,int);
extern int proc_openprom_regdev(struct openpromfs_dev *);
diff -urN linux-bird.FAT/include/linux/qnx4_fs.h linux-bird.BLETCH/include/linux/qnx4_fs.h
--- linux-bird.FAT/include/linux/qnx4_fs.h Thu May 13 07:03:24 1999
+++ linux-bird.BLETCH/include/linux/qnx4_fs.h Tue May 25 09:48:46 1999
@@ -95,7 +95,7 @@
#define QNX4DEBUG(X) (void) 0
#endif

-extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry);
+extern struct dentry *qnx4_lookup(struct inode *, struct dentry *, int);
extern unsigned long qnx4_count_free_inodes(struct super_block *sb);
extern unsigned long qnx4_count_free_blocks(struct super_block *sb);

diff -urN linux-bird.FAT/include/linux/sysv_fs.h linux-bird.BLETCH/include/linux/sysv_fs.h
--- linux-bird.FAT/include/linux/sysv_fs.h Thu May 13 07:03:25 1999
+++ linux-bird.BLETCH/include/linux/sysv_fs.h Tue May 25 15:10:24 1999
@@ -367,7 +367,7 @@
* Function prototypes
*/

-extern struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry);
+extern struct dentry *sysv_lookup(struct inode *, struct dentry *, int);
extern int sysv_create(struct inode * dir, struct dentry * dentry, int mode);
extern int sysv_mkdir(struct inode * dir, struct dentry * dentry, int mode);
extern int sysv_rmdir(struct inode * dir, struct dentry * dentry);
diff -urN linux-bird.FAT/include/linux/ufs_fs.h linux-bird.BLETCH/include/linux/ufs_fs.h
--- linux-bird.FAT/include/linux/ufs_fs.h Thu May 13 07:03:26 1999
+++ linux-bird.BLETCH/include/linux/ufs_fs.h Tue May 25 09:46:10 1999
@@ -540,7 +540,7 @@
extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);

/* namei.c */
-extern struct dentry *ufs_lookup (struct inode *, struct dentry *);
+extern struct dentry *ufs_lookup (struct inode *, struct dentry *, int);
extern int ufs_mkdir(struct inode *, struct dentry *, int);
extern int ufs_rmdir (struct inode *, struct dentry *);
extern int ufs_unlink (struct inode *, struct dentry *);
diff -urN linux-bird.FAT/include/linux/umsdos_fs.p linux-bird.BLETCH/include/linux/umsdos_fs.p
--- linux-bird.FAT/include/linux/umsdos_fs.p Thu May 13 07:03:26 1999
+++ linux-bird.BLETCH/include/linux/umsdos_fs.p Tue May 25 08:59:41 1999
@@ -10,7 +10,7 @@
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 dentry *UMSDOS_lookup(struct inode *, struct dentry *, int);
struct dentry *umsdos_lookup_dentry(struct dentry *, char *, int, int);
struct dentry *umsdos_covered(struct dentry *, char *, int);

@@ -107,7 +107,7 @@

/* 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 dentry *UMSDOS_rlookup (struct inode *dir, struct dentry *dentry, int);

/* symlink.c 23/01/95 03.38.30 */
\
 
 \ /
  Last update: 2005-03-22 13:51    [from the cache]
©2003-2011 Jasper Spaans