Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de5e3dec authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds
Browse files

fuse: fix reserved request wake up



Use wake_up_all instead of wake_up in put_reserved_req(), otherwise it is
possible that the right task is not woken up.

Also create a separate reserved_req_waitq in addition to the blocked_waitq,
since they fulfill totally separate functions.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f92b99b9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
	struct fuse_file *ff = file->private_data;

	do {
		wait_event(fc->blocked_waitq, ff->reserved_req);
		wait_event(fc->reserved_req_waitq, ff->reserved_req);
		spin_lock(&fc->lock);
		if (ff->reserved_req) {
			req = ff->reserved_req;
@@ -155,7 +155,7 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
	fuse_request_init(req);
	BUG_ON(ff->reserved_req);
	ff->reserved_req = req;
	wake_up(&fc->blocked_waitq);
	wake_up_all(&fc->reserved_req_waitq);
	spin_unlock(&fc->lock);
	fput(file);
}
+3 −0
Original line number Diff line number Diff line
@@ -289,6 +289,9 @@ struct fuse_conn {
	/** waitq for blocked connection */
	wait_queue_head_t blocked_waitq;

	/** waitq for reserved requests */
	wait_queue_head_t reserved_req_waitq;

	/** The next unique request id */
	u64 reqctr;

+2 −0
Original line number Diff line number Diff line
@@ -232,6 +232,7 @@ static void fuse_put_super(struct super_block *sb)
	kill_fasync(&fc->fasync, SIGIO, POLL_IN);
	wake_up_all(&fc->waitq);
	wake_up_all(&fc->blocked_waitq);
	wake_up_all(&fc->reserved_req_waitq);
	mutex_lock(&fuse_mutex);
	list_del(&fc->entry);
	fuse_ctl_remove_conn(fc);
@@ -410,6 +411,7 @@ static struct fuse_conn *new_conn(void)
		atomic_set(&fc->count, 1);
		init_waitqueue_head(&fc->waitq);
		init_waitqueue_head(&fc->blocked_waitq);
		init_waitqueue_head(&fc->reserved_req_waitq);
		INIT_LIST_HEAD(&fc->pending);
		INIT_LIST_HEAD(&fc->processing);
		INIT_LIST_HEAD(&fc->io);