# HG changeset patch # User Paul Boddie # Date 1715447829 -7200 # Node ID 018a2139d27269542d79714ed628c74fdbe33289 # Parent d7e231b756a5ee9342c5c4f720c877ad2b592b50 Expanded the refresh operation to return the start and end positions of the mapped region along with the object flags. To properly synchronise a stream when acquiring it from another program, the client library now remaps the memory region after refreshing the stream details. diff -r d7e231b756a5 -r 018a2139d272 docs/wiki/Components --- a/docs/wiki/Components Sat May 11 01:47:53 2024 +0200 +++ b/docs/wiki/Components Sat May 11 19:17:09 2024 +0200 @@ -403,13 +403,14 @@ operation from the `Flush` interface: {{{ -refresh(out offset_t position, out offset_t size, out offset_t region_size) +refresh(out offset_t position, out offset_t start_pos, out offset_t end_pos, + out offset_t size, out object_flags_t object_flags) }}} -This provides details of the recorded access position in a region, the -populated size (or amount of written data) in a region along with the size of -the region. For a writing endpoint, the position and populated size will be -the same. +This provides details of the recorded access position in a region, the start +and end positions defining the span of a region, along with the populated size +(or amount of written data) in a region and the flags describing the object. +For a writing endpoint, the position and populated size will be the same. Navigation to the next available region of the pipe is performed using the following operation from the `Pipe` interface: diff -r d7e231b756a5 -r 018a2139d272 libfsclient/include/fsclient/file.h --- a/libfsclient/include/fsclient/file.h Sat May 11 01:47:53 2024 +0200 +++ b/libfsclient/include/fsclient/file.h Sat May 11 19:17:09 2024 +0200 @@ -166,7 +166,7 @@ /* Pipe region operations. */ -long pipe_current(file_t *pipe, int sync); +long pipe_current(file_t *pipe); long pipe_next(file_t *pipe); long pipe_written(file_t *pipe, offset_t size); diff -r d7e231b756a5 -r 018a2139d272 libfsclient/lib/src/client.cc --- a/libfsclient/lib/src/client.cc Sat May 11 01:47:53 2024 +0200 +++ b/libfsclient/lib/src/client.cc Sat May 11 19:17:09 2024 +0200 @@ -209,7 +209,7 @@ if (file->object_flags & OBJECT_SUPPORTS_MMAP) return client_mmap(file, client_tell(file), count, 0, 0, file_region_flags(file->flags)); - else if (pipe_current(file, 0)) + else if (pipe_current(file)) return NULL; } @@ -278,8 +278,7 @@ stream->flags = flags; stream->ref = ref; - /* Synchronise the state of the stream, testing for pipe-based access and - switching to memory mapped access if not supported. */ + /* Restore the state of the stream. */ client_sync_stream(stream); @@ -311,12 +310,6 @@ if (!client_opened(file)) return -L4_EINVAL; - long err = pipe_current(file, 1); - - if (err != -L4_EBADPROTO) - return err; - - file->object_flags |= OBJECT_SUPPORTS_MMAP; return file_refresh(file); } @@ -568,7 +561,7 @@ if (!client_opened(file)) return -L4_EINVAL; - return pipe_current(file, 0); + return pipe_current(file); } diff -r d7e231b756a5 -r 018a2139d272 libfsclient/lib/src/file.cc --- a/libfsclient/lib/src/file.cc Sat May 11 01:47:53 2024 +0200 +++ b/libfsclient/lib/src/file.cc Sat May 11 19:17:09 2024 +0200 @@ -374,14 +374,38 @@ return -L4_EINVAL; client_Flush _file(file->ref); - long err = _file.refresh(&file->data_current, &file->size, &file->end_pos); + long err; + + /* Unmap any existing region since the endpoint may have been reconfigured. */ + + if (file->memory != NULL) + { + err = ipc_detach_dataspace(file->memory); + if (err) + return err; + + file->memory = NULL; + } + + /* Obtain the new details for the region. */ + + err = _file.refresh(&file->data_current, &file->start_pos, &file->end_pos, + &file->size, &file->object_flags); if (err) return err; _update_extent(file); - return L4_EOK; + /* Attempt to map any replacement region. */ + + if (!file_span(file)) + return L4_EOK; + + return ipc_attach_dataspace_align(file->ref, file_span(file), + L4RE_RM_F_SEARCH_ADDR | file_region_flags(file->flags), + L4_PAGESHIFT, + (void **) &file->memory); } /* Map a region of the given file to a memory region, obtaining an updated file @@ -407,14 +431,10 @@ if (err) return err; - err = ipc_attach_dataspace_align(file->ref, file_span(file), - L4RE_RM_F_SEARCH_ADDR | region_flags, - L4_PAGESHIFT, - (void **) &file->memory); - if (err) - return err; - - return L4_EOK; + return ipc_attach_dataspace_align(file->ref, file_span(file), + L4RE_RM_F_SEARCH_ADDR | region_flags, + L4_PAGESHIFT, + (void **) &file->memory); } /* Request access to a region of the given file, obtaining an updated file size @@ -702,22 +722,22 @@ /* Access the current region for a pipe endpoint. */ -long pipe_current(file_t *pipe, int sync) +long pipe_current(file_t *pipe) { client_Flush _pipe(pipe->ref); + + /* The current position and flags are not updated by the refresh operation. */ + offset_t data_current; - long err = _pipe.refresh(&data_current, &pipe->size, &pipe->end_pos); + object_flags_t object_flags; + long err = _pipe.refresh(&data_current, &pipe->start_pos, &pipe->end_pos, + &pipe->size, &object_flags); if (err) return err; _update_extent(pipe); - /* Obtain the current position if synchronising position state. */ - - if (sync) - pipe->data_current = data_current; - /* Attach memory if necessary. */ if (pipe->memory == NULL) diff -r d7e231b756a5 -r 018a2139d272 libfsserver/include/fsserver/file_pager.h --- a/libfsserver/include/fsserver/file_pager.h Sat May 11 01:47:53 2024 +0200 +++ b/libfsserver/include/fsserver/file_pager.h Sat May 11 19:17:09 2024 +0200 @@ -34,6 +34,7 @@ protected: FileProvider *_provider; flags_t _flags; + object_flags_t _object_flags; offset_t _data_current; /* Notification endpoint for event subscription. */ @@ -51,7 +52,8 @@ public: fileid_t fileid; - explicit FilePager(fileid_t fileid, FileProvider *provider, flags_t flags); + explicit FilePager(fileid_t fileid, FileProvider *provider, flags_t flags, + object_flags_t object_flags); virtual void close(); @@ -66,8 +68,9 @@ virtual long flush(offset_t position, offset_t *size); - virtual long refresh(offset_t *position, offset_t *populated_size, - offset_t *region_size); + virtual long refresh(offset_t *position, offset_t *start_pos, + offset_t *end_pos, offset_t *size, + object_flags_t *object_flags); /* File methods. */ diff -r d7e231b756a5 -r 018a2139d272 libfsserver/include/fsserver/pipe_pager.h --- a/libfsserver/include/fsserver/pipe_pager.h Sat May 11 01:47:53 2024 +0200 +++ b/libfsserver/include/fsserver/pipe_pager.h Sat May 11 19:17:09 2024 +0200 @@ -60,7 +60,8 @@ /* Pager methods. */ - virtual long map(offset_t offset, map_address_t hot_spot, map_flags_t flags, l4_snd_fpage_t *region); + virtual long map(offset_t offset, map_address_t hot_spot, map_flags_t flags, + l4_snd_fpage_t *region); /* Pipe methods. */ @@ -72,7 +73,9 @@ virtual long flush(offset_t position, offset_t *size); - virtual long refresh(offset_t *position, offset_t *populated_size, offset_t *size); + virtual long refresh(offset_t *position, offset_t *start_pos, + offset_t *end_pos, offset_t *size, + object_flags_t *object_flags); /* Notification methods. */ diff -r d7e231b756a5 -r 018a2139d272 libfsserver/lib/files/file_pager.cc --- a/libfsserver/lib/files/file_pager.cc Sat May 11 01:47:53 2024 +0200 +++ b/libfsserver/lib/files/file_pager.cc Sat May 11 19:17:09 2024 +0200 @@ -33,9 +33,11 @@ opening flags and a file registry. The provider offers a shared page mapper for moderating access to loaded pages. */ -FilePager::FilePager(fileid_t fileid, FileProvider *provider, flags_t flags) +FilePager::FilePager(fileid_t fileid, FileProvider *provider, flags_t flags, + object_flags_t object_flags) : Pager(provider->mapper(), file_region_flags(flags)), - _provider(provider), _flags(flags), fileid(fileid) + _provider(provider), _flags(flags), _object_flags(object_flags), + fileid(fileid) { /* Initialise any recorded position in the mapped region for this endpoint. */ @@ -83,12 +85,14 @@ return err; } -long FilePager::refresh(offset_t *position, offset_t *size, - offset_t *region_size) +long FilePager::refresh(offset_t *position, offset_t *start_pos, offset_t *end_pos, + offset_t *size, object_flags_t *object_flags) { *position = _data_current; + *start_pos = _start; + *end_pos = _start + _size; *size = _mapper->get_data_size(); - *region_size = _size; + *object_flags = _object_flags; return L4_EOK; } diff -r d7e231b756a5 -r 018a2139d272 libfsserver/lib/files/file_provider.cc --- a/libfsserver/lib/files/file_provider.cc Sat May 11 01:47:53 2024 +0200 +++ b/libfsserver/lib/files/file_provider.cc Sat May 11 19:17:09 2024 +0200 @@ -1,7 +1,7 @@ /* * An object providing access to file functionality. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 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 @@ -63,16 +63,16 @@ object_flags_t *object_flags, Resource **resource) { + *object_flags = OBJECT_SUPPORTS_MMAP | OBJECT_HAS_SIZE; + /* Initialise the pager with the provider and a reference to this object for detaching from the provider. */ - FilePager *pager = new FilePager(_fileid, this, flags); + FilePager *pager = new FilePager(_fileid, this, flags, *object_flags); - /* Obtain the size details from the pager, also providing appropriate - flags. */ + /* Obtain the size details from the pager. */ *size = pager->get_data_size(); - *object_flags = OBJECT_SUPPORTS_MMAP | OBJECT_HAS_SIZE; this->attach(); *resource = pager; diff -r d7e231b756a5 -r 018a2139d272 libfsserver/lib/pipes/pipe_pager.cc --- a/libfsserver/lib/pipes/pipe_pager.cc Sat May 11 01:47:53 2024 +0200 +++ b/libfsserver/lib/pipes/pipe_pager.cc Sat May 11 19:17:09 2024 +0200 @@ -97,15 +97,24 @@ /* Return details of the current region. */ -long PipePager::refresh(offset_t *position, offset_t *populated_size, offset_t *size) +long PipePager::refresh(offset_t *position, offset_t *start_pos, + offset_t *end_pos, offset_t *size, + object_flags_t *object_flags) { if (_mapper != NULL) { if (position != NULL) *position = _data_current; - *populated_size = _mapper->get_data_size(); - *size = _size; + if (start_pos != NULL) + *start_pos = 0; + + *end_pos = _size; + *size = _mapper->get_data_size(); + + if (object_flags != NULL) + *object_flags = 0; + return L4_EOK; } else @@ -134,7 +143,7 @@ _mapper = mapper; _data_current = 0; - return refresh(NULL, populated_size, size); + return refresh(NULL, NULL, size, populated_size, NULL); } long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size) @@ -154,7 +163,7 @@ _mapper = mapper; _data_current = 0; - return refresh(NULL, populated_size, size); + return refresh(NULL, NULL, size, populated_size, NULL); } long PipePager::pipe_error() diff -r d7e231b756a5 -r 018a2139d272 libsystypes/idl/flush.idl --- a/libsystypes/idl/flush.idl Sat May 11 01:47:53 2024 +0200 +++ b/libsystypes/idl/flush.idl Sat May 11 19:17:09 2024 +0200 @@ -10,9 +10,12 @@ [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. */ + /* Refresh any recorded position information, also obtaining the span + of the mapped region used to access the file or pipe, along with updated + size information. To support the acquisition of files or pipes, the + object flags describing the object are returned. */ - [opcode(16)] void refresh(out offset_t position, out offset_t size, - out offset_t region_size); + [opcode(16)] void refresh(out offset_t position, out offset_t start_pos, + out offset_t end_pos, out offset_t size, + out object_flags_t object_flags); };