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
