here is the link https://virtuozzo.atlassian.net/browse/VSTOR-136027 the AI analysis is valid; I'm working on a new one. ________________________________ From: Pavel Tikhomirov <[email protected]> Sent: 25 June 2026 17:03 To: Kui Liu <[email protected]>; [email protected] <[email protected]> Cc: Andrey Zaitsev <[email protected]> Subject: Re: [Devel] [PATCH VZ10 v2] fs/fuse: align fuse_create_open()'s open path with fuse_open()
On 6/23/26 08:43, Liu Kui wrote: > fuse_create_open()'s close_wait branch was not correct -- in particular > the fput() in its error path was wrong; fuse_open()'s close_wait branch > should apply instead. Refactor the close_wait branch into a new > function used in both places. fuse_sync_release() applies to the > close_wait error path in both places. > Is there a bug link? > Signed-off-by: Liu Kui <[email protected]> > --- > Changes in v2: > - Factor the close_wait open branch into fuse_open_close_wait(); > call it from both fuse_open() and fuse_create_open() instead of > duplicating the block in each. > - Use fuse_sync_release() on the close_wait error path for both > callers. It is functionally equivalent to fuse_release_common() > used in fuse_open(). > > fs/fuse/dir.c | 18 ++----------- > fs/fuse/file.c | 67 +++++++++++++++++++++++++++--------------------- > fs/fuse/fuse_i.h | 1 + > 3 files changed, 41 insertions(+), 45 deletions(-) > > diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c > index 45ee4f1e4b68..2faf052632d6 100644 > --- a/fs/fuse/dir.c > +++ b/fs/fuse/dir.c > @@ -722,22 +722,8 @@ static int fuse_create_open(struct mnt_idmap *idmap, > struct inode *dir, > invalidate_inode_pages2(inode->i_mapping); > } > > - if (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 (err) > - fput(file); > - } > - inode_unlock(inode); > - } > + if (!err && fm->fc->close_wait) > + err = fuse_open_close_wait(inode, file); > > return err; > > diff --git a/fs/fuse/file.c b/fs/fuse/file.c > index 58202a96517e..faf39887125a 100644 > --- a/fs/fuse/file.c > +++ b/fs/fuse/file.c > @@ -337,6 +337,42 @@ static void fuse_truncate_update_attr(struct inode > *inode, struct file *file) > fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE); > } > > +int fuse_open_close_wait(struct inode *inode, struct file *file) > +{ > + struct fuse_conn *fc = get_fuse_conn(inode); > + struct fuse_inode *fi = get_fuse_inode(inode); > + struct fuse_file *ff = file->private_data; > + int err = 0; > + > + inode_lock(inode); > + spin_lock(&fi->lock); > + > + 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 && fc->kio.op && fc->kio.op->file_open) > + err = fc->kio.op->file_open(file, inode); > + > + spin_lock(&fi->lock); > + fi->i_size_unstable = 0; > + if (err) > + fi->num_openers--; > + } > + > + file->f_mode |= FMODE_NOWAIT; > + > + spin_unlock(&fi->lock); > + inode_unlock(inode); > + > + if (err) > + fuse_sync_release(fi, ff, file->f_flags); > + > + return err; > +} > + > static int fuse_open(struct inode *inode, struct file *file) > { > struct fuse_mount *fm = get_fuse_mount(inode); > @@ -399,35 +435,8 @@ static int fuse_open(struct inode *inode, struct file > *file) > if (is_wb_truncate || dax_truncate) > inode_unlock(inode); > > - if (!err && fc->close_wait) { > - inode_lock(inode); > - spin_lock(&fi->lock); > - > - 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 && fc->kio.op && fc->kio.op->file_open) > - err = fc->kio.op->file_open(file, inode); > - > - spin_lock(&fi->lock); > - fi->i_size_unstable = 0; > - if (err) > - fi->num_openers--; > - } > - > - file->f_mode |= FMODE_NOWAIT; > - > - spin_unlock(&fi->lock); > - inode_unlock(inode); > - > - if (err) { > - fuse_release_common(file, false); > - return err; > - } > - } > + if (!err && fc->close_wait) > + err = fuse_open_close_wait(inode, file); > > return err; > } > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h > index a834a5b4dfe2..6f462f0c4c3c 100644 > --- a/fs/fuse/fuse_i.h > +++ b/fs/fuse/fuse_i.h > @@ -1317,6 +1317,7 @@ void fuse_read_args_fill(struct fuse_io_args *ia, > struct file *file, loff_t pos, > struct fuse_file *fuse_file_alloc(struct fuse_mount *fm, bool release); > void fuse_file_free(struct fuse_file *ff); > int fuse_finish_open(struct inode *inode, struct file *file); > +int fuse_open_close_wait(struct inode *inode, struct file *file); > > void fuse_sync_release(struct fuse_inode *fi, struct fuse_file *ff, > unsigned int flags); -- Best regards, Pavel Tikhomirov Senior Software Developer, Virtuozzo.
_______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
