fuse_create_open()'s close_wait branch is not correct -- in particular
the fput() in its error path is wrong. Mirror fuse_open()'s close_wait
branch instead.

Drop the redundant 'return err' in fuse_open()'s close_wait error path.

Signed-off-by: Liu Kui <[email protected]>
---
 fs/fuse/dir.c  | 27 ++++++++++++++++++++-------
 fs/fuse/file.c |  4 +---
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 45ee4f1e4b68..5fe0eb7c7e19 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -722,21 +722,34 @@ static int fuse_create_open(struct mnt_idmap *idmap, 
struct inode *dir,
                        invalidate_inode_pages2(inode->i_mapping);
        }
 
-       if (fm->fc->close_wait) {
+       if (!err && fm->fc->close_wait) {
                struct fuse_inode *fi = get_fuse_inode(inode);
-               bool need_open;
 
                inode_lock(inode);
                spin_lock(&fi->lock);
-               need_open = (++fi->num_openers == 1);
-               spin_unlock(&fi->lock);
 
-               if (need_open && fm->fc->kio.op && fm->fc->kio.op->file_open) {
-                       err = fm->fc->kio.op->file_open(file, inode);
+               if (++fi->num_openers == 1 || fi->i_size_unstable) {
+                       fi->i_size_unstable = 1;
+                       fi->inval_mask = ~0;
+                       spin_unlock(&fi->lock);
+                       err = fuse_update_attributes(inode, file, ~0);
+
+                       if (!err && fm->fc->kio.op && fm->fc->kio.op->file_open)
+                               err = fm->fc->kio.op->file_open(file, inode);
+
+                       spin_lock(&fi->lock);
+                       fi->i_size_unstable = 0;
                        if (err)
-                               fput(file);
+                               fi->num_openers--;
                }
+
+               file->f_mode |= FMODE_NOWAIT;
+
+               spin_unlock(&fi->lock);
                inode_unlock(inode);
+
+               if (err)
+                       fuse_sync_release(fi, ff, flags);
        }
 
        return err;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 58202a96517e..dda4a2a94435 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -423,10 +423,8 @@ static int fuse_open(struct inode *inode, struct file 
*file)
                spin_unlock(&fi->lock);
                inode_unlock(inode);
 
-               if (err) {
+               if (err)
                        fuse_release_common(file, false);
-                       return err;
-               }
        }
 
        return err;
-- 
2.50.1 (Apple Git-155)

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to