1 #include "dataspace_server.h" 2 #include "ipc.h" 3 #include "pager.h" 4 5 6 7 /* Initialise the pager with a page mapper and the given flags controlling 8 access to a file. */ 9 10 Pager::Pager(PageMapper *mapper, flags_t flags) 11 : _start(0), _size(0), _mapper(mapper), _flags(flags) 12 { 13 /* Some pagers may not be initialised with a mapper. */ 14 15 if (_mapper != NULL) 16 _mapper->attach(); 17 } 18 19 /* Close the pager. */ 20 21 void Pager::close() 22 { 23 if (_mapper != NULL) 24 _mapper->detach(); 25 } 26 27 /* Flush data to the file. */ 28 29 long Pager::flush(offset_t populated_size, offset_t *size) 30 { 31 _mapper->flush_all(_start, populated_size); 32 33 *size = _mapper->get_data_size(); 34 return L4_EOK; 35 } 36 37 /* Resize the underlying file. */ 38 39 long Pager::resize(offset_t *size) 40 { 41 _mapper->set_data_size(*size); 42 43 *size = _mapper->get_data_size(); 44 return L4_EOK; 45 } 46 47 /* Expose a region of the file. */ 48 49 long Pager::mmap(offset_t position, offset_t length, offset_t *start_pos, 50 offset_t *end_pos, offset_t *size) 51 { 52 /* Define region characteristics. */ 53 54 _start = trunc(position, PAGE_SIZE); 55 _size = round(position + length, PAGE_SIZE) - _start; 56 57 /* Return the start and end positions plus populated extent. */ 58 59 *start_pos = _start; 60 *end_pos = _start + _size; 61 *size = _mapper->get_data_size(); 62 63 return L4_EOK; 64 } 65 66 /* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' 67 (flexpage offset). */ 68 69 long Pager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, 70 l4_snd_fpage_t *region) 71 { 72 offset_t file_offset = _start + offset; 73 offset_t max_offset = _start + _size; 74 75 /* Prevent access beyond that defined by the pager. */ 76 77 if (flags & ~_flags) 78 return -L4_EACCESS; 79 80 Flexpage *flexpage = _mapper->get(file_offset, flags); 81 82 /* Issue the flexpage via the IPC system. */ 83 84 long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, 85 flags, region); 86 87 if (!err) 88 err = complete_Dataspace_map(*region); 89 90 /* After the flexpage is issued, it is queued for future reuse. */ 91 92 _mapper->queue(flexpage); 93 94 if (err) 95 return err; 96 97 return IPC_MESSAGE_SENT; 98 } 99 100 /* Return the total size of the data. */ 101 102 offset_t Pager::get_data_size() 103 { 104 return _mapper->get_data_size(); 105 } 106 107 // vim: tabstop=4 expandtab shiftwidth=4