Skip to content

Commit

Permalink
pmem: fix char ffi path
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Wünsche committed Jun 22, 2023
1 parent 401895e commit 1bc5258
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 119 deletions.
128 changes: 64 additions & 64 deletions betree/pmem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,88 @@

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

use std::os::raw::c_void;
use std::{
ffi::{c_void, CString},
mem::forget,
ops::{Deref, DerefMut},
path::{Path, PathBuf},
ptr::NonNull,
};

#[derive(Debug)]
pub struct PMem {
pub ptr: *mut c_void,
ptr: NonNull<c_void>,
actually_pmem: bool,
len: usize,
}

impl Drop for PMem {
fn drop(&mut self) {
self.close()
}
}

unsafe impl Send for PMem {}
unsafe impl Sync for PMem {}

impl PMem {
pub fn create(
filepath: &str,
len: u64,
mapped_len: &mut usize,
is_pmem: &mut i32,
) -> Result<Self, std::io::Error> {
pub fn create<P: Into<PathBuf>>(filepath: P, len: usize) -> Result<Self, std::io::Error> {
let mut mapped_len = 0;
let mut is_pmem = 0;
let ptr = unsafe {
pmem_map_file(
filepath.as_ptr() as *const i8,
CString::new(filepath.into().to_string_lossy().into_owned())?.into_raw(),
len as usize,
(PMEM_FILE_CREATE | PMEM_FILE_EXCL) as i32,
0666,
mapped_len,
is_pmem,
&mut mapped_len,
&mut is_pmem,
)
};

if ptr.is_null() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Failed to create memory pool. filepath: {}", filepath),
));
}

Ok(PMem { ptr })
Self::new(ptr, mapped_len, is_pmem)
}

pub fn open(
filepath: &str,
mapped_len: &mut usize,
is_pmem: &mut i32,
) -> Result<Self, std::io::Error> {
pub fn open<P: Into<PathBuf>>(filepath: P) -> Result<Self, std::io::Error> {
let mut mapped_len = 0;
let mut is_pmem = 0;
let ptr = unsafe {
pmem_map_file(
filepath.as_ptr() as *const i8,
CString::new(filepath.into().to_string_lossy().into_owned())?.into_raw(),
0, // Opening an existing file requires no flag(s).
0, // No length as no flag is provided.
0666,
mapped_len,
is_pmem,
&mut mapped_len,
&mut is_pmem,
)
};
Self::new(ptr, mapped_len, is_pmem)
}

if ptr.is_null() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Failed to open the memory pool. filepath: {}", filepath),
));
}

Ok(PMem { ptr })
fn new(ptr: *mut c_void, len: usize, is_pmem: i32) -> Result<Self, std::io::Error> {
NonNull::new(ptr)
.and_then(|valid| {
Some(PMem {
ptr: valid,
actually_pmem: is_pmem != 0,
len,
})
})
.ok_or_else(|| {
let err = unsafe { CString::from_raw(pmem_errormsg() as *mut i8) };
let err_msg = format!(
"Failed to create memory pool. filepath: {}",
err.to_string_lossy()
);
forget(err);
std::io::Error::new(std::io::ErrorKind::Other, err_msg)
})
}

pub fn read(&self, offset: usize, data: &mut [u8], len: usize) -> Result<(), std::io::Error> {
if self.ptr.is_null() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("File handle is missing for the PMEM file."),
));
}

let ptr = unsafe {
pmem_memcpy(
data.as_ptr() as *mut c_void,
self.ptr.add(offset),
self.ptr.as_ptr().add(offset),
len,
PMEM_F_MEM_NOFLUSH, /*| PMEM_F_MEM_TEMPORAL*/
)
Expand All @@ -104,31 +110,25 @@ impl PMem {
data: &[u8],
len: usize,
) -> Result<(), std::io::Error> {
if self.ptr.is_null() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("File handle is missing for the PMEM file."),
));
}

let _ = pmem_memcpy_persist(self.ptr.add(offset), data.as_ptr() as *mut c_void, len);
let _ = pmem_memcpy_persist(
self.ptr.as_ptr().add(offset),
data.as_ptr() as *mut c_void,
len,
);
Ok(())
}

if self.ptr.is_null() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!(
"Failed to write data to PMEM file. Offset: {}, Size: {}",
offset, len
),
));
};
pub fn is_pmem(&self) -> bool {
self.actually_pmem
}

Ok(())
pub fn len(&self) -> usize {
self.len
}

pub fn close(&self, mapped_len: &usize) {
fn close(&mut self) {
unsafe {
pmem_unmap(self.ptr, *mapped_len);
pmem_unmap(self.ptr.as_ptr(), self.len);
}
}
}
14 changes: 3 additions & 11 deletions betree/pmem/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,9 @@ maximus, vestibulum nunc nec, rutrum leo. \0";
const TEXT2: &str = "hello world!";

fn basic_read_write_test() -> Result<(), std::io::Error> {
let mut is_pmem: i32 = 0;
let mut mapped_len: usize = 0;

let pmem = match PMem::create(
&DEST_FILEPATH,
64 * 1024 * 1024,
&mut mapped_len,
&mut is_pmem,
) {
let pmem = match PMem::create(&DEST_FILEPATH, 64 * 1024 * 1024) {
Ok(value) => value,
Err(_) => PMem::open(&DEST_FILEPATH, &mut mapped_len, &mut is_pmem)?,
Err(_) => PMem::open(&DEST_FILEPATH)?,
};

// Writing the long text (TEXT1)
Expand Down Expand Up @@ -71,7 +63,7 @@ fn basic_read_write_test() -> Result<(), std::io::Error> {
let mut buffer3 = vec![0; TEXT.chars().count()];
pmem.read(1000, &mut buffer3, TEXT.chars().count())?;

pmem.close(&mapped_len);
drop(pmem);

// Comparing the read text with the actual one
let read_string = match std::str::from_utf8(&buffer) {
Expand Down
55 changes: 11 additions & 44 deletions betree/src/storage_pool/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,56 +312,23 @@ impl LeafVdev {
format!("memory-{mem}"),
)?)),
#[cfg(feature = "nvm")]
LeafVdev::PMemFile { .. } => {
let (path, len) = match self {
LeafVdev::File(path) => unreachable!(),
LeafVdev::FileWithOpts { .. } => unreachable!(),
LeafVdev::Memory { .. } => unreachable!(),
LeafVdev::PMemFile { path, len } => (path, len),
};

let mut is_pmem: i32 = 0;
let mut mapped_len: usize = 0;
let mut file = match path.to_str() {
Some(filepath_str) => {
match pmem::PMem::open(
format!("{}\0", filepath_str).as_str(),
&mut mapped_len,
&mut is_pmem,
) {
Ok(handle) => handle,
Err(e) => match pmem::PMem::create(
format!("{}\0", filepath_str).as_str(),
*len as u64,
&mut mapped_len,
&mut is_pmem,
) {
Ok(handle) => handle,
Err(e) => {
return Err(io::Error::new(io::ErrorKind::Other,
format!("Failed to create or open handle for pmem file. Path: {}", filepath_str)));
}
},
}
}
None => {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Invalid file path: {:?}", path),
));
}
LeafVdev::PMemFile { ref path, len } => {
let pmem = match pmem::PMem::open(path) {
Ok(p) => p,
Err(_) => pmem::PMem::create(path, len)?,
};

if mapped_len != *len {
if pmem.len() != len {
return Err(io::Error::new(io::ErrorKind::Other,
format!("The file already exists with a differnt length. Provided length: {}, File's length: {}",
len, mapped_len)));
format!("The file already exists with a differentiating length. Provided length: {}, File's length: {}",
len, pmem.len())));
}

let len = pmem.len();
Ok(Leaf::PMemFile(vdev::PMemFile::new(
file,
pmem,
path.to_string_lossy().into_owned(),
mapped_len as u64,
len as u64,
)?))
}
}
Expand Down Expand Up @@ -425,7 +392,7 @@ impl LeafVdev {
writeln!(f, "{:indent$}memory({})", "", mem, indent = indent)
}
#[cfg(feature = "nvm")]
LeafVdev::PMemFile { path, len } => {
LeafVdev::PMemFile { path, len: _ } => {
writeln!(f, "{:indent$}{}", "", path.display(), indent = indent)
}
}
Expand Down

0 comments on commit 1bc5258

Please sign in to comment.