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 void blkconf_blocksizes(BlockConf *conf) 65 { 66 BlockBackend *blk = conf->blk; 67 BlockSizes blocksizes; 68 int backend_ret; 69 70 backend_ret = blk_probe_blocksizes(blk, &blocksizes); 71 /* fill in detected values if they are not defined via qemu command line */ 72 if (!conf->physical_block_size) { 73 if (!backend_ret) { 74 conf->physical_block_size = blocksizes.phys; 75 } else { 76 conf->physical_block_size = BDRV_SECTOR_SIZE; 77 } 78 } 79 if (!conf->logical_block_size) { 80 if (!backend_ret) { 81 conf->logical_block_size = blocksizes.log; 82 } else { 83 conf->logical_block_size = BDRV_SECTOR_SIZE; 84 } 85 } 86 } 87 88 bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, 89 bool resizable, Error **errp) 90 { 91 BlockBackend *blk = conf->blk; 92 BlockdevOnError rerror, werror; 93 uint64_t perm, shared_perm; 94 bool wce; 95 int ret; 96 97 perm = BLK_PERM_CONSISTENT_READ; 98 if (!readonly) { 99 perm |= BLK_PERM_WRITE; 100 } 101 102 shared_perm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED | 103 BLK_PERM_GRAPH_MOD; 104 if (resizable) { 105 shared_perm |= BLK_PERM_RESIZE; 106 } 107 if (conf->share_rw) { 108 shared_perm |= BLK_PERM_WRITE; 109 } 110 111 ret = blk_set_perm(blk, perm, shared_perm, errp); 112 if (ret < 0) { 113 return false; 114 } 115 116 switch (conf->wce) { 117 case ON_OFF_AUTO_ON: wce = true; break; 118 case ON_OFF_AUTO_OFF: wce = false; break; 119 case ON_OFF_AUTO_AUTO: wce = blk_enable_write_cache(blk); break; 120 default: 121 abort(); 122 } 123 124 rerror = conf->rerror; 125 if (rerror == BLOCKDEV_ON_ERROR_AUTO) { 126 rerror = blk_get_on_error(blk, true); 127 } 128 129 werror = conf->werror; 130 if (werror == BLOCKDEV_ON_ERROR_AUTO) { 131 werror = blk_get_on_error(blk, false); 132 } 133 134 blk_set_enable_write_cache(blk, wce); 135 blk_set_on_error(blk, rerror, werror); 136 137 return true; 138 } 139 140 bool blkconf_geometry(BlockConf *conf, int *ptrans, 141 unsigned cyls_max, unsigned heads_max, unsigned secs_max, 142 Error **errp) 143 { 144 if (!conf->cyls && !conf->heads && !conf->secs) { 145 hd_geometry_guess(conf->blk, 146 &conf->cyls, &conf->heads, &conf->secs, 147 ptrans); 148 } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) { 149 *ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs); 150 } 151 if (conf->cyls || conf->heads || conf->secs) { 152 if (conf->cyls < 1 || conf->cyls > cyls_max) { 153 error_setg(errp, "cyls must be between 1 and %u", cyls_max); 154 return false; 155 } 156 if (conf->heads < 1 || conf->heads > heads_max) { 157 error_setg(errp, "heads must be between 1 and %u", heads_max); 158 return false; 159 } 160 if (conf->secs < 1 || conf->secs > secs_max) { 161 error_setg(errp, "secs must be between 1 and %u", secs_max); 162 return false; 163 } 164 } 165 return true; 166 } 167