Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deadlock between spa_errlog_lock and dp_config_rwlock #14289

Merged
merged 1 commit into from
Dec 22, 2022

Commits on Dec 20, 2022

  1. deadlock between spa_errlog_lock and dp_config_rwlock

    There is a lock order inversion deadlock between `spa_errlog_lock` and
    `dp_config_rwlock`:
    
    A thread in `spa_delete_dataset_errlog()` is running from a sync task.
    It is holding the `dp_config_rwlock` for writer (see
    `dsl_sync_task_sync()`), and waiting for the `spa_errlog_lock`.
    
    A thread in `dsl_pool_config_enter()` is holding the `spa_errlog_lock`
    (see `spa_get_errlog_size()`) and waiting for the `dp_config_rwlock` (as
    reader).
    
    Note that this was introduced by openzfs#12812.
    
    This commit address this by defining the lock ordering to be
    dp_config_rwlock first, then spa_errlog_lock / spa_errlist_lock.
    spa_get_errlog() and spa_get_errlog_size() can acquire the locks in this
    order, and then process_error_block() and get_head_and_birth_txg() can
    verify that the dp_config_rwlock is already held.
    
    Additionally, a buffer overrun in `spa_get_errlog()` is corrected.  Many
    code paths didn't check if `*count` got to zero, instead continuing to
    overwrite past the beginning of the userspace buffer at `uaddr`.
    
    Tested by having some errors in the pool (via `zinject -t data
    /path/to/file`), one thread running `zpool iostat 0.001`, and another
    thread runs `zfs destroy` (in a loop, although it hits the first time).
    This reproduces the problem easily without the fix, and works with the
    fix.
    
    Closes openzfs#14239
    Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
    ahrens committed Dec 20, 2022
    Configuration menu
    Copy the full SHA
    4992841 View commit details
    Browse the repository at this point in the history