L4Re/OLD/e2fsserver

Changeset

22:f17b31ddfc96
2019-03-30 Paul Boddie raw files shortlog changelog graph Added support for memory mapping and paging.
include/fs_object.h (file) server/src/fs_object.cc (file)
     1.1 --- a/include/fs_object.h	Sat Mar 30 00:15:38 2019 +0100
     1.2 +++ b/include/fs_object.h	Sat Mar 30 18:39:10 2019 +0100
     1.3 @@ -28,6 +28,7 @@
     1.4  #include <ext2fs/ext2fs.h>
     1.5  
     1.6  #include <fsclient/fsdesc.h>
     1.7 +#include <fsserver/pager.h>
     1.8  #include <fsserver/server.h>
     1.9  #include <ipc/util_ipc.h>
    1.10  
    1.11 @@ -35,7 +36,7 @@
    1.12  
    1.13  /* Filesystem object. */
    1.14  
    1.15 -class Fs_object : public Resource
    1.16 +class Fs_object : public Resource, public Pager
    1.17  {
    1.18  private:
    1.19    /* Interaction with the file from the block device. */
    1.20 @@ -57,6 +58,8 @@
    1.21  
    1.22    void flush(ipc_message_t *msg);
    1.23  
    1.24 +  void mmap(ipc_message_t *msg);
    1.25 +
    1.26    void read(ipc_message_t *msg);
    1.27  
    1.28    void write(ipc_message_t *msg);
    1.29 @@ -64,4 +67,14 @@
    1.30    size_t read_into(char *buffer, size_t to_transfer);
    1.31  
    1.32    size_t write_from(char *buffer, size_t to_transfer);
    1.33 +
    1.34 +  /* Pager methods. */
    1.35 +
    1.36 +  void fill_flexpage_data(Flexpage &flexpage);
    1.37 +
    1.38 +  void flush_flexpage_data(Flexpage &flexpage);
    1.39 +
    1.40 +  unsigned long get_data_start() { return _obj.data_start; };
    1.41 +
    1.42 +  unsigned long get_data_size() { return _obj.size; };
    1.43  };
     2.1 --- a/server/src/fs_object.cc	Sat Mar 30 00:15:38 2019 +0100
     2.2 +++ b/server/src/fs_object.cc	Sat Mar 30 18:39:10 2019 +0100
     2.3 @@ -23,6 +23,7 @@
     2.4  #include <l4/util/util.h>
     2.5  
     2.6  #include <l4/re/c/dataspace.h>
     2.7 +#include <l4/re/protocols.h>
     2.8  #include <l4/sys/types.h>
     2.9  
    2.10  #include <stdlib.h>
    2.11 @@ -33,6 +34,7 @@
    2.12  
    2.13  #include <fsclient/fs_client.h>
    2.14  #include <fsclient/fsdesc.h>
    2.15 +#include <fsserver/pager.h>
    2.16  #include <fsserver/server.h>
    2.17  #include <ipc/util_ipc.h>
    2.18  #include "fs_object.h"
    2.19 @@ -47,12 +49,20 @@
    2.20    _obj.size = size;
    2.21    _data = 0;
    2.22    _enddata = 0;
    2.23 +
    2.24 +  _obj.buffer_size = l4re_ds_size(_obj.ds);
    2.25 +
    2.26 +  Pager::init((l4_addr_t) _obj.buffer, _obj.buffer_size);
    2.27  }
    2.28  
    2.29  void Fs_object::close()
    2.30  {
    2.31    Resource::close();
    2.32  
    2.33 +  /* Flush any open pages. */
    2.34 +
    2.35 +  flush_all();
    2.36 +
    2.37    /* Detach the server side of the descriptor buffer. */
    2.38  
    2.39    fsdesc_deallocate_buffer(&_obj);
    2.40 @@ -70,10 +80,18 @@
    2.41  {
    2.42    switch (l4_msgtag_label(msg->tag))
    2.43    {
    2.44 +    case L4RE_PROTO_DATASPACE:
    2.45 +      dispatch_dataspace(msg);
    2.46 +      break;
    2.47 +
    2.48      case Fs_op_flush:
    2.49        flush(msg);
    2.50        break;
    2.51  
    2.52 +    case Fs_op_mmap:
    2.53 +      mmap(msg);
    2.54 +      break;
    2.55 +
    2.56      case Fs_op_read:
    2.57        read(msg);
    2.58        break;
    2.59 @@ -90,8 +108,20 @@
    2.60  
    2.61  void Fs_object::flush(ipc_message_t *msg)
    2.62  {
    2.63 +  size_t length = ipc_message_get_word(msg, 0);
    2.64 +  size_t size = _obj.data_start + length;
    2.65 +
    2.66 +  if (size > _obj.size)
    2.67 +    _obj.size = size;
    2.68 +
    2.69 +  flush_all();
    2.70 +
    2.71    if (ext2fs_file_flush(_file))
    2.72      send_error(msg, -L4_EIO);
    2.73 +
    2.74 +  /* Send the new size. */
    2.75 +
    2.76 +  ipc_message_add_word(msg, _obj.size);
    2.77  }
    2.78  
    2.79  void Fs_object::read(ipc_message_t *msg)
    2.80 @@ -213,3 +243,44 @@
    2.81  
    2.82    return total;
    2.83  }
    2.84 +
    2.85 +
    2.86 +
    2.87 +/* NOTE: Should be provided by a common "mapped resource" class. */
    2.88 +
    2.89 +void Fs_object::mmap(ipc_message_t *msg)
    2.90 +{
    2.91 +  flush_all();
    2.92 +
    2.93 +  /* Set the position and limit of the region. */
    2.94 +
    2.95 +  _obj.data_start = ipc_message_get_word(msg, 0);
    2.96 +  _obj.data_end = _obj.data_start + ipc_message_get_word(msg, 1);
    2.97 +
    2.98 +  if (_obj.data_end > _obj.size)
    2.99 +    _obj.data_end = _obj.size;
   2.100 +  if (_obj.data_start > _obj.data_end)
   2.101 +    _obj.data_start = _obj.data_end;
   2.102 +
   2.103 +  /* Return the actual size of the region. */
   2.104 +
   2.105 +  ipc_message_add_word(msg, _obj.data_end - _obj.data_start);
   2.106 +}
   2.107 +
   2.108 +
   2.109 +
   2.110 +void Fs_object::fill_flexpage_data(Flexpage &flexpage)
   2.111 +{
   2.112 +  if (ext2fs_file_lseek(_file, get_data_start(), EXT2_SEEK_SET, 0))
   2.113 +    return;
   2.114 +
   2.115 +  read_into((char *) flexpage.get_base(), flexpage.get_data_length());
   2.116 +}
   2.117 +
   2.118 +void Fs_object::flush_flexpage_data(Flexpage &flexpage)
   2.119 +{
   2.120 +  if (ext2fs_file_lseek(_file, get_data_start(), EXT2_SEEK_SET, 0))
   2.121 +    return;
   2.122 +
   2.123 +  write_from((char *) flexpage.get_base(), flexpage.get_data_length());
   2.124 +}