[RHEL7,COMMIT] fuse: Teach fuse_blocked_for_wb() handle no files case

Submitted by Konstantin Khorenko on July 2, 2018, 10:08 a.m.

Details

Message ID 201807021008.w62A84OV001241@finist_ce7.work
State New
Series "fuse: Teach fuse_blocked_for_wb() handle no files case"
Headers show

Commit Message

Konstantin Khorenko July 2, 2018, 10:08 a.m.
The commit is pushed to "branch-rh7-3.10.0-862.3.2.vz7.61.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.3.2.vz7.61.7
------>
commit 29e39d5480edcfa50bc5eb1f31533c8d8a7ebb78
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Mon Jul 2 13:08:04 2018 +0300

    fuse: Teach fuse_blocked_for_wb() handle no files case
    
    Currently, fuse_blocked_for_wb() says inode is blocked for writeback even in
    case of there are no files. This leads to deadlock, since this waiting never
    ends.
    The patch changes the behaviour and makes the function to return "not blocked"
    in case of there is no files linked. It's OK for all current users of the
    function.
    
    Reported-by: Alexey Kuznetsov <kuznet@virtuozzo.com>
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 fs/fuse/file.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 09b04d40b5db..e870697be5ee 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -349,6 +349,7 @@  static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode)
 		rb_erase(&ff->polled_node, &fc->polled_files);
 	spin_unlock(&fc->lock);
 
+	wake_up(&fc->blocked_waitq);
 	wake_up_interruptible_all(&ff->poll_wait);
 
 	inarg->fh = ff->fh;
@@ -2274,7 +2275,7 @@  static inline bool fuse_blocked_for_wb(struct inode *inode)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	struct fuse_inode *fi = get_fuse_inode(inode);
-	bool blocked = true;
+	bool blocked = false;
 
 	if (!fc->blocked)
 		return false;
@@ -2283,8 +2284,8 @@  static inline bool fuse_blocked_for_wb(struct inode *inode)
 	if (!list_empty(&fi->rw_files)) {
 		struct fuse_file *ff = list_entry(fi->rw_files.next,
 						  struct fuse_file, rw_entry);
-		if (test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state))
-			blocked = false;
+		if (!test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state))
+			blocked = true;
 	}
 	spin_unlock(&fc->lock);