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.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index fe549f5ef20f..a847acf4d3cd 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1086,6 +1086,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
1086 struct dentry *res = NULL; 1086 struct dentry *res = NULL;
1087 struct inode *inode; 1087 struct inode *inode;
1088 int open_flags; 1088 int open_flags;
1089 int err;
1089 1090
1090 dfprintk(VFS, "NFS: atomic_lookup(%s/%ld), %s\n", 1091 dfprintk(VFS, "NFS: atomic_lookup(%s/%ld), %s\n",
1091 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1092 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
@@ -1119,9 +1120,8 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
1119 if (!IS_POSIXACL(dir)) 1120 if (!IS_POSIXACL(dir))
1120 attr.ia_mode &= ~current_umask(); 1121 attr.ia_mode &= ~current_umask();
1121 } else { 1122 } else {
1122 open_flags &= ~O_EXCL; 1123 open_flags &= ~(O_EXCL | O_CREAT);
1123 attr.ia_valid = 0; 1124 attr.ia_valid = 0;
1124 BUG_ON(open_flags & O_CREAT);
1125 } 1125 }
1126 1126
1127 /* Open the file on the server */ 1127 /* Open the file on the server */
@@ -1150,13 +1150,18 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
1150 } 1150 }
1151 } 1151 }
1152 res = d_add_unique(dentry, inode); 1152 res = d_add_unique(dentry, inode);
1153 nfs_unblock_sillyrename(dentry->d_parent);
1153 if (res != NULL) { 1154 if (res != NULL) {
1154 dput(ctx->path.dentry); 1155 dput(ctx->path.dentry);
1155 ctx->path.dentry = dget(res); 1156 ctx->path.dentry = dget(res);
1156 dentry = res; 1157 dentry = res;
1157 } 1158 }
1158 nfs_intent_set_file(nd, ctx); 1159 err = nfs_intent_set_file(nd, ctx);
1159 nfs_unblock_sillyrename(dentry->d_parent); 1160 if (err < 0) {
1161 if (res != NULL)
1162 dput(res);
1163 return ERR_PTR(err);
1164 }
1160out: 1165out:
1161 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1166 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1162 return res; 1167 return res;
@@ -1221,11 +1226,13 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1221 } 1226 }
1222 } 1227 }
1223 iput(inode); 1228 iput(inode);
1224 if (inode == dentry->d_inode) { 1229 if (inode != dentry->d_inode)
1225 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1226 nfs_intent_set_file(nd, ctx);
1227 } else
1228 goto out_drop; 1230 goto out_drop;
1231
1232 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1233 ret = nfs_intent_set_file(nd, ctx);
1234 if (ret >= 0)
1235 ret = 1;
1229out: 1236out:
1230 dput(parent); 1237 dput(parent);
1231 return ret; 1238 return ret;
@@ -1262,20 +1269,24 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode,
1262 ctx = nameidata_to_nfs_open_context(dentry, nd); 1269 ctx = nameidata_to_nfs_open_context(dentry, nd);
1263 error = PTR_ERR(ctx); 1270 error = PTR_ERR(ctx);
1264 if (IS_ERR(ctx)) 1271 if (IS_ERR(ctx))
1265 goto out_err; 1272 goto out_err_drop;
1266 } 1273 }
1267 1274
1268 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx); 1275 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx);
1269 if (error != 0) 1276 if (error != 0)
1270 goto out_put_ctx; 1277 goto out_put_ctx;
1271 if (ctx != NULL) 1278 if (ctx != NULL) {
1272 nfs_intent_set_file(nd, ctx); 1279 error = nfs_intent_set_file(nd, ctx);
1280 if (error < 0)
1281 goto out_err;
1282 }
1273 return 0; 1283 return 0;
1274out_put_ctx: 1284out_put_ctx:
1275 if (ctx != NULL) 1285 if (ctx != NULL)
1276 put_nfs_open_context(ctx); 1286 put_nfs_open_context(ctx);
1277out_err: 1287out_err_drop:
1278 d_drop(dentry); 1288 d_drop(dentry);
1289out_err:
1279 return error; 1290 return error;
1280} 1291}
1281 1292