diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2006-09-08 17:22:21 -0400 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2006-09-24 16:50:45 -0400 |
commit | 349457ccf2592c14bdf13b6706170ae2e94931b1 (patch) | |
tree | 3670945b5a62617d38cf1f317487387032d3da4d | |
parent | 1390334b4c697b7588d5661fcf6acaeec409cf4c (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.c | 6 | ||||
-rw-r--r-- | fs/nfs/dir.c | 3 | ||||
-rw-r--r-- | fs/nfs/super.c | 10 | ||||
-rw-r--r-- | include/linux/fs.h | 7 |
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 | ||
77 | struct file_system_type nfs_xdev_fs_type = { | 77 | struct 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 | ||
85 | static struct super_operations nfs_sops = { | 85 | static 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 | ||
113 | struct file_system_type nfs4_xdev_fs_type = { | 113 | struct 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 | ||
121 | struct file_system_type nfs4_referral_fs_type = { | 121 | struct 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 | ||
129 | static struct super_operations nfs4_sops = { | 129 | static 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 | */ |