+++ /dev/null
-From 893cbb6cdc091ab6da8f0590ca625cc58e5650d2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 8 Sep 2019 20:15:18 -0700
-Subject: fuse: fix deadlock with aio poll and fuse_iqueue::waitq.lock
-
-From: Eric Biggers <ebiggers@google.com>
-
-[ Upstream commit 76e43c8ccaa35c30d5df853013561145a0f750a5 ]
-
-When IOCB_CMD_POLL is used on the FUSE device, aio_poll() disables IRQs
-and takes kioctx::ctx_lock, then fuse_iqueue::waitq.lock.
-
-This may have to wait for fuse_iqueue::waitq.lock to be released by one
-of many places that take it with IRQs enabled. Since the IRQ handler
-may take kioctx::ctx_lock, lockdep reports that a deadlock is possible.
-
-Fix it by protecting the state of struct fuse_iqueue with a separate
-spinlock, and only accessing fuse_iqueue::waitq using the versions of
-the waitqueue functions which do IRQ-safe locking internally.
-
-Reproducer:
-
- #include <fcntl.h>
- #include <stdio.h>
- #include <sys/mount.h>
- #include <sys/stat.h>
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/aio_abi.h>
-
- int main()
- {
- char opts[128];
- int fd = open("/dev/fuse", O_RDWR);
- aio_context_t ctx = 0;
- struct iocb cb = { .aio_lio_opcode = IOCB_CMD_POLL, .aio_fildes = fd };
- struct iocb *cbp = &cb;
-
- sprintf(opts, "fd=%d,rootmode=040000,user_id=0,group_id=0", fd);
- mkdir("mnt", 0700);
- mount("foo", "mnt", "fuse", 0, opts);
- syscall(__NR_io_setup, 1, &ctx);
- syscall(__NR_io_submit, ctx, 1, &cbp);
- }
-
-Beginning of lockdep output:
-
- =====================================================
- WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
- 5.3.0-rc5 #9 Not tainted
- -----------------------------------------------------
- syz_fuse/135 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
- 000000003590ceda (&fiq->waitq){+.+.}, at: spin_lock include/linux/spinlock.h:338 [inline]
- 000000003590ceda (&fiq->waitq){+.+.}, at: aio_poll fs/aio.c:1751 [inline]
- 000000003590ceda (&fiq->waitq){+.+.}, at: __io_submit_one.constprop.0+0x203/0x5b0 fs/aio.c:1825
-
- and this task is already holding:
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: spin_lock_irq include/linux/spinlock.h:363 [inline]
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: aio_poll fs/aio.c:1749 [inline]
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: __io_submit_one.constprop.0+0x1f4/0x5b0 fs/aio.c:1825
- which would create a new lock dependency:
- (&(&ctx->ctx_lock)->rlock){..-.} -> (&fiq->waitq){+.+.}
-
- but this new dependency connects a SOFTIRQ-irq-safe lock:
- (&(&ctx->ctx_lock)->rlock){..-.}
-
- [...]
-
-Reported-by: syzbot+af05535bb79520f95431@syzkaller.appspotmail.com
-Reported-by: syzbot+d86c4426a01f60feddc7@syzkaller.appspotmail.com
-Fixes: bfe4037e722e ("aio: implement IOCB_CMD_POLL")
-Cc: <stable@vger.kernel.org> # v4.19+
-Cc: Christoph Hellwig <hch@lst.de>
-Signed-off-by: Eric Biggers <ebiggers@google.com>
-Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/fuse/dev.c | 89 +++++++++++++++++++++++++-----------------------
- fs/fuse/fuse_i.h | 3 ++
- fs/fuse/inode.c | 1 +
- 3 files changed, 50 insertions(+), 43 deletions(-)
-
-diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
-index f580695b7bb9a..368acbbff4bb2 100644
---- a/fs/fuse/dev.c
-+++ b/fs/fuse/dev.c
-@@ -324,7 +324,7 @@ static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req)
- req->in.h.len = sizeof(struct fuse_in_header) +
- len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
- list_add_tail(&req->list, &fiq->pending);
-- wake_up_locked(&fiq->waitq);
-+ wake_up(&fiq->waitq);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- }
-
-@@ -336,16 +336,16 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
- forget->forget_one.nodeid = nodeid;
- forget->forget_one.nlookup = nlookup;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (fiq->connected) {
- fiq->forget_list_tail->next = forget;
- fiq->forget_list_tail = forget;
-- wake_up_locked(&fiq->waitq);
-+ wake_up(&fiq->waitq);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- } else {
- kfree(forget);
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
-
- static void flush_bg_queue(struct fuse_conn *fc)
-@@ -358,10 +358,10 @@ static void flush_bg_queue(struct fuse_conn *fc)
- req = list_entry(fc->bg_queue.next, struct fuse_req, list);
- list_del(&req->list);
- fc->active_background++;
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- req->in.h.unique = fuse_get_unique(fiq);
- queue_request(fiq, req);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
- }
-
-@@ -380,9 +380,9 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
- if (test_and_set_bit(FR_FINISHED, &req->flags))
- goto put_request;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- list_del_init(&req->intr_entry);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- WARN_ON(test_bit(FR_PENDING, &req->flags));
- WARN_ON(test_bit(FR_SENT, &req->flags));
- if (test_bit(FR_BACKGROUND, &req->flags)) {
-@@ -420,16 +420,16 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
-
- static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
- {
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (test_bit(FR_FINISHED, &req->flags)) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return;
- }
- if (list_empty(&req->intr_entry)) {
- list_add_tail(&req->intr_entry, &fiq->interrupts);
- wake_up_locked(&fiq->waitq);
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- }
-
-@@ -459,16 +459,16 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
- if (!err)
- return;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- /* Request is not yet in userspace, bail out */
- if (test_bit(FR_PENDING, &req->flags)) {
- list_del(&req->list);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- __fuse_put_request(req);
- req->out.h.error = -EINTR;
- return;
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
-
- /*
-@@ -483,9 +483,9 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
- struct fuse_iqueue *fiq = &fc->iq;
-
- BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (!fiq->connected) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- req->out.h.error = -ENOTCONN;
- } else {
- req->in.h.unique = fuse_get_unique(fiq);
-@@ -493,7 +493,7 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
- /* acquire extra reference, since request is still needed
- after request_end() */
- __fuse_get_request(req);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- request_wait_answer(fc, req);
- /* Pairs with smp_wmb() in request_end() */
-@@ -626,12 +626,12 @@ static int fuse_request_send_notify_reply(struct fuse_conn *fc,
-
- __clear_bit(FR_ISREPLY, &req->flags);
- req->in.h.unique = unique;
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (fiq->connected) {
- queue_request(fiq, req);
- err = 0;
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- return err;
- }
-@@ -1075,12 +1075,12 @@ static int request_pending(struct fuse_iqueue *fiq)
- * Unlike other requests this is assembled on demand, without a need
- * to allocate a separate fuse_req structure.
- *
-- * Called with fiq->waitq.lock held, releases it
-+ * Called with fiq->lock held, releases it
- */
- static int fuse_read_interrupt(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes, struct fuse_req *req)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- struct fuse_in_header ih;
- struct fuse_interrupt_in arg;
-@@ -1096,7 +1096,7 @@ __releases(fiq->waitq.lock)
- ih.unique = req->intr_unique;
- arg.unique = req->in.h.unique;
-
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- if (nbytes < reqsize)
- return -EINVAL;
-
-@@ -1133,7 +1133,7 @@ static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq,
- static int fuse_read_single_forget(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- int err;
- struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL);
-@@ -1147,7 +1147,7 @@ __releases(fiq->waitq.lock)
- .len = sizeof(ih) + sizeof(arg),
- };
-
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- kfree(forget);
- if (nbytes < ih.len)
- return -EINVAL;
-@@ -1165,7 +1165,7 @@ __releases(fiq->waitq.lock)
-
- static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs, size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- int err;
- unsigned max_forgets;
-@@ -1179,13 +1179,13 @@ __releases(fiq->waitq.lock)
- };
-
- if (nbytes < ih.len) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return -EINVAL;
- }
-
- max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
- head = dequeue_forget(fiq, max_forgets, &count);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- arg.count = count;
- ih.len += count * sizeof(struct fuse_forget_one);
-@@ -1215,7 +1215,7 @@ __releases(fiq->waitq.lock)
- static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
- return fuse_read_single_forget(fiq, cs, nbytes);
-@@ -1244,16 +1244,19 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- unsigned reqsize;
-
- restart:
-- spin_lock(&fiq->waitq.lock);
-- err = -EAGAIN;
-- if ((file->f_flags & O_NONBLOCK) && fiq->connected &&
-- !request_pending(fiq))
-- goto err_unlock;
-+ for (;;) {
-+ spin_lock(&fiq->lock);
-+ if (!fiq->connected || request_pending(fiq))
-+ break;
-+ spin_unlock(&fiq->lock);
-
-- err = wait_event_interruptible_exclusive_locked(fiq->waitq,
-+ if (file->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ err = wait_event_interruptible_exclusive(fiq->waitq,
- !fiq->connected || request_pending(fiq));
-- if (err)
-- goto err_unlock;
-+ if (err)
-+ return err;
-+ }
-
- err = -ENODEV;
- if (!fiq->connected)
-@@ -1276,7 +1279,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- req = list_entry(fiq->pending.next, struct fuse_req, list);
- clear_bit(FR_PENDING, &req->flags);
- list_del_init(&req->list);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- in = &req->in;
- reqsize = in->h.len;
-@@ -1339,7 +1342,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- return err;
-
- err_unlock:
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return err;
- }
-
-@@ -2050,12 +2053,12 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
- fiq = &fud->fc->iq;
- poll_wait(file, &fiq->waitq, wait);
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (!fiq->connected)
- mask = POLLERR;
- else if (request_pending(fiq))
- mask |= POLLIN | POLLRDNORM;
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- return mask;
- }
-@@ -2146,15 +2149,15 @@ void fuse_abort_conn(struct fuse_conn *fc)
- fc->max_background = UINT_MAX;
- flush_bg_queue(fc);
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- fiq->connected = 0;
- list_splice_init(&fiq->pending, &to_end2);
- list_for_each_entry(req, &to_end2, list)
- clear_bit(FR_PENDING, &req->flags);
- while (forget_pending(fiq))
- kfree(dequeue_forget(fiq, 1, NULL));
-- wake_up_all_locked(&fiq->waitq);
-- spin_unlock(&fiq->waitq.lock);
-+ wake_up_all(&fiq->waitq);
-+ spin_unlock(&fiq->lock);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- end_polls(fc);
- wake_up_all(&fc->blocked_waitq);
-diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
-index e682f2eff6c0d..12a8a19b76da2 100644
---- a/fs/fuse/fuse_i.h
-+++ b/fs/fuse/fuse_i.h
-@@ -387,6 +387,9 @@ struct fuse_iqueue {
- /** Connection established */
- unsigned connected;
-
-+ /** Lock protecting accesses to members of this structure */
-+ spinlock_t lock;
-+
- /** Readers of the connection are waiting on this */
- wait_queue_head_t waitq;
-
-diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
-index ffb61787d77af..d97619c52376f 100644
---- a/fs/fuse/inode.c
-+++ b/fs/fuse/inode.c
-@@ -584,6 +584,7 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
- static void fuse_iqueue_init(struct fuse_iqueue *fiq)
- {
- memset(fiq, 0, sizeof(struct fuse_iqueue));
-+ spin_lock_init(&fiq->lock);
- init_waitqueue_head(&fiq->waitq);
- INIT_LIST_HEAD(&fiq->pending);
- INIT_LIST_HEAD(&fiq->interrupts);
---
-2.20.1
-
cifs-fix-max-ea-value-size.patch
cifs-fix-oplock-handling-for-smb-2.1-protocols.patch
md-raid0-avoid-raid0-data-corruption-due-to-layout-c.patch
-fuse-fix-deadlock-with-aio-poll-and-fuse_iqueue-wait.patch
mm-compaction.c-clear-total_-migrate-free-_scanned-b.patch
btrfs-qgroup-drop-quota_root-and-fs_info-parameters-.patch
btrfs-fix-race-setting-up-and-completing-qgroup-resc.patch
+++ /dev/null
-From a7cdb9053b16ef05bdd896df8e548215ff97223a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 8 Sep 2019 20:15:18 -0700
-Subject: fuse: fix deadlock with aio poll and fuse_iqueue::waitq.lock
-
-From: Eric Biggers <ebiggers@google.com>
-
-[ Upstream commit 76e43c8ccaa35c30d5df853013561145a0f750a5 ]
-
-When IOCB_CMD_POLL is used on the FUSE device, aio_poll() disables IRQs
-and takes kioctx::ctx_lock, then fuse_iqueue::waitq.lock.
-
-This may have to wait for fuse_iqueue::waitq.lock to be released by one
-of many places that take it with IRQs enabled. Since the IRQ handler
-may take kioctx::ctx_lock, lockdep reports that a deadlock is possible.
-
-Fix it by protecting the state of struct fuse_iqueue with a separate
-spinlock, and only accessing fuse_iqueue::waitq using the versions of
-the waitqueue functions which do IRQ-safe locking internally.
-
-Reproducer:
-
- #include <fcntl.h>
- #include <stdio.h>
- #include <sys/mount.h>
- #include <sys/stat.h>
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/aio_abi.h>
-
- int main()
- {
- char opts[128];
- int fd = open("/dev/fuse", O_RDWR);
- aio_context_t ctx = 0;
- struct iocb cb = { .aio_lio_opcode = IOCB_CMD_POLL, .aio_fildes = fd };
- struct iocb *cbp = &cb;
-
- sprintf(opts, "fd=%d,rootmode=040000,user_id=0,group_id=0", fd);
- mkdir("mnt", 0700);
- mount("foo", "mnt", "fuse", 0, opts);
- syscall(__NR_io_setup, 1, &ctx);
- syscall(__NR_io_submit, ctx, 1, &cbp);
- }
-
-Beginning of lockdep output:
-
- =====================================================
- WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
- 5.3.0-rc5 #9 Not tainted
- -----------------------------------------------------
- syz_fuse/135 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
- 000000003590ceda (&fiq->waitq){+.+.}, at: spin_lock include/linux/spinlock.h:338 [inline]
- 000000003590ceda (&fiq->waitq){+.+.}, at: aio_poll fs/aio.c:1751 [inline]
- 000000003590ceda (&fiq->waitq){+.+.}, at: __io_submit_one.constprop.0+0x203/0x5b0 fs/aio.c:1825
-
- and this task is already holding:
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: spin_lock_irq include/linux/spinlock.h:363 [inline]
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: aio_poll fs/aio.c:1749 [inline]
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: __io_submit_one.constprop.0+0x1f4/0x5b0 fs/aio.c:1825
- which would create a new lock dependency:
- (&(&ctx->ctx_lock)->rlock){..-.} -> (&fiq->waitq){+.+.}
-
- but this new dependency connects a SOFTIRQ-irq-safe lock:
- (&(&ctx->ctx_lock)->rlock){..-.}
-
- [...]
-
-Reported-by: syzbot+af05535bb79520f95431@syzkaller.appspotmail.com
-Reported-by: syzbot+d86c4426a01f60feddc7@syzkaller.appspotmail.com
-Fixes: bfe4037e722e ("aio: implement IOCB_CMD_POLL")
-Cc: <stable@vger.kernel.org> # v4.19+
-Cc: Christoph Hellwig <hch@lst.de>
-Signed-off-by: Eric Biggers <ebiggers@google.com>
-Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/fuse/dev.c | 89 +++++++++++++++++++++++++-----------------------
- fs/fuse/fuse_i.h | 3 ++
- fs/fuse/inode.c | 1 +
- 3 files changed, 50 insertions(+), 43 deletions(-)
-
-diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
-index f5d2d2340b44d..8cd5a775d13be 100644
---- a/fs/fuse/dev.c
-+++ b/fs/fuse/dev.c
-@@ -338,7 +338,7 @@ static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req)
- req->in.h.len = sizeof(struct fuse_in_header) +
- len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
- list_add_tail(&req->list, &fiq->pending);
-- wake_up_locked(&fiq->waitq);
-+ wake_up(&fiq->waitq);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- }
-
-@@ -350,16 +350,16 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
- forget->forget_one.nodeid = nodeid;
- forget->forget_one.nlookup = nlookup;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (fiq->connected) {
- fiq->forget_list_tail->next = forget;
- fiq->forget_list_tail = forget;
-- wake_up_locked(&fiq->waitq);
-+ wake_up(&fiq->waitq);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- } else {
- kfree(forget);
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
-
- static void flush_bg_queue(struct fuse_conn *fc)
-@@ -372,10 +372,10 @@ static void flush_bg_queue(struct fuse_conn *fc)
- req = list_entry(fc->bg_queue.next, struct fuse_req, list);
- list_del(&req->list);
- fc->active_background++;
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- req->in.h.unique = fuse_get_unique(fiq);
- queue_request(fiq, req);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
- }
-
-@@ -394,9 +394,9 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
- if (test_and_set_bit(FR_FINISHED, &req->flags))
- goto put_request;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- list_del_init(&req->intr_entry);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- WARN_ON(test_bit(FR_PENDING, &req->flags));
- WARN_ON(test_bit(FR_SENT, &req->flags));
- if (test_bit(FR_BACKGROUND, &req->flags)) {
-@@ -435,16 +435,16 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
-
- static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
- {
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (test_bit(FR_FINISHED, &req->flags)) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return;
- }
- if (list_empty(&req->intr_entry)) {
- list_add_tail(&req->intr_entry, &fiq->interrupts);
- wake_up_locked(&fiq->waitq);
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- }
-
-@@ -479,16 +479,16 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
- if (!err)
- return;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- /* Request is not yet in userspace, bail out */
- if (test_bit(FR_PENDING, &req->flags)) {
- list_del(&req->list);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- __fuse_put_request(req);
- req->out.h.error = -EINTR;
- return;
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
-
- /*
-@@ -503,9 +503,9 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
- struct fuse_iqueue *fiq = &fc->iq;
-
- BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (!fiq->connected) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- req->out.h.error = -ENOTCONN;
- } else {
- req->in.h.unique = fuse_get_unique(fiq);
-@@ -513,7 +513,7 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
- /* acquire extra reference, since request is still needed
- after request_end() */
- __fuse_get_request(req);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- request_wait_answer(fc, req);
- /* Pairs with smp_wmb() in request_end() */
-@@ -647,12 +647,12 @@ static int fuse_request_send_notify_reply(struct fuse_conn *fc,
-
- __clear_bit(FR_ISREPLY, &req->flags);
- req->in.h.unique = unique;
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (fiq->connected) {
- queue_request(fiq, req);
- err = 0;
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- return err;
- }
-@@ -1097,12 +1097,12 @@ static int request_pending(struct fuse_iqueue *fiq)
- * Unlike other requests this is assembled on demand, without a need
- * to allocate a separate fuse_req structure.
- *
-- * Called with fiq->waitq.lock held, releases it
-+ * Called with fiq->lock held, releases it
- */
- static int fuse_read_interrupt(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes, struct fuse_req *req)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- struct fuse_in_header ih;
- struct fuse_interrupt_in arg;
-@@ -1118,7 +1118,7 @@ __releases(fiq->waitq.lock)
- ih.unique = req->intr_unique;
- arg.unique = req->in.h.unique;
-
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- if (nbytes < reqsize)
- return -EINVAL;
-
-@@ -1155,7 +1155,7 @@ static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq,
- static int fuse_read_single_forget(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- int err;
- struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL);
-@@ -1169,7 +1169,7 @@ __releases(fiq->waitq.lock)
- .len = sizeof(ih) + sizeof(arg),
- };
-
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- kfree(forget);
- if (nbytes < ih.len)
- return -EINVAL;
-@@ -1187,7 +1187,7 @@ __releases(fiq->waitq.lock)
-
- static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs, size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- int err;
- unsigned max_forgets;
-@@ -1201,13 +1201,13 @@ __releases(fiq->waitq.lock)
- };
-
- if (nbytes < ih.len) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return -EINVAL;
- }
-
- max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
- head = dequeue_forget(fiq, max_forgets, &count);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- arg.count = count;
- ih.len += count * sizeof(struct fuse_forget_one);
-@@ -1237,7 +1237,7 @@ __releases(fiq->waitq.lock)
- static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
- return fuse_read_single_forget(fiq, cs, nbytes);
-@@ -1266,16 +1266,19 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- unsigned reqsize;
-
- restart:
-- spin_lock(&fiq->waitq.lock);
-- err = -EAGAIN;
-- if ((file->f_flags & O_NONBLOCK) && fiq->connected &&
-- !request_pending(fiq))
-- goto err_unlock;
-+ for (;;) {
-+ spin_lock(&fiq->lock);
-+ if (!fiq->connected || request_pending(fiq))
-+ break;
-+ spin_unlock(&fiq->lock);
-
-- err = wait_event_interruptible_exclusive_locked(fiq->waitq,
-+ if (file->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ err = wait_event_interruptible_exclusive(fiq->waitq,
- !fiq->connected || request_pending(fiq));
-- if (err)
-- goto err_unlock;
-+ if (err)
-+ return err;
-+ }
-
- err = -ENODEV;
- if (!fiq->connected)
-@@ -1298,7 +1301,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- req = list_entry(fiq->pending.next, struct fuse_req, list);
- clear_bit(FR_PENDING, &req->flags);
- list_del_init(&req->list);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- in = &req->in;
- reqsize = in->h.len;
-@@ -1354,7 +1357,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- return err;
-
- err_unlock:
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return err;
- }
-
-@@ -2098,12 +2101,12 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
- fiq = &fud->fc->iq;
- poll_wait(file, &fiq->waitq, wait);
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (!fiq->connected)
- mask = POLLERR;
- else if (request_pending(fiq))
- mask |= POLLIN | POLLRDNORM;
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- return mask;
- }
-@@ -2194,15 +2197,15 @@ void fuse_abort_conn(struct fuse_conn *fc)
- fc->max_background = UINT_MAX;
- flush_bg_queue(fc);
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- fiq->connected = 0;
- list_splice_init(&fiq->pending, &to_end2);
- list_for_each_entry(req, &to_end2, list)
- clear_bit(FR_PENDING, &req->flags);
- while (forget_pending(fiq))
- kfree(dequeue_forget(fiq, 1, NULL));
-- wake_up_all_locked(&fiq->waitq);
-- spin_unlock(&fiq->waitq.lock);
-+ wake_up_all(&fiq->waitq);
-+ spin_unlock(&fiq->lock);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- end_polls(fc);
- wake_up_all(&fc->blocked_waitq);
-diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
-index c6eb35a95fcc9..5109f1acda0df 100644
---- a/fs/fuse/fuse_i.h
-+++ b/fs/fuse/fuse_i.h
-@@ -390,6 +390,9 @@ struct fuse_iqueue {
- /** Connection established */
- unsigned connected;
-
-+ /** Lock protecting accesses to members of this structure */
-+ spinlock_t lock;
-+
- /** Readers of the connection are waiting on this */
- wait_queue_head_t waitq;
-
-diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
-index 4b2eb65be0d40..b353787fa35a0 100644
---- a/fs/fuse/inode.c
-+++ b/fs/fuse/inode.c
-@@ -567,6 +567,7 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
- static void fuse_iqueue_init(struct fuse_iqueue *fiq)
- {
- memset(fiq, 0, sizeof(struct fuse_iqueue));
-+ spin_lock_init(&fiq->lock);
- init_waitqueue_head(&fiq->waitq);
- INIT_LIST_HEAD(&fiq->pending);
- INIT_LIST_HEAD(&fiq->interrupts);
---
-2.20.1
-
ovl-filter-of-trusted-xattr-results-in-audit.patch
btrfs-fix-use-after-free-when-using-the-tree-modification-log.patch
btrfs-relinquish-cpus-in-btrfs_compare_trees.patch
-fuse-fix-deadlock-with-aio-poll-and-fuse_iqueue-wait.patch
btrfs-fix-race-setting-up-and-completing-qgroup-resc.patch
+++ /dev/null
-From 5242268a759931c34ad6262d1646f3eb45c8d19f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 8 Sep 2019 20:15:18 -0700
-Subject: fuse: fix deadlock with aio poll and fuse_iqueue::waitq.lock
-
-From: Eric Biggers <ebiggers@google.com>
-
-[ Upstream commit 76e43c8ccaa35c30d5df853013561145a0f750a5 ]
-
-When IOCB_CMD_POLL is used on the FUSE device, aio_poll() disables IRQs
-and takes kioctx::ctx_lock, then fuse_iqueue::waitq.lock.
-
-This may have to wait for fuse_iqueue::waitq.lock to be released by one
-of many places that take it with IRQs enabled. Since the IRQ handler
-may take kioctx::ctx_lock, lockdep reports that a deadlock is possible.
-
-Fix it by protecting the state of struct fuse_iqueue with a separate
-spinlock, and only accessing fuse_iqueue::waitq using the versions of
-the waitqueue functions which do IRQ-safe locking internally.
-
-Reproducer:
-
- #include <fcntl.h>
- #include <stdio.h>
- #include <sys/mount.h>
- #include <sys/stat.h>
- #include <sys/syscall.h>
- #include <unistd.h>
- #include <linux/aio_abi.h>
-
- int main()
- {
- char opts[128];
- int fd = open("/dev/fuse", O_RDWR);
- aio_context_t ctx = 0;
- struct iocb cb = { .aio_lio_opcode = IOCB_CMD_POLL, .aio_fildes = fd };
- struct iocb *cbp = &cb;
-
- sprintf(opts, "fd=%d,rootmode=040000,user_id=0,group_id=0", fd);
- mkdir("mnt", 0700);
- mount("foo", "mnt", "fuse", 0, opts);
- syscall(__NR_io_setup, 1, &ctx);
- syscall(__NR_io_submit, ctx, 1, &cbp);
- }
-
-Beginning of lockdep output:
-
- =====================================================
- WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
- 5.3.0-rc5 #9 Not tainted
- -----------------------------------------------------
- syz_fuse/135 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
- 000000003590ceda (&fiq->waitq){+.+.}, at: spin_lock include/linux/spinlock.h:338 [inline]
- 000000003590ceda (&fiq->waitq){+.+.}, at: aio_poll fs/aio.c:1751 [inline]
- 000000003590ceda (&fiq->waitq){+.+.}, at: __io_submit_one.constprop.0+0x203/0x5b0 fs/aio.c:1825
-
- and this task is already holding:
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: spin_lock_irq include/linux/spinlock.h:363 [inline]
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: aio_poll fs/aio.c:1749 [inline]
- 0000000075037284 (&(&ctx->ctx_lock)->rlock){..-.}, at: __io_submit_one.constprop.0+0x1f4/0x5b0 fs/aio.c:1825
- which would create a new lock dependency:
- (&(&ctx->ctx_lock)->rlock){..-.} -> (&fiq->waitq){+.+.}
-
- but this new dependency connects a SOFTIRQ-irq-safe lock:
- (&(&ctx->ctx_lock)->rlock){..-.}
-
- [...]
-
-Reported-by: syzbot+af05535bb79520f95431@syzkaller.appspotmail.com
-Reported-by: syzbot+d86c4426a01f60feddc7@syzkaller.appspotmail.com
-Fixes: bfe4037e722e ("aio: implement IOCB_CMD_POLL")
-Cc: <stable@vger.kernel.org> # v4.19+
-Cc: Christoph Hellwig <hch@lst.de>
-Signed-off-by: Eric Biggers <ebiggers@google.com>
-Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/fuse/dev.c | 89 +++++++++++++++++++++++++-----------------------
- fs/fuse/fuse_i.h | 3 ++
- fs/fuse/inode.c | 1 +
- 3 files changed, 50 insertions(+), 43 deletions(-)
-
-diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
-index 8016cd059db12..638ec50e606e2 100644
---- a/fs/fuse/dev.c
-+++ b/fs/fuse/dev.c
-@@ -319,7 +319,7 @@ static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req)
- req->in.h.len = sizeof(struct fuse_in_header) +
- len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
- list_add_tail(&req->list, &fiq->pending);
-- wake_up_locked(&fiq->waitq);
-+ wake_up(&fiq->waitq);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- }
-
-@@ -331,16 +331,16 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
- forget->forget_one.nodeid = nodeid;
- forget->forget_one.nlookup = nlookup;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (fiq->connected) {
- fiq->forget_list_tail->next = forget;
- fiq->forget_list_tail = forget;
-- wake_up_locked(&fiq->waitq);
-+ wake_up(&fiq->waitq);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- } else {
- kfree(forget);
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
-
- static void flush_bg_queue(struct fuse_conn *fc)
-@@ -353,10 +353,10 @@ static void flush_bg_queue(struct fuse_conn *fc)
- req = list_entry(fc->bg_queue.next, struct fuse_req, list);
- list_del(&req->list);
- fc->active_background++;
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- req->in.h.unique = fuse_get_unique(fiq);
- queue_request(fiq, req);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
- }
-
-@@ -375,9 +375,9 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
- if (test_and_set_bit(FR_FINISHED, &req->flags))
- goto put_request;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- list_del_init(&req->intr_entry);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- WARN_ON(test_bit(FR_PENDING, &req->flags));
- WARN_ON(test_bit(FR_SENT, &req->flags));
- if (test_bit(FR_BACKGROUND, &req->flags)) {
-@@ -416,16 +416,16 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
-
- static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
- {
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (test_bit(FR_FINISHED, &req->flags)) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return;
- }
- if (list_empty(&req->intr_entry)) {
- list_add_tail(&req->intr_entry, &fiq->interrupts);
- wake_up_locked(&fiq->waitq);
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- }
-
-@@ -455,16 +455,16 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
- if (!err)
- return;
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- /* Request is not yet in userspace, bail out */
- if (test_bit(FR_PENDING, &req->flags)) {
- list_del(&req->list);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- __fuse_put_request(req);
- req->out.h.error = -EINTR;
- return;
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- }
-
- /*
-@@ -479,9 +479,9 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
- struct fuse_iqueue *fiq = &fc->iq;
-
- BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (!fiq->connected) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- req->out.h.error = -ENOTCONN;
- } else {
- req->in.h.unique = fuse_get_unique(fiq);
-@@ -489,7 +489,7 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
- /* acquire extra reference, since request is still needed
- after request_end() */
- __fuse_get_request(req);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- request_wait_answer(fc, req);
- /* Pairs with smp_wmb() in request_end() */
-@@ -623,12 +623,12 @@ static int fuse_request_send_notify_reply(struct fuse_conn *fc,
-
- __clear_bit(FR_ISREPLY, &req->flags);
- req->in.h.unique = unique;
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (fiq->connected) {
- queue_request(fiq, req);
- err = 0;
- }
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- return err;
- }
-@@ -1072,12 +1072,12 @@ static int request_pending(struct fuse_iqueue *fiq)
- * Unlike other requests this is assembled on demand, without a need
- * to allocate a separate fuse_req structure.
- *
-- * Called with fiq->waitq.lock held, releases it
-+ * Called with fiq->lock held, releases it
- */
- static int fuse_read_interrupt(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes, struct fuse_req *req)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- struct fuse_in_header ih;
- struct fuse_interrupt_in arg;
-@@ -1093,7 +1093,7 @@ __releases(fiq->waitq.lock)
- ih.unique = req->intr_unique;
- arg.unique = req->in.h.unique;
-
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- if (nbytes < reqsize)
- return -EINVAL;
-
-@@ -1130,7 +1130,7 @@ static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq,
- static int fuse_read_single_forget(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- int err;
- struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL);
-@@ -1144,7 +1144,7 @@ __releases(fiq->waitq.lock)
- .len = sizeof(ih) + sizeof(arg),
- };
-
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- kfree(forget);
- if (nbytes < ih.len)
- return -EINVAL;
-@@ -1162,7 +1162,7 @@ __releases(fiq->waitq.lock)
-
- static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs, size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- int err;
- unsigned max_forgets;
-@@ -1176,13 +1176,13 @@ __releases(fiq->waitq.lock)
- };
-
- if (nbytes < ih.len) {
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return -EINVAL;
- }
-
- max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
- head = dequeue_forget(fiq, max_forgets, &count);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- arg.count = count;
- ih.len += count * sizeof(struct fuse_forget_one);
-@@ -1212,7 +1212,7 @@ __releases(fiq->waitq.lock)
- static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
- struct fuse_copy_state *cs,
- size_t nbytes)
--__releases(fiq->waitq.lock)
-+__releases(fiq->lock)
- {
- if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
- return fuse_read_single_forget(fiq, cs, nbytes);
-@@ -1241,16 +1241,19 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- unsigned reqsize;
-
- restart:
-- spin_lock(&fiq->waitq.lock);
-- err = -EAGAIN;
-- if ((file->f_flags & O_NONBLOCK) && fiq->connected &&
-- !request_pending(fiq))
-- goto err_unlock;
-+ for (;;) {
-+ spin_lock(&fiq->lock);
-+ if (!fiq->connected || request_pending(fiq))
-+ break;
-+ spin_unlock(&fiq->lock);
-
-- err = wait_event_interruptible_exclusive_locked(fiq->waitq,
-+ if (file->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ err = wait_event_interruptible_exclusive(fiq->waitq,
- !fiq->connected || request_pending(fiq));
-- if (err)
-- goto err_unlock;
-+ if (err)
-+ return err;
-+ }
-
- err = -ENODEV;
- if (!fiq->connected)
-@@ -1273,7 +1276,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- req = list_entry(fiq->pending.next, struct fuse_req, list);
- clear_bit(FR_PENDING, &req->flags);
- list_del_init(&req->list);
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- in = &req->in;
- reqsize = in->h.len;
-@@ -1329,7 +1332,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- return err;
-
- err_unlock:
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
- return err;
- }
-
-@@ -2040,12 +2043,12 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
- fiq = &fud->fc->iq;
- poll_wait(file, &fiq->waitq, wait);
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- if (!fiq->connected)
- mask = POLLERR;
- else if (request_pending(fiq))
- mask |= POLLIN | POLLRDNORM;
-- spin_unlock(&fiq->waitq.lock);
-+ spin_unlock(&fiq->lock);
-
- return mask;
- }
-@@ -2136,15 +2139,15 @@ void fuse_abort_conn(struct fuse_conn *fc)
- fc->max_background = UINT_MAX;
- flush_bg_queue(fc);
-
-- spin_lock(&fiq->waitq.lock);
-+ spin_lock(&fiq->lock);
- fiq->connected = 0;
- list_splice_init(&fiq->pending, &to_end2);
- list_for_each_entry(req, &to_end2, list)
- clear_bit(FR_PENDING, &req->flags);
- while (forget_pending(fiq))
- kfree(dequeue_forget(fiq, 1, NULL));
-- wake_up_all_locked(&fiq->waitq);
-- spin_unlock(&fiq->waitq.lock);
-+ wake_up_all(&fiq->waitq);
-+ spin_unlock(&fiq->lock);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
- end_polls(fc);
- wake_up_all(&fc->blocked_waitq);
-diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
-index 1c905c7666dec..ac9add774db77 100644
---- a/fs/fuse/fuse_i.h
-+++ b/fs/fuse/fuse_i.h
-@@ -385,6 +385,9 @@ struct fuse_iqueue {
- /** Connection established */
- unsigned connected;
-
-+ /** Lock protecting accesses to members of this structure */
-+ spinlock_t lock;
-+
- /** Readers of the connection are waiting on this */
- wait_queue_head_t waitq;
-
-diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
-index 7a9b1069d267b..2c942a8279040 100644
---- a/fs/fuse/inode.c
-+++ b/fs/fuse/inode.c
-@@ -590,6 +590,7 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
- static void fuse_iqueue_init(struct fuse_iqueue *fiq)
- {
- memset(fiq, 0, sizeof(struct fuse_iqueue));
-+ spin_lock_init(&fiq->lock);
- init_waitqueue_head(&fiq->waitq);
- INIT_LIST_HEAD(&fiq->pending);
- INIT_LIST_HEAD(&fiq->interrupts);
---
-2.20.1
-
i2c-riic-clear-nack-in-tend-isr.patch
cifs-fix-max-ea-value-size.patch
cifs-fix-oplock-handling-for-smb-2.1-protocols.patch
-fuse-fix-deadlock-with-aio-poll-and-fuse_iqueue-wait.patch
btrfs-qgroup-drop-quota_root-and-fs_info-parameters-.patch
btrfs-fix-race-setting-up-and-completing-qgroup-resc.patch