1#ifndef BLOCK_H
2#define BLOCK_H
3
4#include "block/aio.h"
5#include "qapi/qapi-types-block-core.h"
6#include "block/aio-wait.h"
7#include "qemu/iov.h"
8#include "qemu/coroutine.h"
9#include "block/accounting.h"
10#include "block/dirty-bitmap.h"
11#include "block/blockjob.h"
12#include "qemu/hbitmap.h"
13
14
15typedef struct BlockDriver BlockDriver;
16typedef struct BdrvChild BdrvChild;
17typedef struct BdrvChildRole BdrvChildRole;
18
19typedef struct BlockDriverInfo {
20
21 int cluster_size;
22
23 int64_t vm_state_offset;
24 bool is_dirty;
25
26
27
28
29 bool unallocated_blocks_are_zero;
30
31
32
33 bool needs_compressed_writes;
34} BlockDriverInfo;
35
36typedef struct BlockFragInfo {
37 uint64_t allocated_clusters;
38 uint64_t total_clusters;
39 uint64_t fragmented_clusters;
40 uint64_t compressed_clusters;
41} BlockFragInfo;
42
43typedef enum {
44 BDRV_REQ_COPY_ON_READ = 0x1,
45 BDRV_REQ_ZERO_WRITE = 0x2,
46
47
48
49
50
51
52
53 BDRV_REQ_MAY_UNMAP = 0x4,
54
55
56
57
58
59
60
61
62
63
64
65
66 BDRV_REQ_NO_SERIALISING = 0x8,
67 BDRV_REQ_FUA = 0x10,
68 BDRV_REQ_WRITE_COMPRESSED = 0x20,
69
70
71
72 BDRV_REQ_WRITE_UNCHANGED = 0x40,
73
74
75
76
77
78
79
80
81
82
83
84 BDRV_REQ_SERIALISING = 0x80,
85
86
87 BDRV_REQ_MASK = 0xff,
88} BdrvRequestFlags;
89
90typedef struct BlockSizes {
91 uint32_t phys;
92 uint32_t log;
93} BlockSizes;
94
95typedef struct HDGeometry {
96 uint32_t heads;
97 uint32_t sectors;
98 uint32_t cylinders;
99} HDGeometry;
100
101#define BDRV_O_RDWR 0x0002
102#define BDRV_O_RESIZE 0x0004
103#define BDRV_O_SNAPSHOT 0x0008
104#define BDRV_O_TEMPORARY 0x0010
105#define BDRV_O_NOCACHE 0x0020
106#define BDRV_O_NATIVE_AIO 0x0080
107#define BDRV_O_NO_BACKING 0x0100
108#define BDRV_O_NO_FLUSH 0x0200
109#define BDRV_O_COPY_ON_READ 0x0400
110#define BDRV_O_INACTIVE 0x0800
111#define BDRV_O_CHECK 0x1000
112#define BDRV_O_ALLOW_RDWR 0x2000
113#define BDRV_O_UNMAP 0x4000
114#define BDRV_O_PROTOCOL 0x8000
115
116
117#define BDRV_O_NO_IO 0x10000
118
119#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
120
121
122
123
124#define BDRV_OPT_CACHE_WB "cache.writeback"
125#define BDRV_OPT_CACHE_DIRECT "cache.direct"
126#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
127#define BDRV_OPT_READ_ONLY "read-only"
128#define BDRV_OPT_DISCARD "discard"
129#define BDRV_OPT_FORCE_SHARE "force-share"
130
131
132#define BDRV_SECTOR_BITS 9
133#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
134#define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1)
135
136#define BDRV_REQUEST_MAX_SECTORS MIN(SIZE_MAX >> BDRV_SECTOR_BITS, \
137 INT_MAX >> BDRV_SECTOR_BITS)
138#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174#define BDRV_BLOCK_DATA 0x01
175#define BDRV_BLOCK_ZERO 0x02
176#define BDRV_BLOCK_OFFSET_VALID 0x04
177#define BDRV_BLOCK_RAW 0x08
178#define BDRV_BLOCK_ALLOCATED 0x10
179#define BDRV_BLOCK_EOF 0x20
180#define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK
181
182typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
183
184typedef struct BDRVReopenState {
185 BlockDriverState *bs;
186 int flags;
187 uint64_t perm, shared_perm;
188 QDict *options;
189 QDict *explicit_options;
190 void *opaque;
191} BDRVReopenState;
192
193
194
195
196typedef enum BlockOpType {
197 BLOCK_OP_TYPE_BACKUP_SOURCE,
198 BLOCK_OP_TYPE_BACKUP_TARGET,
199 BLOCK_OP_TYPE_CHANGE,
200 BLOCK_OP_TYPE_COMMIT_SOURCE,
201 BLOCK_OP_TYPE_COMMIT_TARGET,
202 BLOCK_OP_TYPE_DATAPLANE,
203 BLOCK_OP_TYPE_DRIVE_DEL,
204 BLOCK_OP_TYPE_EJECT,
205 BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
206 BLOCK_OP_TYPE_INTERNAL_SNAPSHOT,
207 BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
208 BLOCK_OP_TYPE_MIRROR_SOURCE,
209 BLOCK_OP_TYPE_MIRROR_TARGET,
210 BLOCK_OP_TYPE_RESIZE,
211 BLOCK_OP_TYPE_STREAM,
212 BLOCK_OP_TYPE_REPLACE,
213 BLOCK_OP_TYPE_MAX,
214} BlockOpType;
215
216
217enum {
218
219
220
221
222
223
224
225
226
227
228 BLK_PERM_CONSISTENT_READ = 0x01,
229
230
231 BLK_PERM_WRITE = 0x02,
232
233
234
235
236
237
238
239
240
241 BLK_PERM_WRITE_UNCHANGED = 0x04,
242
243
244 BLK_PERM_RESIZE = 0x08,
245
246
247
248
249
250 BLK_PERM_GRAPH_MOD = 0x10,
251
252 BLK_PERM_ALL = 0x1f,
253
254 DEFAULT_PERM_PASSTHROUGH = BLK_PERM_CONSISTENT_READ
255 | BLK_PERM_WRITE
256 | BLK_PERM_WRITE_UNCHANGED
257 | BLK_PERM_RESIZE,
258
259 DEFAULT_PERM_UNCHANGED = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
260};
261
262char *bdrv_perm_names(uint64_t perm);
263
264
265void bdrv_init(void);
266void bdrv_init_with_whitelist(void);
267bool bdrv_uses_whitelist(void);
268int bdrv_is_whitelisted(BlockDriver *drv, bool read_only);
269BlockDriver *bdrv_find_protocol(const char *filename,
270 bool allow_protocol_prefix,
271 Error **errp);
272BlockDriver *bdrv_find_format(const char *format_name);
273int bdrv_create(BlockDriver *drv, const char* filename,
274 QemuOpts *opts, Error **errp);
275int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
276BlockDriverState *bdrv_new(void);
277void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
278 Error **errp);
279void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
280 Error **errp);
281
282int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough);
283int bdrv_parse_discard_flags(const char *mode, int *flags);
284BdrvChild *bdrv_open_child(const char *filename,
285 QDict *options, const char *bdref_key,
286 BlockDriverState* parent,
287 const BdrvChildRole *child_role,
288 bool allow_none, Error **errp);
289BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
290void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
291 Error **errp);
292int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
293 const char *bdref_key, Error **errp);
294BlockDriverState *bdrv_open(const char *filename, const char *reference,
295 QDict *options, int flags, Error **errp);
296BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
297 int flags, Error **errp);
298BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
299 BlockDriverState *bs,
300 QDict *options, int flags);
301int bdrv_reopen_multiple(AioContext *ctx, BlockReopenQueue *bs_queue, Error **errp);
302int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp);
303int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
304 BlockReopenQueue *queue, Error **errp);
305void bdrv_reopen_commit(BDRVReopenState *reopen_state);
306void bdrv_reopen_abort(BDRVReopenState *reopen_state);
307int bdrv_read(BdrvChild *child, int64_t sector_num,
308 uint8_t *buf, int nb_sectors);
309int bdrv_write(BdrvChild *child, int64_t sector_num,
310 const uint8_t *buf, int nb_sectors);
311int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
312 int bytes, BdrvRequestFlags flags);
313int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags);
314int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int bytes);
315int bdrv_preadv(BdrvChild *child, int64_t offset, QEMUIOVector *qiov);
316int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int bytes);
317int bdrv_pwritev(BdrvChild *child, int64_t offset, QEMUIOVector *qiov);
318int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
319 const void *buf, int count);
320
321
322
323
324
325
326int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
327 int bytes, BdrvRequestFlags flags);
328BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
329 const char *backing_file);
330void bdrv_refresh_filename(BlockDriverState *bs);
331
332int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
333 PreallocMode prealloc, Error **errp);
334int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
335 Error **errp);
336
337int64_t bdrv_nb_sectors(BlockDriverState *bs);
338int64_t bdrv_getlength(BlockDriverState *bs);
339int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
340BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
341 BlockDriverState *in_bs, Error **errp);
342void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
343void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
344int bdrv_commit(BlockDriverState *bs);
345int bdrv_change_backing_file(BlockDriverState *bs,
346 const char *backing_file, const char *backing_fmt);
347void bdrv_register(BlockDriver *bdrv);
348int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
349 const char *backing_file_str);
350BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
351 BlockDriverState *bs);
352BlockDriverState *bdrv_find_base(BlockDriverState *bs);
353
354
355typedef struct BdrvCheckResult {
356 int corruptions;
357 int leaks;
358 int check_errors;
359 int corruptions_fixed;
360 int leaks_fixed;
361 int64_t image_end_offset;
362 BlockFragInfo bfi;
363} BdrvCheckResult;
364
365typedef enum {
366 BDRV_FIX_LEAKS = 1,
367 BDRV_FIX_ERRORS = 2,
368} BdrvCheckMode;
369
370int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
371
372
373
374
375typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
376 int64_t total_work_size, void *opaque);
377int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
378 BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
379 Error **errp);
380
381
382bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
383 BlockDriverState *candidate);
384bool bdrv_is_first_non_filter(BlockDriverState *candidate);
385
386
387BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
388 const char *node_name, Error **errp);
389
390
391void bdrv_aio_cancel(BlockAIOCB *acb);
392void bdrv_aio_cancel_async(BlockAIOCB *acb);
393
394
395int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
396
397
398void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp);
399void bdrv_invalidate_cache_all(Error **errp);
400int bdrv_inactivate_all(void);
401
402
403int bdrv_flush(BlockDriverState *bs);
404int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
405int bdrv_flush_all(void);
406void bdrv_close_all(void);
407void bdrv_drain(BlockDriverState *bs);
408void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
409void bdrv_drain_all_begin(void);
410void bdrv_drain_all_end(void);
411void bdrv_drain_all(void);
412
413
414AioWait *bdrv_get_aio_wait(BlockDriverState *bs);
415
416#define BDRV_POLL_WHILE(bs, cond) ({ \
417 BlockDriverState *bs_ = (bs); \
418 AIO_WAIT_WHILE(bdrv_get_aio_wait(bs_), \
419 bdrv_get_aio_context(bs_), \
420 cond); })
421
422int bdrv_pdiscard(BdrvChild *child, int64_t offset, int bytes);
423int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes);
424int bdrv_has_zero_init_1(BlockDriverState *bs);
425int bdrv_has_zero_init(BlockDriverState *bs);
426bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
427bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
428int bdrv_block_status(BlockDriverState *bs, int64_t offset,
429 int64_t bytes, int64_t *pnum, int64_t *map,
430 BlockDriverState **file);
431int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
432 int64_t offset, int64_t bytes, int64_t *pnum,
433 int64_t *map, BlockDriverState **file);
434int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
435 int64_t *pnum);
436int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
437 int64_t offset, int64_t bytes, int64_t *pnum);
438
439bool bdrv_is_read_only(BlockDriverState *bs);
440int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
441 bool ignore_allow_rdw, Error **errp);
442int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
443bool bdrv_is_writable(BlockDriverState *bs);
444bool bdrv_is_sg(BlockDriverState *bs);
445bool bdrv_is_inserted(BlockDriverState *bs);
446void bdrv_lock_medium(BlockDriverState *bs, bool locked);
447void bdrv_eject(BlockDriverState *bs, bool eject_flag);
448const char *bdrv_get_format_name(BlockDriverState *bs);
449BlockDriverState *bdrv_find_node(const char *node_name);
450BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp);
451BlockDriverState *bdrv_lookup_bs(const char *device,
452 const char *node_name,
453 Error **errp);
454bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
455BlockDriverState *bdrv_next_node(BlockDriverState *bs);
456BlockDriverState *bdrv_next_all_states(BlockDriverState *bs);
457
458typedef struct BdrvNextIterator {
459 enum {
460 BDRV_NEXT_BACKEND_ROOTS,
461 BDRV_NEXT_MONITOR_OWNED,
462 } phase;
463 BlockBackend *blk;
464 BlockDriverState *bs;
465} BdrvNextIterator;
466
467BlockDriverState *bdrv_first(BdrvNextIterator *it);
468BlockDriverState *bdrv_next(BdrvNextIterator *it);
469void bdrv_next_cleanup(BdrvNextIterator *it);
470
471BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
472bool bdrv_is_encrypted(BlockDriverState *bs);
473void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
474 void *opaque);
475const char *bdrv_get_node_name(const BlockDriverState *bs);
476const char *bdrv_get_device_name(const BlockDriverState *bs);
477const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
478int bdrv_get_flags(BlockDriverState *bs);
479int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
480ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs);
481void bdrv_round_to_clusters(BlockDriverState *bs,
482 int64_t offset, int64_t bytes,
483 int64_t *cluster_offset,
484 int64_t *cluster_bytes);
485
486const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
487void bdrv_get_backing_filename(BlockDriverState *bs,
488 char *filename, int filename_size);
489void bdrv_get_full_backing_filename(BlockDriverState *bs,
490 char *dest, size_t sz, Error **errp);
491void bdrv_get_full_backing_filename_from_filename(const char *backed,
492 const char *backing,
493 char *dest, size_t sz,
494 Error **errp);
495
496int path_has_protocol(const char *path);
497int path_is_absolute(const char *path);
498void path_combine(char *dest, int dest_size,
499 const char *base_path,
500 const char *filename);
501
502int bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
503int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
504int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
505 int64_t pos, int size);
506
507int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
508 int64_t pos, int size);
509
510void bdrv_img_create(const char *filename, const char *fmt,
511 const char *base_filename, const char *base_fmt,
512 char *options, uint64_t img_size, int flags,
513 bool quiet, Error **errp);
514
515
516
517size_t bdrv_min_mem_align(BlockDriverState *bs);
518
519size_t bdrv_opt_mem_align(BlockDriverState *bs);
520void *qemu_blockalign(BlockDriverState *bs, size_t size);
521void *qemu_blockalign0(BlockDriverState *bs, size_t size);
522void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
523void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
524bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
525
526void bdrv_enable_copy_on_read(BlockDriverState *bs);
527void bdrv_disable_copy_on_read(BlockDriverState *bs);
528
529void bdrv_ref(BlockDriverState *bs);
530void bdrv_unref(BlockDriverState *bs);
531void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
532BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
533 BlockDriverState *child_bs,
534 const char *child_name,
535 const BdrvChildRole *child_role,
536 Error **errp);
537
538bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
539void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason);
540void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason);
541void bdrv_op_block_all(BlockDriverState *bs, Error *reason);
542void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
543bool bdrv_op_blocker_is_empty(BlockDriverState *bs);
544
545#define BLKDBG_EVENT(child, evt) \
546 do { \
547 if (child) { \
548 bdrv_debug_event(child->bs, evt); \
549 } \
550 } while (0)
551
552void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event);
553
554int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
555 const char *tag);
556int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
557int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
558bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
559
560
561
562
563
564
565AioContext *bdrv_get_aio_context(BlockDriverState *bs);
566
567
568
569
570void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
571
572
573
574
575
576
577
578
579
580void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
581int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
582int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
583
584void bdrv_io_plug(BlockDriverState *bs);
585void bdrv_io_unplug(BlockDriverState *bs);
586
587
588
589
590
591
592
593void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore,
594 bool ignore_bds_parents);
595
596
597
598
599
600
601
602void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll);
603
604
605
606
607
608
609
610void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore,
611 bool ignore_bds_parents);
612
613
614
615
616
617
618
619
620
621
622
623
624
625bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
626 BdrvChild *ignore_parent, bool ignore_bds_parents);
627
628
629
630
631
632
633
634
635
636
637
638void bdrv_drained_begin(BlockDriverState *bs);
639
640
641
642
643
644
645
646void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
647 BdrvChild *parent, bool ignore_bds_parents);
648
649
650
651
652
653void bdrv_subtree_drained_begin(BlockDriverState *bs);
654
655
656
657
658
659
660void bdrv_drained_end(BlockDriverState *bs);
661
662
663
664
665void bdrv_subtree_drained_end(BlockDriverState *bs);
666
667void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
668 Error **errp);
669void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
670
671bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
672 uint32_t granularity, Error **errp);
673
674
675
676
677
678
679
680
681void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size);
682void bdrv_unregister_buf(BlockDriverState *bs, void *host);
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713int coroutine_fn bdrv_co_copy_range(BdrvChild *src, uint64_t src_offset,
714 BdrvChild *dst, uint64_t dst_offset,
715 uint64_t bytes, BdrvRequestFlags read_flags,
716 BdrvRequestFlags write_flags);
717#endif
718