aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2006-09-08 17:22:21 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2006-09-24 16:50:45 -0400
commit349457ccf2592c14bdf13b6706170ae2e94931b1 (patch)
tree3670945b5a62617d38cf1f317487387032d3da4d
parent1390334b4c697b7588d5661fcf6acaeec409cf4c (diff)
[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>
-rw-r--r--fs/namei.c6
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/super.c10
-rw-r--r--include/linux/fs.h7
4 files changed, 13 insertions, 13 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 432d6bc6fab0..6b591c01b09f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2370,7 +2370,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
2370 dput(new_dentry); 2370 dput(new_dentry);
2371 } 2371 }
2372 if (!error) 2372 if (!error)
2373 d_move(old_dentry,new_dentry); 2373 if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
2374 d_move(old_dentry,new_dentry);
2374 return error; 2375 return error;
2375} 2376}
2376 2377
@@ -2393,8 +2394,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
2393 else 2394 else
2394 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); 2395 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
2395 if (!error) { 2396 if (!error) {
2396 /* The following d_move() should become unconditional */ 2397 if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
2397 if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
2398 d_move(old_dentry, new_dentry); 2398 d_move(old_dentry, new_dentry);
2399 } 2399 }
2400 if (target) 2400 if (target)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 3419c2da9ba9..7432f1a43f3d 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1669,8 +1669,7 @@ out:
1669 if (rehash) 1669 if (rehash)
1670 d_rehash(rehash); 1670 d_rehash(rehash);
1671 if (!error) { 1671 if (!error) {
1672 if (!S_ISDIR(old_inode->i_mode)) 1672 d_move(old_dentry, new_dentry);
1673 d_move(old_dentry, new_dentry);
1674 nfs_renew_times(new_dentry); 1673 nfs_renew_times(new_dentry);
1675 nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir)); 1674 nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir));
1676 } 1675 }
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index b99113b0f65f..e8d40030cab4 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -71,7 +71,7 @@ static struct file_system_type nfs_fs_type = {
71 .name = "nfs", 71 .name = "nfs",
72 .get_sb = nfs_get_sb, 72 .get_sb = nfs_get_sb,
73 .kill_sb = nfs_kill_super, 73 .kill_sb = nfs_kill_super,
74 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 74 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
75}; 75};
76 76
77struct file_system_type nfs_xdev_fs_type = { 77struct file_system_type nfs_xdev_fs_type = {
@@ -79,7 +79,7 @@ struct file_system_type nfs_xdev_fs_type = {
79 .name = "nfs", 79 .name = "nfs",
80 .get_sb = nfs_xdev_get_sb, 80 .get_sb = nfs_xdev_get_sb,
81 .kill_sb = nfs_kill_super, 81 .kill_sb = nfs_kill_super,
82 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 82 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
83}; 83};
84 84
85static struct super_operations nfs_sops = { 85static struct super_operations nfs_sops = {
@@ -107,7 +107,7 @@ static struct file_system_type nfs4_fs_type = {
107 .name = "nfs4", 107 .name = "nfs4",
108 .get_sb = nfs4_get_sb, 108 .get_sb = nfs4_get_sb,
109 .kill_sb = nfs4_kill_super, 109 .kill_sb = nfs4_kill_super,
110 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 110 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
111}; 111};
112 112
113struct file_system_type nfs4_xdev_fs_type = { 113struct file_system_type nfs4_xdev_fs_type = {
@@ -115,7 +115,7 @@ struct file_system_type nfs4_xdev_fs_type = {
115 .name = "nfs4", 115 .name = "nfs4",
116 .get_sb = nfs4_xdev_get_sb, 116 .get_sb = nfs4_xdev_get_sb,
117 .kill_sb = nfs4_kill_super, 117 .kill_sb = nfs4_kill_super,
118 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 118 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
119}; 119};
120 120
121struct file_system_type nfs4_referral_fs_type = { 121struct file_system_type nfs4_referral_fs_type = {
@@ -123,7 +123,7 @@ struct file_system_type nfs4_referral_fs_type = {
123 .name = "nfs4", 123 .name = "nfs4",
124 .get_sb = nfs4_referral_get_sb, 124 .get_sb = nfs4_referral_get_sb,
125 .kill_sb = nfs4_kill_super, 125 .kill_sb = nfs4_kill_super,
126 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 126 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
127}; 127};
128 128
129static struct super_operations nfs4_sops = { 129static struct super_operations nfs4_sops = {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 555bc195c420..1d3e601ece73 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -92,9 +92,10 @@ extern int dir_notify_enable;
92#define FS_REQUIRES_DEV 1 92#define FS_REQUIRES_DEV 1
93#define FS_BINARY_MOUNTDATA 2 93#define FS_BINARY_MOUNTDATA 2
94#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */ 94#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
95#define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon 95#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move()
96 * as nfs_rename() will be cleaned up 96 * during rename() internally.
97 */ 97 */
98
98/* 99/*
99 * These are the fs-independent mount-flags: up to 32 flags are supported 100 * These are the fs-independent mount-flags: up to 32 flags are supported
100 */ 101 */