1.1 --- a/docs/wiki/Components Fri May 10 21:51:44 2024 +0200
1.2 +++ b/docs/wiki/Components Sat May 11 01:48:03 2024 +0200
1.3 @@ -348,7 +348,7 @@
1.4 Directory -> Reader1;
1.5 Reader1 -> Client2;
1.6
1.7 - Client3 -> Reader2 [label="current_region()"];
1.8 + Client3 -> Reader2 [label="refresh()"];
1.9 Reader3 -> Memory -> Client4;
1.10 }
1.11 }}}
1.12 @@ -360,7 +360,7 @@
1.13
1.14 {{{
1.15 reader = directory.opendir()
1.16 -reader.current_region()
1.17 +reader.refresh()
1.18 entries = reader.read() # this being a memory access operation
1.19 }}}
1.20
1.21 @@ -397,14 +397,13 @@
1.22 fully populated region. Naturally, the reader may not advance ahead of the
1.23 writer.
1.24
1.25 -Pipes implement the `Pipe` interface and a number of operations to support
1.26 -this interaction mechanism.
1.27 +Pipes implement a number of operations to support this interaction mechanism.
1.28
1.29 The details of an endpoint's current region can be queried using the following
1.30 -operation:
1.31 +operation from the `Flush` interface:
1.32
1.33 {{{
1.34 -current_region(inout offset_t position, out offset_t populated_size, out offset_t size)
1.35 +refresh(out offset_t position, out offset_t size, out offset_t region_size)
1.36 }}}
1.37
1.38 This provides details of the recorded access position in a region, the
1.39 @@ -413,7 +412,7 @@
1.40 the same.
1.41
1.42 Navigation to the next available region of the pipe is performed using the
1.43 -following operation:
1.44 +following operation from the `Pipe` interface:
1.45
1.46 {{{
1.47 next_region(inout offset_t populated_size, out offset_t size)
2.1 --- a/libfsclient/include/fsclient/file.h Fri May 10 21:51:44 2024 +0200
2.2 +++ b/libfsclient/include/fsclient/file.h Sat May 11 01:48:03 2024 +0200
2.3 @@ -114,13 +114,17 @@
2.4 /* File and region operations. */
2.5
2.6 long file_flush(file_t *file);
2.7 +long file_refresh(file_t *file);
2.8 +
2.9 long file_mmap(file_t *file, offset_t position, offset_t length,
2.10 offset_t start_visible, offset_t end_visible,
2.11 rm_flags_t region_flags);
2.12 long file_mmap_only(file_t *file, offset_t position, offset_t length,
2.13 offset_t start_visible, offset_t end_visible);
2.14 +
2.15 flags_t file_opening_flags(rm_flags_t rm_flags);
2.16 rm_flags_t file_region_flags(flags_t flags);
2.17 +
2.18 long file_resize(file_t *file, offset_t size);
2.19
2.20 /* File and region properties. */
3.1 --- a/libfsclient/lib/src/client.cc Fri May 10 21:51:44 2024 +0200
3.2 +++ b/libfsclient/lib/src/client.cc Sat May 11 01:48:03 2024 +0200
3.3 @@ -281,10 +281,7 @@
3.4 /* Synchronise the state of the stream, testing for pipe-based access and
3.5 switching to memory mapped access if not supported. */
3.6
3.7 - long err = client_sync_stream(stream);
3.8 -
3.9 - if (err == -L4_EBADPROTO)
3.10 - stream->object_flags |= OBJECT_SUPPORTS_MMAP;
3.11 + client_sync_stream(stream);
3.12
3.13 /* Enforce blocking if necessary.
3.14 NOTE: Ignoring any event subscription error. */
3.15 @@ -314,7 +311,13 @@
3.16 if (!client_opened(file))
3.17 return -L4_EINVAL;
3.18
3.19 - return pipe_current(file, 1);
3.20 + long err = pipe_current(file, 1);
3.21 +
3.22 + if (err != -L4_EBADPROTO)
3.23 + return err;
3.24 +
3.25 + file->object_flags |= OBJECT_SUPPORTS_MMAP;
3.26 + return file_refresh(file);
3.27 }
3.28
3.29
4.1 --- a/libfsclient/lib/src/file.cc Fri May 10 21:51:44 2024 +0200
4.2 +++ b/libfsclient/lib/src/file.cc Sat May 11 01:48:03 2024 +0200
4.3 @@ -62,6 +62,11 @@
4.4
4.5 else
4.6 file->data_end = 0;
4.7 +
4.8 + /* Reset the current position if a region is empty. */
4.9 +
4.10 + if (!file->data_end)
4.11 + file->data_current = 0;
4.12 }
4.13
4.14
4.15 @@ -343,8 +348,7 @@
4.16
4.17
4.18
4.19 -/* Flush populated data and obtain an updated file size and populated data
4.20 - details. */
4.21 +/* Flush populated data and obtain an updated file size. */
4.22
4.23 long file_flush(file_t *file)
4.24 {
4.25 @@ -362,6 +366,24 @@
4.26 return L4_EOK;
4.27 }
4.28
4.29 +/* Refresh position and size data from the file or pipe. */
4.30 +
4.31 +long file_refresh(file_t *file)
4.32 +{
4.33 + if (l4_is_invalid_cap(file->ref))
4.34 + return -L4_EINVAL;
4.35 +
4.36 + client_Flush _file(file->ref);
4.37 + long err = _file.refresh(&file->data_current, &file->size, &file->end_pos);
4.38 +
4.39 + if (err)
4.40 + return err;
4.41 +
4.42 + _update_extent(file);
4.43 +
4.44 + return L4_EOK;
4.45 +}
4.46 +
4.47 /* Map a region of the given file to a memory region, obtaining an updated file
4.48 size and populated data details. Unmap any previously mapped region. */
4.49
4.50 @@ -449,7 +471,7 @@
4.51 return rm_flags;
4.52 }
4.53
4.54 -/* Resize a file, obtaining updated file size and populated data details. */
4.55 +/* Resize a file, obtaining updated file size details. */
4.56
4.57 long file_resize(file_t *file, offset_t size)
4.58 {
4.59 @@ -682,25 +704,20 @@
4.60
4.61 long pipe_current(file_t *pipe, int sync)
4.62 {
4.63 - client_Pipe _pipe(pipe->ref);
4.64 + client_Flush _pipe(pipe->ref);
4.65 offset_t data_current;
4.66 - long err = _pipe.current_region(&data_current, &pipe->data_end, &pipe->size);
4.67 + long err = _pipe.refresh(&data_current, &pipe->size, &pipe->end_pos);
4.68
4.69 if (err)
4.70 return err;
4.71
4.72 - pipe->end_pos = pipe->size;
4.73 + _update_extent(pipe);
4.74
4.75 /* Obtain the current position if synchronising position state. */
4.76
4.77 if (sync)
4.78 pipe->data_current = data_current;
4.79
4.80 - /* Handle any case where the current region has been exhausted. */
4.81 -
4.82 - if (!file_populated_span(pipe))
4.83 - pipe->data_current = 0;
4.84 -
4.85 /* Attach memory if necessary. */
4.86
4.87 if (pipe->memory == NULL)
4.88 @@ -714,23 +731,26 @@
4.89 }
4.90
4.91 /* Access the next region for a pipe endpoint, updating the eventual size of
4.92 - the current region. */
4.93 + the current region if writing. */
4.94
4.95 long pipe_next(file_t *pipe)
4.96 {
4.97 client_Pipe _pipe(pipe->ref);
4.98 - long err = _pipe.next_region(&pipe->data_end, &pipe->size);
4.99 + offset_t size = pipe->data_current;
4.100 + long err = _pipe.next_region(&size, &pipe->end_pos);
4.101
4.102 if (err)
4.103 return err;
4.104
4.105 + pipe->size = size;
4.106 + _update_extent(pipe);
4.107 +
4.108 if (pipe->memory != NULL)
4.109 err = ipc_detach_dataspace(pipe->memory);
4.110
4.111 if (err)
4.112 return err;
4.113
4.114 - pipe->end_pos = pipe->size;
4.115 pipe->data_current = 0;
4.116 pipe->memory = NULL;
4.117
5.1 --- a/libfsserver/include/fsserver/file_pager.h Fri May 10 21:51:44 2024 +0200
5.2 +++ b/libfsserver/include/fsserver/file_pager.h Sat May 11 01:48:03 2024 +0200
5.3 @@ -34,6 +34,7 @@
5.4 protected:
5.5 FileProvider *_provider;
5.6 flags_t _flags;
5.7 + offset_t _data_current;
5.8
5.9 /* Notification endpoint for event subscription. */
5.10
5.11 @@ -61,10 +62,15 @@
5.12 void *interface()
5.13 { return static_cast<MappedFileObject *>(this); }
5.14
5.15 - /* File methods. */
5.16 + /* Flush methods. */
5.17
5.18 virtual long flush(offset_t position, offset_t *size);
5.19
5.20 + virtual long refresh(offset_t *position, offset_t *populated_size,
5.21 + offset_t *region_size);
5.22 +
5.23 + /* File methods. */
5.24 +
5.25 virtual long reopen(flags_t flags, offset_t *size, l4_cap_idx_t *file,
5.26 object_flags_t *object_flags);
5.27
6.1 --- a/libfsserver/include/fsserver/pipe_pager.h Fri May 10 21:51:44 2024 +0200
6.2 +++ b/libfsserver/include/fsserver/pipe_pager.h Sat May 11 01:48:03 2024 +0200
6.3 @@ -1,7 +1,7 @@
6.4 /*
6.5 * A pipe pager providing access to pipe content and navigation support.
6.6 *
6.7 - * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
6.8 + * Copyright (C) 2021, 2022, 2023, 2024 Paul Boddie <paul@boddie.org.uk>
6.9 *
6.10 * This program is free software; you can redistribute it and/or
6.11 * modify it under the terms of the GNU General Public License as
6.12 @@ -66,14 +66,14 @@
6.13
6.14 virtual long closed(int *closed);
6.15
6.16 - virtual long current_region(offset_t *position, offset_t *populated_size, offset_t *size);
6.17 -
6.18 virtual long next_region(offset_t *populated_size, offset_t *size);
6.19
6.20 /* Flushing/synchronisation. */
6.21
6.22 virtual long flush(offset_t position, offset_t *size);
6.23
6.24 + virtual long refresh(offset_t *position, offset_t *populated_size, offset_t *size);
6.25 +
6.26 /* Notification methods. */
6.27
6.28 virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags);
7.1 --- a/libfsserver/lib/files/file_pager.cc Fri May 10 21:51:44 2024 +0200
7.2 +++ b/libfsserver/lib/files/file_pager.cc Sat May 11 01:48:03 2024 +0200
7.3 @@ -37,6 +37,10 @@
7.4 : Pager(provider->mapper(), file_region_flags(flags)),
7.5 _provider(provider), _flags(flags), fileid(fileid)
7.6 {
7.7 + /* Initialise any recorded position in the mapped region for this
7.8 + endpoint. */
7.9 +
7.10 + _data_current = 0;
7.11 }
7.12
7.13 ipc_server_default_config_type FilePager::config()
7.14 @@ -62,12 +66,14 @@
7.15
7.16
7.17
7.18 -/* File-specific operations. */
7.19 +/* Flush operations. */
7.20
7.21 long FilePager::flush(offset_t position, offset_t *size)
7.22 {
7.23 long err = Pager::flush(position, size);
7.24
7.25 + _data_current = position;
7.26 +
7.27 if (_resized)
7.28 {
7.29 _provider->notify_others(_notifier, NOTIFY_CONTENT_AVAILABLE, NOTIFY_VALUES_NULL);
7.30 @@ -77,6 +83,20 @@
7.31 return err;
7.32 }
7.33
7.34 +long FilePager::refresh(offset_t *position, offset_t *size,
7.35 + offset_t *region_size)
7.36 +{
7.37 + *position = _data_current;
7.38 + *size = _mapper->get_data_size();
7.39 + *region_size = _size;
7.40 +
7.41 + return L4_EOK;
7.42 +}
7.43 +
7.44 +
7.45 +
7.46 +/* File-specific operations. */
7.47 +
7.48 long FilePager::reopen(flags_t flags, offset_t *size, l4_cap_idx_t *file,
7.49 object_flags_t *object_flags)
7.50 {
8.1 --- a/libfsserver/lib/pipes/pipe_pager.cc Fri May 10 21:51:44 2024 +0200
8.2 +++ b/libfsserver/lib/pipes/pipe_pager.cc Sat May 11 01:48:03 2024 +0200
8.3 @@ -36,7 +36,8 @@
8.4
8.5 _size = _paging->region_size();
8.6
8.7 - /* Initialise any recorded position in the region. */
8.8 + /* Initialise any recorded position in the mapped region for this
8.9 + endpoint. */
8.10
8.11 _data_current = 0;
8.12
8.13 @@ -96,7 +97,7 @@
8.14
8.15 /* Return details of the current region. */
8.16
8.17 -long PipePager::current_region(offset_t *position, offset_t *populated_size, offset_t *size)
8.18 +long PipePager::refresh(offset_t *position, offset_t *populated_size, offset_t *size)
8.19 {
8.20 if (_mapper != NULL)
8.21 {
8.22 @@ -133,7 +134,7 @@
8.23 _mapper = mapper;
8.24 _data_current = 0;
8.25
8.26 - return current_region(NULL, populated_size, size);
8.27 + return refresh(NULL, populated_size, size);
8.28 }
8.29
8.30 long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size)
8.31 @@ -153,7 +154,7 @@
8.32 _mapper = mapper;
8.33 _data_current = 0;
8.34
8.35 - return current_region(NULL, populated_size, size);
8.36 + return refresh(NULL, populated_size, size);
8.37 }
8.38
8.39 long PipePager::pipe_error()
9.1 --- a/libsystypes/idl/flush.idl Fri May 10 21:51:44 2024 +0200
9.2 +++ b/libsystypes/idl/flush.idl Sat May 11 01:48:03 2024 +0200
9.3 @@ -9,4 +9,10 @@
9.4 indicates the point from which data is being consumed by a client. */
9.5
9.6 [opcode(5)] void flush(in offset_t position, out offset_t size);
9.7 +
9.8 + /* Refresh any recorded position and size information, also obtaining the span
9.9 + of the mapped region used to access the file or pipe. */
9.10 +
9.11 + [opcode(16)] void refresh(out offset_t position, out offset_t size,
9.12 + out offset_t region_size);
9.13 };
10.1 --- a/libsystypes/idl/pipe.idl Fri May 10 21:51:44 2024 +0200
10.2 +++ b/libsystypes/idl/pipe.idl Sat May 11 01:48:03 2024 +0200
10.3 @@ -4,12 +4,11 @@
10.4
10.5 interface Pipe
10.6 {
10.7 - /* Obtain details of the current region of shared memory. */
10.8 + /* Advance to the next region of shared memory, indicating and obtaining the
10.9 + populated limit of the region and obtaining the region size.
10.10
10.11 - [opcode(16)] void current_region(out offset_t position, out offset_t populated_size, out offset_t size);
10.12 -
10.13 - /* Advance to the next region of shared memory, indicating and obtaining the
10.14 - populated limit of the region and obtaining the region size. */
10.15 + The current region details are available via the Flush interface's refresh
10.16 + operation. */
10.17
10.18 [opcode(17)] void next_region(inout offset_t populated_size, out offset_t size);
10.19