[Devel] [PATCH RHEL7 COMMIT] fuse kio: Make struct fuse_inode::num_openers int

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jul 13 15:30:58 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-862.6.3.vz7.62.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.6.3.vz7.62.3
------>
commit 700184e1e0cf307ff23c920c5e7460637402d15f
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Fri Jul 13 15:30:58 2018 +0300

    fuse kio: Make struct fuse_inode::num_openers int
    
    We always access this field under fuse_conn::lock; the only exception is in
    fuse_release(), but there is also dependence of the lock unlock. This field is
    always analyzed in connection with some other actions, so atomic does not have
    a sense. It just confuses a reader and may be a reason of bugs and
    misunderstood (this spin_unlock_wait() was added as a fix later, while it was
    skipped initially).
    
    So, this patch kills unneeded atomic.
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    Reviewed-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
 fs/fuse/dir.c    |  2 +-
 fs/fuse/file.c   | 15 +++++----------
 fs/fuse/fuse_i.h |  2 +-
 fs/fuse/inode.c  |  4 ++--
 4 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 66eff240cbb6..eee4887e9591 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -503,7 +503,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
 
 		mutex_lock(&inode->i_mutex);
 		spin_lock(&fc->lock);
-		need_open = (atomic_inc_return(&fi->num_openers) == 1);
+		need_open = (++fi->num_openers == 1);
 		spin_unlock(&fc->lock);
 
 		if (need_open && fc->kio.op && fc->kio.op->file_open) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 7f762c87d3bc..d7bd723635ec 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -299,7 +299,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
 		mutex_lock(&inode->i_mutex);
 		spin_lock(&fc->lock);
 
-		if (atomic_inc_return(&fi->num_openers) == 1) {
+		if (++fi->num_openers == 1) {
 			fi->i_size_unstable = 1;
 			spin_unlock(&fc->lock);
 			err = fuse_getattr_size(inode, file, &size);
@@ -310,7 +310,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
 			spin_lock(&fc->lock);
 			fi->i_size_unstable = 0;
 			if (err)
-				atomic_dec(&fi->num_openers);
+				fi->num_openers--;
 			else
 				i_size_write(inode, size);
 		}
@@ -439,15 +439,10 @@ static int fuse_release(struct inode *inode, struct file *file)
 		else
 			wait_event(fi->page_waitq, atomic_read(&ff->count) == 1);
 
-		/* Wait for threads just released ff to leave their critical sections.
-		 * Taking spinlock is the first thing fuse_release_common does, so that
-		 * this is unneseccary, but it is still good to emphasize right here,
-		 * that we need this.
-		 */
-		spin_unlock_wait(&ff->fc->lock);
-
+		spin_lock(&ff->fc->lock);
 		/* since now we can trust userspace attr.size */
-		atomic_dec(&fi->num_openers);
+		fi->num_openers--;
+		spin_unlock(&ff->fc->lock);
 	} else if (ff->fc->close_wait)
 		wait_event(fi->page_waitq, atomic_read(&ff->count) == 1);
 
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 0314be536799..da5cf0aed3ba 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -130,7 +130,7 @@ struct fuse_inode {
 	unsigned long state;
 
 	/** Mostly to detect very first open */
-	atomic_t num_openers;
+	int num_openers;
 
 	/** Even though num_openers>0, trust server i_size */
 	int i_size_unstable;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index df7789a40ca4..7a81025e3979 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -237,7 +237,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
 	 * attr->size coming from server can be stale. We cannot trust it.
 	 */
 	if (!is_wb || !S_ISREG(inode->i_mode) ||
-	    !atomic_read(&fi->num_openers) || fi->i_size_unstable)
+	    !fi->num_openers || fi->i_size_unstable)
 		i_size_write(inode, attr->size);
 	spin_unlock(&fc->lock);
 
@@ -269,8 +269,8 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
 static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 {
 	struct fuse_inode *fi = get_fuse_inode(inode);
-	atomic_set(&fi->num_openers, 0);
 
+	fi->num_openers = 0;
 	inode->i_mode = attr->mode & S_IFMT;
 	inode->i_size = attr->size;
 	inode->i_mtime.tv_sec  = attr->mtime;


More information about the Devel mailing list