Merge tag 'nfs-for-4.19-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[sfrench/cifs-2.6.git] / fs / nfs / dir.c
index a004b8fc02da34cebc036450a6d14268079da779..8bfaa658b2c190ddfa61f8a52acb4895b9f63b1d 100644 (file)
@@ -1440,12 +1440,11 @@ static int do_open(struct inode *inode, struct file *filp)
 
 static int nfs_finish_open(struct nfs_open_context *ctx,
                           struct dentry *dentry,
-                          struct file *file, unsigned open_flags,
-                          int *opened)
+                          struct file *file, unsigned open_flags)
 {
        int err;
 
-       err = finish_open(file, dentry, do_open, opened);
+       err = finish_open(file, dentry, do_open);
        if (err)
                goto out;
        if (S_ISREG(file->f_path.dentry->d_inode->i_mode))
@@ -1458,7 +1457,7 @@ out:
 
 int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
                    struct file *file, unsigned open_flags,
-                   umode_t mode, int *opened)
+                   umode_t mode)
 {
        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
        struct nfs_open_context *ctx;
@@ -1467,6 +1466,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
        struct inode *inode;
        unsigned int lookup_flags = 0;
        bool switched = false;
+       int created = 0;
        int err;
 
        /* Expect a negative dentry */
@@ -1527,7 +1527,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
                goto out;
 
        trace_nfs_atomic_open_enter(dir, ctx, open_flags);
-       inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr, opened);
+       inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr, &created);
+       if (created)
+               file->f_mode |= FMODE_CREATED;
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
@@ -1552,7 +1554,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
                goto out;
        }
 
-       err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened);
+       err = nfs_finish_open(ctx, ctx->dentry, file, open_flags);
        trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
        put_nfs_open_context(ctx);
 out:
@@ -1647,6 +1649,7 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
        struct dentry *parent = dget_parent(dentry);
        struct inode *dir = d_inode(parent);
        struct inode *inode;
+       struct dentry *d;
        int error = -EACCES;
 
        d_drop(dentry);
@@ -1668,10 +1671,12 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
                        goto out_error;
        }
        inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
-       error = PTR_ERR(inode);
-       if (IS_ERR(inode))
+       d = d_splice_alias(inode, dentry);
+       if (IS_ERR(d)) {
+               error = PTR_ERR(d);
                goto out_error;
-       d_add(dentry, inode);
+       }
+       dput(d);
 out:
        dput(parent);
        return 0;