diff options
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 996dd8989a91..d33da530097a 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -438,7 +438,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
438 | if (dentry == NULL) | 438 | if (dentry == NULL) |
439 | return; | 439 | return; |
440 | 440 | ||
441 | dentry->d_op = NFS_PROTO(dir)->dentry_ops; | 441 | d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops); |
442 | inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); | 442 | inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); |
443 | if (IS_ERR(inode)) | 443 | if (IS_ERR(inode)) |
444 | goto out; | 444 | goto out; |
@@ -938,7 +938,8 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry) | |||
938 | * component of the path. | 938 | * component of the path. |
939 | * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT. | 939 | * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT. |
940 | */ | 940 | */ |
941 | static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask) | 941 | static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, |
942 | unsigned int mask) | ||
942 | { | 943 | { |
943 | if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT)) | 944 | if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT)) |
944 | return 0; | 945 | return 0; |
@@ -1018,7 +1019,7 @@ int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, | |||
1018 | * If the parent directory is seen to have changed, we throw out the | 1019 | * If the parent directory is seen to have changed, we throw out the |
1019 | * cached dentry and do a new lookup. | 1020 | * cached dentry and do a new lookup. |
1020 | */ | 1021 | */ |
1021 | static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) | 1022 | static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) |
1022 | { | 1023 | { |
1023 | struct inode *dir; | 1024 | struct inode *dir; |
1024 | struct inode *inode; | 1025 | struct inode *inode; |
@@ -1027,6 +1028,9 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) | |||
1027 | struct nfs_fattr *fattr = NULL; | 1028 | struct nfs_fattr *fattr = NULL; |
1028 | int error; | 1029 | int error; |
1029 | 1030 | ||
1031 | if (nd->flags & LOOKUP_RCU) | ||
1032 | return -ECHILD; | ||
1033 | |||
1030 | parent = dget_parent(dentry); | 1034 | parent = dget_parent(dentry); |
1031 | dir = parent->d_inode; | 1035 | dir = parent->d_inode; |
1032 | nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE); | 1036 | nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE); |
@@ -1117,7 +1121,7 @@ out_error: | |||
1117 | /* | 1121 | /* |
1118 | * This is called from dput() when d_count is going to 0. | 1122 | * This is called from dput() when d_count is going to 0. |
1119 | */ | 1123 | */ |
1120 | static int nfs_dentry_delete(struct dentry *dentry) | 1124 | static int nfs_dentry_delete(const struct dentry *dentry) |
1121 | { | 1125 | { |
1122 | dfprintk(VFS, "NFS: dentry_delete(%s/%s, %x)\n", | 1126 | dfprintk(VFS, "NFS: dentry_delete(%s/%s, %x)\n", |
1123 | dentry->d_parent->d_name.name, dentry->d_name.name, | 1127 | dentry->d_parent->d_name.name, dentry->d_name.name, |
@@ -1188,7 +1192,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru | |||
1188 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) | 1192 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) |
1189 | goto out; | 1193 | goto out; |
1190 | 1194 | ||
1191 | dentry->d_op = NFS_PROTO(dir)->dentry_ops; | 1195 | d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops); |
1192 | 1196 | ||
1193 | /* | 1197 | /* |
1194 | * If we're doing an exclusive create, optimize away the lookup | 1198 | * If we're doing an exclusive create, optimize away the lookup |
@@ -1333,7 +1337,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
1333 | res = ERR_PTR(-ENAMETOOLONG); | 1337 | res = ERR_PTR(-ENAMETOOLONG); |
1334 | goto out; | 1338 | goto out; |
1335 | } | 1339 | } |
1336 | dentry->d_op = NFS_PROTO(dir)->dentry_ops; | 1340 | d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops); |
1337 | 1341 | ||
1338 | /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash | 1342 | /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash |
1339 | * the dentry. */ | 1343 | * the dentry. */ |
@@ -1718,11 +1722,9 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1718 | dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, | 1722 | dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, |
1719 | dir->i_ino, dentry->d_name.name); | 1723 | dir->i_ino, dentry->d_name.name); |
1720 | 1724 | ||
1721 | spin_lock(&dcache_lock); | ||
1722 | spin_lock(&dentry->d_lock); | 1725 | spin_lock(&dentry->d_lock); |
1723 | if (atomic_read(&dentry->d_count) > 1) { | 1726 | if (dentry->d_count > 1) { |
1724 | spin_unlock(&dentry->d_lock); | 1727 | spin_unlock(&dentry->d_lock); |
1725 | spin_unlock(&dcache_lock); | ||
1726 | /* Start asynchronous writeout of the inode */ | 1728 | /* Start asynchronous writeout of the inode */ |
1727 | write_inode_now(dentry->d_inode, 0); | 1729 | write_inode_now(dentry->d_inode, 0); |
1728 | error = nfs_sillyrename(dir, dentry); | 1730 | error = nfs_sillyrename(dir, dentry); |
@@ -1733,7 +1735,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1733 | need_rehash = 1; | 1735 | need_rehash = 1; |
1734 | } | 1736 | } |
1735 | spin_unlock(&dentry->d_lock); | 1737 | spin_unlock(&dentry->d_lock); |
1736 | spin_unlock(&dcache_lock); | ||
1737 | error = nfs_safe_remove(dentry); | 1738 | error = nfs_safe_remove(dentry); |
1738 | if (!error || error == -ENOENT) { | 1739 | if (!error || error == -ENOENT) { |
1739 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1740 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
@@ -1868,7 +1869,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1868 | dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n", | 1869 | dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n", |
1869 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, | 1870 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
1870 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name, | 1871 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name, |
1871 | atomic_read(&new_dentry->d_count)); | 1872 | new_dentry->d_count); |
1872 | 1873 | ||
1873 | /* | 1874 | /* |
1874 | * For non-directories, check whether the target is busy and if so, | 1875 | * For non-directories, check whether the target is busy and if so, |
@@ -1886,7 +1887,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1886 | rehash = new_dentry; | 1887 | rehash = new_dentry; |
1887 | } | 1888 | } |
1888 | 1889 | ||
1889 | if (atomic_read(&new_dentry->d_count) > 2) { | 1890 | if (new_dentry->d_count > 2) { |
1890 | int err; | 1891 | int err; |
1891 | 1892 | ||
1892 | /* copy the target dentry's name */ | 1893 | /* copy the target dentry's name */ |
@@ -2188,11 +2189,14 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags) | |||
2188 | return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); | 2189 | return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); |
2189 | } | 2190 | } |
2190 | 2191 | ||
2191 | int nfs_permission(struct inode *inode, int mask) | 2192 | int nfs_permission(struct inode *inode, int mask, unsigned int flags) |
2192 | { | 2193 | { |
2193 | struct rpc_cred *cred; | 2194 | struct rpc_cred *cred; |
2194 | int res = 0; | 2195 | int res = 0; |
2195 | 2196 | ||
2197 | if (flags & IPERM_FLAG_RCU) | ||
2198 | return -ECHILD; | ||
2199 | |||
2196 | nfs_inc_stats(inode, NFSIOS_VFSACCESS); | 2200 | nfs_inc_stats(inode, NFSIOS_VFSACCESS); |
2197 | 2201 | ||
2198 | if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) | 2202 | if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) |
@@ -2240,7 +2244,7 @@ out: | |||
2240 | out_notsup: | 2244 | out_notsup: |
2241 | res = nfs_revalidate_inode(NFS_SERVER(inode), inode); | 2245 | res = nfs_revalidate_inode(NFS_SERVER(inode), inode); |
2242 | if (res == 0) | 2246 | if (res == 0) |
2243 | res = generic_permission(inode, mask, NULL); | 2247 | res = generic_permission(inode, mask, flags, NULL); |
2244 | goto out; | 2248 | goto out; |
2245 | } | 2249 | } |
2246 | 2250 | ||