aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 196775c70948..dc93d356341b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1204,16 +1204,36 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1204 * operations that change the directory. We therefore save the 1204 * operations that change the directory. We therefore save the
1205 * change attribute *before* we do the RPC call. 1205 * change attribute *before* we do the RPC call.
1206 */ 1206 */
1207 ret = nfs4_open_revalidate(dir, ctx, openflags); 1207 inode = nfs4_atomic_open(dir, ctx, openflags, NULL);
1208 if (ret == 1) 1208 if (IS_ERR(inode)) {
1209 ret = PTR_ERR(inode);
1210 switch (ret) {
1211 case -EPERM:
1212 case -EACCES:
1213 case -EDQUOT:
1214 case -ENOSPC:
1215 case -EROFS:
1216 goto out_put_ctx;
1217 default:
1218 goto out_drop;
1219 }
1220 }
1221 iput(inode);
1222 if (inode == dentry->d_inode) {
1223 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1209 nfs_intent_set_file(nd, ctx); 1224 nfs_intent_set_file(nd, ctx);
1210 else 1225 } else
1211 put_nfs_open_context(ctx); 1226 goto out_drop;
1212out: 1227out:
1213 dput(parent); 1228 dput(parent);
1214 if (!ret)
1215 d_drop(dentry);
1216 return ret; 1229 return ret;
1230out_drop:
1231 d_drop(dentry);
1232 ret = 0;
1233out_put_ctx:
1234 put_nfs_open_context(ctx);
1235 goto out;
1236
1217no_open_dput: 1237no_open_dput:
1218 dput(parent); 1238 dput(parent);
1219no_open: 1239no_open: