1.1 --- a/files/block_file_accessor.cc Wed Mar 17 00:10:47 2021 +0100
1.2 +++ b/files/block_file_accessor.cc Thu Mar 18 00:59:55 2021 +0100
1.3 @@ -45,13 +45,44 @@
1.4 fclose(fp);
1.5 }
1.6
1.7 +/* Update the size of the file. */
1.8 +
1.9 +void BlockFileAccessor::set_size(offset_t size)
1.10 +{
1.11 + void *new_data = realloc(_data, size);
1.12 +
1.13 + if (new_data != NULL)
1.14 + {
1.15 + _data = (char *) new_data;
1.16 +
1.17 + if (size > _size)
1.18 + memset(_data + _size, 0, size - _size);
1.19 +
1.20 + Accessor::set_size(size);
1.21 + }
1.22 +}
1.23 +
1.24 /* Data transfer methods. */
1.25
1.26 void BlockFileAccessor::fill(Flexpage *flexpage)
1.27 {
1.28 offset_t filepos = flexpage->base_offset;
1.29 offset_t addr = flexpage->base_addr;
1.30 - offset_t populated_size = std::min(flexpage->size, _size - filepos);
1.31 + offset_t populated_size;
1.32 +
1.33 + /* Filling completely beyond the end of file should produce an empty
1.34 + flexpage. This could potentially be a shared read-only flexpage that
1.35 + would be replaced by an independent writable flexpage if ever written. */
1.36 +
1.37 + if (filepos > _size)
1.38 + {
1.39 + memset((void *) addr, 0, flexpage->size);
1.40 + return;
1.41 + }
1.42 +
1.43 + /* Otherwise, fill the populated portion of a flexpage. */
1.44 +
1.45 + populated_size = std::min(flexpage->size, _size - filepos);
1.46
1.47 /* Tag the region with file state. */
1.48
1.49 @@ -71,7 +102,17 @@
1.50 {
1.51 offset_t addr = flexpage->base_addr;
1.52 offset_t filepos = flexpage->base_offset;
1.53 - offset_t populated_size = std::min(flexpage->size, _size - filepos);
1.54 + offset_t populated_size;
1.55 +
1.56 + /* Flushing completely beyond the end of file should discard the
1.57 + flexpage. */
1.58 +
1.59 + if (filepos > _size)
1.60 + return;
1.61 +
1.62 + /* Otherwise, only the populated portion of a flexpage should be flushed. */
1.63 +
1.64 + populated_size = std::min(flexpage->size, _size - filepos);
1.65
1.66 /* Remove the file state tag from the region. */
1.67