# HG changeset patch # User Paul Boddie # Date 1715384883 -7200 # Node ID 5c1c19c5e2a39cbb563c87516b25de024f07cd88 # Parent d9ea3cac8ace0dca5a7c9f46b085ee8659f3bd8d# Parent d7e231b756a5ee9342c5c4f720c877ad2b592b50 Merged changes from the default branch. diff -r d9ea3cac8ace -r 5c1c19c5e2a3 docs/wiki/Components --- a/docs/wiki/Components Fri May 10 21:51:44 2024 +0200 +++ b/docs/wiki/Components Sat May 11 01:48:03 2024 +0200 @@ -348,7 +348,7 @@ Directory -> Reader1; Reader1 -> Client2; - Client3 -> Reader2 [label="current_region()"]; + Client3 -> Reader2 [label="refresh()"]; Reader3 -> Memory -> Client4; } }}} @@ -360,7 +360,7 @@ {{{ reader = directory.opendir() -reader.current_region() +reader.refresh() entries = reader.read() # this being a memory access operation }}} @@ -397,14 +397,13 @@ fully populated region. Naturally, the reader may not advance ahead of the writer. -Pipes implement the `Pipe` interface and a number of operations to support -this interaction mechanism. +Pipes implement a number of operations to support this interaction mechanism. The details of an endpoint's current region can be queried using the following -operation: +operation from the `Flush` interface: {{{ -current_region(inout offset_t position, out offset_t populated_size, out offset_t size) +refresh(out offset_t position, out offset_t size, out offset_t region_size) }}} This provides details of the recorded access position in a region, the @@ -413,7 +412,7 @@ the same. Navigation to the next available region of the pipe is performed using the -following operation: +following operation from the `Pipe` interface: {{{ next_region(inout offset_t populated_size, out offset_t size) diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libfsclient/include/fsclient/file.h --- a/libfsclient/include/fsclient/file.h Fri May 10 21:51:44 2024 +0200 +++ b/libfsclient/include/fsclient/file.h Sat May 11 01:48:03 2024 +0200 @@ -114,13 +114,17 @@ /* File and region operations. */ long file_flush(file_t *file); +long file_refresh(file_t *file); + long file_mmap(file_t *file, offset_t position, offset_t length, offset_t start_visible, offset_t end_visible, rm_flags_t region_flags); long file_mmap_only(file_t *file, offset_t position, offset_t length, offset_t start_visible, offset_t end_visible); + flags_t file_opening_flags(rm_flags_t rm_flags); rm_flags_t file_region_flags(flags_t flags); + long file_resize(file_t *file, offset_t size); /* File and region properties. */ diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libfsclient/lib/src/client.cc --- a/libfsclient/lib/src/client.cc Fri May 10 21:51:44 2024 +0200 +++ b/libfsclient/lib/src/client.cc Sat May 11 01:48:03 2024 +0200 @@ -281,10 +281,7 @@ /* Synchronise the state of the stream, testing for pipe-based access and switching to memory mapped access if not supported. */ - long err = client_sync_stream(stream); - - if (err == -L4_EBADPROTO) - stream->object_flags |= OBJECT_SUPPORTS_MMAP; + client_sync_stream(stream); /* Enforce blocking if necessary. NOTE: Ignoring any event subscription error. */ @@ -314,7 +311,13 @@ if (!client_opened(file)) return -L4_EINVAL; - return pipe_current(file, 1); + long err = pipe_current(file, 1); + + if (err != -L4_EBADPROTO) + return err; + + file->object_flags |= OBJECT_SUPPORTS_MMAP; + return file_refresh(file); } diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libfsclient/lib/src/file.cc --- a/libfsclient/lib/src/file.cc Fri May 10 21:51:44 2024 +0200 +++ b/libfsclient/lib/src/file.cc Sat May 11 01:48:03 2024 +0200 @@ -62,6 +62,11 @@ else file->data_end = 0; + + /* Reset the current position if a region is empty. */ + + if (!file->data_end) + file->data_current = 0; } @@ -343,8 +348,7 @@ -/* Flush populated data and obtain an updated file size and populated data - details. */ +/* Flush populated data and obtain an updated file size. */ long file_flush(file_t *file) { @@ -362,6 +366,24 @@ return L4_EOK; } +/* Refresh position and size data from the file or pipe. */ + +long file_refresh(file_t *file) +{ + if (l4_is_invalid_cap(file->ref)) + return -L4_EINVAL; + + client_Flush _file(file->ref); + long err = _file.refresh(&file->data_current, &file->size, &file->end_pos); + + if (err) + return err; + + _update_extent(file); + + return L4_EOK; +} + /* Map a region of the given file to a memory region, obtaining an updated file size and populated data details. Unmap any previously mapped region. */ @@ -449,7 +471,7 @@ return rm_flags; } -/* Resize a file, obtaining updated file size and populated data details. */ +/* Resize a file, obtaining updated file size details. */ long file_resize(file_t *file, offset_t size) { @@ -682,25 +704,20 @@ long pipe_current(file_t *pipe, int sync) { - client_Pipe _pipe(pipe->ref); + client_Flush _pipe(pipe->ref); offset_t data_current; - long err = _pipe.current_region(&data_current, &pipe->data_end, &pipe->size); + long err = _pipe.refresh(&data_current, &pipe->size, &pipe->end_pos); if (err) return err; - pipe->end_pos = pipe->size; + _update_extent(pipe); /* Obtain the current position if synchronising position state. */ if (sync) pipe->data_current = data_current; - /* Handle any case where the current region has been exhausted. */ - - if (!file_populated_span(pipe)) - pipe->data_current = 0; - /* Attach memory if necessary. */ if (pipe->memory == NULL) @@ -714,23 +731,26 @@ } /* Access the next region for a pipe endpoint, updating the eventual size of - the current region. */ + the current region if writing. */ long pipe_next(file_t *pipe) { client_Pipe _pipe(pipe->ref); - long err = _pipe.next_region(&pipe->data_end, &pipe->size); + offset_t size = pipe->data_current; + long err = _pipe.next_region(&size, &pipe->end_pos); if (err) return err; + pipe->size = size; + _update_extent(pipe); + if (pipe->memory != NULL) err = ipc_detach_dataspace(pipe->memory); if (err) return err; - pipe->end_pos = pipe->size; pipe->data_current = 0; pipe->memory = NULL; diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libfsserver/include/fsserver/file_pager.h --- a/libfsserver/include/fsserver/file_pager.h Fri May 10 21:51:44 2024 +0200 +++ b/libfsserver/include/fsserver/file_pager.h Sat May 11 01:48:03 2024 +0200 @@ -34,6 +34,7 @@ protected: FileProvider *_provider; flags_t _flags; + offset_t _data_current; /* Notification endpoint for event subscription. */ @@ -61,10 +62,15 @@ void *interface() { return static_cast(this); } - /* File methods. */ + /* Flush methods. */ virtual long flush(offset_t position, offset_t *size); + virtual long refresh(offset_t *position, offset_t *populated_size, + offset_t *region_size); + + /* File methods. */ + virtual long reopen(flags_t flags, offset_t *size, l4_cap_idx_t *file, object_flags_t *object_flags); diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libfsserver/include/fsserver/pipe_pager.h --- a/libfsserver/include/fsserver/pipe_pager.h Fri May 10 21:51:44 2024 +0200 +++ b/libfsserver/include/fsserver/pipe_pager.h Sat May 11 01:48:03 2024 +0200 @@ -1,7 +1,7 @@ /* * A pipe pager providing access to pipe content and navigation support. * - * Copyright (C) 2021, 2022, 2023 Paul Boddie + * Copyright (C) 2021, 2022, 2023, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -66,14 +66,14 @@ virtual long closed(int *closed); - virtual long current_region(offset_t *position, offset_t *populated_size, offset_t *size); - virtual long next_region(offset_t *populated_size, offset_t *size); /* Flushing/synchronisation. */ virtual long flush(offset_t position, offset_t *size); + virtual long refresh(offset_t *position, offset_t *populated_size, offset_t *size); + /* Notification methods. */ virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libfsserver/lib/files/file_pager.cc --- a/libfsserver/lib/files/file_pager.cc Fri May 10 21:51:44 2024 +0200 +++ b/libfsserver/lib/files/file_pager.cc Sat May 11 01:48:03 2024 +0200 @@ -37,6 +37,10 @@ : Pager(provider->mapper(), file_region_flags(flags)), _provider(provider), _flags(flags), fileid(fileid) { + /* Initialise any recorded position in the mapped region for this + endpoint. */ + + _data_current = 0; } ipc_server_default_config_type FilePager::config() @@ -62,12 +66,14 @@ -/* File-specific operations. */ +/* Flush operations. */ long FilePager::flush(offset_t position, offset_t *size) { long err = Pager::flush(position, size); + _data_current = position; + if (_resized) { _provider->notify_others(_notifier, NOTIFY_CONTENT_AVAILABLE, NOTIFY_VALUES_NULL); @@ -77,6 +83,20 @@ return err; } +long FilePager::refresh(offset_t *position, offset_t *size, + offset_t *region_size) +{ + *position = _data_current; + *size = _mapper->get_data_size(); + *region_size = _size; + + return L4_EOK; +} + + + +/* File-specific operations. */ + long FilePager::reopen(flags_t flags, offset_t *size, l4_cap_idx_t *file, object_flags_t *object_flags) { diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libfsserver/lib/pipes/pipe_pager.cc --- a/libfsserver/lib/pipes/pipe_pager.cc Fri May 10 21:51:44 2024 +0200 +++ b/libfsserver/lib/pipes/pipe_pager.cc Sat May 11 01:48:03 2024 +0200 @@ -36,7 +36,8 @@ _size = _paging->region_size(); - /* Initialise any recorded position in the region. */ + /* Initialise any recorded position in the mapped region for this + endpoint. */ _data_current = 0; @@ -96,7 +97,7 @@ /* Return details of the current region. */ -long PipePager::current_region(offset_t *position, offset_t *populated_size, offset_t *size) +long PipePager::refresh(offset_t *position, offset_t *populated_size, offset_t *size) { if (_mapper != NULL) { @@ -133,7 +134,7 @@ _mapper = mapper; _data_current = 0; - return current_region(NULL, populated_size, size); + return refresh(NULL, populated_size, size); } long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size) @@ -153,7 +154,7 @@ _mapper = mapper; _data_current = 0; - return current_region(NULL, populated_size, size); + return refresh(NULL, populated_size, size); } long PipePager::pipe_error() diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libsystypes/idl/flush.idl --- a/libsystypes/idl/flush.idl Fri May 10 21:51:44 2024 +0200 +++ b/libsystypes/idl/flush.idl Sat May 11 01:48:03 2024 +0200 @@ -9,4 +9,10 @@ indicates the point from which data is being consumed by a client. */ [opcode(5)] void flush(in offset_t position, out offset_t size); + + /* Refresh any recorded position and size information, also obtaining the span + of the mapped region used to access the file or pipe. */ + + [opcode(16)] void refresh(out offset_t position, out offset_t size, + out offset_t region_size); }; diff -r d9ea3cac8ace -r 5c1c19c5e2a3 libsystypes/idl/pipe.idl --- a/libsystypes/idl/pipe.idl Fri May 10 21:51:44 2024 +0200 +++ b/libsystypes/idl/pipe.idl Sat May 11 01:48:03 2024 +0200 @@ -4,12 +4,11 @@ interface Pipe { - /* Obtain details of the current region of shared memory. */ + /* Advance to the next region of shared memory, indicating and obtaining the + populated limit of the region and obtaining the region size. - [opcode(16)] void current_region(out offset_t position, out offset_t populated_size, out offset_t size); - - /* Advance to the next region of shared memory, indicating and obtaining the - populated limit of the region and obtaining the region size. */ + The current region details are available via the Flush interface's refresh + operation. */ [opcode(17)] void next_region(inout offset_t populated_size, out offset_t size);