Skip to content

Commit

Permalink
sys::mman: adding MREMAP_DONTUNMAP flag for mremap on Linux.
Browse files Browse the repository at this point in the history
Is meant to be used with `MREMAP_MAYMOVE` and allow to not unmapping
`old_address`.
  • Loading branch information
devnexen committed Dec 5, 2024
1 parent f9ed9f0 commit ef5d9ae
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/2555.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `MremapFlags::MREMAP_DONTUNMAP` to `sys::mman::mremap` for linux target.
4 changes: 4 additions & 0 deletions src/sys/mman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ libc_bitflags! {
/// Place the mapping at exactly the address specified in `new_address`.
#[cfg(target_os = "linux")]
MREMAP_FIXED;
/// Works in conjunction with `MREMAP_MAYMOVE` but does not unmap `old_address`.
/// Note that, in this case, `old_size` and `new_size` must be the same.
#[cfg(target_os = "linux")]
MREMAP_DONTUNMAP;
/// Place the mapping at exactly the address specified in `new_address`.
#[cfg(target_os = "netbsd")]
MAP_FIXED;
Expand Down
37 changes: 37 additions & 0 deletions test/sys/test_mman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,40 @@ fn test_mremap_shrink() {
// The first KB should still be accessible and have the old data in it.
assert_eq!(slice[ONE_K - 1], 0xFF);
}

#[test]
#[cfg(target_os = "linux")]
fn test_mremap_dontunmap() {
use nix::libc::size_t;
use nix::sys::mman::{mremap, MRemapFlags};
use std::num::NonZeroUsize;
use std::ptr::NonNull;

const ONE_K: size_t = 1024;
let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();

let slice: &mut [u8] = unsafe {
let mem = mmap_anonymous(
None,
one_k_non_zero,
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
MapFlags::MAP_PRIVATE,
)
.unwrap();
std::slice::from_raw_parts_mut(mem.as_ptr().cast(), ONE_K)
};

// because we do not unmap `slice`, `old_size` and `new_size`
// need to be equal or `EINVAL` is set.
let _new_slice: &mut [u8] = unsafe {
let mem = mremap(
NonNull::from(&mut slice[..]).cast(),
ONE_K,
ONE_K,
MRemapFlags::MREMAP_MAYMOVE | MRemapFlags::MREMAP_DONTUNMAP,
None,
)
.unwrap();
std::slice::from_raw_parts_mut(mem.cast().as_ptr(), 10 * ONE_K)
};
}

0 comments on commit ef5d9ae

Please sign in to comment.