xref: /openbmc/qemu/hw/block/block.c (revision 24f920ad5ad038364407effce092945c40a46fe9)
149ab747fSPaolo Bonzini /*
249ab747fSPaolo Bonzini  * Common code for block device models
349ab747fSPaolo Bonzini  *
449ab747fSPaolo Bonzini  * Copyright (C) 2012 Red Hat, Inc.
549ab747fSPaolo Bonzini  *
649ab747fSPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2 or
749ab747fSPaolo Bonzini  * later.  See the COPYING file in the top-level directory.
849ab747fSPaolo Bonzini  */
949ab747fSPaolo Bonzini 
1080c71a24SPeter Maydell #include "qemu/osdep.h"
11e2c1c34fSMarkus Armbruster #include "block/block_int-common.h"
1249ab747fSPaolo Bonzini #include "sysemu/blockdev.h"
134be74634SMarkus Armbruster #include "sysemu/block-backend.h"
1449ab747fSPaolo Bonzini #include "hw/block/block.h"
15da34e65cSMarkus Armbruster #include "qapi/error.h"
169af23989SMarkus Armbruster #include "qapi/qapi-types-block.h"
1706f15217SMarkus Armbruster 
1806f15217SMarkus Armbruster /*
19a4b15a8bSXiang Zheng  * Read the non-zeroes parts of @blk into @buf
20a4b15a8bSXiang Zheng  * Reading all of the @blk is expensive if the zeroes parts of @blk
21a4b15a8bSXiang Zheng  * is large enough. Therefore check the block status and only write
22a4b15a8bSXiang Zheng  * the non-zeroes block into @buf.
23a4b15a8bSXiang Zheng  *
24a4b15a8bSXiang Zheng  * Return 0 on success, non-zero on error.
25a4b15a8bSXiang Zheng  */
blk_pread_nonzeroes(BlockBackend * blk,hwaddr size,void * buf)26a4b15a8bSXiang Zheng static int blk_pread_nonzeroes(BlockBackend *blk, hwaddr size, void *buf)
27a4b15a8bSXiang Zheng {
28a4b15a8bSXiang Zheng     int ret;
29a4b15a8bSXiang Zheng     int64_t bytes, offset = 0;
30a4b15a8bSXiang Zheng     BlockDriverState *bs = blk_bs(blk);
31a4b15a8bSXiang Zheng 
32a4b15a8bSXiang Zheng     for (;;) {
33d5eaeefbSStefan Hajnoczi         bytes = MIN(size - offset, BDRV_REQUEST_MAX_BYTES);
34a4b15a8bSXiang Zheng         if (bytes <= 0) {
35a4b15a8bSXiang Zheng             return 0;
36a4b15a8bSXiang Zheng         }
37a4b15a8bSXiang Zheng         ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
38a4b15a8bSXiang Zheng         if (ret < 0) {
39a4b15a8bSXiang Zheng             return ret;
40a4b15a8bSXiang Zheng         }
41a4b15a8bSXiang Zheng         if (!(ret & BDRV_BLOCK_ZERO)) {
423c6f3f65SKevin Wolf             ret = blk_pread(blk, offset, bytes, (uint8_t *) buf + offset, 0);
43a4b15a8bSXiang Zheng             if (ret < 0) {
44a4b15a8bSXiang Zheng                 return ret;
45a4b15a8bSXiang Zheng             }
46a4b15a8bSXiang Zheng         }
47a4b15a8bSXiang Zheng         offset += bytes;
48a4b15a8bSXiang Zheng     }
49a4b15a8bSXiang Zheng }
50a4b15a8bSXiang Zheng 
51a4b15a8bSXiang Zheng /*
5206f15217SMarkus Armbruster  * Read the entire contents of @blk into @buf.
5306f15217SMarkus Armbruster  * @blk's contents must be @size bytes, and @size must be at most
5406f15217SMarkus Armbruster  * BDRV_REQUEST_MAX_BYTES.
5506f15217SMarkus Armbruster  * On success, return true.
5606f15217SMarkus Armbruster  * On failure, store an error through @errp and return false.
57*954b33daSManos Pitsidianakis  *
5806f15217SMarkus Armbruster  * This function not intended for actual block devices, which read on
5906f15217SMarkus Armbruster  * demand.  It's for things like memory devices that (ab)use a block
6006f15217SMarkus Armbruster  * backend to provide persistence.
6106f15217SMarkus Armbruster  */
blk_check_size_and_read_all(BlockBackend * blk,DeviceState * dev,void * buf,hwaddr size,Error ** errp)62*954b33daSManos Pitsidianakis bool blk_check_size_and_read_all(BlockBackend *blk, DeviceState *dev,
63*954b33daSManos Pitsidianakis                                  void *buf, hwaddr size, Error **errp)
6406f15217SMarkus Armbruster {
6506f15217SMarkus Armbruster     int64_t blk_len;
6606f15217SMarkus Armbruster     int ret;
67*954b33daSManos Pitsidianakis     g_autofree char *dev_id = NULL;
6806f15217SMarkus Armbruster 
6906f15217SMarkus Armbruster     blk_len = blk_getlength(blk);
7006f15217SMarkus Armbruster     if (blk_len < 0) {
7106f15217SMarkus Armbruster         error_setg_errno(errp, -blk_len,
72*954b33daSManos Pitsidianakis                          "can't get size of %s block backend", blk_name(blk));
7306f15217SMarkus Armbruster         return false;
7406f15217SMarkus Armbruster     }
7506f15217SMarkus Armbruster     if (blk_len != size) {
76*954b33daSManos Pitsidianakis         dev_id = qdev_get_human_name(dev);
77*954b33daSManos Pitsidianakis         error_setg(errp, "%s device '%s' requires %" HWADDR_PRIu
78*954b33daSManos Pitsidianakis                    " bytes, %s block backend provides %" PRIu64 " bytes",
79*954b33daSManos Pitsidianakis                    object_get_typename(OBJECT(dev)), dev_id, size,
80*954b33daSManos Pitsidianakis                    blk_name(blk), blk_len);
8106f15217SMarkus Armbruster         return false;
8206f15217SMarkus Armbruster     }
8306f15217SMarkus Armbruster 
8406f15217SMarkus Armbruster     /*
8506f15217SMarkus Armbruster      * We could loop for @size > BDRV_REQUEST_MAX_BYTES, but if we
8606f15217SMarkus Armbruster      * ever get to the point we want to read *gigabytes* here, we
8706f15217SMarkus Armbruster      * should probably rework the device to be more like an actual
8806f15217SMarkus Armbruster      * block device and read only on demand.
8906f15217SMarkus Armbruster      */
9006f15217SMarkus Armbruster     assert(size <= BDRV_REQUEST_MAX_BYTES);
91a4b15a8bSXiang Zheng     ret = blk_pread_nonzeroes(blk, size, buf);
9206f15217SMarkus Armbruster     if (ret < 0) {
93*954b33daSManos Pitsidianakis         dev_id = qdev_get_human_name(dev);
94*954b33daSManos Pitsidianakis         error_setg_errno(errp, -ret, "can't read %s block backend"
95*954b33daSManos Pitsidianakis                          " for %s device '%s'",
96*954b33daSManos Pitsidianakis                          blk_name(blk), object_get_typename(OBJECT(dev)),
97*954b33daSManos Pitsidianakis                          dev_id);
9806f15217SMarkus Armbruster         return false;
9906f15217SMarkus Armbruster     }
10006f15217SMarkus Armbruster     return true;
10106f15217SMarkus Armbruster }
10249ab747fSPaolo Bonzini 
blkconf_blocksizes(BlockConf * conf,Error ** errp)103c56ee92fSRoman Kagan bool blkconf_blocksizes(BlockConf *conf, Error **errp)
1040eb28a42SEkaterina Tumanova {
1050eb28a42SEkaterina Tumanova     BlockBackend *blk = conf->blk;
1060eb28a42SEkaterina Tumanova     BlockSizes blocksizes;
10712a521b5SAkihiko Odaki     BlockDriverState *bs;
10812a521b5SAkihiko Odaki     bool use_blocksizes;
10912a521b5SAkihiko Odaki     bool use_bs;
1100eb28a42SEkaterina Tumanova 
11112a521b5SAkihiko Odaki     switch (conf->backend_defaults) {
11212a521b5SAkihiko Odaki     case ON_OFF_AUTO_AUTO:
11312a521b5SAkihiko Odaki         use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
11412a521b5SAkihiko Odaki         use_bs = false;
11512a521b5SAkihiko Odaki         break;
11612a521b5SAkihiko Odaki 
11712a521b5SAkihiko Odaki     case ON_OFF_AUTO_ON:
11812a521b5SAkihiko Odaki         use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
11912a521b5SAkihiko Odaki         bs = blk_bs(blk);
12012a521b5SAkihiko Odaki         use_bs = bs;
12112a521b5SAkihiko Odaki         break;
12212a521b5SAkihiko Odaki 
12312a521b5SAkihiko Odaki     case ON_OFF_AUTO_OFF:
12412a521b5SAkihiko Odaki         use_blocksizes = false;
12512a521b5SAkihiko Odaki         use_bs = false;
12612a521b5SAkihiko Odaki         break;
12712a521b5SAkihiko Odaki 
12812a521b5SAkihiko Odaki     default:
12912a521b5SAkihiko Odaki         abort();
13012a521b5SAkihiko Odaki     }
13112a521b5SAkihiko Odaki 
1320eb28a42SEkaterina Tumanova     /* fill in detected values if they are not defined via qemu command line */
1330eb28a42SEkaterina Tumanova     if (!conf->physical_block_size) {
13412a521b5SAkihiko Odaki         if (use_blocksizes) {
1350eb28a42SEkaterina Tumanova            conf->physical_block_size = blocksizes.phys;
1360eb28a42SEkaterina Tumanova         } else {
1370eb28a42SEkaterina Tumanova             conf->physical_block_size = BDRV_SECTOR_SIZE;
1380eb28a42SEkaterina Tumanova         }
1390eb28a42SEkaterina Tumanova     }
1400eb28a42SEkaterina Tumanova     if (!conf->logical_block_size) {
14112a521b5SAkihiko Odaki         if (use_blocksizes) {
1420eb28a42SEkaterina Tumanova             conf->logical_block_size = blocksizes.log;
1430eb28a42SEkaterina Tumanova         } else {
1440eb28a42SEkaterina Tumanova             conf->logical_block_size = BDRV_SECTOR_SIZE;
1450eb28a42SEkaterina Tumanova         }
1460eb28a42SEkaterina Tumanova     }
14712a521b5SAkihiko Odaki     if (use_bs) {
14812a521b5SAkihiko Odaki         if (!conf->opt_io_size) {
14912a521b5SAkihiko Odaki             conf->opt_io_size = bs->bl.opt_transfer;
15012a521b5SAkihiko Odaki         }
15112a521b5SAkihiko Odaki         if (conf->discard_granularity == -1) {
15212a521b5SAkihiko Odaki             if (bs->bl.pdiscard_alignment) {
15312a521b5SAkihiko Odaki                 conf->discard_granularity = bs->bl.pdiscard_alignment;
15412a521b5SAkihiko Odaki             } else if (bs->bl.request_alignment != 1) {
15512a521b5SAkihiko Odaki                 conf->discard_granularity = bs->bl.request_alignment;
15612a521b5SAkihiko Odaki             }
15712a521b5SAkihiko Odaki         }
15812a521b5SAkihiko Odaki     }
159c56ee92fSRoman Kagan 
160c56ee92fSRoman Kagan     if (conf->logical_block_size > conf->physical_block_size) {
161c56ee92fSRoman Kagan         error_setg(errp,
162c56ee92fSRoman Kagan                    "logical_block_size > physical_block_size not supported");
163c56ee92fSRoman Kagan         return false;
164c56ee92fSRoman Kagan     }
165c56ee92fSRoman Kagan 
166c56ee92fSRoman Kagan     if (!QEMU_IS_ALIGNED(conf->min_io_size, conf->logical_block_size)) {
167c56ee92fSRoman Kagan         error_setg(errp,
168c56ee92fSRoman Kagan                    "min_io_size must be a multiple of logical_block_size");
169c56ee92fSRoman Kagan         return false;
170c56ee92fSRoman Kagan     }
171c56ee92fSRoman Kagan 
1724f44bbc5SRoman Kagan     /*
1734f44bbc5SRoman Kagan      * all devices which support min_io_size (scsi and virtio-blk) expose it to
1744f44bbc5SRoman Kagan      * the guest as a uint16_t in units of logical blocks
1754f44bbc5SRoman Kagan      */
1764f44bbc5SRoman Kagan     if (conf->min_io_size / conf->logical_block_size > UINT16_MAX) {
1774f44bbc5SRoman Kagan         error_setg(errp, "min_io_size must not exceed %u logical blocks",
1784f44bbc5SRoman Kagan                    UINT16_MAX);
1794f44bbc5SRoman Kagan         return false;
1804f44bbc5SRoman Kagan     }
1814f44bbc5SRoman Kagan 
182c56ee92fSRoman Kagan     if (!QEMU_IS_ALIGNED(conf->opt_io_size, conf->logical_block_size)) {
183c56ee92fSRoman Kagan         error_setg(errp,
184c56ee92fSRoman Kagan                    "opt_io_size must be a multiple of logical_block_size");
185c56ee92fSRoman Kagan         return false;
186c56ee92fSRoman Kagan     }
187c56ee92fSRoman Kagan 
188c56ee92fSRoman Kagan     if (conf->discard_granularity != -1 &&
189c56ee92fSRoman Kagan         !QEMU_IS_ALIGNED(conf->discard_granularity,
190c56ee92fSRoman Kagan                          conf->logical_block_size)) {
191c56ee92fSRoman Kagan         error_setg(errp, "discard_granularity must be "
192c56ee92fSRoman Kagan                    "a multiple of logical_block_size");
193c56ee92fSRoman Kagan         return false;
194c56ee92fSRoman Kagan     }
195c56ee92fSRoman Kagan 
196c56ee92fSRoman Kagan     return true;
1970eb28a42SEkaterina Tumanova }
1980eb28a42SEkaterina Tumanova 
blkconf_apply_backend_options(BlockConf * conf,bool readonly,bool resizable,Error ** errp)1999d3b1551SMao Zhongyi bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
200a17c17a2SKevin Wolf                                    bool resizable, Error **errp)
201f6166a06SKevin Wolf {
202f6166a06SKevin Wolf     BlockBackend *blk = conf->blk;
2038c398252SKevin Wolf     BlockdevOnError rerror, werror;
204a17c17a2SKevin Wolf     uint64_t perm, shared_perm;
205f6166a06SKevin Wolf     bool wce;
206a17c17a2SKevin Wolf     int ret;
207a17c17a2SKevin Wolf 
208a17c17a2SKevin Wolf     perm = BLK_PERM_CONSISTENT_READ;
209a17c17a2SKevin Wolf     if (!readonly) {
210a17c17a2SKevin Wolf         perm |= BLK_PERM_WRITE;
211a17c17a2SKevin Wolf     }
212a17c17a2SKevin Wolf 
21364631f36SVladimir Sementsov-Ogievskiy     shared_perm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
214a17c17a2SKevin Wolf     if (resizable) {
215a17c17a2SKevin Wolf         shared_perm |= BLK_PERM_RESIZE;
216a17c17a2SKevin Wolf     }
217dabd18f6SKevin Wolf     if (conf->share_rw) {
218dabd18f6SKevin Wolf         shared_perm |= BLK_PERM_WRITE;
219dabd18f6SKevin Wolf     }
220a17c17a2SKevin Wolf 
221a17c17a2SKevin Wolf     ret = blk_set_perm(blk, perm, shared_perm, errp);
222a17c17a2SKevin Wolf     if (ret < 0) {
2239d3b1551SMao Zhongyi         return false;
224a17c17a2SKevin Wolf     }
225f6166a06SKevin Wolf 
226f6166a06SKevin Wolf     switch (conf->wce) {
227f6166a06SKevin Wolf     case ON_OFF_AUTO_ON:    wce = true; break;
228f6166a06SKevin Wolf     case ON_OFF_AUTO_OFF:   wce = false; break;
229f6166a06SKevin Wolf     case ON_OFF_AUTO_AUTO:  wce = blk_enable_write_cache(blk); break;
230f6166a06SKevin Wolf     default:
231f6166a06SKevin Wolf         abort();
232f6166a06SKevin Wolf     }
233f6166a06SKevin Wolf 
2348c398252SKevin Wolf     rerror = conf->rerror;
2358c398252SKevin Wolf     if (rerror == BLOCKDEV_ON_ERROR_AUTO) {
2368c398252SKevin Wolf         rerror = blk_get_on_error(blk, true);
2378c398252SKevin Wolf     }
2388c398252SKevin Wolf 
2398c398252SKevin Wolf     werror = conf->werror;
2408c398252SKevin Wolf     if (werror == BLOCKDEV_ON_ERROR_AUTO) {
2418c398252SKevin Wolf         werror = blk_get_on_error(blk, false);
2428c398252SKevin Wolf     }
2438c398252SKevin Wolf 
244f6166a06SKevin Wolf     blk_set_enable_write_cache(blk, wce);
2458c398252SKevin Wolf     blk_set_on_error(blk, rerror, werror);
2469d3b1551SMao Zhongyi 
24762a6c300SDenis V. Lunev     block_acct_setup(blk_get_stats(blk), conf->account_invalid,
24862a6c300SDenis V. Lunev                      conf->account_failed);
2499d3b1551SMao Zhongyi     return true;
250f6166a06SKevin Wolf }
251f6166a06SKevin Wolf 
blkconf_geometry(BlockConf * conf,int * ptrans,unsigned cyls_max,unsigned heads_max,unsigned secs_max,Error ** errp)2529d3b1551SMao Zhongyi bool blkconf_geometry(BlockConf *conf, int *ptrans,
2535ff5efb4SFam Zheng                       unsigned cyls_max, unsigned heads_max, unsigned secs_max,
2545ff5efb4SFam Zheng                       Error **errp)
25549ab747fSPaolo Bonzini {
25649ab747fSPaolo Bonzini     if (!conf->cyls && !conf->heads && !conf->secs) {
2574be74634SMarkus Armbruster         hd_geometry_guess(conf->blk,
25849ab747fSPaolo Bonzini                           &conf->cyls, &conf->heads, &conf->secs,
25949ab747fSPaolo Bonzini                           ptrans);
26049ab747fSPaolo Bonzini     } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
26149ab747fSPaolo Bonzini         *ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
26249ab747fSPaolo Bonzini     }
26349ab747fSPaolo Bonzini     if (conf->cyls || conf->heads || conf->secs) {
26449ab747fSPaolo Bonzini         if (conf->cyls < 1 || conf->cyls > cyls_max) {
2655ff5efb4SFam Zheng             error_setg(errp, "cyls must be between 1 and %u", cyls_max);
2669d3b1551SMao Zhongyi             return false;
26749ab747fSPaolo Bonzini         }
26849ab747fSPaolo Bonzini         if (conf->heads < 1 || conf->heads > heads_max) {
2695ff5efb4SFam Zheng             error_setg(errp, "heads must be between 1 and %u", heads_max);
2709d3b1551SMao Zhongyi             return false;
27149ab747fSPaolo Bonzini         }
27249ab747fSPaolo Bonzini         if (conf->secs < 1 || conf->secs > secs_max) {
2735ff5efb4SFam Zheng             error_setg(errp, "secs must be between 1 and %u", secs_max);
2749d3b1551SMao Zhongyi             return false;
27549ab747fSPaolo Bonzini         }
27649ab747fSPaolo Bonzini     }
2779d3b1551SMao Zhongyi     return true;
27849ab747fSPaolo Bonzini }
279