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, offset_t *end_pos, offset_t *data_end) 50 { 51 _start = trunc(position, PAGE_SIZE); 52 _size = round(position + length, PAGE_SIZE) - _start; 53 54 *start_pos = _start; 55 *end_pos = _start + _size; 56 *data_end = 0; 57 58 return L4_EOK; 59 } 60 61 /* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' 62 (flexpage offset). */ 63 64 long Pager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 65 { 66 offset_t file_offset = _start + offset; 67 offset_t max_offset = _start + _size; 68 69 /* Prevent access beyond that defined by the pager. */ 70 71 if (flags & ~_flags) 72 return -L4_EACCESS; 73 74 Flexpage *flexpage = _mapper->get(file_offset, flags); 75 76 /* Issue the flexpage via the IPC system. */ 77 78 long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, 79 flags, region); 80 81 if (!err) 82 err = complete_Dataspace_map(*region); 83 84 /* After the flexpage is issued, it is queued for future reuse. */ 85 86 _mapper->queue(flexpage); 87 88 if (err) 89 return err; 90 91 return IPC_MESSAGE_SENT; 92 } 93 94 /* Return the total size of the data. */ 95 96 offset_t Pager::get_data_size() 97 { 98 return _mapper->get_data_size(); 99 } 100 101 // vim: tabstop=4 expandtab shiftwidth=4