All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Liu Kui <kui.liu@virtuozzo.com>
To: Konstantin Khorenko <khorenko@virtuozzo.com>
Cc: azaitsev@virtuozzo.com, devel@openvz.org,
	Liu Kui <kui.liu@virtuozzo.com>
Subject: [Devel] [PATCH hci-8.1 1/3] fs/fuse: give num_openers and i_size_unstable each a single role
Date: Wed, 30 Sep 2026 13:44:48 +0800	[thread overview]
Message-ID: <20260930-close-wait-rework-v2-v1-1-f8062178544a@virtuozzo.com> (raw)
In-Reply-To: <20260930-close-wait-rework-v2-v1-0-f8062178544a@virtuozzo.com>

Currently fi->num_openers serves two purposes: it helps decide whether
the i_size attribute needs to be taken from the server, and it manages
when kio's file_open/file_close methods need to be called. The former
role already requires the extra i_size_unstable flag to handle lease
revokes, which makes num_openers redundant for that purpose.

Give each field a single role: use i_size_unstable as the "take the
attributes from the server" flag, and make num_openers a pure open
count managing the calls of kio's file_open/file_close. A new inode
starts with the i_size_unstable flag set, an open finding it set
refreshes the attributes and clears it on success, and the last
release sets it back after writeback has drained.

Also fix a bug where a failed refresh could re-trust stale local
attributes.

https://virtuozzo.atlassian.net/browse/VSTOR-147878

Signed-off-by: Liu Kui <kui.liu@virtuozzo.com>
---
 fs/fuse/file.c   | 21 ++++++++++++++++-----
 fs/fuse/fuse_i.h |  4 ++--
 fs/fuse/inode.c  |  5 +++--
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index e0efb524cda7..c41d6445c7e5 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -293,8 +293,14 @@ static int fuse_open_close_wait(struct inode *inode, struct file *file)
 		inode_lock(inode);
 	spin_lock(&fi->lock);
 
-	if (++fi->num_openers == 1 || fi->i_size_unstable) {
-		fi->i_size_unstable = 1;
+	fi->num_openers++;
+	/*
+	 * i_size_unstable set means the attributes must be taken from the
+	 * server: no open has refreshed them yet (first open), the last
+	 * opener is gone, or the files were invalidated by a lease revoke.
+	 * Refresh the attributes so ours can be trusted again.
+	 */
+	if (fi->i_size_unstable) {
 		fi->inval_mask = ~0;
 		spin_unlock(&fi->lock);
 		err = fuse_update_attributes(inode, file, ~0);
@@ -303,9 +309,10 @@ static int fuse_open_close_wait(struct inode *inode, struct file *file)
 			err = fc->kio.op->file_open(file, inode);
 
 		spin_lock(&fi->lock);
-		fi->i_size_unstable = 0;
 		if (err)
 			fi->num_openers--;
+		else
+			fi->i_size_unstable = 0;
 	}
 
 	file->f_mode |= FMODE_NOWAIT;
@@ -583,8 +590,12 @@ static int fuse_release(struct inode *inode, struct file *file)
 			wait_event(fi->page_waitq, refcount_read(&ff->count) == 1);
 
 		spin_lock(&fi->lock);
-		/* since now we can trust userspace attr.size */
-		fi->num_openers--;
+		/*
+		 * Last opener is gone and its writeback has drained: from
+		 * now on take the attributes from the server again.
+		 */
+		if (--fi->num_openers == 0)
+			fi->i_size_unstable = 1;
 		spin_unlock(&fi->lock);
 	} else if (fc->close_wait)
 		wait_event(fi->page_waitq, refcount_read(&ff->count) == 1);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 21f873337627..f6da643b9c86 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -200,10 +200,10 @@ struct fuse_inode {
 	/** Reference to backing file in passthrough mode */
 	struct fuse_backing *fb;
 #endif
-	/** Mostly to detect very first open */
+	/** Number of opens, drives kio file_open/file_close pairing */
 	int num_openers;
 
-	/** Even though num_openers>0, trust server i_size */
+	/** Take attributes (i_size) from the server, don't trust ours */
 	int i_size_unstable;
 
 	/** Private kdirect io context */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index eb2e9a4f8756..4eaa89d9c46c 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -116,7 +116,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
 	fi->orig_ino = 0;
 	fi->state = 0;
 	fi->submount_lookup = NULL;
-	fi->i_size_unstable = 0;
+	/* take attributes from the server until the first open */
+	fi->i_size_unstable = 1;
 	fi->private = NULL;
 	fi->inval_files_seq = 0;
 	INIT_LIST_HEAD(&fi->rw_files);
@@ -328,7 +329,7 @@ u32 fuse_get_cache_mask(struct inode *inode)
 	if (fc->close_wait) {
 		struct fuse_inode *fi = get_fuse_inode(inode);
 
-		if (!fi->num_openers || fi->i_size_unstable)
+		if (fi->i_size_unstable)
 			return 0;
 	}
 

-- 
Git-155)

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  reply	other threads:[~2026-09-30  5:46 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30  5:44 [Devel] [PATCH hci-8.1 0/3] fs/fuse: rework close_wait handling Liu Kui
2026-09-30  5:44 ` Liu Kui [this message]
2026-09-30  5:50   ` [Devel] [PATCH hci-8.1 1/3] fs/fuse: give num_openers and i_size_unstable each a single role no-reply
2026-09-30  5:44 ` [Devel] [PATCH hci-8.1 2/3] fs/fuse: move the close_wait handling of fuse_release() into a helper Liu Kui
2026-09-30  5:49   ` no-reply
2026-09-30  5:44 ` [Devel] [PATCH hci-8.1 3/3] fs/fuse: use wait_var_event to wait for fuse file references Liu Kui
2026-09-30  5:51   ` no-reply
2026-09-30 15:39 ` [Devel] [PATCH hci-8.1 0/3] fs/fuse: rework close_wait handling Konstantin Khorenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260930-close-wait-rework-v2-v1-1-f8062178544a@virtuozzo.com \
    --to=kui.liu@virtuozzo.com \
    --cc=azaitsev@virtuozzo.com \
    --cc=devel@openvz.org \
    --cc=khorenko@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.