xref: /qemu/hw/block/block.c (revision aa90f1161bb17a4863e16ec2f75104cff0752d4e)
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 "block/block_int-common.h"
12 #include "system/blockdev.h"
13 #include "system/block-backend.h"
14 #include "hw/block/block.h"
15 #include "migration/cpr.h"
16 #include "qapi/error.h"
17 #include "qapi/qapi-types-block.h"
18 
19 /*
20  * Read the non-zeroes parts of @blk into @buf
21  * Reading all of the @blk is expensive if the zeroes parts of @blk
22  * is large enough. Therefore check the block status and only write
23  * the non-zeroes block into @buf.
24  *
25  * Return 0 on success, non-zero on error.
26  */
blk_pread_nonzeroes(BlockBackend * blk,hwaddr size,void * buf)27 static int blk_pread_nonzeroes(BlockBackend *blk, hwaddr size, void *buf)
28 {
29     int ret;
30     int64_t bytes, offset = 0;
31     BlockDriverState *bs = blk_bs(blk);
32 
33     for (;;) {
34         bytes = MIN(size - offset, BDRV_REQUEST_MAX_BYTES);
35         if (bytes <= 0) {
36             return 0;
37         }
38         ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
39         if (ret < 0) {
40             return ret;
41         }
42         if (!(ret & BDRV_BLOCK_ZERO)) {
43             ret = blk_pread(blk, offset, bytes, (uint8_t *) buf + offset, 0);
44             if (ret < 0) {
45                 return ret;
46             }
47         }
48         offset += bytes;
49     }
50 }
51 
52 /*
53  * Read the entire contents of @blk into @buf.
54  * @blk's contents must be @size bytes, and @size must be at most
55  * BDRV_REQUEST_MAX_BYTES.
56  * On success, return true.
57  * On failure, store an error through @errp and return false.
58  *
59  * This function not intended for actual block devices, which read on
60  * demand.  It's for things like memory devices that (ab)use a block
61  * backend to provide persistence.
62  */
blk_check_size_and_read_all(BlockBackend * blk,DeviceState * dev,void * buf,hwaddr size,Error ** errp)63 bool blk_check_size_and_read_all(BlockBackend *blk, DeviceState *dev,
64                                  void *buf, hwaddr size, Error **errp)
65 {
66     int64_t blk_len;
67     int ret;
68     g_autofree char *dev_id = NULL;
69 
70     if (cpr_is_incoming()) {
71         return true;
72     }
73 
74     blk_len = blk_getlength(blk);
75     if (blk_len < 0) {
76         error_setg_errno(errp, -blk_len,
77                          "can't get size of %s block backend", blk_name(blk));
78         return false;
79     }
80     if (blk_len != size) {
81         dev_id = qdev_get_human_name(dev);
82         error_setg(errp, "%s device '%s' requires %" HWADDR_PRIu
83                    " bytes, %s block backend provides %" PRIu64 " bytes",
84                    object_get_typename(OBJECT(dev)), dev_id, size,
85                    blk_name(blk), blk_len);
86         return false;
87     }
88 
89     /*
90      * We could loop for @size > BDRV_REQUEST_MAX_BYTES, but if we
91      * ever get to the point we want to read *gigabytes* here, we
92      * should probably rework the device to be more like an actual
93      * block device and read only on demand.
94      */
95     assert(size <= BDRV_REQUEST_MAX_BYTES);
96     ret = blk_pread_nonzeroes(blk, size, buf);
97     if (ret < 0) {
98         dev_id = qdev_get_human_name(dev);
99         error_setg_errno(errp, -ret, "can't read %s block backend"
100                          " for %s device '%s'",
101                          blk_name(blk), object_get_typename(OBJECT(dev)),
102                          dev_id);
103         return false;
104     }
105     return true;
106 }
107 
blkconf_blocksizes(BlockConf * conf,Error ** errp)108 bool blkconf_blocksizes(BlockConf *conf, Error **errp)
109 {
110     BlockBackend *blk = conf->blk;
111     BlockSizes blocksizes;
112     BlockDriverState *bs;
113     bool use_blocksizes;
114     bool use_bs;
115 
116     switch (conf->backend_defaults) {
117     case ON_OFF_AUTO_AUTO:
118         use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
119         use_bs = false;
120         break;
121 
122     case ON_OFF_AUTO_ON:
123         use_blocksizes = !blk_probe_blocksizes(blk, &blocksizes);
124         bs = blk_bs(blk);
125         use_bs = bs;
126         break;
127 
128     case ON_OFF_AUTO_OFF:
129         use_blocksizes = false;
130         use_bs = false;
131         break;
132 
133     default:
134         abort();
135     }
136 
137     /* fill in detected values if they are not defined via qemu command line */
138     if (!conf->physical_block_size) {
139         if (use_blocksizes) {
140            conf->physical_block_size = blocksizes.phys;
141         } else {
142             conf->physical_block_size = BDRV_SECTOR_SIZE;
143         }
144     }
145     if (!conf->logical_block_size) {
146         if (use_blocksizes) {
147             conf->logical_block_size = blocksizes.log;
148         } else {
149             conf->logical_block_size = BDRV_SECTOR_SIZE;
150         }
151     }
152     if (use_bs) {
153         if (!conf->opt_io_size) {
154             conf->opt_io_size = bs->bl.opt_transfer;
155         }
156         if (conf->discard_granularity == -1) {
157             if (bs->bl.pdiscard_alignment) {
158                 conf->discard_granularity = bs->bl.pdiscard_alignment;
159             } else if (bs->bl.request_alignment != 1) {
160                 conf->discard_granularity = bs->bl.request_alignment;
161             }
162         }
163     }
164 
165     if (conf->logical_block_size > conf->physical_block_size) {
166         error_setg(errp,
167                    "logical_block_size > physical_block_size not supported");
168         return false;
169     }
170 
171     if (!QEMU_IS_ALIGNED(conf->min_io_size, conf->logical_block_size)) {
172         error_setg(errp,
173                    "min_io_size must be a multiple of logical_block_size");
174         return false;
175     }
176 
177     /*
178      * all devices which support min_io_size (scsi and virtio-blk) expose it to
179      * the guest as a uint16_t in units of logical blocks
180      */
181     if (conf->min_io_size / conf->logical_block_size > UINT16_MAX) {
182         error_setg(errp, "min_io_size must not exceed %u logical blocks",
183                    UINT16_MAX);
184         return false;
185     }
186 
187     if (!QEMU_IS_ALIGNED(conf->opt_io_size, conf->logical_block_size)) {
188         error_setg(errp,
189                    "opt_io_size must be a multiple of logical_block_size");
190         return false;
191     }
192 
193     if (conf->discard_granularity != -1 &&
194         !QEMU_IS_ALIGNED(conf->discard_granularity,
195                          conf->logical_block_size)) {
196         error_setg(errp, "discard_granularity must be "
197                    "a multiple of logical_block_size");
198         return false;
199     }
200 
201     return true;
202 }
203 
blkconf_apply_backend_options(BlockConf * conf,bool readonly,bool resizable,Error ** errp)204 bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
205                                    bool resizable, Error **errp)
206 {
207     BlockBackend *blk = conf->blk;
208     BlockdevOnError rerror, werror;
209     uint64_t perm, shared_perm;
210     bool wce;
211     int ret;
212 
213     perm = BLK_PERM_CONSISTENT_READ;
214     if (!readonly) {
215         perm |= BLK_PERM_WRITE;
216     }
217 
218     shared_perm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
219     if (resizable) {
220         shared_perm |= BLK_PERM_RESIZE;
221     }
222     if (conf->share_rw) {
223         shared_perm |= BLK_PERM_WRITE;
224     }
225 
226     ret = blk_set_perm(blk, perm, shared_perm, errp);
227     if (ret < 0) {
228         return false;
229     }
230 
231     switch (conf->wce) {
232     case ON_OFF_AUTO_ON:    wce = true; break;
233     case ON_OFF_AUTO_OFF:   wce = false; break;
234     case ON_OFF_AUTO_AUTO:  wce = blk_enable_write_cache(blk); break;
235     default:
236         abort();
237     }
238 
239     rerror = conf->rerror;
240     if (rerror == BLOCKDEV_ON_ERROR_AUTO) {
241         rerror = blk_get_on_error(blk, true);
242     }
243 
244     werror = conf->werror;
245     if (werror == BLOCKDEV_ON_ERROR_AUTO) {
246         werror = blk_get_on_error(blk, false);
247     }
248 
249     blk_set_enable_write_cache(blk, wce);
250     blk_set_on_error(blk, rerror, werror);
251 
252     block_acct_setup(blk_get_stats(blk), conf->account_invalid,
253                      conf->account_failed);
254     return true;
255 }
256 
blkconf_geometry(BlockConf * conf,int * ptrans,unsigned cyls_max,unsigned heads_max,unsigned secs_max,Error ** errp)257 bool blkconf_geometry(BlockConf *conf, int *ptrans,
258                       unsigned cyls_max, unsigned heads_max, unsigned secs_max,
259                       Error **errp)
260 {
261     if (!conf->cyls && !conf->heads && !conf->secs) {
262         hd_geometry_guess(conf->blk,
263                           &conf->cyls, &conf->heads, &conf->secs,
264                           ptrans);
265     } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
266         *ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
267     }
268     if (conf->cyls || conf->heads || conf->secs) {
269         if (conf->cyls < 1 || conf->cyls > cyls_max) {
270             error_setg(errp, "cyls must be between 1 and %u", cyls_max);
271             return false;
272         }
273         if (conf->heads < 1 || conf->heads > heads_max) {
274             error_setg(errp, "heads must be between 1 and %u", heads_max);
275             return false;
276         }
277         if (conf->secs < 1 || conf->secs > secs_max) {
278             error_setg(errp, "secs must be between 1 and %u", secs_max);
279             return false;
280         }
281     }
282     return true;
283 }
284