Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2020-01-15 17:57:37 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2020-01-15 17:57:37 +0300
commit03da2db2ef9c9316dbdf541ee29ff0a5a9993da9 (patch)
treec8bd863602e5c612c1236b16984ae52e6f4a2fc6 /include/llfio/v2.0/mapped_file_handle.hpp
parent75cc45b6d26b3f96075e4b5e54b26be4c7eb6f51 (diff)
Fix long standing issue #28 where Windows would fail to map a read only file if it used address reservation.
Diffstat (limited to 'include/llfio/v2.0/mapped_file_handle.hpp')
-rw-r--r--include/llfio/v2.0/mapped_file_handle.hpp44
1 files changed, 35 insertions, 9 deletions
diff --git a/include/llfio/v2.0/mapped_file_handle.hpp b/include/llfio/v2.0/mapped_file_handle.hpp
index ff2b10af..7d7de349 100644
--- a/include/llfio/v2.0/mapped_file_handle.hpp
+++ b/include/llfio/v2.0/mapped_file_handle.hpp
@@ -80,19 +80,17 @@ file into the beginning of the reservation. The remainder of the pages may be in
and may generate a segfault, or they may automatically reflect any growth in the underlying
file. This is why `read()` and `write()` only know about the reservation size, and will read
and write memory up to that reservation size, without checking if the memory involved exists
-or not yet. You are guaranteed that `address()` will not return a new
+or not yet. You are guaranteed on POSIX only that `address()` will not return a new
value unless you truncate from a bigger length to a smaller length, or you call `reserve()`
with a new reservation or `truncate()` with a value bigger than the reservation.
-`maximum_extent()` reports the last truncated length of the mapped file (possibly by any process in
-the system) up to the reservation limit, NOT the maximum extent of the underlying file.
-When you know that another process has extended the file and you wish to map the newly appended
-data, you can call `update_map()` which guarantees that the mapping your
-process sees is up to date, rather than relying on any kernel-specific automatic mapping.
-Whether automatic or enforced by `update_map()`, the reservation limit will not be exceeded
-nor will `address()` suddenly return something different.
+`maximum_extent()` in mapped file handle is an alias for `update_map()`. `update_map()`
+fetches the maximum extent of the underlying file, and if it has changed from the map's
+length, the map is updated to match the underlying file, up to the reservation limit.
+You can of course explicitly call `update_map()` whenever you need the map to reflect
+changes to the maximum extent of the underlying file.
-It is thus up to you to detect that the reservation has been exhausted, and to
+It is up to you to detect that the reservation has been exhausted, and to
reserve a new reservation which will change the value returned by `address()`. This
entirely manual system is a bit tedious and cumbersome to use, but as mapping files
is an expensive operation given TLB shootdown, we leave it up to the end user to decide
@@ -103,6 +101,34 @@ not using this `mapped_file_handle` to write the new data. With unified page cac
mixing mapped and normal i/o is generally safe except at the end of a file where race
conditions and outright kernel bugs tend to abound. To avoid these, solely and exclusively
use a dedicated handle configured to atomic append only to do the appends.
+
+## Microsoft Windows only
+
+Microsoft Windows can have quite different semantics to POSIX, which are important to be
+aware of.
+
+On Windows, the length of any section object for a file can never exceed the maximum
+extent of the file. Open section objects therefore clamp the valid maximum extent of
+a file to no lower than the largest of the section objects open upon the file. This
+is enforced by Windows, which will return an error if you try to truncate a file to
+smaller than any of its section objects on the system.
+
+Windows only implements address space reservation for sections opened with write
+permissions. LLFIO names the section object backing every mapped file uniquely to
+the file's inode, and all those section objects are shared between all LLFIO processes
+for the current Windows session. This means that if any one process updates a section
+object's length, the section's length gets updated for all processes, and all maps
+of that section in all processes get automatically updated.
+
+This works great if, and only if, the very first mapping of any file is with a writable
+file handle, as that permits the global section object to be writable, and all other
+LLFIO processes then discover that writable global section object. If however the
+very first mapping of any file is with a read-only file handle, that creates a
+read-only section object, and that in turn **disables all address space reservation
+permanently for all processes** using that file.
+
+So long as you ensure that any shared mapped file is always opened first with writable
+privileges, which is usually the case, all works like POSIX on Microsoft Windows.
*/
class LLFIO_DECL mapped_file_handle : public file_handle
{