[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: 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>
This commit is contained in:
parent
1390334b4c
commit
349457ccf2
|
@ -2370,6 +2370,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
|
||||||
dput(new_dentry);
|
dput(new_dentry);
|
||||||
}
|
}
|
||||||
if (!error)
|
if (!error)
|
||||||
|
if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
|
||||||
d_move(old_dentry,new_dentry);
|
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,
|
||||||
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,7 +1669,6 @@ out:
|
||||||
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 = {
|
||||||
.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 = {
|
||||||
.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 = {
|
||||||
.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 = {
|
||||||
.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 = {
|
||||||
.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;
|
||||||
#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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue