qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

block.c (7305B)


      1 /*
      2  * Common code for block device models
      3  *
      4  * Copyright (C) 2012 Red Hat, Inc.
      5  *
      6  * This work is licensed under the terms of the GNU GPL, version 2 or
      7  * later.  See the COPYING file in the top-level directory.
      8  */
      9 
     10 #include "qemu/osdep.h"
     11 #include "sysemu/blockdev.h"
     12 #include "sysemu/block-backend.h"
     13 #include "hw/block/block.h"
     14 #include "qapi/error.h"
     15 #include "qapi/qapi-types-block.h"
     16 
     17 /*
     18  * Read the entire contents of @blk into @buf.
     19  * @blk's contents must be @size bytes, and @size must be at most
     20  * BDRV_REQUEST_MAX_BYTES.
     21  * On success, return true.
     22  * On failure, store an error through @errp and return false.
     23  * Note that the error messages do not identify the block backend.
     24  * TODO Since callers don't either, this can result in confusing
     25  * errors.
     26  * This function not intended for actual block devices, which read on
     27  * demand.  It's for things like memory devices that (ab)use a block
     28  * backend to provide persistence.
     29  */
     30 bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
     31                                  Error **errp)
     32 {
     33     int64_t blk_len;
     34     int ret;
     35 
     36     blk_len = blk_getlength(blk);
     37     if (blk_len < 0) {
     38         error_setg_errno(errp, -blk_len,
     39                          "can't get size of block backend");
     40         return false;
     41     }
     42     if (blk_len != size) {
     43         error_setg(errp, "device requires %" HWADDR_PRIu " bytes, "
     44                    "block backend provides %" PRIu64 " bytes",
     45                    size, blk_len);
     46         return false;
     47     }
     48 
     49     /*
     50      * We could loop for @size > BDRV_REQUEST_MAX_BYTES, but if we
     51      * ever get to the point we want to read *gigabytes* here, we
     52      * should probably rework the device to be more like an actual
     53      * block device and read only on demand.
     54      */
     55     assert(size <= BDRV_REQUEST_MAX_BYTES);
     56     ret = blk_pread(blk, 0, size, buf, 0);
     57     if (ret < 0) {
     58         error_setg_errno(errp, -ret, "can't read block backend");
     59         return false;
     60     }
     61     return true;
     62 }
     63 
     64 bool blkconf_blocksizes(BlockConf *conf, Error **errp)
     65 {
     66     BlockBackend *blk = conf->blk;
     67     BlockSizes blocksizes;
     68     BlockDriverState *bs;
     69     bool use_blocksizes;
     70     bool use_bs;
     71 
     72     switch (conf->backend_defaults) {
     73     case ON_OFF_AUTO_AUTO:
     74         use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
     75         use_bs = false;
     76         break;
     77 
     78     case ON_OFF_AUTO_ON:
     79         use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
     80         bs = blk_bs(blk);
     81         use_bs = bs;
     82         break;
     83 
     84     case ON_OFF_AUTO_OFF:
     85         use_blocksizes = false;
     86         use_bs = false;
     87         break;
     88 
     89     default:
     90         abort();
     91     }
     92 
     93     /* fill in detected values if they are not defined via qemu command line */
     94     if (!conf->physical_block_size) {
     95         if (use_blocksizes) {
     96            conf->physical_block_size = blocksizes.phys;
     97         } else {
     98             conf->physical_block_size = BDRV_SECTOR_SIZE;
     99         }
    100     }
    101     if (!conf->logical_block_size) {
    102         if (use_blocksizes) {
    103             conf->logical_block_size = blocksizes.log;
    104         } else {
    105             conf->logical_block_size = BDRV_SECTOR_SIZE;
    106         }
    107     }
    108     if (use_bs) {
    109         if (!conf->opt_io_size) {
    110             conf->opt_io_size = bs->bl.opt_transfer;
    111         }
    112         if (conf->discard_granularity == -1) {
    113             if (bs->bl.pdiscard_alignment) {
    114                 conf->discard_granularity = bs->bl.pdiscard_alignment;
    115             } else if (bs->bl.request_alignment != 1) {
    116                 conf->discard_granularity = bs->bl.request_alignment;
    117             }
    118         }
    119     }
    120 
    121     if (conf->logical_block_size > conf->physical_block_size) {
    122         error_setg(errp,
    123                    "logical_block_size > physical_block_size not supported");
    124         return false;
    125     }
    126 
    127     if (!QEMU_IS_ALIGNED(conf->min_io_size, conf->logical_block_size)) {
    128         error_setg(errp,
    129                    "min_io_size must be a multiple of logical_block_size");
    130         return false;
    131     }
    132 
    133     /*
    134      * all devices which support min_io_size (scsi and virtio-blk) expose it to
    135      * the guest as a uint16_t in units of logical blocks
    136      */
    137     if (conf->min_io_size / conf->logical_block_size > UINT16_MAX) {
    138         error_setg(errp, "min_io_size must not exceed %u logical blocks",
    139                    UINT16_MAX);
    140         return false;
    141     }
    142 
    143     if (!QEMU_IS_ALIGNED(conf->opt_io_size, conf->logical_block_size)) {
    144         error_setg(errp,
    145                    "opt_io_size must be a multiple of logical_block_size");
    146         return false;
    147     }
    148 
    149     if (conf->discard_granularity != -1 &&
    150         !QEMU_IS_ALIGNED(conf->discard_granularity,
    151                          conf->logical_block_size)) {
    152         error_setg(errp, "discard_granularity must be "
    153                    "a multiple of logical_block_size");
    154         return false;
    155     }
    156 
    157     return true;
    158 }
    159 
    160 bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
    161                                    bool resizable, Error **errp)
    162 {
    163     BlockBackend *blk = conf->blk;
    164     BlockdevOnError rerror, werror;
    165     uint64_t perm, shared_perm;
    166     bool wce;
    167     int ret;
    168 
    169     perm = BLK_PERM_CONSISTENT_READ;
    170     if (!readonly) {
    171         perm |= BLK_PERM_WRITE;
    172     }
    173 
    174     shared_perm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
    175     if (resizable) {
    176         shared_perm |= BLK_PERM_RESIZE;
    177     }
    178     if (conf->share_rw) {
    179         shared_perm |= BLK_PERM_WRITE;
    180     }
    181 
    182     ret = blk_set_perm(blk, perm, shared_perm, errp);
    183     if (ret < 0) {
    184         return false;
    185     }
    186 
    187     switch (conf->wce) {
    188     case ON_OFF_AUTO_ON:    wce = true; break;
    189     case ON_OFF_AUTO_OFF:   wce = false; break;
    190     case ON_OFF_AUTO_AUTO:  wce = blk_enable_write_cache(blk); break;
    191     default:
    192         abort();
    193     }
    194 
    195     rerror = conf->rerror;
    196     if (rerror == BLOCKDEV_ON_ERROR_AUTO) {
    197         rerror = blk_get_on_error(blk, true);
    198     }
    199 
    200     werror = conf->werror;
    201     if (werror == BLOCKDEV_ON_ERROR_AUTO) {
    202         werror = blk_get_on_error(blk, false);
    203     }
    204 
    205     blk_set_enable_write_cache(blk, wce);
    206     blk_set_on_error(blk, rerror, werror);
    207 
    208     block_acct_setup(blk_get_stats(blk), conf->account_invalid,
    209                      conf->account_failed);
    210     return true;
    211 }
    212 
    213 bool blkconf_geometry(BlockConf *conf, int *ptrans,
    214                       unsigned cyls_max, unsigned heads_max, unsigned secs_max,
    215                       Error **errp)
    216 {
    217     if (!conf->cyls && !conf->heads && !conf->secs) {
    218         hd_geometry_guess(conf->blk,
    219                           &conf->cyls, &conf->heads, &conf->secs,
    220                           ptrans);
    221     } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
    222         *ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
    223     }
    224     if (conf->cyls || conf->heads || conf->secs) {
    225         if (conf->cyls < 1 || conf->cyls > cyls_max) {
    226             error_setg(errp, "cyls must be between 1 and %u", cyls_max);
    227             return false;
    228         }
    229         if (conf->heads < 1 || conf->heads > heads_max) {
    230             error_setg(errp, "heads must be between 1 and %u", heads_max);
    231             return false;
    232         }
    233         if (conf->secs < 1 || conf->secs > secs_max) {
    234             error_setg(errp, "secs must be between 1 and %u", secs_max);
    235             return false;
    236         }
    237     }
    238     return true;
    239 }