Josef Bacik cf74982385 Btrfs: fix deadlock between alloc_mutex/chunk_mutex
This fixes a deadlock that happens between the alloc_mutex and chunk_mutex.
Process A comes in, decides to do a do_chunk_alloc, which takes the
chunk_mutex, and is holding the alloc_mutex because the only way you get to
do_chunk_alloc is by holding the alloc_mutex.  btrfs_alloc_chunk does its thing
and goes to insert a new item, which results in a cow of the block.

We get into del_pending_extents from there, where if we need to be rescheduled
we drop the alloc_mutex and schedule.  At this point process B comes in to do
an allocation and gets the alloc_mutex, and because process A did not do the
chunk allocation completely it thinks its a good time to do a chunk allocation
as well, and hangs on the chunk_mutex.

Process A wakes up and tries to take the alloc_mutex and cannot.  The way to
fix this is do a mutex_trylock() on chunk_mutex.  If we return 0 we didn't get
the lock, and if this is just a "hey it may be a good time to allocate a chunk"
then we just exit.  If we are trying to force an allocation then we reschedule
and keep trying to acquire the chunk_mutex.  If once we acquire it the space is
already full then we can just exit, otherwise we can continue with the chunk
allocation.  Thank you,

Signed-off-by: Josef Bacik <jbacik@redhat.com>
2008-10-01 19:11:18 -04:00
..
2008-08-04 21:31:34 -07:00
2008-02-08 09:22:40 -08:00
2008-09-13 14:41:51 -07:00
2008-08-20 15:40:32 -07:00
2008-08-01 11:25:29 -04:00
2008-08-13 12:47:36 -05:00
2008-08-25 01:18:04 -04:00
2008-04-29 08:06:00 -07:00
2008-07-26 20:53:40 -04:00
2008-07-26 20:53:40 -04:00
2008-07-25 10:53:34 -07:00
2007-10-18 14:37:31 -07:00
2008-09-02 19:21:37 -07:00
2008-09-10 01:44:08 -07:00
2008-07-04 09:52:14 +02:00
2008-07-26 12:00:07 -07:00
2008-09-05 20:02:35 +03:00
2008-09-08 20:31:04 +02:00
2008-07-25 10:53:34 -07:00
2008-07-26 20:53:40 -04:00
2008-07-26 12:00:08 -07:00
2008-07-26 12:00:08 -07:00
2008-07-26 12:00:08 -07:00
2008-01-30 13:31:46 +01:00
2008-07-26 12:00:06 -07:00
2008-05-01 13:08:16 -04:00
2008-08-01 11:25:24 -04:00
2008-07-26 20:53:40 -04:00
2007-05-08 11:15:01 -07:00
2008-07-14 19:10:52 +03:00
2008-02-06 10:41:07 -08:00
2008-04-29 08:06:00 -07:00
2008-07-28 18:10:28 +09:00
2008-02-14 21:13:33 -08:00
2006-10-01 00:39:19 -07:00
2008-07-25 10:53:35 -07:00
2008-07-02 15:06:27 -06:00
2008-08-04 21:31:34 -07:00