[fuse] fix deadlock between fuse_put_super() and request_end()
authorMiklos Szeredi <miklos@szeredi.hu>
Tue, 11 Apr 2006 19:14:26 +0000 (21:14 +0200)
committerMiklos Szeredi <miklos@szeredi.hu>
Tue, 11 Apr 2006 19:14:26 +0000 (21:14 +0200)
commit73ce8355c243a434524a34c05cc417dd0467996e
treea5bc5bfb31c41a5806caf763533943e7411e6543
parent2514395ef88b46e895726a8d40966cb83de7940c
[fuse] fix deadlock between fuse_put_super() and request_end()

A deadlock was possible, when the last reference to the superblock was
held due to a background request containing a file reference.

Releasing the file would release the vfsmount which in turn would
release the superblock.  Since sbput_sem is held during the fput() and
fuse_put_super() tries to acquire this same semaphore, a deadlock
results.

The chosen soltuion is to get rid of sbput_sem, and instead use the
spinlock to ensure the referenced inodes/file are released only once.
Since the actual release may sleep, defer these outside the locked
region, but using local variables instead of the structure members.

This is a much more rubust solution.

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
fs/fuse/dev.c
fs/fuse/fuse_i.h
fs/fuse/inode.c