Lines Matching full:log

13  * This file covers the functionality of the metadata log writing, parsing, and
34 VHDXLogEntries log; member
45 /* The log located on the disk is circular buffer containing
59 vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log, in vhdx_log_peek_hdr() argument
69 if (log->read % VHDX_LOG_SECTOR_SIZE) { in vhdx_log_peek_hdr()
74 read = log->read; in vhdx_log_peek_hdr()
75 /* we are guaranteed that a) log sectors are 4096 bytes, in vhdx_log_peek_hdr()
76 * and b) the log length is a multiple of 1MB. So, there in vhdx_log_peek_hdr()
78 if ((read + sizeof(VHDXLogEntryHeader)) > log->length) { in vhdx_log_peek_hdr()
82 if (read == log->write) { in vhdx_log_peek_hdr()
87 offset = log->offset + read; in vhdx_log_peek_hdr()
99 /* Index increment for log, based on sector boundaries */
103 /* we are guaranteed that a) log sectors are 4096 bytes, in vhdx_log_inc_idx()
104 * and b) the log length is a multiple of 1MB. So, there in vhdx_log_inc_idx()
110 /* Reset the log to empty */
114 s->log.read = s->log.write = 0; in vhdx_log_reset()
115 /* a log guid of 0 indicates an empty log to any parser of v0 in vhdx_log_reset()
120 /* Reads num_sectors from the log (all log sectors are 4096 bytes),
132 vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log, in vhdx_log_read_sectors() argument
140 read = log->read; in vhdx_log_read_sectors()
144 if (read == log->write) { in vhdx_log_read_sectors()
148 offset = log->offset + read; in vhdx_log_read_sectors()
154 read = vhdx_log_inc_idx(read, log->length); in vhdx_log_read_sectors()
162 log->read = read; in vhdx_log_read_sectors()
167 /* Writes num_sectors to the log (all log sectors are 4096 bytes),
175 vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log, in vhdx_log_write_sectors() argument
190 write = log->write; in vhdx_log_write_sectors()
195 offset = log->offset + write; in vhdx_log_write_sectors()
196 write = vhdx_log_inc_idx(write, log->length); in vhdx_log_write_sectors()
197 if (write == log->read) { in vhdx_log_write_sectors()
207 log->write = write; in vhdx_log_write_sectors()
217 /* Validates a log entry header */
218 static bool vhdx_log_hdr_is_valid(VHDXLogEntries *log, VHDXLogEntryHeader *hdr, in vhdx_log_hdr_is_valid() argument
227 /* if the individual entry length is larger than the whole log in vhdx_log_hdr_is_valid()
229 if (log->length < hdr->entry_length) { in vhdx_log_hdr_is_valid()
233 /* length of entire entry must be in units of 4KB (log sector size) */ in vhdx_log_hdr_is_valid()
243 /* log entries are only valid if they match the file-wide log guid in vhdx_log_hdr_is_valid()
260 * Given a log header, this will validate that the descriptors and the
271 * @hdr: the log entry header
302 /* Prior to sector data for a log entry, there is the header
309 * The first sector in a log entry has a 64 byte header, and
334 /* Reads the log header, and subsequent descriptors (if any). This
339 vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogEntries *log, in vhdx_log_read_desc() argument
352 ret = vhdx_log_peek_hdr(bs, log, &hdr); in vhdx_log_read_desc()
357 if (vhdx_log_hdr_is_valid(log, &hdr, s) == false) { in vhdx_log_read_desc()
370 ret = vhdx_log_read_sectors(bs, log, &sectors_read, desc_entries, in vhdx_log_read_desc()
463 error_report("Invalid VHDX log descriptor entry signature 0x%" PRIx32, in vhdx_log_flush_desc()
486 /* Flush the entire log (as described by 'logs') to the VHDX image
487 * file, and then set the log to 'empty' status once complete.
489 * The log entries should be validate prior to flushing */
511 /* each iteration represents one log sequence, which may span multiple in vhdx_log_flush()
514 ret = vhdx_log_peek_hdr(bs, &logs->log, &hdr_tmp); in vhdx_log_flush()
523 /* if the log shows a FlushedFileOffset larger than our current file in vhdx_log_flush()
531 ret = vhdx_log_read_desc(bs, s, &logs->log, &desc_entries, true); in vhdx_log_flush()
539 ret = vhdx_log_read_sectors(bs, &logs->log, &sectors_read, in vhdx_log_flush()
580 /* once the log is fully flushed, indicate that we have an empty log in vhdx_log_flush()
581 * now. This also sets the log guid to 0, to indicate an empty log */ in vhdx_log_flush()
592 VHDXLogEntries *log, uint64_t seq, in vhdx_validate_log_entry() argument
604 ret = vhdx_log_peek_hdr(bs, log, &hdr); in vhdx_validate_log_entry()
609 if (vhdx_log_hdr_is_valid(log, &hdr, s) == false) { in vhdx_validate_log_entry()
621 /* Read all log sectors, and calculate log checksum */ in vhdx_validate_log_entry()
627 ret = vhdx_log_read_desc(bs, s, log, &desc_buffer, false); in vhdx_validate_log_entry()
640 ret = vhdx_log_read_sectors(bs, log, &sectors_read, buffer, in vhdx_validate_log_entry()
659 log->read = vhdx_log_inc_idx(log->read, log->length); in vhdx_validate_log_entry()
667 /* Search through the log circular buffer, and find the valid, active
668 * log sequence, if any exists
680 memcpy(&curr_log, &s->log, sizeof(VHDXLogEntries)); in vhdx_log_search()
681 curr_log.write = curr_log.length; /* assume log is full */ in vhdx_log_search()
685 /* now we will go through the whole log sector by sector, until in vhdx_log_search()
686 * we find a valid, active log sequence, or reach the end of the in vhdx_log_search()
687 * log buffer */ in vhdx_log_search()
702 current.log = curr_log; in vhdx_log_search()
703 current.log.read = tail; in vhdx_log_search()
704 current.log.write = curr_log.read; in vhdx_log_search()
718 current.log.write = curr_log.read; in vhdx_log_search()
741 s->log.sequence = candidate.hdr.sequence_number + 1; in vhdx_log_search()
749 /* Parse the replay log. Per the VHDX spec, if the log is present
752 * If read-only, we must replay the log in RAM (or refuse to open
765 /* s->log.hdr is freed in vhdx_close() */ in vhdx_parse_log()
766 if (s->log.hdr == NULL) { in vhdx_parse_log()
767 s->log.hdr = qemu_blockalign(bs, sizeof(VHDXLogEntryHeader)); in vhdx_parse_log()
770 s->log.offset = hdr->log_offset; in vhdx_parse_log()
771 s->log.length = hdr->log_length; in vhdx_parse_log()
773 if (s->log.offset < VHDX_LOG_MIN_SIZE || in vhdx_parse_log()
774 s->log.offset % VHDX_LOG_MIN_SIZE) { in vhdx_parse_log()
779 /* per spec, only log version of 0 is supported */ in vhdx_parse_log()
785 /* If either the log guid, or log length is zero, in vhdx_parse_log()
786 * then a replay log is not present */ in vhdx_parse_log()
801 /* The log is present, we need to find if and where there is an active in vhdx_parse_log()
802 * sequence of valid entries present in the log. */ in vhdx_parse_log()
815 "contains a log that needs to be replayed", in vhdx_parse_log()
817 error_append_hint(errp, "To replay the log, run:\n" in vhdx_parse_log()
822 /* now flush the log */ in vhdx_parse_log()
841 /* 8 + 4084 + 4 = 4096, 1 log sector */ in vhdx_log_raw_to_le_sector()
890 /* no log present. we could create a log here instead of failing */ in vhdx_log_write()
899 /* currently, we require that the log be flushed after in vhdx_log_write()
906 * log write (or a wrapped seq) */ in vhdx_log_write()
907 if (s->log.sequence == 0) { in vhdx_log_write()
908 s->log.sequence = 1; in vhdx_log_write()
943 .tail = s->log.tail, in vhdx_log_write()
944 .sequence_number = s->log.sequence, in vhdx_log_write()
967 /* All log sectors are 4KB, so for any partial sectors we must in vhdx_log_write()
974 new_desc->sequence_number = s->log.sequence; in vhdx_log_write()
1007 s->log.sequence); in vhdx_log_write()
1015 /* checksum covers entire entry, from the log header through the in vhdx_log_write()
1020 /* now write to the log */ in vhdx_log_write()
1021 ret = vhdx_log_write_sectors(bs, &s->log, &sectors_written, buffer, in vhdx_log_write()
1028 /* instead of failing, we could flush the log here */ in vhdx_log_write()
1033 s->log.sequence++; in vhdx_log_write()
1035 s->log.tail = s->log.write; in vhdx_log_write()
1043 /* Perform a log write, and then immediately flush the entire log */
1055 * on disk, before creating log entry */ in vhdx_log_write_and_flush()
1065 logs.log = s->log; in vhdx_log_write_and_flush()
1067 /* Make sure log is stable on disk */ in vhdx_log_write_and_flush()
1078 s->log = logs.log; in vhdx_log_write_and_flush()