Thread (120 messages) 120 messages, 14 authors, 2013-11-29

Re: [RFC][PATCH] Re: [BUG] ext4: cannot unfreeze a filesystem due to a deadlock

From: Yongqiang Yang <hidden>
Date: 2011-03-31 08:48:39
Also in: linux-fsdevel

On Thu, Mar 31, 2011 at 4:37 PM, Yongqiang Yang [off-list ref] wrote:
Hi everyone,

Amir met a deadlock when he tested ext4 with snapshot.  The deadlock
was reported on
https://github.com/amir73il/ext4-snapshots/commit/56396185d922a73524a091b545e665543abf741a.
 It is difficult to reproduce the deadlock.  There is a deadlock
reported on http://www.spinics.net/lists/linux-ext4/msg23018.html.
Actually, these two deadlocks come from a same source.

Below are my analysis on the 1st one.  Mail is not a good place to
describe parallel processes.  I have submitted the analysis to
https://github.com/YANGYongqiang/ext4-snapshots/blob/9e0ae9ae9907125e6bf45aa91db296d4cc041b17/fs/ext4/BUGS#L143.
 It is much more readable.

-- deadlock in ext4 with snapshot
      ext4 with snapshot calls freeze_super() to bring
      a fs be in a clean state when a user takes a snapshot.

    freeze                  truncate              kjournald

                   |  ext4_ext_truncate     |
   freeze_super()  |   starts a handle      |
   sets s_frozen   |                        |
                   |  ext4_ext_truncate     |
                   |  holds i_data_sem      |
 ext4_freeze()     |                        |   commit_transaction()
  wait for updates |                        |   waits for i_data_sem
                   |  ext4_free_blocks      |
                   |  calls dquot_free_block|
                   |                        |
                   |  dquot_free_block call |
                   |  ext4_dirty_inode      |
                   |                        |
                   |  ext4_dirty_inode      |
                   |  trys to start a handle|
                   |                        |
                   |  block due to s_frozen |

in ext3, ext3_freeze() prevents journal from being updated by
lock_journal_updates(), ext3_unfreeze() allow journal to be updated by
unlock_journal_updates().

in ext4, however, before ext4_freeze() returns, it unlock journal, and
ext4 prevents journal from being updated by s_frozen. s_frozen is in
an upper layer, so it is out control of ext4 and deadlock is easy to
happen.
Virtually,  it is not right to block ext4_journal_start_sb() before we
confirm that current thread has no a active handle. But ext4 does like
that. Deadlock is thus easy to happen.   Right?
Could someone explain why ext4 does like above but not follow ext3?

Yongqiang.
--
Best Wishes
Yongqiang Yang


-- 
Best Wishes
Yongqiang Yang
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help