Skip to content
  • Kiyoshi Ueda's avatar
    dm table: remove dm_get from dm_table_get_md · ecdb2e25
    Kiyoshi Ueda authored
    
    
    Remove the dm_get() in dm_table_get_md() because dm_table_get_md() could
    be called from presuspend/postsuspend, which are called while
    mapped_device is in DMF_FREEING state, where dm_get() is not allowed.
    
    Justification for that is the lifetime of both objects: As far as the
    current dm design/implementation, mapped_device is never freed while
    targets are doing something, because dm core waits for targets to become
    quiet in dm_put() using presuspend/postsuspend.  So targets should be
    able to touch mapped_device without holding reference count of the
    mapped_device, and we should allow targets to touch mapped_device even
    if it is in DMF_FREEING state.
    
    Backgrounds:
    I'm trying to remove the multipath internal queue, since dm core now has
    a generic queue for request-based dm.  In the patch-set, the multipath
    target wants to request dm core to start/stop queue.  One of such
    start/stop requests can happen during postsuspend() while the target
    waits for pg-init to complete, because the target stops queue when
    starting pg-init and tries to restart it when completing pg-init.  Since
    queue belongs to mapped_device, it involves calling dm_table_get_md()
    and dm_put().  On the other hand, postsuspend() is called in dm_put()
    for mapped_device which is in DMF_FREEING state, and that triggers
    BUG_ON(DMF_FREEING) in the 2nd dm_put().
    
    I had tried to solve this problem by changing only multipath not to
    touch mapped_device which is in DMF_FREEING state, but I couldn't and I
    came up with a question why we need dm_get() in dm_table_get_md().
    
    Signed-off-by: default avatarKiyoshi Ueda <k-ueda@ct.jp.nec.com>
    Signed-off-by: default avatarJun'ichi Nomura <j-nomura@ce.jp.nec.com>
    Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
    ecdb2e25