[PATCH] Allow file systems to manually d_move() inside of ->rename()
authorMark Fasheh <mark.fasheh@oracle.com>
Fri, 8 Sep 2006 21:22:21 +0000 (14:22 -0700)
committerMark Fasheh <mark.fasheh@oracle.com>
Sun, 24 Sep 2006 20:50:45 +0000 (13:50 -0700)
Some file systems want to manually d_move() the dentries involved in a
rename.  We can do this by making use of the FS_ODD_RENAME flag if we just
have nfs_rename() unconditionally do the d_move().  While there, we rename
the flag to be more descriptive.

OCFS2 uses this to protect that part of the rename operation with a cluster
lock.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
fs/namei.c
fs/nfs/dir.c
fs/nfs/super.c
include/linux/fs.h

index 432d6bc6fab086ef8254119a0b39fc97bee7025b..6b591c01b09fcbff6775cbcb8ca7fc8a62c195ca 100644 (file)
@@ -2370,7 +2370,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
                dput(new_dentry);
        }
        if (!error)
-               d_move(old_dentry,new_dentry);
+               if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
+                       d_move(old_dentry,new_dentry);
        return error;
 }
 
@@ -2393,8 +2394,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
        else
                error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
        if (!error) {
-               /* The following d_move() should become unconditional */
-               if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
+               if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
                        d_move(old_dentry, new_dentry);
        }
        if (target)
index 3419c2da9ba9d25e40dcbc67846ba627477cdad2..7432f1a43f3d6bc66c3aee43366a3111a46b8ad8 100644 (file)
@@ -1669,8 +1669,7 @@ out:
        if (rehash)
                d_rehash(rehash);
        if (!error) {
-               if (!S_ISDIR(old_inode->i_mode))
-                       d_move(old_dentry, new_dentry);
+               d_move(old_dentry, new_dentry);
                nfs_renew_times(new_dentry);
                nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir));
        }
index b99113b0f65fa222acfdb29e1e8443755b18add5..e8d40030cab4939264b4e2d2350cea9ae6c60546 100644 (file)
@@ -71,7 +71,7 @@ static struct file_system_type nfs_fs_type = {
        .name           = "nfs",
        .get_sb         = nfs_get_sb,
        .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
 struct file_system_type nfs_xdev_fs_type = {
@@ -79,7 +79,7 @@ struct file_system_type nfs_xdev_fs_type = {
        .name           = "nfs",
        .get_sb         = nfs_xdev_get_sb,
        .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
 static struct super_operations nfs_sops = {
@@ -107,7 +107,7 @@ static struct file_system_type nfs4_fs_type = {
        .name           = "nfs4",
        .get_sb         = nfs4_get_sb,
        .kill_sb        = nfs4_kill_super,
-       .fs_flags       = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
 struct file_system_type nfs4_xdev_fs_type = {
@@ -115,7 +115,7 @@ struct file_system_type nfs4_xdev_fs_type = {
        .name           = "nfs4",
        .get_sb         = nfs4_xdev_get_sb,
        .kill_sb        = nfs4_kill_super,
-       .fs_flags       = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
 struct file_system_type nfs4_referral_fs_type = {
@@ -123,7 +123,7 @@ struct file_system_type nfs4_referral_fs_type = {
        .name           = "nfs4",
        .get_sb         = nfs4_referral_get_sb,
        .kill_sb        = nfs4_kill_super,
-       .fs_flags       = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
 static struct super_operations nfs4_sops = {
index 555bc195c4207cbecf1dba61a43268a1e7692326..1d3e601ece7396263ef5cc40c14c6c0691548452 100644 (file)
@@ -92,9 +92,10 @@ extern int dir_notify_enable;
 #define FS_REQUIRES_DEV 1 
 #define FS_BINARY_MOUNTDATA 2
 #define FS_REVAL_DOT   16384   /* Check the paths ".", ".." for staleness */
-#define FS_ODD_RENAME  32768   /* Temporary stuff; will go away as soon
-                                 * as nfs_rename() will be cleaned up
-                                 */
+#define FS_RENAME_DOES_D_MOVE  32768   /* FS will handle d_move()
+                                        * during rename() internally.
+                                        */
+
 /*
  * These are the fs-independent mount-flags: up to 32 flags are supported
  */