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 }