1.1 --- a/libfsserver/include/fsserver/file_pager.h Sun May 29 00:58:31 2022 +0200
1.2 +++ b/libfsserver/include/fsserver/file_pager.h Mon May 30 00:47:07 2022 +0200
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * File-specific pager functionality.
1.6 *
1.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or
1.11 * modify it under the terms of the GNU General Public License as
1.12 @@ -33,6 +33,7 @@
1.13 {
1.14 protected:
1.15 FileProvider *_provider;
1.16 + flags_t _flags;
1.17
1.18 /* Notification endpoint for event subscription. */
1.19
1.20 @@ -42,10 +43,14 @@
1.21
1.22 bool _resized = false;
1.23
1.24 + /* Helper methods. */
1.25 +
1.26 + bool copy_on_write();
1.27 +
1.28 public:
1.29 fileid_t fileid;
1.30
1.31 - explicit FilePager(fileid_t fileid, FileProvider *provider, map_flags_t flags);
1.32 + explicit FilePager(fileid_t fileid, FileProvider *provider, flags_t flags);
1.33
1.34 virtual void close();
1.35
2.1 --- a/libfsserver/include/fsserver/file_provider.h Sun May 29 00:58:31 2022 +0200
2.2 +++ b/libfsserver/include/fsserver/file_provider.h Mon May 30 00:47:07 2022 +0200
2.3 @@ -31,7 +31,6 @@
2.4 class FileProvider : public Provider
2.5 {
2.6 protected:
2.7 - map_flags_t _flags;
2.8 PageMapper *_mapper;
2.9
2.10 public:
2.11 @@ -42,7 +41,7 @@
2.12
2.13 virtual PageMapper *mapper();
2.14
2.15 - virtual long make_resource(map_flags_t flags, offset_t *size,
2.16 + virtual long make_resource(flags_t flags, offset_t *size,
2.17 object_flags_t *object_flags,
2.18 Resource **resource);
2.19
3.1 --- a/libfsserver/include/fsserver/pager.h Sun May 29 00:58:31 2022 +0200
3.2 +++ b/libfsserver/include/fsserver/pager.h Mon May 30 00:47:07 2022 +0200
3.3 @@ -35,16 +35,16 @@
3.4 protected:
3.5 offset_t _start, _size;
3.6 GenericPageMapper *_mapper, *_mapper_base, *_mapper_masked, *_mapper_copied;
3.7 - map_flags_t _flags;
3.8 + map_flags_t _map_flags;
3.9
3.10 public:
3.11 - explicit Pager(GenericPageMapper *mapper, map_flags_t flags);
3.12 + explicit Pager(GenericPageMapper *mapper, map_flags_t map_flags);
3.13
3.14 virtual void close();
3.15
3.16 /* Paging methods. */
3.17
3.18 - virtual long map(offset_t offset, address_t hot_spot, map_flags_t flags,
3.19 + virtual long map(offset_t offset, address_t hot_spot, map_flags_t map_flags,
3.20 l4_snd_fpage_t *region);
3.21
3.22 /* Limit methods. */
4.1 --- a/libfsserver/lib/files/file_pager.cc Sun May 29 00:58:31 2022 +0200
4.2 +++ b/libfsserver/lib/files/file_pager.cc Mon May 30 00:47:07 2022 +0200
4.3 @@ -19,18 +19,22 @@
4.4 * Boston, MA 02110-1301, USA
4.5 */
4.6
4.7 +#include <fsclient/file.h> /* file_region_flags */
4.8 +#include <systypes/fcntl.h>
4.9 +
4.10 +#include "copied_page_mapper.h"
4.11 #include "file_pager.h"
4.12 #include "mapped_file_object_server.h"
4.13
4.14
4.15
4.16 /* Initialise a pager for a file with a unique file identifier, file provider,
4.17 - mapping flags and a file registry. The provider offers a shared page mapper
4.18 + opening flags and a file registry. The provider offers a shared page mapper
4.19 for moderating access to loaded pages. */
4.20
4.21 -FilePager::FilePager(fileid_t fileid, FileProvider *provider, map_flags_t flags)
4.22 -: Pager(provider->mapper(), flags),
4.23 - _provider(provider), fileid(fileid)
4.24 +FilePager::FilePager(fileid_t fileid, FileProvider *provider, flags_t flags)
4.25 +: Pager(provider->mapper(), file_region_flags(flags)),
4.26 + _provider(provider), _flags(flags), fileid(fileid)
4.27 {
4.28 }
4.29
4.30 @@ -96,17 +100,37 @@
4.31 {
4.32 /* Set the limits of the paged region. */
4.33
4.34 - return Pager::mmap(position, length, start_visible, end_visible, start_pos,
4.35 - end_pos, size);
4.36 + long err = Pager::mmap(position, length, start_visible, end_visible, start_pos,
4.37 + end_pos, size);
4.38 +
4.39 + if (err)
4.40 + return err;
4.41 +
4.42 + /* Impose copy-on-write semantics where appropriate. */
4.43 +
4.44 + if ((_mapper != _mapper_copied) && copy_on_write())
4.45 + {
4.46 + _mapper_copied = new CopiedPageMapper(_mapper);
4.47 + _mapper = _mapper_copied;
4.48 + }
4.49 +
4.50 + return L4_EOK;
4.51 +}
4.52 +
4.53 +/* Return whether the pager should employ copy-on-write semantics. */
4.54 +
4.55 +bool FilePager::copy_on_write()
4.56 +{
4.57 + return (_flags == O_RDONLY) && (_map_flags & L4RE_DS_F_W);
4.58 }
4.59
4.60
4.61
4.62 /* Generic pager operations. */
4.63
4.64 -long FilePager::map(offset_t offset, address_t hot_spot, map_flags_t flags, l4_snd_fpage_t *region)
4.65 +long FilePager::map(offset_t offset, address_t hot_spot, map_flags_t map_flags, l4_snd_fpage_t *region)
4.66 {
4.67 - return Pager::map(offset, hot_spot, flags, region);
4.68 + return Pager::map(offset, hot_spot, map_flags, region);
4.69 }
4.70
4.71
5.1 --- a/libfsserver/lib/files/file_provider.cc Sun May 29 00:58:31 2022 +0200
5.2 +++ b/libfsserver/lib/files/file_provider.cc Mon May 30 00:47:07 2022 +0200
5.3 @@ -54,7 +54,7 @@
5.4
5.5 /* Return a file pager initialised with a provider, page mapper and accessor. */
5.6
5.7 -long FileProvider::make_resource(map_flags_t flags, offset_t *size,
5.8 +long FileProvider::make_resource(flags_t flags, offset_t *size,
5.9 object_flags_t *object_flags,
5.10 Resource **resource)
5.11 {
6.1 --- a/libfsserver/lib/generic/pager.cc Sun May 29 00:58:31 2022 +0200
6.2 +++ b/libfsserver/lib/generic/pager.cc Mon May 30 00:47:07 2022 +0200
6.3 @@ -31,11 +31,11 @@
6.4 /* Initialise the pager with a page mapper and the given flags controlling
6.5 access to a file. */
6.6
6.7 -Pager::Pager(GenericPageMapper *mapper, map_flags_t flags)
6.8 +Pager::Pager(GenericPageMapper *mapper, map_flags_t map_flags)
6.9 : _start(0), _size(0),
6.10 _mapper(mapper), _mapper_base(mapper), _mapper_masked(NULL),
6.11 _mapper_copied(NULL),
6.12 - _flags(flags)
6.13 + _map_flags(map_flags)
6.14 {
6.15 }
6.16
6.17 @@ -113,7 +113,7 @@
6.18 /* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot'
6.19 (flexpage offset). */
6.20
6.21 -long Pager::map(offset_t offset, address_t hot_spot, map_flags_t flags,
6.22 +long Pager::map(offset_t offset, address_t hot_spot, map_flags_t map_flags,
6.23 l4_snd_fpage_t *region)
6.24 {
6.25 offset_t file_offset = _start + offset;
6.26 @@ -123,17 +123,17 @@
6.27 NOTE: Permitting executable requests here. This needs to be configured
6.28 when opening the pager or by another means. */
6.29
6.30 - if (flags & (~(_flags | L4RE_DS_F_X)))
6.31 + if (map_flags & (~(_map_flags | L4RE_DS_F_X)))
6.32 return -L4_EACCESS;
6.33
6.34 /* Obtain a flexpage from the page mapper. */
6.35
6.36 - Flexpage *flexpage = _mapper->get(file_offset, flags);
6.37 + Flexpage *flexpage = _mapper->get(file_offset, map_flags);
6.38
6.39 /* Issue the flexpage via the IPC system. */
6.40
6.41 long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset,
6.42 - hot_spot, flags, region);
6.43 + hot_spot, map_flags, region);
6.44
6.45 if (!err)
6.46 err = complete_Dataspace_map(*region);
7.1 --- a/libfsserver/lib/generic/resource_registry.cc Sun May 29 00:58:31 2022 +0200
7.2 +++ b/libfsserver/lib/generic/resource_registry.cc Mon May 30 00:47:07 2022 +0200
7.3 @@ -23,7 +23,6 @@
7.4 #include "file_pager.h"
7.5 #include "resource_registry.h"
7.6
7.7 -#include <fsclient/file.h> /* file_region_flags */
7.8 #include <systypes/fcntl.h>
7.9
7.10
7.11 @@ -38,15 +37,6 @@
7.12
7.13
7.14
7.15 -/* Convert opening flags to map-compatible paging flags. */
7.16 -
7.17 -map_flags_t ResourceRegistry::get_flags(flags_t flags)
7.18 -{
7.19 - return file_region_flags(flags);
7.20 -}
7.21 -
7.22 -
7.23 -
7.24 /* Make a directory provider. */
7.25
7.26 long ResourceRegistry::make_directory_provider(FileOpening *opening,
7.27 @@ -168,7 +158,7 @@
7.28
7.29 /* Make a resource for the provider. */
7.30
7.31 - return provider->make_resource(get_flags(flags), size, object_flags, resource);
7.32 + return provider->make_resource(flags, size, object_flags, resource);
7.33 }
7.34
7.35 /* Request the removal of a filesystem object through any active provider or