fuse: Call end_queued_requests() after releasing fc->lock in fuse_dev_release()
Orabug:
27215268
During fs teardown,the following self deadlock can happen.
[<
ffffffff8173891a>] _raw_spin_lock+0x2a/0x60
[<
ffffffffa08a7ef1>] ? fuse_abort_conn+0x31/0x270 [fuse]
[<
ffffffffa08763c0>] ? cuse_read_iter+0x70/0x70 [cuse]
[<
ffffffffa0876414>] cuse_process_init_reply+0x54/0x490 [cuse]
[<
ffffffffa08763c0>] ? cuse_read_iter+0x70/0x70 [cuse]
[<
ffffffffa08a5bbf>] request_end+0xbf/0x170 [fuse]
[<
ffffffffa08a7d16>] end_queued_requests.isra.19+0x86/0x160 [fuse]
[<
ffffffffa08a7e8f>] fuse_dev_release+0x9f/0xd0 [fuse]
[<
ffffffffa087611a>] cuse_channel_release+0x8a/0xa0 [cuse]
[<
ffffffff81214cf4>] __fput+0xe4/0x220
[<
ffffffff81214e7e>] ____fput+0xe/0x10
[<
ffffffff810a5557>] task_work_run+0xb7/0xf0
[<
ffffffff81017c6d>] do_notify_resume+0x8d/0xa0
[<
ffffffff81738dbc>] int_signal+0x12/0x17
The deadlock happens when an attempt is made to take fc->lock in
fuse_abort_conn(). The same lock has already been taken in
fuse_dev_release() in the stack.
This flow is initiated from cuse_process_init_reply() in case of an error
and so, it is a very rare scenario, but it can lockup the fuse fs.
Fix this by releasing the spin lock before calling end_queued_requests()
instead of after, since it does not make a difference anyway.
Signed-off-by: Ashish Samant <ashish.samant@oracle.com>
Reviewed-by: Somasundaram Krishnasamy <somasundaram.krishnasamy@oracle.com>