diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-10-21 13:24:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-21 16:35:06 -0400 |
commit | 9eaef27b36a6b716384948da94b8fc5bfba7b712 (patch) | |
tree | ab69cf9c3863bb7ca564574c914e5b6bf8ad3162 /fs/nfs/dir.c | |
parent | 3f7705eab6722ad1a346d748c4aad55755d6c241 (diff) |
[PATCH] VFS: Make d_materialise_unique() enforce directory uniqueness
If the caller tries to instantiate a directory using an inode that already
has a dentry alias, then we attempt to rename the existing dentry instead
of instantiating a new one. Fail with an ELOOP error if the rename would
affect one of our parent directories.
This behaviour is needed in order to avoid issues such as
http://bugzilla.kernel.org/show_bug.cgi?id=7178
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Maneesh Soni <maneesh@in.ibm.com>
Cc: Dipankar Sarma <dipankar@in.ibm.com>
Cc: Neil Brown <neilb@cse.unsw.edu.au>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 4133ef5264e5..27b5a1051b1c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -935,8 +935,11 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru | |||
935 | 935 | ||
936 | no_entry: | 936 | no_entry: |
937 | res = d_materialise_unique(dentry, inode); | 937 | res = d_materialise_unique(dentry, inode); |
938 | if (res != NULL) | 938 | if (res != NULL) { |
939 | if (IS_ERR(res)) | ||
940 | goto out_unlock; | ||
939 | dentry = res; | 941 | dentry = res; |
942 | } | ||
940 | nfs_renew_times(dentry); | 943 | nfs_renew_times(dentry); |
941 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 944 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
942 | out_unlock: | 945 | out_unlock: |
@@ -1132,6 +1135,8 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) | |||
1132 | alias = d_materialise_unique(dentry, inode); | 1135 | alias = d_materialise_unique(dentry, inode); |
1133 | if (alias != NULL) { | 1136 | if (alias != NULL) { |
1134 | dput(dentry); | 1137 | dput(dentry); |
1138 | if (IS_ERR(alias)) | ||
1139 | return NULL; | ||
1135 | dentry = alias; | 1140 | dentry = alias; |
1136 | } | 1141 | } |
1137 | 1142 | ||