Messages in this thread Patch in this message | | | Subject | Re: [RFC][PATCH] rename() on braindead filesystems | From | (Eric W. Biederman) | Date | 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/
| |