L4Re/OLD/e2fsserver

Changeset

107:c5c6c356a056
2019-11-26 Paul Boddie raw files shortlog changelog graph Introduced interface definitions to formalise directory listing communications. Further refinement of the generated code and interfaces would be desirable.
idl/directory_listing.idl (file) idl/directory_listing_private.idl (file) include/fs_directory_listing.h (file) server/src/Makefile (file) server/src/fs_directory_listing.cc (file)
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/idl/directory_listing.idl	Tue Nov 26 22:21:42 2019 +0100
     1.3 @@ -0,0 +1,15 @@
     1.4 +/* Signalling between a directory and a directory listing activity. */
     1.5 +
     1.6 +#include <sys/types.h>      /* size_t */
     1.7 +
     1.8 +interface DirectoryListing
     1.9 +{
    1.10 +  /* Terminate a directory listing activity. */
    1.11 +
    1.12 +  [opcode(0)] void terminate();
    1.13 +
    1.14 +  /* Read a directory listing entry. The actual entry is communicated via a
    1.15 +     mechanism established outside this interface. */
    1.16 +
    1.17 +  [opcode(1)] void read(in size_t position, out size_t size);
    1.18 +};
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/idl/directory_listing_private.idl	Tue Nov 26 22:21:42 2019 +0100
     2.3 @@ -0,0 +1,17 @@
     2.4 +/* Signalling between a directory and a directory listing activity. This
     2.5 +   interface is used only by the server and features a read operation that is
     2.6 +   initiated and then completed later. */
     2.7 +
     2.8 +#include <sys/types.h>      /* size_t */
     2.9 +
    2.10 +interface DirectoryListingPrivate
    2.11 +{
    2.12 +  /* Terminate a directory listing activity. */
    2.13 +
    2.14 +  [opcode(0)] void terminate();
    2.15 +
    2.16 +  /* Read a directory listing entry. The actual entry is communicated via a
    2.17 +     mechanism established outside this interface. */
    2.18 +
    2.19 +  [opcode(1), completion] void read(in size_t position, out size_t size);
    2.20 +};
     3.1 --- a/include/fs_directory_listing.h	Sat Nov 09 17:21:27 2019 +0100
     3.2 +++ b/include/fs_directory_listing.h	Tue Nov 26 22:21:42 2019 +0100
     3.3 @@ -29,12 +29,11 @@
     3.4  #include <sys/stat.h>
     3.5  
     3.6  #include <ext2fs/ext2fs.h>
     3.7 -
     3.8 -
     3.9 +#include <ipc/message.h>
    3.10  
    3.11 -/* Directory listing operations. */
    3.12 +/* Employed interface. */
    3.13  
    3.14 -enum { Fsdir_op_terminate, Fsdir_op_read };
    3.15 +#include "directory_listing_private_interface.h"
    3.16  
    3.17  
    3.18  
    3.19 @@ -70,9 +69,10 @@
    3.20  
    3.21  
    3.22  
    3.23 -/* Filesystem directory resource. */
    3.24 +/* Filesystem directory resource employing an interface for private use by the
    3.25 +   server. */
    3.26  
    3.27 -class Fs_directory_listing
    3.28 +class Fs_directory_listing : public DirectoryListingPrivate
    3.29  {
    3.30  private:
    3.31    ext2_filsys _fs;
    3.32 @@ -92,13 +92,13 @@
    3.33  
    3.34    pthread_t _thread;
    3.35    l4_cap_idx_t _thread_ep;
    3.36 -  l4_msgtag_t _tag;
    3.37 +  bool _terminating;
    3.38  
    3.39  public:
    3.40    explicit Fs_directory_listing(ext2_filsys fs, ext2_ino_t dir, int flags=0)
    3.41 -  : _fs(fs), _dir(dir), _flags(flags)
    3.42 -  {
    3.43 -  }
    3.44 +  : _fs(fs), _dir(dir), _flags(flags) { }
    3.45 +
    3.46 +  virtual ~Fs_directory_listing() { }
    3.47  
    3.48    /* Activation. */
    3.49  
    3.50 @@ -108,7 +108,7 @@
    3.51  
    3.52    void close();
    3.53  
    3.54 -  /* Operation methods. */
    3.55 +  /* Accessor-operated methods. */
    3.56  
    3.57    size_t read_into(size_t start, char *buffer, size_t length);
    3.58  
    3.59 @@ -134,10 +134,13 @@
    3.60  
    3.61    /* Concurrency methods. */
    3.62  
    3.63 -  size_t _read(size_t seek_pos);
    3.64 -  int _terminating();
    3.65 -  size_t _wait();
    3.66 -  size_t _yield(size_t read);
    3.67 +  void _wait();
    3.68 +  void _yield(size_t size);
    3.69 +
    3.70 +  /* IPC operation methods. */
    3.71 +
    3.72 +  virtual long read(size_t position);
    3.73 +  virtual long terminate();
    3.74  
    3.75  protected:
    3.76    /* Reply to requests for results. */
     4.1 --- a/server/src/Makefile	Sat Nov 09 17:21:27 2019 +0100
     4.2 +++ b/server/src/Makefile	Tue Nov 26 22:21:42 2019 +0100
     4.3 @@ -4,9 +4,26 @@
     4.4  TARGET		= e2fsserver
     4.5  MODE		= shared
     4.6  
     4.7 +# Locations for interface input and generated output.
     4.8 +
     4.9 +IDL_DIR                 = $(PKGDIR)/idl
    4.10 +IDL_MK_DIR              = $(L4DIR)/pkg/libsystypes/idl/mk
    4.11 +IDL_BUILD_DIR           = .
    4.12 +IDL_EXPORT_DIR          = .
    4.13 +
    4.14 +include $(IDL_MK_DIR)/idl.mk
    4.15 +
    4.16 +# Individual interfaces.
    4.17 +
    4.18 +CLIENT_INTERFACES       = directory_listing
    4.19 +
    4.20 +SERVER_INTERFACES       = directory_listing directory_listing_private
    4.21 +
    4.22  # Normal definitions.
    4.23  
    4.24  SRC_CC		= \
    4.25 +		$(call interfaces_to_server_cc,$(SERVER_INTERFACES)) \
    4.26 +		$(call interfaces_to_client_cc,$(CLIENT_INTERFACES)) \
    4.27  		fs_accessor.cc fs_directory.cc fs_directory_accessor.cc \
    4.28  		fs_directory_listing.cc fs_directory_listing_accessor.cc \
    4.29    		fs_filesystem.cc fs_user_filesystem.cc \
    4.30 @@ -18,6 +35,7 @@
    4.31  		libe2access libext2fs_blockserver \
    4.32  		libsystypes
    4.33  
    4.34 -PRIVATE_INCDIR	= $(PKGDIR)/include
    4.35 +PRIVATE_INCDIR	= $(PKGDIR)/include $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR)
    4.36  
    4.37  include $(L4DIR)/mk/prog.mk
    4.38 +include $(IDL_MK_DIR)/interface_rules.mk
     5.1 --- a/server/src/fs_directory_listing.cc	Sat Nov 09 17:21:27 2019 +0100
     5.2 +++ b/server/src/fs_directory_listing.cc	Tue Nov 26 22:21:42 2019 +0100
     5.3 @@ -28,6 +28,11 @@
     5.4  #include <ipc/util_ipc.h>
     5.5  #include "fs_directory_listing.h"
     5.6  
     5.7 +/* Client and server interfaces. */
     5.8 +
     5.9 +#include "directory_listing_client.h"
    5.10 +#include "directory_listing_private_server.h"
    5.11 +
    5.12  
    5.13  
    5.14  /* Callback function for ext2fs_dir_iterate. */
    5.15 @@ -84,8 +89,9 @@
    5.16  {
    5.17    /* Notify the thread of the termination. */
    5.18  
    5.19 -  l4_ipc_call(_thread_ep, l4_utcb(), l4_msgtag(Fsdir_op_terminate, 0, 0, 0),
    5.20 -              L4_IPC_BOTH_TIMEOUT_0);
    5.21 +  client_DirectoryListing listing(_thread_ep);
    5.22 +
    5.23 +  listing.terminate();
    5.24  
    5.25    /* Wait for the thread to terminate. */
    5.26  
    5.27 @@ -107,19 +113,26 @@
    5.28  
    5.29  size_t Fs_directory_listing::read_into(size_t start, char *buffer, size_t length)
    5.30  {
    5.31 +  size_t size;
    5.32 +
    5.33    _buffer = buffer;
    5.34    _buffer_size = length;
    5.35  
    5.36 -  return _read(start);
    5.37 +  client_DirectoryListing listing(_thread_ep);
    5.38 +
    5.39 +  if (listing.read(start, &size))
    5.40 +    return 0;
    5.41 +  else
    5.42 +    return size;
    5.43  }
    5.44  
    5.45  void Fs_directory_listing::mainloop()
    5.46  {
    5.47    /* Wait for parameters. */
    5.48  
    5.49 -  _seek_pos = _wait();
    5.50 +  _wait();
    5.51  
    5.52 -  while (!_terminating())
    5.53 +  while (!_terminating)
    5.54    {
    5.55      /* Always start at the beginning of the listing. */
    5.56  
    5.57 @@ -135,7 +148,7 @@
    5.58      /* Test termination conditions before assuming that iteration completed
    5.59         normally. */
    5.60  
    5.61 -    if (_terminating())
    5.62 +    if (_terminating)
    5.63        break;
    5.64  
    5.65      /* Restart iteration if the next available data is after the desired
    5.66 @@ -154,7 +167,7 @@
    5.67  
    5.68      /* Test for a termination request. */
    5.69  
    5.70 -    if (_terminating())
    5.71 +    if (_terminating)
    5.72        break;
    5.73  
    5.74      /* Expect a request seeking to the end of the results, iterating again
    5.75 @@ -169,7 +182,7 @@
    5.76      if (need_page)
    5.77        reply();
    5.78      else
    5.79 -      _seek_pos = _yield(0);
    5.80 +      _yield(0);
    5.81    }
    5.82  }
    5.83  
    5.84 @@ -285,7 +298,7 @@
    5.85  
    5.86    /* Test for a termination request. */
    5.87  
    5.88 -  if (_terminating())
    5.89 +  if (_terminating)
    5.90      return DIRENT_ABORT;
    5.91  
    5.92    /* Test the requested start position. If it is before the current entry,
    5.93 @@ -405,7 +418,7 @@
    5.94    /* Deliver the end position to the caller, waiting for the new start position
    5.95       before continuing. */
    5.96  
    5.97 -  _seek_pos = _yield(_buffer_size);
    5.98 +  _yield(_buffer_size);
    5.99  
   5.100    /* Start any new page from the beginning. */
   5.101  
   5.102 @@ -414,45 +427,40 @@
   5.103  
   5.104  
   5.105  
   5.106 -/* Send parameters to the thread. */
   5.107 -
   5.108 -size_t Fs_directory_listing::_read(size_t seek_pos)
   5.109 -{
   5.110 -  l4_utcb_mr()->mr[0] = seek_pos;
   5.111 -
   5.112 -  if (l4_error(l4_ipc_call(_thread_ep, l4_utcb(),
   5.113 -                           l4_msgtag(Fsdir_op_read, 1, 0, 0),
   5.114 -                           L4_IPC_NEVER)))
   5.115 -    return 0;
   5.116 -
   5.117 -  return l4_utcb_mr()->mr[0];
   5.118 -}
   5.119 -
   5.120 -/* Indicate termination. */
   5.121 -
   5.122 -int Fs_directory_listing::_terminating()
   5.123 -{
   5.124 -  return l4_msgtag_label(_tag) == Fsdir_op_terminate;
   5.125 -}
   5.126 -
   5.127  /* Wait for parameters. */
   5.128  
   5.129 -size_t Fs_directory_listing::_wait()
   5.130 +void Fs_directory_listing::_wait()
   5.131  {
   5.132 -  _tag = ipc_server_wait((l4_umword_t) this);
   5.133 +  l4_umword_t label = 0;
   5.134 +  ipc_message_t msg;
   5.135  
   5.136 -  return l4_utcb_mr()->mr[0];
   5.137 +  while ((label & ~3UL) != l4_umword_t(this))
   5.138 +    ipc_message_wait(&msg, &label);
   5.139 +
   5.140 +  /* Invoke the appropriate method. */
   5.141 +
   5.142 +  handle_DirectoryListingPrivate(&msg, this);
   5.143  }
   5.144  
   5.145  /* Yield control and wait to regain control again. */
   5.146  
   5.147 -size_t Fs_directory_listing::_yield(size_t read)
   5.148 +void Fs_directory_listing::_yield(size_t read)
   5.149  {
   5.150 -  l4_utcb_mr()->mr[0] = read;
   5.151 +  /* Complete the read operation, reply and wait.
   5.152 +     NOTE: A special "reply" label is used. */
   5.153 +
   5.154 +  complete_DirectoryListingPrivate_read(L4_INVALID_CAP | L4_SYSF_REPLY, read);
   5.155 +  _wait();
   5.156 +}
   5.157  
   5.158 -  /* Reply with one message word. */
   5.159 +long Fs_directory_listing::read(size_t position)
   5.160 +{
   5.161 +  _seek_pos = position;
   5.162 +  return L4_EOK;
   5.163 +}
   5.164  
   5.165 -  util_ipc_reply(l4_msgtag(0, 1, 0, 0));
   5.166 -
   5.167 -  return _wait();
   5.168 +long Fs_directory_listing::terminate()
   5.169 +{
   5.170 +  _terminating = true;
   5.171 +  return L4_EOK;
   5.172  }