Commit 349457cc authored by Mark Fasheh's avatar Mark Fasheh

[PATCH] Allow file systems to manually d_move() inside of ->rename()

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: default avatarMark 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: default avatarAndrew Morton <akpm@osdl.org>
parent 1390334b
...@@ -2370,7 +2370,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, ...@@ -2370,7 +2370,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
dput(new_dentry); dput(new_dentry);
} }
if (!error) 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; return error;
} }
...@@ -2393,8 +2394,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, ...@@ -2393,8 +2394,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
else else
error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
if (!error) { if (!error) {
/* The following d_move() should become unconditional */ if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
d_move(old_dentry, new_dentry); d_move(old_dentry, new_dentry);
} }
if (target) if (target)
......
...@@ -1669,8 +1669,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1669,8 +1669,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (rehash) if (rehash)
d_rehash(rehash); d_rehash(rehash);
if (!error) { 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_renew_times(new_dentry);
nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir)); nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir));
} }
......
...@@ -71,7 +71,7 @@ static struct file_system_type nfs_fs_type = { ...@@ -71,7 +71,7 @@ static struct file_system_type nfs_fs_type = {
.name = "nfs", .name = "nfs",
.get_sb = nfs_get_sb, .get_sb = nfs_get_sb,
.kill_sb = nfs_kill_super, .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 = { struct file_system_type nfs_xdev_fs_type = {
...@@ -79,7 +79,7 @@ struct file_system_type nfs_xdev_fs_type = { ...@@ -79,7 +79,7 @@ struct file_system_type nfs_xdev_fs_type = {
.name = "nfs", .name = "nfs",
.get_sb = nfs_xdev_get_sb, .get_sb = nfs_xdev_get_sb,
.kill_sb = nfs_kill_super, .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 = { static struct super_operations nfs_sops = {
...@@ -107,7 +107,7 @@ static struct file_system_type nfs4_fs_type = { ...@@ -107,7 +107,7 @@ static struct file_system_type nfs4_fs_type = {
.name = "nfs4", .name = "nfs4",
.get_sb = nfs4_get_sb, .get_sb = nfs4_get_sb,
.kill_sb = nfs4_kill_super, .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 = { struct file_system_type nfs4_xdev_fs_type = {
...@@ -115,7 +115,7 @@ struct file_system_type nfs4_xdev_fs_type = { ...@@ -115,7 +115,7 @@ struct file_system_type nfs4_xdev_fs_type = {
.name = "nfs4", .name = "nfs4",
.get_sb = nfs4_xdev_get_sb, .get_sb = nfs4_xdev_get_sb,
.kill_sb = nfs4_kill_super, .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 = { struct file_system_type nfs4_referral_fs_type = {
...@@ -123,7 +123,7 @@ struct file_system_type nfs4_referral_fs_type = { ...@@ -123,7 +123,7 @@ struct file_system_type nfs4_referral_fs_type = {
.name = "nfs4", .name = "nfs4",
.get_sb = nfs4_referral_get_sb, .get_sb = nfs4_referral_get_sb,
.kill_sb = nfs4_kill_super, .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 = { static struct super_operations nfs4_sops = {
......
...@@ -92,9 +92,10 @@ extern int dir_notify_enable; ...@@ -92,9 +92,10 @@ extern int dir_notify_enable;
#define FS_REQUIRES_DEV 1 #define FS_REQUIRES_DEV 1
#define FS_BINARY_MOUNTDATA 2 #define FS_BINARY_MOUNTDATA 2
#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */ #define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
#define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move()
* as nfs_rename() will be cleaned up * during rename() internally.
*/ */
/* /*
* These are the fs-independent mount-flags: up to 32 flags are supported * These are the fs-independent mount-flags: up to 32 flags are supported
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment