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, buf, size); 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 BLK_PERM_GRAPH_MOD; 176 if (resizable) { 177 shared_perm |= BLK_PERM_RESIZE; 178 } 179 if (conf->share_rw) { 180 shared_perm |= BLK_PERM_WRITE; 181 } 182 183 ret = blk_set_perm(blk, perm, shared_perm, errp); 184 if (ret < 0) { 185 return false; 186 } 187 188 switch (conf->wce) { 189 case ON_OFF_AUTO_ON: wce = true; break; 190 case ON_OFF_AUTO_OFF: wce = false; break; 191 case ON_OFF_AUTO_AUTO: wce = blk_enable_write_cache(blk); break; 192 default: 193 abort(); 194 } 195 196 rerror = conf->rerror; 197 if (rerror == BLOCKDEV_ON_ERROR_AUTO) { 198 rerror = blk_get_on_error(blk, true); 199 } 200 201 werror = conf->werror; 202 if (werror == BLOCKDEV_ON_ERROR_AUTO) { 203 werror = blk_get_on_error(blk, false); 204 } 205 206 blk_set_enable_write_cache(blk, wce); 207 blk_set_on_error(blk, rerror, werror); 208 209 return true; 210 } 211 212 bool blkconf_geometry(BlockConf *conf, int *ptrans, 213 unsigned cyls_max, unsigned heads_max, unsigned secs_max, 214 Error **errp) 215 { 216 if (!conf->cyls && !conf->heads && !conf->secs) { 217 hd_geometry_guess(conf->blk, 218 &conf->cyls, &conf->heads, &conf->secs, 219 ptrans); 220 } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) { 221 *ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs); 222 } 223 if (conf->cyls || conf->heads || conf->secs) { 224 if (conf->cyls < 1 || conf->cyls > cyls_max) { 225 error_setg(errp, "cyls must be between 1 and %u", cyls_max); 226 return false; 227 } 228 if (conf->heads < 1 || conf->heads > heads_max) { 229 error_setg(errp, "heads must be between 1 and %u", heads_max); 230 return false; 231 } 232 if (conf->secs < 1 || conf->secs > secs_max) { 233 error_setg(errp, "secs must be between 1 and %u", secs_max); 234 return false; 235 } 236 } 237 return true; 238 } 239