L4Re/departure

libfsserver/lib/mapping/copied_page_mapper.cc

618:7123a7307a82
8 months ago Paul Boddie Introduced some debugging output control.
     1 /*     2  * A page mapper providing copied memory pages or deferring to another page     3  * mapper to satisfy file accesses.     4  *     5  * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>     6  *     7  * This program is free software; you can redistribute it and/or     8  * modify it under the terms of the GNU General Public License as     9  * published by the Free Software Foundation; either version 2 of    10  * the License, or (at your option) any later version.    11  *    12  * This program is distributed in the hope that it will be useful,    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    15  * GNU General Public License for more details.    16  *    17  * You should have received a copy of the GNU General Public License    18  * along with this program; if not, write to the Free Software    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,    20  * Boston, MA  02110-1301, USA    21  */    22     23 #include <l4/re/c/dataspace.h>    24     25 #include <string.h>    26     27 #include "copied_page_mapper.h"    28     29     30     31 /* Provide mapped pages populated with the given 'mapper', with pages obtained    32    from the given 'pages' collection. */    33     34 CopiedPageMapper::CopiedPageMapper(GenericPageMapper *mapper)    35 : _mapper(mapper)    36 {    37     _size = _mapper->get_data_size();    38 }    39     40 /* Upon deallocation, release allocated flexpages. */    41     42 CopiedPageMapper::~CopiedPageMapper()    43 {    44     while (!_queue.empty())    45     {    46         Flexpage *flexpage = _queue.front();    47     48         _queue.pop_front();    49         _memory.release(flexpage->region);    50         delete flexpage;    51     }    52 }    53     54 /* Interface for the pager. */    55     56 /* Return a flexpage providing access to the indicated file 'offset'.    57     58    The returned flexpage will either provide direct access to the underlying    59    file content or be a completely new flexpage modified through writes to    60    memory. */    61     62 Flexpage *CopiedPageMapper::get(offset_t offset, map_flags_t flags)    63 {    64     Flexpage *f = find(offset);    65     66     /* Defer to the underlying page mapper if no flexpage was found. */    67     68     if (f == NULL)    69     {    70         f = _mapper->get(offset, flags);    71     72         /* Replicate the underlying flexpage if writing. */    73     74         if (flags & L4RE_DS_F_W)    75         {    76             Flexpage *rf = replicate_flexpage(offset, f);    77             _mapper->queue(f);    78             f = rf;    79         }    80     }    81     82     /* Upgrade the access flags. */    83     84     f->upgrade(flags);    85     return f;    86 }    87     88 /* Queue the given 'flexpage'. */    89     90 void CopiedPageMapper::queue(Flexpage *flexpage)    91 {    92     if (dynamic_cast<CopiedFlexpage *>(flexpage) == NULL)    93         _mapper->queue(flexpage);    94 }    95     96 /* Flush pages in the given range from 'start' with 'size'. */    97     98 void CopiedPageMapper::flush_all(offset_t start, offset_t size)    99 {   100     /* NOTE: This might be superfluous since copy-on-write regions should not   101              update content. */   102    103     _mapper->flush_all(start, size);   104 }   105    106 /* Return the maximum extent of the mapped resource. */   107    108 offset_t CopiedPageMapper::get_data_size()   109 {   110     return _size;   111 }   112    113 /* Set the maximum extent of the mapped resource. */   114    115 void CopiedPageMapper::set_data_size(offset_t size)   116 {   117     _size = size;   118 }   119    120 /* Internal flexpage retrieval methods. */   121    122 /* Find an existing flexpage for 'offset'. */   123    124 Flexpage *CopiedPageMapper::find(offset_t offset)   125 {   126     return _map.find(offset);   127 }   128    129 /* Replicate an underlying flexpage for the file 'offset' using the given   130    'flexpage'. */   131    132 Flexpage *CopiedPageMapper::replicate_flexpage(offset_t offset, Flexpage *flexpage)   133 {   134     /* Obtain a new memory region and a new flexpage. */   135    136     Region *region = _memory.region(flexpage->size);   137     Flexpage *replicated = new CopiedFlexpage(region);   138    139     /* Configure the flexpage for the file region. */   140    141     replicated->reset(offset);   142    143     /* Copy the contents of the underlying flexpage. */   144    145     memcpy((void *) region->start, (const void *) flexpage->region->start, flexpage->size);   146    147     /* Register the flexpage for future accesses and for deallocation. */   148    149     _map.insert(replicated);   150     _queue.push_back(replicated);   151     return replicated;   152 }   153    154    155    156 /* Copied flexpage constructor. */   157    158 CopiedFlexpage::CopiedFlexpage(Region *region)   159 : Flexpage(region)   160 {   161 }   162    163 // vim: tabstop=4 expandtab shiftwidth=4