diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/memmap2 | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/memmap2')
-rw-r--r-- | vendor/memmap2/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | vendor/memmap2/CHANGELOG.md | 21 | ||||
-rw-r--r-- | vendor/memmap2/Cargo.lock | 2 | ||||
-rw-r--r-- | vendor/memmap2/Cargo.toml | 2 | ||||
-rw-r--r-- | vendor/memmap2/src/advice.rs | 216 | ||||
-rw-r--r-- | vendor/memmap2/src/lib.rs | 198 | ||||
-rw-r--r-- | vendor/memmap2/src/unix.rs | 12 |
7 files changed, 324 insertions, 129 deletions
diff --git a/vendor/memmap2/.cargo-checksum.json b/vendor/memmap2/.cargo-checksum.json index 429cb178c..c42c7f2d3 100644 --- a/vendor/memmap2/.cargo-checksum.json +++ b/vendor/memmap2/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"67640899b2caa11f3850b8e2669c19c0dd1171309f66ce44cc59c9278723daa5","Cargo.lock":"839badf10332e415a7435010fb7d93a7b35a71c9f80cc21b6266adc434da6739","Cargo.toml":"a978043b7232691abf6c43ed5bd0c6e8a2fee4411c20194d28c52d537c86c3c9","LICENSE-APACHE":"04ea4849dba9dcae07113850c6f1b1a69052c625210639914eee352023f750ad","LICENSE-MIT":"0d25d03b5ab49576178ad0cae7a2648d12c17ad0452fe49c07e55e4b59aa5257","README.md":"c7b3cd928f0d1a10faa255e2f84a2a06636e55ea3e7edd4f6334dd9215151205","examples/cat.rs":"ab0b575d19662e2d5b6c7cea2756b57530e495d56acdb4fd2b56c0ba4d768dfd","src/advice.rs":"aa1c1435ade0c093c6c2ace9fdfd549671c524b08897156e4f956084f0716156","src/lib.rs":"a0389856273f6040ce93e0038d8746bb10c4dfaa198c5fc45f4d042677431ec4","src/stub.rs":"691da940edbe807a815d4a6bb3233df01bca8ab12b306ce7d67c75b4baa14e26","src/unix.rs":"b6c87b45ab302abc3ba5baf4e5c7b37b5027adc1d70c1b91ad436033f7503354","src/windows.rs":"ba820e315a31cd74fee49fcf7606af0172c0817b4a0fe3b1d113024efa79684f"},"package":"f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6"}
\ No newline at end of file +{"files":{"CHANGELOG.md":"3ab3a2661e53cdd316a6f466d869e258afa558f26ba9dc51d3da15e84394d0b1","Cargo.lock":"fe9b4febc16ec66978076379ab0b04c6f3acc655114ebc94bf02ca408800a51d","Cargo.toml":"3108880d3a34b1b83fcd330249118a753acc4720e73267d0cfbaf906122b5e3c","LICENSE-APACHE":"04ea4849dba9dcae07113850c6f1b1a69052c625210639914eee352023f750ad","LICENSE-MIT":"0d25d03b5ab49576178ad0cae7a2648d12c17ad0452fe49c07e55e4b59aa5257","README.md":"c7b3cd928f0d1a10faa255e2f84a2a06636e55ea3e7edd4f6334dd9215151205","examples/cat.rs":"ab0b575d19662e2d5b6c7cea2756b57530e495d56acdb4fd2b56c0ba4d768dfd","src/advice.rs":"d617cd0fc8f6dbe25f146209021c3e10822c4216c112752d09353c5f3bf974d0","src/lib.rs":"985cd42fd1370deead0195b356de72266cc0721039f7afbd160544b64eef23ec","src/stub.rs":"691da940edbe807a815d4a6bb3233df01bca8ab12b306ce7d67c75b4baa14e26","src/unix.rs":"8bf6edabffbaed8bf878d3d8a5d3a79ae3a95e12a877d521dcbbc60403f81b60","src/windows.rs":"ba820e315a31cd74fee49fcf7606af0172c0817b4a0fe3b1d113024efa79684f"},"package":"deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375"}
\ No newline at end of file diff --git a/vendor/memmap2/CHANGELOG.md b/vendor/memmap2/CHANGELOG.md index 8772aaeff..99137b853 100644 --- a/vendor/memmap2/CHANGELOG.md +++ b/vendor/memmap2/CHANGELOG.md @@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [0.9.0] - 2023-10-03 +### Changed +- The `Advice` struct was split into two enums: `Advice` and `UncheckedAdvice`.<br> + `Advice` can be passed to safe `advise` and `advise_range` methods. + And `UncheckedAdvice` can be passed to unsafe `unchecked_advise` + and `unchecked_advise_range` methods.<br> + [@adamreichold](https://github.com/adamreichold) + +## [0.8.0] - 2023-09-25 +### Changed +- The `Advice` type is a struct and not an enum now. + [@adamreichold](https://github.com/adamreichold) + +### Fixed +- Some of the `Advise` variants were unsound and now require `unsafe` to be constructed. + [@adamreichold](https://github.com/adamreichold) + ## [0.7.1] - 2023-06-24 ### Fixed - Mapping beyond 4GB offset on 32 bit glibc. Linux-only. @@ -165,7 +182,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Removed - `winapi` dependency. [memmap-rs/pull/89](https://github.com/danburkert/memmap-rs/pull/89) -[Unreleased]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.7.1...HEAD +[Unreleased]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.9.0...HEAD +[0.9.0]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.8.0...v0.9.0 +[0.8.0]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.7.1...v0.8.0 [0.7.1]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.7.0...v0.7.1 [0.7.0]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.6.2...v0.7.0 [0.6.2]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.6.1...v0.6.2 diff --git a/vendor/memmap2/Cargo.lock b/vendor/memmap2/Cargo.lock index c53316443..5f93eb424 100644 --- a/vendor/memmap2/Cargo.lock +++ b/vendor/memmap2/Cargo.lock @@ -40,7 +40,7 @@ checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "memmap2" -version = "0.7.1" +version = "0.9.0" dependencies = [ "libc", "owning_ref", diff --git a/vendor/memmap2/Cargo.toml b/vendor/memmap2/Cargo.toml index 62030d7eb..005d8b080 100644 --- a/vendor/memmap2/Cargo.toml +++ b/vendor/memmap2/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2018" name = "memmap2" -version = "0.7.1" +version = "0.9.0" authors = [ "Dan Burkert <dan@danburkert.com>", "Yevhenii Reizner <razrfalcon@gmail.com>", diff --git a/vendor/memmap2/src/advice.rs b/vendor/memmap2/src/advice.rs index 0181615ef..4316058fc 100644 --- a/vendor/memmap2/src/advice.rs +++ b/vendor/memmap2/src/advice.rs @@ -1,8 +1,5 @@ -// The use statement is needed for the `cargo docs` -#[allow(unused_imports)] -use crate::{Mmap, MmapMut}; - -/// Values supported by [Mmap::advise] and [MmapMut::advise] functions. +/// Values supported by [`Mmap::advise`][crate::Mmap::advise] and [`MmapMut::advise`][crate::MmapMut::advise] functions. +/// /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. #[repr(i32)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] @@ -31,87 +28,6 @@ pub enum Advice { /// good idea to read some pages ahead.) WillNeed = libc::MADV_WILLNEED, - /// **MADV_DONTNEED** - /// - /// Do not expect access in the near future. (For the time - /// being, the application is finished with the given range, - /// so the kernel can free resources associated with it.) - /// - /// After a successful MADV_DONTNEED operation, the semantics - /// of memory access in the specified region are changed: - /// subsequent accesses of pages in the range will succeed, - /// but will result in either repopulating the memory contents - /// from the up-to-date contents of the underlying mapped file - /// (for shared file mappings, shared anonymous mappings, and - /// shmem-based techniques such as System V shared memory - /// segments) or zero-fill-on-demand pages for anonymous - /// private mappings. - /// - /// Note that, when applied to shared mappings, MADV_DONTNEED - /// might not lead to immediate freeing of the pages in the - /// range. The kernel is free to delay freeing the pages - /// until an appropriate moment. The resident set size (RSS) - /// of the calling process will be immediately reduced - /// however. - /// - /// **MADV_DONTNEED** cannot be applied to locked pages, Huge TLB - /// pages, or VM_PFNMAP pages. (Pages marked with the kernel- - /// internal VM_PFNMAP flag are special memory areas that are - /// not managed by the virtual memory subsystem. Such pages - /// are typically created by device drivers that map the pages - /// into user space.) - DontNeed = libc::MADV_DONTNEED, - - // - // The rest are Linux-specific - // - /// **MADV_FREE** - Linux (since Linux 4.5) and Darwin - /// - /// The application no longer requires the pages in the range - /// specified by addr and len. The kernel can thus free these - /// pages, but the freeing could be delayed until memory - /// pressure occurs. For each of the pages that has been - /// marked to be freed but has not yet been freed, the free - /// operation will be canceled if the caller writes into the - /// page. After a successful MADV_FREE operation, any stale - /// data (i.e., dirty, unwritten pages) will be lost when the - /// kernel frees the pages. However, subsequent writes to - /// pages in the range will succeed and then kernel cannot - /// free those dirtied pages, so that the caller can always - /// see just written data. If there is no subsequent write, - /// the kernel can free the pages at any time. Once pages in - /// the range have been freed, the caller will see zero-fill- - /// on-demand pages upon subsequent page references. - /// - /// The MADV_FREE operation can be applied only to private - /// anonymous pages (see mmap(2)). In Linux before version - /// 4.12, when freeing pages on a swapless system, the pages - /// in the given range are freed instantly, regardless of - /// memory pressure. - #[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios"))] - Free = libc::MADV_FREE, - - /// **MADV_REMOVE** - Linux only (since Linux 2.6.16) - /// - /// Free up a given range of pages and its associated backing - /// store. This is equivalent to punching a hole in the - /// corresponding byte range of the backing store (see - /// fallocate(2)). Subsequent accesses in the specified - /// address range will see bytes containing zero. - /// - /// The specified address range must be mapped shared and - /// writable. This flag cannot be applied to locked pages, - /// Huge TLB pages, or VM_PFNMAP pages. - /// - /// In the initial implementation, only tmpfs(5) was supported - /// **MADV_REMOVE**; but since Linux 3.5, any filesystem which - /// supports the fallocate(2) FALLOC_FL_PUNCH_HOLE mode also - /// supports MADV_REMOVE. Hugetlbfs fails with the error - /// EINVAL and other filesystems fail with the error - /// EOPNOTSUPP. - #[cfg(target_os = "linux")] - Remove = libc::MADV_REMOVE, - /// **MADV_DONTFORK** - Linux only (since Linux 2.6.16) /// /// Do not make the pages in this range available to the child @@ -316,10 +232,132 @@ pub enum Advice { /// with madvise() system call. #[cfg(any(target_os = "macos", target_os = "ios"))] ZeroWiredPages = libc::MADV_ZERO_WIRED_PAGES, +} + +/// Values supported by [`Mmap::unsafe_advise`][crate::Mmap::unsafe_advise] and [`MmapMut::unsafe_advise`][crate::MmapMut::unsafe_advise] functions. +/// +/// These flags can be passed to the [madvise (2)][man_page] system call +/// and effects on the mapped pages which are conceptually writes, +/// i.e. the change the observable contents of these pages which +/// implies undefined behaviour if the mapping is still borrowed. +/// +/// Hence, these potentially unsafe flags must be used with the unsafe +/// methods and the programmer has to justify that the code +/// does not keep any borrows of the mapping active while the mapped pages +/// are updated by the kernel's memory management subsystem. +/// +/// [man_page]: https://man7.org/linux/man-pages/man2/madvise.2.html +#[repr(i32)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum UncheckedAdvice { + /// **MADV_DONTNEED** + /// + /// Do not expect access in the near future. (For the time + /// being, the application is finished with the given range, + /// so the kernel can free resources associated with it.) + /// + /// After a successful MADV_DONTNEED operation, the semantics + /// of memory access in the specified region are changed: + /// subsequent accesses of pages in the range will succeed, + /// but will result in either repopulating the memory contents + /// from the up-to-date contents of the underlying mapped file + /// (for shared file mappings, shared anonymous mappings, and + /// shmem-based techniques such as System V shared memory + /// segments) or zero-fill-on-demand pages for anonymous + /// private mappings. + /// + /// Note that, when applied to shared mappings, MADV_DONTNEED + /// might not lead to immediate freeing of the pages in the + /// range. The kernel is free to delay freeing the pages + /// until an appropriate moment. The resident set size (RSS) + /// of the calling process will be immediately reduced + /// however. + /// + /// **MADV_DONTNEED** cannot be applied to locked pages, Huge TLB + /// pages, or VM_PFNMAP pages. (Pages marked with the kernel- + /// internal VM_PFNMAP flag are special memory areas that are + /// not managed by the virtual memory subsystem. Such pages + /// are typically created by device drivers that map the pages + /// into user space.) + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping when the pages + /// are freed results in undefined behaviour. + DontNeed = libc::MADV_DONTNEED, + + // + // The rest are Linux-specific + // + /// **MADV_FREE** - Linux (since Linux 4.5) and Darwin + /// + /// The application no longer requires the pages in the range + /// specified by addr and len. The kernel can thus free these + /// pages, but the freeing could be delayed until memory + /// pressure occurs. For each of the pages that has been + /// marked to be freed but has not yet been freed, the free + /// operation will be canceled if the caller writes into the + /// page. After a successful MADV_FREE operation, any stale + /// data (i.e., dirty, unwritten pages) will be lost when the + /// kernel frees the pages. However, subsequent writes to + /// pages in the range will succeed and then kernel cannot + /// free those dirtied pages, so that the caller can always + /// see just written data. If there is no subsequent write, + /// the kernel can free the pages at any time. Once pages in + /// the range have been freed, the caller will see zero-fill- + /// on-demand pages upon subsequent page references. + /// + /// The MADV_FREE operation can be applied only to private + /// anonymous pages (see mmap(2)). In Linux before version + /// 4.12, when freeing pages on a swapless system, the pages + /// in the given range are freed instantly, regardless of + /// memory pressure. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping while the pages + /// are still being freed results in undefined behaviour. + #[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios"))] + Free = libc::MADV_FREE, + + /// **MADV_REMOVE** - Linux only (since Linux 2.6.16) + /// + /// Free up a given range of pages and its associated backing + /// store. This is equivalent to punching a hole in the + /// corresponding byte range of the backing store (see + /// fallocate(2)). Subsequent accesses in the specified + /// address range will see bytes containing zero. + /// + /// The specified address range must be mapped shared and + /// writable. This flag cannot be applied to locked pages, + /// Huge TLB pages, or VM_PFNMAP pages. + /// + /// In the initial implementation, only tmpfs(5) was supported + /// **MADV_REMOVE**; but since Linux 3.5, any filesystem which + /// supports the fallocate(2) FALLOC_FL_PUNCH_HOLE mode also + /// supports MADV_REMOVE. Hugetlbfs fails with the error + /// EINVAL and other filesystems fail with the error + /// EOPNOTSUPP. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping when the pages + /// are freed results in undefined behaviour. + #[cfg(target_os = "linux")] + Remove = libc::MADV_REMOVE, /// **MADV_FREE_REUSABLE** - Darwin only /// /// Behaves like **MADV_FREE**, but the freed pages are accounted for in the RSS of the process. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping while the pages + /// are still being freed results in undefined behaviour. #[cfg(any(target_os = "macos", target_os = "ios"))] FreeReusable = libc::MADV_FREE_REUSABLE, @@ -328,6 +366,12 @@ pub enum Advice { /// Marks a memory region previously freed by **MADV_FREE_REUSABLE** as non-reusable, accounts /// for the pages in the RSS of the process. Pages that have been freed will be replaced by /// zero-filled pages on demand, other pages will be left as is. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping while the pages + /// are still being freed results in undefined behaviour. #[cfg(any(target_os = "macos", target_os = "ios"))] FreeReuse = libc::MADV_FREE_REUSE, } diff --git a/vendor/memmap2/src/lib.rs b/vendor/memmap2/src/lib.rs index dd99ba12e..d6a185d0f 100644 --- a/vendor/memmap2/src/lib.rs +++ b/vendor/memmap2/src/lib.rs @@ -36,6 +36,8 @@ //! you can use [`MmapOptions`] in order to further configure a mapping //! before you create it. +#![allow(clippy::len_without_is_empty, clippy::missing_safety_doc)] + #[cfg_attr(unix, path = "unix.rs")] #[cfg_attr(windows, path = "windows.rs")] #[cfg_attr(not(any(unix, windows)), path = "stub.rs")] @@ -45,7 +47,7 @@ use crate::os::{file_len, MmapInner}; #[cfg(unix)] mod advice; #[cfg(unix)] -pub use crate::advice::Advice; +pub use crate::advice::{Advice, UncheckedAdvice}; use std::fmt; #[cfg(not(any(unix, windows)))] @@ -529,7 +531,7 @@ impl MmapOptions { /// Dereferencing and accessing the bytes of the buffer may result in page faults (e.g. swapping /// the mapped pages into physical memory) though the details of this are platform specific. /// -/// `Mmap` is [`Sync`](std::marker::Sync) and [`Send`](std::marker::Send). +/// `Mmap` is [`Sync`] and [`Send`]. /// /// ## Safety /// @@ -637,24 +639,55 @@ impl Mmap { Ok(MmapMut { inner: self.inner }) } - /// Advise OS how this memory map will be accessed. Only supported on Unix. + /// Advise OS how this memory map will be accessed. + /// + /// Only supported on Unix. /// /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. #[cfg(unix)] pub fn advise(&self, advice: Advice) -> Result<()> { - self.inner.advise(advice, 0, self.inner.len()) + self.inner + .advise(advice as libc::c_int, 0, self.inner.len()) } - /// Advise OS how this range of memory map will be accessed. + /// Advise OS how this memory map will be accessed. /// - /// The offset and length must be in the bounds of the memory map. + /// Used with the [unchecked flags][UncheckedAdvice]. Only supported on Unix. + /// + /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. + #[cfg(unix)] + pub unsafe fn unchecked_advise(&self, advice: UncheckedAdvice) -> Result<()> { + self.inner + .advise(advice as libc::c_int, 0, self.inner.len()) + } + + /// Advise OS how this range of memory map will be accessed. /// /// Only supported on Unix. /// + /// The offset and length must be in the bounds of the memory map. + /// /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. #[cfg(unix)] pub fn advise_range(&self, advice: Advice, offset: usize, len: usize) -> Result<()> { - self.inner.advise(advice, offset, len) + self.inner.advise(advice as libc::c_int, offset, len) + } + + /// Advise OS how this range of memory map will be accessed. + /// + /// Used with the [unchecked flags][UncheckedAdvice]. Only supported on Unix. + /// + /// The offset and length must be in the bounds of the memory map. + /// + /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. + #[cfg(unix)] + pub unsafe fn unchecked_advise_range( + &self, + advice: UncheckedAdvice, + offset: usize, + len: usize, + ) -> Result<()> { + self.inner.advise(advice as libc::c_int, offset, len) } /// Lock the whole memory map into RAM. Only supported on Unix. @@ -850,12 +883,26 @@ impl MmapRaw { self.inner.flush_async(offset, len) } - /// Advise OS how this memory map will be accessed. Only supported on Unix. + /// Advise OS how this memory map will be accessed. + /// + /// Only supported on Unix. /// /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. #[cfg(unix)] pub fn advise(&self, advice: Advice) -> Result<()> { - self.inner.advise(advice, 0, self.inner.len()) + self.inner + .advise(advice as libc::c_int, 0, self.inner.len()) + } + + /// Advise OS how this memory map will be accessed. + /// + /// Used with the [unchecked flags][UncheckedAdvice]. Only supported on Unix. + /// + /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. + #[cfg(unix)] + pub unsafe fn unchecked_advise(&self, advice: UncheckedAdvice) -> Result<()> { + self.inner + .advise(advice as libc::c_int, 0, self.inner.len()) } /// Advise OS how this range of memory map will be accessed. @@ -867,7 +914,24 @@ impl MmapRaw { /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. #[cfg(unix)] pub fn advise_range(&self, advice: Advice, offset: usize, len: usize) -> Result<()> { - self.inner.advise(advice, offset, len) + self.inner.advise(advice as libc::c_int, offset, len) + } + + /// Advise OS how this range of memory map will be accessed. + /// + /// Used with the [unchecked flags][UncheckedAdvice]. Only supported on Unix. + /// + /// The offset and length must be in the bounds of the memory map. + /// + /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. + #[cfg(unix)] + pub unsafe fn unchecked_advise_range( + &self, + advice: UncheckedAdvice, + offset: usize, + len: usize, + ) -> Result<()> { + self.inner.advise(advice as libc::c_int, offset, len) } /// Lock the whole memory map into RAM. Only supported on Unix. @@ -946,7 +1010,7 @@ impl From<MmapMut> for MmapRaw { /// Dereferencing and accessing the bytes of the buffer may result in page faults (e.g. swapping /// the mapped pages into physical memory) though the details of this are platform specific. /// -/// `Mmap` is [`Sync`](std::marker::Sync) and [`Send`](std::marker::Send). +/// `Mmap` is [`Sync`] and [`Send`]. /// /// See [`Mmap`] for the immutable version. /// @@ -1140,24 +1204,55 @@ impl MmapMut { Ok(Mmap { inner: self.inner }) } - /// Advise OS how this memory map will be accessed. Only supported on Unix. + /// Advise OS how this memory map will be accessed. + /// + /// Only supported on Unix. /// /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. #[cfg(unix)] pub fn advise(&self, advice: Advice) -> Result<()> { - self.inner.advise(advice, 0, self.inner.len()) + self.inner + .advise(advice as libc::c_int, 0, self.inner.len()) } - /// Advise OS how this range of memory map will be accessed. + /// Advise OS how this memory map will be accessed. /// - /// The offset and length must be in the bounds of the memory map. + /// Used with the [unchecked flags][UncheckedAdvice]. Only supported on Unix. + /// + /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. + #[cfg(unix)] + pub unsafe fn unchecked_advise(&self, advice: UncheckedAdvice) -> Result<()> { + self.inner + .advise(advice as libc::c_int, 0, self.inner.len()) + } + + /// Advise OS how this range of memory map will be accessed. /// /// Only supported on Unix. /// + /// The offset and length must be in the bounds of the memory map. + /// /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. #[cfg(unix)] pub fn advise_range(&self, advice: Advice, offset: usize, len: usize) -> Result<()> { - self.inner.advise(advice, offset, len) + self.inner.advise(advice as libc::c_int, offset, len) + } + + /// Advise OS how this range of memory map will be accessed. + /// + /// Used with the [unchecked flags][UncheckedAdvice]. Only supported on Unix. + /// + /// The offset and length must be in the bounds of the memory map. + /// + /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. + #[cfg(unix)] + pub fn unchecked_advise_range( + &self, + advice: UncheckedAdvice, + offset: usize, + len: usize, + ) -> Result<()> { + self.inner.advise(advice as libc::c_int, offset, len) } /// Lock the whole memory map into RAM. Only supported on Unix. @@ -1291,7 +1386,7 @@ mod test { extern crate tempfile; #[cfg(unix)] - use crate::advice::Advice; + use crate::advice::{Advice, UncheckedAdvice}; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; use std::mem; @@ -1315,7 +1410,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(expected_len as u64).unwrap(); @@ -1348,7 +1443,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(expected_len as u64).unwrap(); @@ -1380,7 +1475,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); let mmap = unsafe { Mmap::map(&file).unwrap() }; assert!(mmap.is_empty()); @@ -1435,7 +1530,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(128).unwrap(); @@ -1459,7 +1554,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(128).unwrap(); let write = b"abc123"; @@ -1485,7 +1580,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(128).unwrap(); @@ -1521,7 +1616,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(128).unwrap(); @@ -1546,10 +1641,10 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); - let offset = u32::max_value() as u64 + 2; + let offset = u32::MAX as u64 + 2; let len = 5432; file.set_len(offset + len as u64).unwrap(); @@ -1633,7 +1728,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&tempdir.path().join("jit_x86")) + .open(tempdir.path().join("jit_x86")) .expect("open"); file.set_len(4096).expect("set_len"); @@ -1653,7 +1748,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .expect("open"); file.set_len(256_u64).expect("set_len"); @@ -1699,7 +1794,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .expect("open"); file.set_len(256_u64).expect("set_len"); @@ -1753,7 +1848,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .expect("open"); file.write_all(b"abc123").unwrap(); let mmap = MmapOptions::new().map_raw(&file).unwrap(); @@ -1807,7 +1902,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(expected_len as u64).unwrap(); @@ -1845,6 +1940,45 @@ mod test { assert_eq!(&incr[..], &mmap[..]); } + #[test] + #[cfg(target_os = "linux")] + fn advise_writes_unsafely() { + let mut mmap = MmapMut::map_anon(4096).unwrap(); + mmap.as_mut().fill(255); + let mmap = mmap.make_read_only().unwrap(); + + let a = mmap.as_ref()[0]; + unsafe { + mmap.unchecked_advise(UncheckedAdvice::DontNeed).unwrap(); + } + let b = mmap.as_ref()[0]; + + assert_eq!(a, 255); + assert_eq!(b, 0); + } + + #[test] + #[cfg(target_os = "linux")] + fn advise_writes_unsafely_to_part_of_map() { + let mut mmap = MmapMut::map_anon(8192).unwrap(); + mmap.as_mut().fill(255); + let mmap = mmap.make_read_only().unwrap(); + + let a = mmap.as_ref()[0]; + let b = mmap.as_ref()[4096]; + unsafe { + mmap.unchecked_advise_range(UncheckedAdvice::DontNeed, 4096, 4096) + .unwrap(); + } + let c = mmap.as_ref()[0]; + let d = mmap.as_ref()[4096]; + + assert_eq!(a, 255); + assert_eq!(b, 255); + assert_eq!(c, 255); + assert_eq!(d, 0); + } + /// Returns true if a non-zero amount of memory is locked. #[cfg(target_os = "linux")] fn is_locked() -> bool { @@ -1869,7 +2003,7 @@ mod test { .read(true) .write(true) .create(true) - .open(&path) + .open(path) .unwrap(); file.set_len(128).unwrap(); diff --git a/vendor/memmap2/src/unix.rs b/vendor/memmap2/src/unix.rs index faa3b36d3..1df5691e9 100644 --- a/vendor/memmap2/src/unix.rs +++ b/vendor/memmap2/src/unix.rs @@ -6,8 +6,6 @@ use std::os::unix::io::{FromRawFd, RawFd}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::{io, ptr}; -use crate::advice::Advice; - #[cfg(any( all(target_os = "linux", not(target_arch = "mips")), target_os = "freebsd", @@ -48,7 +46,7 @@ pub struct MmapInner { impl MmapInner { /// Creates a new `MmapInner`. /// - /// This is a thin wrapper around the `mmap` sytem call. + /// This is a thin wrapper around the `mmap` system call. fn new( len: usize, prot: libc::c_int, @@ -59,7 +57,7 @@ impl MmapInner { let alignment = offset % page_size() as u64; let aligned_offset = offset - alignment; - let (map_len, map_offset) = Self::adjust_mmap_params(len as usize, alignment as usize)?; + let (map_len, map_offset) = Self::adjust_mmap_params(len, alignment as usize)?; unsafe { let ptr = mmap( @@ -197,7 +195,7 @@ impl MmapInner { debug_assert!(offset < page_size(), "offset larger than page size"); Self { - ptr: ptr.offset(offset as isize), + ptr: ptr.add(offset), len, } } @@ -342,12 +340,12 @@ impl MmapInner { self.len } - pub fn advise(&self, advice: Advice, offset: usize, len: usize) -> io::Result<()> { + pub fn advise(&self, advice: libc::c_int, offset: usize, len: usize) -> io::Result<()> { let alignment = (self.ptr as usize + offset) % page_size(); let offset = offset as isize - alignment as isize; let len = len + alignment; unsafe { - if libc::madvise(self.ptr.offset(offset), len, advice as i32) != 0 { + if libc::madvise(self.ptr.offset(offset), len, advice) != 0 { Err(io::Error::last_os_error()) } else { Ok(()) |