1.1 --- a/libexec/lib/src/segment.cc Sun May 22 23:46:17 2022 +0200
1.2 +++ b/libexec/lib/src/segment.cc Tue May 24 00:34:05 2022 +0200
1.3 @@ -73,30 +73,14 @@
1.4
1.5 long Segment::fill(file_t *file)
1.6 {
1.7 - /* NOTE: This should be replaced by copy-on-write dataspace usage. */
1.8 -
1.9 - if (_flags & L4RE_RM_F_W)
1.10 - {
1.11 - long err = allocate();
1.12 -
1.13 - if (err)
1.14 - return err;
1.15 -
1.16 - client_seek(file, _file_offset - _region_offset, SEEK_SET);
1.17 - offset_t nread = client_read(file, _buf, _region_size);
1.18 -
1.19 - memset(_buf, 0, _region_offset);
1.20 - memset(_buf + _region_offset + _file_contents, 0, _region_size - _region_offset - _file_contents);
1.21 -
1.22 - if (nread < _file_contents)
1.23 - return -L4_EIO;
1.24 - else
1.25 - return L4_EOK;
1.26 - }
1.27 -
1.28 /* Provide the exposed file contents in a masked memory mapped region. */
1.29
1.30 - _buf = (char *) client_mmap(file, _file_offset - _region_offset, _region_size, 0, 0, _flags);
1.31 + _buf = (char *) client_mmap(file,
1.32 + _file_offset - _region_offset,
1.33 + _region_size,
1.34 + _file_offset,
1.35 + _file_offset + _file_contents,
1.36 + _flags);
1.37
1.38 if (_buf == NULL)
1.39 return -L4_EIO;
2.1 --- a/libfsserver/include/fsserver/pager.h Sun May 22 23:46:17 2022 +0200
2.2 +++ b/libfsserver/include/fsserver/pager.h Tue May 24 00:34:05 2022 +0200
2.3 @@ -38,12 +38,15 @@
2.4 PageMapper *_mapper;
2.5 map_flags_t _flags;
2.6
2.7 + /* Support for masked regions and replicated flexpages. */
2.8 +
2.9 + MemoryIncremental _memory;
2.10 +
2.11 /* Masked region support. */
2.12
2.13 bool _is_masked;
2.14 offset_t _start_visible, _end_visible;
2.15 Flexpage _start_flexpage, _end_flexpage, _zero_flexpage;
2.16 - MemoryIncremental _memory;
2.17
2.18 Flexpage *get_masked_flexpage(Flexpage *flexpage);
2.19
2.20 @@ -52,6 +55,11 @@
2.21 void populate_region(Flexpage *flexpage, Flexpage &masked,
2.22 bool has_start, bool has_end);
2.23
2.24 + /* Replicated flexpage support. */
2.25 +
2.26 + AccessMap _map;
2.27 + Flexpage *get_replicated_flexpage(Flexpage *flexpage, map_flags_t flags);
2.28 +
2.29 public:
2.30 explicit Pager(PageMapper *mapper, map_flags_t flags);
2.31
3.1 --- a/libfsserver/lib/generic/pager.cc Sun May 22 23:46:17 2022 +0200
3.2 +++ b/libfsserver/lib/generic/pager.cc Tue May 24 00:34:05 2022 +0200
3.3 @@ -40,6 +40,7 @@
3.4
3.5 void Pager::close()
3.6 {
3.7 + /* NOTE: Need to deallocate any allocated regions and flexpages. */
3.8 }
3.9
3.10 /* Flush data to the file. */
3.11 @@ -109,11 +110,30 @@
3.12 if (flags & (~(_flags | L4RE_DS_F_X)))
3.13 return -L4_EACCESS;
3.14
3.15 - Flexpage *flexpage = _mapper->get(file_offset, flags);
3.16 + Flexpage *issued_flexpage = NULL, *obtained_flexpage = NULL;
3.17 +
3.18 + /* Obtain any replicated flexpage.
3.19 + NOTE: An additional condition should be introduced to test for the
3.20 + relevance of replicated flexpages. */
3.21 +
3.22 + if (flags & L4RE_DS_F_W)
3.23 + issued_flexpage = _map.find(file_offset);
3.24 +
3.25 + /* Without any replicated flexpage, obtain one for the shared, underlying
3.26 + file data. */
3.27
3.28 - /* Determine if the flexpage should be masked. */
3.29 + if (issued_flexpage == NULL)
3.30 + {
3.31 + obtained_flexpage = _mapper->get(file_offset, flags);
3.32 +
3.33 + /* Determine if the flexpage should be masked. */
3.34
3.35 - Flexpage *issued_flexpage = get_masked_flexpage(flexpage);
3.36 + issued_flexpage = get_masked_flexpage(obtained_flexpage);
3.37 +
3.38 + /* Determine if the flexpage should be replicated. */
3.39 +
3.40 + issued_flexpage = get_replicated_flexpage(issued_flexpage, flags);
3.41 + }
3.42
3.43 /* Issue the flexpage via the IPC system. */
3.44
3.45 @@ -123,9 +143,10 @@
3.46 if (!err)
3.47 err = complete_Dataspace_map(*region);
3.48
3.49 - /* After the flexpage is issued, it is queued for future reuse. */
3.50 + /* After the obtained flexpage is issued, it is queued for future reuse. */
3.51
3.52 - _mapper->queue(flexpage);
3.53 + if (obtained_flexpage != NULL)
3.54 + _mapper->queue(obtained_flexpage);
3.55
3.56 if (err)
3.57 return err;
3.58 @@ -151,7 +172,7 @@
3.59 return flexpage;
3.60
3.61 /* Determine whether the flexpage involves the limits of the visible
3.62 - region. */
3.63 + region or is beyond such limits. */
3.64
3.65 bool has_start = flexpage->supports_position(_start_visible) &&
3.66 flexpage->base_offset != _start_visible;
3.67 @@ -165,9 +186,7 @@
3.68 return flexpage;
3.69
3.70 /* Allocate and populate a region in one of the preallocated flexpages for
3.71 - masked content.
3.72 - NOTE: A general copy-on-write solution will maintain a collection of
3.73 - flexpages. */
3.74 + masked content. */
3.75
3.76 Flexpage &masked = has_start ? _start_flexpage :
3.77 has_end ? _end_flexpage :
3.78 @@ -179,6 +198,7 @@
3.79 /* Associate the preallocated flexpage with the original flexpage. */
3.80
3.81 flexpage->associate(&masked);
3.82 +
3.83 return &masked;
3.84 }
3.85
3.86 @@ -229,4 +249,28 @@
3.87 memset((void *) (masked.region->start + end_offset), 0, masked.size - end_offset);
3.88 }
3.89
3.90 +/* Detect flexpages with replicated content, introducing separate flexpages
3.91 + offering replicated content from the same region. */
3.92 +
3.93 +Flexpage *Pager::get_replicated_flexpage(Flexpage *flexpage, map_flags_t flags)
3.94 +{
3.95 + /* NOTE: An additional condition should be introduced to test for the
3.96 + relevance of replicated flexpages. For now, detect copy-on-write
3.97 + situations. */
3.98 +
3.99 + if (_is_masked && (flags & L4RE_DS_F_W))
3.100 + {
3.101 + Region *region = _memory.region(flexpage->size);
3.102 + Flexpage *replicated = new Flexpage(region);
3.103 +
3.104 + replicated->reset(flexpage->base_offset);
3.105 +
3.106 + memcpy((void *) region->start, (const void *) flexpage->region->start, flexpage->size);
3.107 + _map.insert(replicated);
3.108 + return replicated;
3.109 + }
3.110 + else
3.111 + return flexpage;
3.112 +}
3.113 +
3.114 // vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/libfsserver/lib/mapping/page_mapper.cc Sun May 22 23:46:17 2022 +0200
4.2 +++ b/libfsserver/lib/mapping/page_mapper.cc Tue May 24 00:34:05 2022 +0200
4.3 @@ -1,7 +1,7 @@
4.4 /*
4.5 * A page mapper providing memory pages to satisfy file accesses.
4.6 *
4.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
4.8 + * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
4.9 *
4.10 * This program is free software; you can redistribute it and/or
4.11 * modify it under the terms of the GNU General Public License as