<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="color: rgb(0, 0, 0);"><span style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt;"><br>
</span><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", -apple-system, "system-ui", Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; background-color: rgb(255, 255, 255);">here is the link </span></div>
<div class="elementToProof" style="font-family: "Segoe UI", "Segoe UI Web (West European)", -apple-system, "system-ui", Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; color: rgb(0, 0, 0);">
<span style="background-color: rgb(255, 255, 255);"><a href="https://virtuozzo.atlassian.net/browse/VSTOR-136027">https://virtuozzo.atlassian.net/browse/VSTOR-136027</a></span></div>
<div class="elementToProof" style="font-family: "Segoe UI", "Segoe UI Web (West European)", -apple-system, "system-ui", Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; color: rgb(0, 0, 0);">
<span style="background-color: rgb(255, 255, 255);">the AI analysis is valid; I'm working on a new one. </span></div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Pavel Tikhomirov <ptikhomirov@virtuozzo.com><br>
<b>Sent:</b> 25 June 2026 17:03<br>
<b>To:</b> Kui Liu <kui.liu@virtuozzo.com>; devel@openvz.org <devel@openvz.org><br>
<b>Cc:</b> Andrey Zaitsev <azaitsev@virtuozzo.com><br>
<b>Subject:</b> Re: [Devel] [PATCH VZ10 v2] fs/fuse: align fuse_create_open()'s open path with fuse_open()</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText"><br>
<br>
On 6/23/26 08:43, Liu Kui wrote:<br>
> fuse_create_open()'s close_wait branch was not correct -- in particular<br>
> the fput() in its error path was wrong; fuse_open()'s close_wait branch<br>
> should apply instead. Refactor the close_wait branch into a new<br>
> function used in both places. fuse_sync_release() applies to the<br>
> close_wait error path in both places.<br>
> <br>
<br>
Is there a bug link?<br>
<br>
> Signed-off-by: Liu Kui <kui.liu@virtuozzo.com><br>
> ---<br>
> Changes in v2:<br>
> - Factor the close_wait open branch into fuse_open_close_wait(); <br>
> call it from both fuse_open() and fuse_create_open() instead of<br>
> duplicating the block in each.<br>
> - Use fuse_sync_release() on the close_wait error path for both<br>
> callers. It is functionally equivalent to fuse_release_common() <br>
> used in fuse_open(). <br>
> <br>
> fs/fuse/dir.c | 18 ++-----------<br>
> fs/fuse/file.c | 67 +++++++++++++++++++++++++++---------------------<br>
> fs/fuse/fuse_i.h | 1 +<br>
> 3 files changed, 41 insertions(+), 45 deletions(-)<br>
> <br>
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c<br>
> index 45ee4f1e4b68..2faf052632d6 100644<br>
> --- a/fs/fuse/dir.c<br>
> +++ b/fs/fuse/dir.c<br>
> @@ -722,22 +722,8 @@ static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,<br>
> invalidate_inode_pages2(inode->i_mapping);<br>
> }<br>
> <br>
> - if (fm->fc->close_wait) {<br>
> - struct fuse_inode *fi = get_fuse_inode(inode);<br>
> - bool need_open;<br>
> -<br>
> - inode_lock(inode);<br>
> - spin_lock(&fi->lock);<br>
> - need_open = (++fi->num_openers == 1);<br>
> - spin_unlock(&fi->lock);<br>
> -<br>
> - if (need_open && fm->fc->kio.op && fm->fc->kio.op->file_open) {<br>
> - err = fm->fc->kio.op->file_open(file, inode);<br>
> - if (err)<br>
> - fput(file);<br>
> - }<br>
> - inode_unlock(inode);<br>
> - }<br>
> + if (!err && fm->fc->close_wait)<br>
> + err = fuse_open_close_wait(inode, file);<br>
> <br>
> return err;<br>
> <br>
> diff --git a/fs/fuse/file.c b/fs/fuse/file.c<br>
> index 58202a96517e..faf39887125a 100644<br>
> --- a/fs/fuse/file.c<br>
> +++ b/fs/fuse/file.c<br>
> @@ -337,6 +337,42 @@ static void fuse_truncate_update_attr(struct inode *inode, struct file *file)<br>
> fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);<br>
> }<br>
> <br>
> +int fuse_open_close_wait(struct inode *inode, struct file *file)<br>
> +{<br>
> + struct fuse_conn *fc = get_fuse_conn(inode);<br>
> + struct fuse_inode *fi = get_fuse_inode(inode);<br>
> + struct fuse_file *ff = file->private_data;<br>
> + int err = 0;<br>
> +<br>
> + inode_lock(inode);<br>
> + spin_lock(&fi->lock);<br>
> +<br>
> + if (++fi->num_openers == 1 || fi->i_size_unstable) {<br>
> + fi->i_size_unstable = 1;<br>
> + fi->inval_mask = ~0;<br>
> + spin_unlock(&fi->lock);<br>
> + err = fuse_update_attributes(inode, file, ~0);<br>
> +<br>
> + if (!err && fc->kio.op && fc->kio.op->file_open)<br>
> + err = fc->kio.op->file_open(file, inode);<br>
> +<br>
> + spin_lock(&fi->lock);<br>
> + fi->i_size_unstable = 0;<br>
> + if (err)<br>
> + fi->num_openers--;<br>
> + }<br>
> +<br>
> + file->f_mode |= FMODE_NOWAIT;<br>
> +<br>
> + spin_unlock(&fi->lock);<br>
> + inode_unlock(inode);<br>
> +<br>
> + if (err)<br>
> + fuse_sync_release(fi, ff, file->f_flags);<br>
> +<br>
> + return err;<br>
> +}<br>
> +<br>
> static int fuse_open(struct inode *inode, struct file *file)<br>
> {<br>
> struct fuse_mount *fm = get_fuse_mount(inode);<br>
> @@ -399,35 +435,8 @@ static int fuse_open(struct inode *inode, struct file *file)<br>
> if (is_wb_truncate || dax_truncate)<br>
> inode_unlock(inode);<br>
> <br>
> - if (!err && fc->close_wait) {<br>
> - inode_lock(inode);<br>
> - spin_lock(&fi->lock);<br>
> -<br>
> - if (++fi->num_openers == 1 || fi->i_size_unstable) {<br>
> - fi->i_size_unstable = 1;<br>
> - fi->inval_mask = ~0;<br>
> - spin_unlock(&fi->lock);<br>
> - err = fuse_update_attributes(inode, file, ~0);<br>
> -<br>
> - if (!err && fc->kio.op && fc->kio.op->file_open)<br>
> - err = fc->kio.op->file_open(file, inode);<br>
> -<br>
> - spin_lock(&fi->lock);<br>
> - fi->i_size_unstable = 0;<br>
> - if (err)<br>
> - fi->num_openers--;<br>
> - }<br>
> -<br>
> - file->f_mode |= FMODE_NOWAIT;<br>
> -<br>
> - spin_unlock(&fi->lock);<br>
> - inode_unlock(inode);<br>
> -<br>
> - if (err) {<br>
> - fuse_release_common(file, false);<br>
> - return err;<br>
> - }<br>
> - }<br>
> + if (!err && fc->close_wait)<br>
> + err = fuse_open_close_wait(inode, file);<br>
> <br>
> return err;<br>
> }<br>
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h<br>
> index a834a5b4dfe2..6f462f0c4c3c 100644<br>
> --- a/fs/fuse/fuse_i.h<br>
> +++ b/fs/fuse/fuse_i.h<br>
> @@ -1317,6 +1317,7 @@ void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,<br>
> struct fuse_file *fuse_file_alloc(struct fuse_mount *fm, bool release);<br>
> void fuse_file_free(struct fuse_file *ff);<br>
> int fuse_finish_open(struct inode *inode, struct file *file);<br>
> +int fuse_open_close_wait(struct inode *inode, struct file *file);<br>
> <br>
> void fuse_sync_release(struct fuse_inode *fi, struct fuse_file *ff,<br>
> unsigned int flags);<br>
<br>
-- <br>
Best regards, Pavel Tikhomirov<br>
Senior Software Developer, Virtuozzo.<br>
<br>
</div>
</span></font></div>
</body>
</html>