Re: [RFC][PATCH] rename() on braindead filesystems

Eric W. Biederman (ebiederm+eric@ccr.net)
29 May 1999 12:22:00 -0500


For handling case changes how about something like this:

Where the idea is for renames:
a) Always change the case of the name in the dcache, (if the bytes don't match)
It doesn't hurt as it hashes the same, and compares the same,
and could be anything anyway, d_lookup is what sets it.
b) Explicitly allow the case where old_dentry->d_inode == new_dentry->d_inode
and the case has changed. (Either by calling inode->i_op->rename,
or a new function inode->i_op->case_change..)
c) In the filesystems affected handle the case where new_dentry == old_dentry.

The code below mostly implements this but it doesn't handle storage allocation
properly.

Eric

--- namei.c.good Sat May 29 11:08:15 1999
+++ namei.c Sat May 29 11:42:08 1999
@@ -1240,9 +1240,6 @@
int error;
int need_rehash = 0;

- if (old_dentry->d_inode == new_dentry->d_inode)
- return 0;
-
error = may_delete(old_dir, old_dentry, 1);
if (error)
return error;
@@ -1297,9 +1294,6 @@
{
int error;

- if (old_dentry->d_inode == new_dentry->d_inode)
- return 0;
-
error = may_delete(old_dir, old_dentry, 0);
if (error)
return error;
@@ -1330,8 +1324,19 @@
}

int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
+ struct inode *new_dir, struct dentry *new_dentry,
+ char *newname)
{
+ int byte_change = 0;
+ if (strcmp(new_dentry->d_name, newname) != 0) {
+ byte_change = 1;
+ strcpy(new_dentry->d_name, newname);
+ }
+ if ((old_dentry->d_inode == new_dentry->d_inode)
+ && (!byte_change || (new_dentry != old_dentry))) {
+ return 0;
+ }
+
if (S_ISDIR(old_dentry->d_inode->i_mode))
return vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
else
@@ -1373,7 +1378,7 @@
error = -ENOENT;
if (check_parent(old_dir, old_dentry) && check_parent(new_dir, new_dentry))
error = vfs_rename(old_dir->d_inode, old_dentry,
- new_dir->d_inode, new_dentry);
+ new_dir->d_inode, new_dentry, newname);

double_unlock(new_dir, old_dir);
dput(new_dentry);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/