lkml.org 
[lkml]   [2019]   [Jan]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 88/99] loop: Push loop_ctl_mutex down to loop_set_status()
    Date
    4.19-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Jan Kara <jack@suse.cz>

    commit 550df5fdacff94229cde0ed9b8085155654c1696 upstream.

    Push loop_ctl_mutex down to loop_set_status(). We will need this to be
    able to call loop_reread_partitions() without loop_ctl_mutex.

    Signed-off-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/block/loop.c | 51 +++++++++++++++++++++++++--------------------------
    1 file changed, 25 insertions(+), 26 deletions(-)

    --- a/drivers/block/loop.c
    +++ b/drivers/block/loop.c
    @@ -1142,46 +1142,55 @@ loop_set_status(struct loop_device *lo,
    struct loop_func_table *xfer;
    kuid_t uid = current_uid();

    + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
    + if (err)
    + return err;
    if (lo->lo_encrypt_key_size &&
    !uid_eq(lo->lo_key_owner, uid) &&
    - !capable(CAP_SYS_ADMIN))
    - return -EPERM;
    - if (lo->lo_state != Lo_bound)
    - return -ENXIO;
    - if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
    - return -EINVAL;
    + !capable(CAP_SYS_ADMIN)) {
    + err = -EPERM;
    + goto out_unlock;
    + }
    + if (lo->lo_state != Lo_bound) {
    + err = -ENXIO;
    + goto out_unlock;
    + }
    + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) {
    + err = -EINVAL;
    + goto out_unlock;
    + }

    /* I/O need to be drained during transfer transition */
    blk_mq_freeze_queue(lo->lo_queue);

    err = loop_release_xfer(lo);
    if (err)
    - goto exit;
    + goto out_unfreeze;

    if (info->lo_encrypt_type) {
    unsigned int type = info->lo_encrypt_type;

    if (type >= MAX_LO_CRYPT) {
    err = -EINVAL;
    - goto exit;
    + goto out_unfreeze;
    }
    xfer = xfer_funcs[type];
    if (xfer == NULL) {
    err = -EINVAL;
    - goto exit;
    + goto out_unfreeze;
    }
    } else
    xfer = NULL;

    err = loop_init_xfer(lo, xfer, info);
    if (err)
    - goto exit;
    + goto out_unfreeze;

    if (lo->lo_offset != info->lo_offset ||
    lo->lo_sizelimit != info->lo_sizelimit) {
    if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
    err = -EFBIG;
    - goto exit;
    + goto out_unfreeze;
    }
    }

    @@ -1213,7 +1222,7 @@ loop_set_status(struct loop_device *lo,
    /* update dio if lo_offset or transfer is changed */
    __loop_update_dio(lo, lo->use_dio);

    - exit:
    +out_unfreeze:
    blk_mq_unfreeze_queue(lo->lo_queue);

    if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
    @@ -1222,6 +1231,8 @@ loop_set_status(struct loop_device *lo,
    lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
    loop_reread_partitions(lo, lo->lo_device);
    }
    +out_unlock:
    + mutex_unlock(&loop_ctl_mutex);

    return err;
    }
    @@ -1468,12 +1479,8 @@ static int lo_ioctl(struct block_device
    case LOOP_SET_STATUS:
    err = -EPERM;
    if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
    - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
    - if (err)
    - return err;
    err = loop_set_status_old(lo,
    (struct loop_info __user *)arg);
    - mutex_unlock(&loop_ctl_mutex);
    }
    break;
    case LOOP_GET_STATUS:
    @@ -1481,12 +1488,8 @@ static int lo_ioctl(struct block_device
    case LOOP_SET_STATUS64:
    err = -EPERM;
    if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
    - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
    - if (err)
    - return err;
    err = loop_set_status64(lo,
    (struct loop_info64 __user *) arg);
    - mutex_unlock(&loop_ctl_mutex);
    }
    break;
    case LOOP_GET_STATUS64:
    @@ -1631,12 +1634,8 @@ static int lo_compat_ioctl(struct block_

    switch(cmd) {
    case LOOP_SET_STATUS:
    - err = mutex_lock_killable(&loop_ctl_mutex);
    - if (!err) {
    - err = loop_set_status_compat(lo,
    - (const struct compat_loop_info __user *)arg);
    - mutex_unlock(&loop_ctl_mutex);
    - }
    + err = loop_set_status_compat(lo,
    + (const struct compat_loop_info __user *)arg);
    break;
    case LOOP_GET_STATUS:
    err = loop_get_status_compat(lo,

    \
     
     \ /
      Last update: 2019-01-21 15:02    [W:3.691 / U:0.136 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site