xref: /openbmc/qemu/block/vhdx-log.c (revision 48151859)
1 /*
2  * Block driver for Hyper-V VHDX Images
3  *
4  * Copyright (c) 2013 Red Hat, Inc.,
5  *
6  * Authors:
7  *  Jeff Cody <jcody@redhat.com>
8  *
9  *  This is based on the "VHDX Format Specification v1.00", published 8/25/2012
10  *  by Microsoft:
11  *      https://www.microsoft.com/en-us/download/details.aspx?id=34750
12  *
13  * This file covers the functionality of the metadata log writing, parsing, and
14  * replay.
15  *
16  * This work is licensed under the terms of the GNU LGPL, version 2 or later.
17  * See the COPYING.LIB file in the top-level directory.
18  *
19  */
20 #include "qemu/osdep.h"
21 #include "qapi/error.h"
22 #include "qemu-common.h"
23 #include "block/block_int.h"
24 #include "qemu/error-report.h"
25 #include "qemu/module.h"
26 #include "qemu/bswap.h"
27 #include "block/vhdx.h"
28 
29 
30 typedef struct VHDXLogSequence {
31     bool valid;
32     uint32_t count;
33     VHDXLogEntries log;
34     VHDXLogEntryHeader hdr;
35 } VHDXLogSequence;
36 
37 typedef struct VHDXLogDescEntries {
38     VHDXLogEntryHeader hdr;
39     VHDXLogDescriptor desc[];
40 } VHDXLogDescEntries;
41 
42 static const MSGUID zero_guid = { 0 };
43 
44 /* The log located on the disk is circular buffer containing
45  * sectors of 4096 bytes each.
46  *
47  * It is assumed for the read/write functions below that the
48  * circular buffer scheme uses a 'one sector open' to indicate
49  * the buffer is full.  Given the validation methods used for each
50  * sector, this method should be compatible with other methods that
51  * do not waste a sector.
52  */
53 
54 
55 /* Allow peeking at the hdr entry at the beginning of the current
56  * read index, without advancing the read index */
57 static int vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log,
58                              VHDXLogEntryHeader *hdr)
59 {
60     int ret = 0;
61     uint64_t offset;
62     uint32_t read;
63 
64     assert(hdr != NULL);
65 
66     /* peek is only supported on sector boundaries */
67     if (log->read % VHDX_LOG_SECTOR_SIZE) {
68         ret = -EFAULT;
69         goto exit;
70     }
71 
72     read = log->read;
73     /* we are guaranteed that a) log sectors are 4096 bytes,
74      * and b) the log length is a multiple of 1MB. So, there
75      * is always a round number of sectors in the buffer */
76     if ((read + sizeof(VHDXLogEntryHeader)) > log->length) {
77         read = 0;
78     }
79 
80     if (read == log->write) {
81         ret = -EINVAL;
82         goto exit;
83     }
84 
85     offset = log->offset + read;
86 
87     ret = bdrv_pread(bs->file, offset, hdr, sizeof(VHDXLogEntryHeader));
88     if (ret < 0) {
89         goto exit;
90     }
91     vhdx_log_entry_hdr_le_import(hdr);
92 
93 exit:
94     return ret;
95 }
96 
97 /* Index increment for log, based on sector boundaries */
98 static int vhdx_log_inc_idx(uint32_t idx, uint64_t length)
99 {
100     idx += VHDX_LOG_SECTOR_SIZE;
101     /* we are guaranteed that a) log sectors are 4096 bytes,
102      * and b) the log length is a multiple of 1MB. So, there
103      * is always a round number of sectors in the buffer */
104     return idx >= length ? 0 : idx;
105 }
106 
107 
108 /* Reset the log to empty */
109 static void vhdx_log_reset(BlockDriverState *bs, BDRVVHDXState *s)
110 {
111     MSGUID guid = { 0 };
112     s->log.read = s->log.write = 0;
113     /* a log guid of 0 indicates an empty log to any parser of v0
114      * VHDX logs */
115     vhdx_update_headers(bs, s, false, &guid);
116 }
117 
118 /* Reads num_sectors from the log (all log sectors are 4096 bytes),
119  * into buffer 'buffer'.  Upon return, *sectors_read will contain
120  * the number of sectors successfully read.
121  *
122  * It is assumed that 'buffer' is already allocated, and of sufficient
123  * size (i.e. >= 4096*num_sectors).
124  *
125  * If 'peek' is true, then the tail (read) pointer for the circular buffer is
126  * not modified.
127  *
128  * 0 is returned on success, -errno otherwise.  */
129 static int vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log,
130                                  uint32_t *sectors_read, void *buffer,
131                                  uint32_t num_sectors, bool peek)
132 {
133     int ret = 0;
134     uint64_t offset;
135     uint32_t read;
136 
137     read = log->read;
138 
139     *sectors_read = 0;
140     while (num_sectors) {
141         if (read == log->write) {
142             /* empty */
143             break;
144         }
145         offset = log->offset + read;
146 
147         ret = bdrv_pread(bs->file, offset, buffer, VHDX_LOG_SECTOR_SIZE);
148         if (ret < 0) {
149             goto exit;
150         }
151         read = vhdx_log_inc_idx(read, log->length);
152 
153         *sectors_read = *sectors_read + 1;
154         num_sectors--;
155     }
156 
157 exit:
158     if (!peek) {
159         log->read = read;
160     }
161     return ret;
162 }
163 
164 /* Writes num_sectors to the log (all log sectors are 4096 bytes),
165  * from buffer 'buffer'.  Upon return, *sectors_written will contain
166  * the number of sectors successfully written.
167  *
168  * It is assumed that 'buffer' is at least 4096*num_sectors large.
169  *
170  * 0 is returned on success, -errno otherwise */
171 static int vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log,
172                                   uint32_t *sectors_written, void *buffer,
173                                   uint32_t num_sectors)
174 {
175     int ret = 0;
176     uint64_t offset;
177     uint32_t write;
178     void *buffer_tmp;
179     BDRVVHDXState *s = bs->opaque;
180 
181     ret = vhdx_user_visible_write(bs, s);
182     if (ret < 0) {
183         goto exit;
184     }
185 
186     write = log->write;
187 
188     buffer_tmp = buffer;
189     while (num_sectors) {
190 
191         offset = log->offset + write;
192         write = vhdx_log_inc_idx(write, log->length);
193         if (write == log->read) {
194             /* full */
195             break;
196         }
197         ret = bdrv_pwrite(bs->file, offset, buffer_tmp,
198                           VHDX_LOG_SECTOR_SIZE);
199         if (ret < 0) {
200             goto exit;
201         }
202         buffer_tmp += VHDX_LOG_SECTOR_SIZE;
203 
204         log->write = write;
205         *sectors_written = *sectors_written + 1;
206         num_sectors--;
207     }
208 
209 exit:
210     return ret;
211 }
212 
213 
214 /* Validates a log entry header */
215 static bool vhdx_log_hdr_is_valid(VHDXLogEntries *log, VHDXLogEntryHeader *hdr,
216                                   BDRVVHDXState *s)
217 {
218     int valid = false;
219 
220     if (hdr->signature != VHDX_LOG_SIGNATURE) {
221         goto exit;
222     }
223 
224     /* if the individual entry length is larger than the whole log
225      * buffer, that is obviously invalid */
226     if (log->length < hdr->entry_length) {
227         goto exit;
228     }
229 
230     /* length of entire entry must be in units of 4KB (log sector size) */
231     if (hdr->entry_length % (VHDX_LOG_SECTOR_SIZE)) {
232         goto exit;
233     }
234 
235     /* per spec, sequence # must be > 0 */
236     if (hdr->sequence_number == 0) {
237         goto exit;
238     }
239 
240     /* log entries are only valid if they match the file-wide log guid
241      * found in the active header */
242     if (!guid_eq(hdr->log_guid, s->headers[s->curr_header]->log_guid)) {
243         goto exit;
244     }
245 
246     if (hdr->descriptor_count * sizeof(VHDXLogDescriptor) > hdr->entry_length) {
247         goto exit;
248     }
249 
250     valid = true;
251 
252 exit:
253     return valid;
254 }
255 
256 /*
257  * Given a log header, this will validate that the descriptors and the
258  * corresponding data sectors (if applicable)
259  *
260  * Validation consists of:
261  *      1. Making sure the sequence numbers matches the entry header
262  *      2. Verifying a valid signature ('zero' or 'desc' for descriptors)
263  *      3. File offset field is a multiple of 4KB
264  *      4. If a data descriptor, the corresponding data sector
265  *         has its signature ('data') and matching sequence number
266  *
267  * @desc: the data buffer containing the descriptor
268  * @hdr:  the log entry header
269  *
270  * Returns true if valid
271  */
272 static bool vhdx_log_desc_is_valid(VHDXLogDescriptor *desc,
273                                    VHDXLogEntryHeader *hdr)
274 {
275     bool ret = false;
276 
277     if (desc->sequence_number != hdr->sequence_number) {
278         goto exit;
279     }
280     if (desc->file_offset % VHDX_LOG_SECTOR_SIZE) {
281         goto exit;
282     }
283 
284     if (desc->signature == VHDX_LOG_ZERO_SIGNATURE) {
285         if (desc->zero_length % VHDX_LOG_SECTOR_SIZE == 0) {
286             /* valid */
287             ret = true;
288         }
289     } else if (desc->signature == VHDX_LOG_DESC_SIGNATURE) {
290             /* valid */
291             ret = true;
292     }
293 
294 exit:
295     return ret;
296 }
297 
298 
299 /* Prior to sector data for a log entry, there is the header
300  * and the descriptors referenced in the header:
301  *
302  * [] = 4KB sector
303  *
304  * [ hdr, desc ][   desc   ][ ... ][ data ][ ... ]
305  *
306  * The first sector in a log entry has a 64 byte header, and
307  * up to 126 32-byte descriptors.  If more descriptors than
308  * 126 are required, then subsequent sectors can have up to 128
309  * descriptors.  Each sector is 4KB.  Data follows the descriptor
310  * sectors.
311  *
312  * This will return the number of sectors needed to encompass
313  * the passed number of descriptors in desc_cnt.
314  *
315  * This will never return 0, even if desc_cnt is 0.
316  */
317 static int vhdx_compute_desc_sectors(uint32_t desc_cnt)
318 {
319     uint32_t desc_sectors;
320 
321     desc_cnt += 2; /* account for header in first sector */
322     desc_sectors = desc_cnt / 128;
323     if (desc_cnt % 128) {
324         desc_sectors++;
325     }
326 
327     return desc_sectors;
328 }
329 
330 
331 /* Reads the log header, and subsequent descriptors (if any).  This
332  * will allocate all the space for buffer, which must be NULL when
333  * passed into this function. Each descriptor will also be validated,
334  * and error returned if any are invalid. */
335 static int vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s,
336                               VHDXLogEntries *log, VHDXLogDescEntries **buffer,
337                               bool convert_endian)
338 {
339     int ret = 0;
340     uint32_t desc_sectors;
341     uint32_t sectors_read;
342     VHDXLogEntryHeader hdr;
343     VHDXLogDescEntries *desc_entries = NULL;
344     VHDXLogDescriptor desc;
345     int i;
346 
347     assert(*buffer == NULL);
348 
349     ret = vhdx_log_peek_hdr(bs, log, &hdr);
350     if (ret < 0) {
351         goto exit;
352     }
353 
354     if (vhdx_log_hdr_is_valid(log, &hdr, s) == false) {
355         ret = -EINVAL;
356         goto exit;
357     }
358 
359     desc_sectors = vhdx_compute_desc_sectors(hdr.descriptor_count);
360     desc_entries = qemu_try_blockalign(bs->file->bs,
361                                        desc_sectors * VHDX_LOG_SECTOR_SIZE);
362     if (desc_entries == NULL) {
363         ret = -ENOMEM;
364         goto exit;
365     }
366 
367     ret = vhdx_log_read_sectors(bs, log, &sectors_read, desc_entries,
368                                 desc_sectors, false);
369     if (ret < 0) {
370         goto free_and_exit;
371     }
372     if (sectors_read != desc_sectors) {
373         ret = -EINVAL;
374         goto free_and_exit;
375     }
376 
377     /* put in proper endianness, and validate each desc */
378     for (i = 0; i < hdr.descriptor_count; i++) {
379         desc = desc_entries->desc[i];
380         vhdx_log_desc_le_import(&desc);
381         if (convert_endian) {
382             desc_entries->desc[i] = desc;
383         }
384         if (vhdx_log_desc_is_valid(&desc, &hdr) == false) {
385             ret = -EINVAL;
386             goto free_and_exit;
387         }
388     }
389     if (convert_endian) {
390         desc_entries->hdr = hdr;
391     }
392 
393     *buffer = desc_entries;
394     goto exit;
395 
396 free_and_exit:
397     qemu_vfree(desc_entries);
398 exit:
399     return ret;
400 }
401 
402 
403 /* Flushes the descriptor described by desc to the VHDX image file.
404  * If the descriptor is a data descriptor, than 'data' must be non-NULL,
405  * and >= 4096 bytes (VHDX_LOG_SECTOR_SIZE), containing the data to be
406  * written.
407  *
408  * Verification is performed to make sure the sequence numbers of a data
409  * descriptor match the sequence number in the desc.
410  *
411  * For a zero descriptor, it may describe multiple sectors to fill with zeroes.
412  * In this case, it should be noted that zeroes are written to disk, and the
413  * image file is not extended as a sparse file.  */
414 static int vhdx_log_flush_desc(BlockDriverState *bs, VHDXLogDescriptor *desc,
415                                VHDXLogDataSector *data)
416 {
417     int ret = 0;
418     uint64_t seq, file_offset;
419     uint32_t offset = 0;
420     void *buffer = NULL;
421     uint64_t count = 1;
422     int i;
423 
424     buffer = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);
425 
426     if (desc->signature == VHDX_LOG_DESC_SIGNATURE) {
427         /* data sector */
428         if (data == NULL) {
429             ret = -EFAULT;
430             goto exit;
431         }
432 
433         /* The sequence number of the data sector must match that
434          * in the descriptor */
435         seq = data->sequence_high;
436         seq <<= 32;
437         seq |= data->sequence_low & 0xffffffff;
438 
439         if (seq != desc->sequence_number) {
440             ret = -EINVAL;
441             goto exit;
442         }
443 
444         /* Each data sector is in total 4096 bytes, however the first
445          * 8 bytes, and last 4 bytes, are located in the descriptor */
446         memcpy(buffer, &desc->leading_bytes, 8);
447         offset += 8;
448 
449         memcpy(buffer+offset, data->data, 4084);
450         offset += 4084;
451 
452         memcpy(buffer+offset, &desc->trailing_bytes, 4);
453 
454     } else if (desc->signature == VHDX_LOG_ZERO_SIGNATURE) {
455         /* write 'count' sectors of sector */
456         memset(buffer, 0, VHDX_LOG_SECTOR_SIZE);
457         count = desc->zero_length / VHDX_LOG_SECTOR_SIZE;
458     } else {
459         error_report("Invalid VHDX log descriptor entry signature 0x%" PRIx32,
460                       desc->signature);
461         ret = -EINVAL;
462         goto exit;
463     }
464 
465     file_offset = desc->file_offset;
466 
467     /* count is only > 1 if we are writing zeroes */
468     for (i = 0; i < count; i++) {
469         ret = bdrv_pwrite_sync(bs->file, file_offset, buffer,
470                                VHDX_LOG_SECTOR_SIZE);
471         if (ret < 0) {
472             goto exit;
473         }
474         file_offset += VHDX_LOG_SECTOR_SIZE;
475     }
476 
477 exit:
478     qemu_vfree(buffer);
479     return ret;
480 }
481 
482 /* Flush the entire log (as described by 'logs') to the VHDX image
483  * file, and then set the log to 'empty' status once complete.
484  *
485  * The log entries should be validate prior to flushing */
486 static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
487                           VHDXLogSequence *logs)
488 {
489     int ret = 0;
490     int i;
491     uint32_t cnt, sectors_read;
492     uint64_t new_file_size;
493     void *data = NULL;
494     VHDXLogDescEntries *desc_entries = NULL;
495     VHDXLogEntryHeader hdr_tmp = { 0 };
496 
497     cnt = logs->count;
498 
499     data = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);
500 
501     ret = vhdx_user_visible_write(bs, s);
502     if (ret < 0) {
503         goto exit;
504     }
505 
506     /* each iteration represents one log sequence, which may span multiple
507      * sectors */
508     while (cnt--) {
509         ret = vhdx_log_peek_hdr(bs, &logs->log, &hdr_tmp);
510         if (ret < 0) {
511             goto exit;
512         }
513         /* if the log shows a FlushedFileOffset larger than our current file
514          * size, then that means the file has been truncated / corrupted, and
515          * we must refused to open it / use it */
516         if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file->bs)) {
517             ret = -EINVAL;
518             goto exit;
519         }
520 
521         ret = vhdx_log_read_desc(bs, s, &logs->log, &desc_entries, true);
522         if (ret < 0) {
523             goto exit;
524         }
525 
526         for (i = 0; i < desc_entries->hdr.descriptor_count; i++) {
527             if (desc_entries->desc[i].signature == VHDX_LOG_DESC_SIGNATURE) {
528                 /* data sector, so read a sector to flush */
529                 ret = vhdx_log_read_sectors(bs, &logs->log, &sectors_read,
530                                             data, 1, false);
531                 if (ret < 0) {
532                     goto exit;
533                 }
534                 if (sectors_read != 1) {
535                     ret = -EINVAL;
536                     goto exit;
537                 }
538                 vhdx_log_data_le_import(data);
539             }
540 
541             ret = vhdx_log_flush_desc(bs, &desc_entries->desc[i], data);
542             if (ret < 0) {
543                 goto exit;
544             }
545         }
546         if (bdrv_getlength(bs->file->bs) < desc_entries->hdr.last_file_offset) {
547             new_file_size = desc_entries->hdr.last_file_offset;
548             if (new_file_size % (1024*1024)) {
549                 /* round up to nearest 1MB boundary */
550                 new_file_size = ((new_file_size >> 20) + 1) << 20;
551                 bdrv_truncate(bs->file->bs, new_file_size);
552             }
553         }
554         qemu_vfree(desc_entries);
555         desc_entries = NULL;
556     }
557 
558     bdrv_flush(bs);
559     /* once the log is fully flushed, indicate that we have an empty log
560      * now.  This also sets the log guid to 0, to indicate an empty log */
561     vhdx_log_reset(bs, s);
562 
563 exit:
564     qemu_vfree(data);
565     qemu_vfree(desc_entries);
566     return ret;
567 }
568 
569 static int vhdx_validate_log_entry(BlockDriverState *bs, BDRVVHDXState *s,
570                                    VHDXLogEntries *log, uint64_t seq,
571                                    bool *valid, VHDXLogEntryHeader *entry)
572 {
573     int ret = 0;
574     VHDXLogEntryHeader hdr;
575     void *buffer = NULL;
576     uint32_t i, desc_sectors, total_sectors, crc;
577     uint32_t sectors_read = 0;
578     VHDXLogDescEntries *desc_buffer = NULL;
579 
580     *valid = false;
581 
582     ret = vhdx_log_peek_hdr(bs, log, &hdr);
583     if (ret < 0) {
584         goto inc_and_exit;
585     }
586 
587     if (vhdx_log_hdr_is_valid(log, &hdr, s) == false) {
588         goto inc_and_exit;
589     }
590 
591     if (seq > 0) {
592         if (hdr.sequence_number != seq + 1) {
593             goto inc_and_exit;
594         }
595     }
596 
597     desc_sectors = vhdx_compute_desc_sectors(hdr.descriptor_count);
598 
599     /* Read all log sectors, and calculate log checksum */
600 
601     total_sectors = hdr.entry_length / VHDX_LOG_SECTOR_SIZE;
602 
603 
604     /* read_desc() will increment the read idx */
605     ret = vhdx_log_read_desc(bs, s, log, &desc_buffer, false);
606     if (ret < 0) {
607         goto free_and_exit;
608     }
609 
610     crc = vhdx_checksum_calc(0xffffffff, (void *)desc_buffer,
611                             desc_sectors * VHDX_LOG_SECTOR_SIZE, 4);
612     crc ^= 0xffffffff;
613 
614     buffer = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);
615     if (total_sectors > desc_sectors) {
616         for (i = 0; i < total_sectors - desc_sectors; i++) {
617             sectors_read = 0;
618             ret = vhdx_log_read_sectors(bs, log, &sectors_read, buffer,
619                                         1, false);
620             if (ret < 0 || sectors_read != 1) {
621                 goto free_and_exit;
622             }
623             crc = vhdx_checksum_calc(crc, buffer, VHDX_LOG_SECTOR_SIZE, -1);
624             crc ^= 0xffffffff;
625         }
626     }
627     crc ^= 0xffffffff;
628     if (crc != hdr.checksum) {
629         goto free_and_exit;
630     }
631 
632     *valid = true;
633     *entry = hdr;
634     goto free_and_exit;
635 
636 inc_and_exit:
637     log->read = vhdx_log_inc_idx(log->read, log->length);
638 
639 free_and_exit:
640     qemu_vfree(buffer);
641     qemu_vfree(desc_buffer);
642     return ret;
643 }
644 
645 /* Search through the log circular buffer, and find the valid, active
646  * log sequence, if any exists
647  * */
648 static int vhdx_log_search(BlockDriverState *bs, BDRVVHDXState *s,
649                            VHDXLogSequence *logs)
650 {
651     int ret = 0;
652     uint32_t tail;
653     bool seq_valid = false;
654     VHDXLogSequence candidate = { 0 };
655     VHDXLogEntryHeader hdr = { 0 };
656     VHDXLogEntries curr_log;
657 
658     memcpy(&curr_log, &s->log, sizeof(VHDXLogEntries));
659     curr_log.write = curr_log.length;   /* assume log is full */
660     curr_log.read = 0;
661 
662 
663     /* now we will go through the whole log sector by sector, until
664      * we find a valid, active log sequence, or reach the end of the
665      * log buffer */
666     for (;;) {
667         uint64_t curr_seq = 0;
668         VHDXLogSequence current = { 0 };
669 
670         tail = curr_log.read;
671 
672         ret = vhdx_validate_log_entry(bs, s, &curr_log, curr_seq,
673                                       &seq_valid, &hdr);
674         if (ret < 0) {
675             goto exit;
676         }
677 
678         if (seq_valid) {
679             current.valid     = true;
680             current.log       = curr_log;
681             current.log.read  = tail;
682             current.log.write = curr_log.read;
683             current.count     = 1;
684             current.hdr       = hdr;
685 
686 
687             for (;;) {
688                 ret = vhdx_validate_log_entry(bs, s, &curr_log, curr_seq,
689                                               &seq_valid, &hdr);
690                 if (ret < 0) {
691                     goto exit;
692                 }
693                 if (seq_valid == false) {
694                     break;
695                 }
696                 current.log.write = curr_log.read;
697                 current.count++;
698 
699                 curr_seq = hdr.sequence_number;
700             }
701         }
702 
703         if (current.valid) {
704             if (candidate.valid == false ||
705                 current.hdr.sequence_number > candidate.hdr.sequence_number) {
706                 candidate = current;
707             }
708         }
709 
710         if (curr_log.read < tail) {
711             break;
712         }
713     }
714 
715     *logs = candidate;
716 
717     if (candidate.valid) {
718         /* this is the next sequence number, for writes */
719         s->log.sequence = candidate.hdr.sequence_number + 1;
720     }
721 
722 
723 exit:
724     return ret;
725 }
726 
727 /* Parse the replay log.  Per the VHDX spec, if the log is present
728  * it must be replayed prior to opening the file, even read-only.
729  *
730  * If read-only, we must replay the log in RAM (or refuse to open
731  * a dirty VHDX file read-only) */
732 int vhdx_parse_log(BlockDriverState *bs, BDRVVHDXState *s, bool *flushed,
733                    Error **errp)
734 {
735     int ret = 0;
736     VHDXHeader *hdr;
737     VHDXLogSequence logs = { 0 };
738 
739     hdr = s->headers[s->curr_header];
740 
741     *flushed = false;
742 
743     /* s->log.hdr is freed in vhdx_close() */
744     if (s->log.hdr == NULL) {
745         s->log.hdr = qemu_blockalign(bs, sizeof(VHDXLogEntryHeader));
746     }
747 
748     s->log.offset = hdr->log_offset;
749     s->log.length = hdr->log_length;
750 
751     if (s->log.offset < VHDX_LOG_MIN_SIZE ||
752         s->log.offset % VHDX_LOG_MIN_SIZE) {
753         ret = -EINVAL;
754         goto exit;
755     }
756 
757     /* per spec, only log version of 0 is supported */
758     if (hdr->log_version != 0) {
759         ret = -EINVAL;
760         goto exit;
761     }
762 
763     /* If either the log guid, or log length is zero,
764      * then a replay log is not present */
765     if (guid_eq(hdr->log_guid, zero_guid)) {
766         goto exit;
767     }
768 
769     if (hdr->log_length == 0) {
770         goto exit;
771     }
772 
773     if (hdr->log_length % VHDX_LOG_MIN_SIZE) {
774         ret = -EINVAL;
775         goto exit;
776     }
777 
778 
779     /* The log is present, we need to find if and where there is an active
780      * sequence of valid entries present in the log.  */
781 
782     ret = vhdx_log_search(bs, s, &logs);
783     if (ret < 0) {
784         goto exit;
785     }
786 
787     if (logs.valid) {
788         if (bs->read_only) {
789             ret = -EPERM;
790             error_setg(errp,
791                        "VHDX image file '%s' opened read-only, but "
792                        "contains a log that needs to be replayed",
793                        bs->filename);
794             error_append_hint(errp,  "To replay the log, run:\n"
795                               "qemu-img check -r all '%s'\n",
796                               bs->filename);
797             goto exit;
798         }
799         /* now flush the log */
800         ret = vhdx_log_flush(bs, s, &logs);
801         if (ret < 0) {
802             goto exit;
803         }
804         *flushed = true;
805     }
806 
807 
808 exit:
809     return ret;
810 }
811 
812 
813 
814 static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
815                                       VHDXLogDataSector *sector, void *data,
816                                       uint64_t seq)
817 {
818     /* 8 + 4084 + 4 = 4096, 1 log sector */
819     memcpy(&desc->leading_bytes, data, 8);
820     data += 8;
821     cpu_to_le64s(&desc->leading_bytes);
822     memcpy(sector->data, data, 4084);
823     data += 4084;
824     memcpy(&desc->trailing_bytes, data, 4);
825     cpu_to_le32s(&desc->trailing_bytes);
826     data += 4;
827 
828     sector->sequence_high  = (uint32_t) (seq >> 32);
829     sector->sequence_low   = (uint32_t) (seq & 0xffffffff);
830     sector->data_signature = VHDX_LOG_DATA_SIGNATURE;
831 
832     vhdx_log_desc_le_export(desc);
833     vhdx_log_data_le_export(sector);
834 }
835 
836 
837 static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
838                           void *data, uint32_t length, uint64_t offset)
839 {
840     int ret = 0;
841     void *buffer = NULL;
842     void *merged_sector = NULL;
843     void *data_tmp, *sector_write;
844     unsigned int i;
845     int sector_offset;
846     uint32_t desc_sectors, sectors, total_length;
847     uint32_t sectors_written = 0;
848     uint32_t aligned_length;
849     uint32_t leading_length = 0;
850     uint32_t trailing_length = 0;
851     uint32_t partial_sectors = 0;
852     uint32_t bytes_written = 0;
853     uint64_t file_offset;
854     VHDXHeader *header;
855     VHDXLogEntryHeader new_hdr;
856     VHDXLogDescriptor *new_desc = NULL;
857     VHDXLogDataSector *data_sector = NULL;
858     MSGUID new_guid = { 0 };
859 
860     header = s->headers[s->curr_header];
861 
862     /* need to have offset read data, and be on 4096 byte boundary */
863 
864     if (length > header->log_length) {
865         /* no log present.  we could create a log here instead of failing */
866         ret = -EINVAL;
867         goto exit;
868     }
869 
870     if (guid_eq(header->log_guid, zero_guid)) {
871         vhdx_guid_generate(&new_guid);
872         vhdx_update_headers(bs, s, false, &new_guid);
873     } else {
874         /* currently, we require that the log be flushed after
875          * every write. */
876         ret = -ENOTSUP;
877         goto exit;
878     }
879 
880     /* 0 is an invalid sequence number, but may also represent the first
881      * log write (or a wrapped seq) */
882     if (s->log.sequence == 0) {
883         s->log.sequence = 1;
884     }
885 
886     sector_offset = offset % VHDX_LOG_SECTOR_SIZE;
887     file_offset = (offset / VHDX_LOG_SECTOR_SIZE) * VHDX_LOG_SECTOR_SIZE;
888 
889     aligned_length = length;
890 
891     /* add in the unaligned head and tail bytes */
892     if (sector_offset) {
893         leading_length = (VHDX_LOG_SECTOR_SIZE - sector_offset);
894         leading_length = leading_length > length ? length : leading_length;
895         aligned_length -= leading_length;
896         partial_sectors++;
897     }
898 
899     sectors = aligned_length / VHDX_LOG_SECTOR_SIZE;
900     trailing_length = aligned_length - (sectors * VHDX_LOG_SECTOR_SIZE);
901     if (trailing_length) {
902         partial_sectors++;
903     }
904 
905     sectors += partial_sectors;
906 
907     /* sectors is now how many sectors the data itself takes, not
908      * including the header and descriptor metadata */
909 
910     new_hdr = (VHDXLogEntryHeader) {
911                 .signature           = VHDX_LOG_SIGNATURE,
912                 .tail                = s->log.tail,
913                 .sequence_number     = s->log.sequence,
914                 .descriptor_count    = sectors,
915                 .reserved            = 0,
916                 .flushed_file_offset = bdrv_getlength(bs->file->bs),
917                 .last_file_offset    = bdrv_getlength(bs->file->bs),
918               };
919 
920     new_hdr.log_guid = header->log_guid;
921 
922     desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count);
923 
924     total_length = (desc_sectors + sectors) * VHDX_LOG_SECTOR_SIZE;
925     new_hdr.entry_length = total_length;
926 
927     vhdx_log_entry_hdr_le_export(&new_hdr);
928 
929     buffer = qemu_blockalign(bs, total_length);
930     memcpy(buffer, &new_hdr, sizeof(new_hdr));
931 
932     new_desc = buffer + sizeof(new_hdr);
933     data_sector = buffer + (desc_sectors * VHDX_LOG_SECTOR_SIZE);
934     data_tmp = data;
935 
936     /* All log sectors are 4KB, so for any partial sectors we must
937      * merge the data with preexisting data from the final file
938      * destination */
939     merged_sector = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);
940 
941     for (i = 0; i < sectors; i++) {
942         new_desc->signature       = VHDX_LOG_DESC_SIGNATURE;
943         new_desc->sequence_number = s->log.sequence;
944         new_desc->file_offset     = file_offset;
945 
946         if (i == 0 && leading_length) {
947             /* partial sector at the front of the buffer */
948             ret = bdrv_pread(bs->file, file_offset, merged_sector,
949                              VHDX_LOG_SECTOR_SIZE);
950             if (ret < 0) {
951                 goto exit;
952             }
953             memcpy(merged_sector + sector_offset, data_tmp, leading_length);
954             bytes_written = leading_length;
955             sector_write = merged_sector;
956         } else if (i == sectors - 1 && trailing_length) {
957             /* partial sector at the end of the buffer */
958             ret = bdrv_pread(bs->file,
959                             file_offset,
960                             merged_sector + trailing_length,
961                             VHDX_LOG_SECTOR_SIZE - trailing_length);
962             if (ret < 0) {
963                 goto exit;
964             }
965             memcpy(merged_sector, data_tmp, trailing_length);
966             bytes_written = trailing_length;
967             sector_write = merged_sector;
968         } else {
969             bytes_written = VHDX_LOG_SECTOR_SIZE;
970             sector_write = data_tmp;
971         }
972 
973         /* populate the raw sector data into the proper structures,
974          * as well as update the descriptor, and convert to proper
975          * endianness */
976         vhdx_log_raw_to_le_sector(new_desc, data_sector, sector_write,
977                                   s->log.sequence);
978 
979         data_tmp += bytes_written;
980         data_sector++;
981         new_desc++;
982         file_offset += VHDX_LOG_SECTOR_SIZE;
983     }
984 
985     /* checksum covers entire entry, from the log header through the
986      * last data sector */
987     vhdx_update_checksum(buffer, total_length,
988                          offsetof(VHDXLogEntryHeader, checksum));
989 
990     /* now write to the log */
991     ret = vhdx_log_write_sectors(bs, &s->log, &sectors_written, buffer,
992                                  desc_sectors + sectors);
993     if (ret < 0) {
994         goto exit;
995     }
996 
997     if (sectors_written != desc_sectors + sectors) {
998         /* instead of failing, we could flush the log here */
999         ret = -EINVAL;
1000         goto exit;
1001     }
1002 
1003     s->log.sequence++;
1004     /* write new tail */
1005     s->log.tail = s->log.write;
1006 
1007 exit:
1008     qemu_vfree(buffer);
1009     qemu_vfree(merged_sector);
1010     return ret;
1011 }
1012 
1013 /* Perform a log write, and then immediately flush the entire log */
1014 int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
1015                              void *data, uint32_t length, uint64_t offset)
1016 {
1017     int ret = 0;
1018     VHDXLogSequence logs = { .valid = true,
1019                              .count = 1,
1020                              .hdr = { 0 } };
1021 
1022 
1023     /* Make sure data written (new and/or changed blocks) is stable
1024      * on disk, before creating log entry */
1025     bdrv_flush(bs);
1026     ret = vhdx_log_write(bs, s, data, length, offset);
1027     if (ret < 0) {
1028         goto exit;
1029     }
1030     logs.log = s->log;
1031 
1032     /* Make sure log is stable on disk */
1033     bdrv_flush(bs);
1034     ret = vhdx_log_flush(bs, s, &logs);
1035     if (ret < 0) {
1036         goto exit;
1037     }
1038 
1039     s->log = logs.log;
1040 
1041 exit:
1042     return ret;
1043 }
1044 
1045