HomeFreeBSD

Fix zvol_open() lock inversion

Description

Fix zvol_open() lock inversion

When restructuring the zvol_open() logic for the Linux 5.13 kernel
a lock inversion was accidentally introduced. In the updated code
the spa_namespace_lock is now taken before the zv_suspend_lock
allowing the following scenario to occur:

    down_read <=== waiting for zv_suspend_lock
    zvol_open <=== holds spa_namespace_lock
    __blkdev_get
    blkdev_get_by_dev
    blkdev_open
    ...

     mutex_lock <== waiting for spa_namespace_lock
     spa_open_common
     spa_open
     dsl_pool_hold
     dmu_objset_hold_flags
     dmu_objset_hold
     dsl_prop_get
     dsl_prop_get_integer
     zvol_create_minor
     dmu_recv_end
     zfs_ioc_recv_impl <=== holds zv_suspend_lock via zvol_suspend()
     zfs_ioc_recv
     ...

This commit resolves the issue by moving the acquisition of the
spa_namespace_lock back to after the zv_suspend_lock which restores
the original ordering.

Additionally, as part of this change the error exit paths were
simplified where possible.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Rich Ercolani <rincebrain@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #12863

Details

Provenance
Brian Behlendorf <behlendorf1@llnl.gov>Authored on Dec 17 2021, 5:52 PM
Tony Hutter <hutter2@llnl.gov>Committed on Feb 3 2022, 11:28 PM
Parents
rG4b2bac5fe954: FreeBSD: Update argument types for VOP_READDIR
Branches
Unknown
Tags
Unknown

Event Timeline

Tony Hutter <hutter2@llnl.gov> committed rG9ec630ff2cd7: Fix zvol_open() lock inversion (authored by Brian Behlendorf <behlendorf1@llnl.gov>).Feb 3 2022, 11:28 PM