Use positioned IO scheme interface.

This commit is contained in:
4lDO2
2024-06-12 17:37:06 +02:00
parent 3800bf1510
commit 8a31d1b6a6
4 changed files with 65 additions and 130 deletions
Generated
+2 -2
View File
@@ -303,7 +303,7 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
[[package]]
name = "redox-scheme"
version = "0.2.0"
source = "git+https://gitlab.redox-os.org/4lDO2/redox-scheme.git?branch=schemev2#40c29c6f08e095e7b3739feae47a3c24f469c4d3"
source = "git+https://gitlab.redox-os.org/4lDO2/redox-scheme.git?branch=schemev2plus#ca239589c873374a17715b637be1f9385345721c"
dependencies = [
"libredox 0.1.3",
"redox_syscall 0.5.1",
@@ -321,7 +321,7 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.1"
source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=schemev2#495a0adbd8333fd21fae2d97129b094607878ba7"
source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=schemev2plus#b4f9a8952cec870ed7f457e3c15652d09aa0c9c7"
dependencies = [
"bitflags 2.5.0",
]
+2 -2
View File
@@ -46,7 +46,7 @@ termion = { version = "2", optional = true }
uuid = { version = "1.4", default-features = false }
redox-path = "0.3.0"
libredox = { version = "0.1.3", optional = true }
redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2" }
redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2plus" }
[features]
default = ["std", "log"]
@@ -71,4 +71,4 @@ libc = { version = "0.2", optional = true }
time = { version = "0.1", optional = true }
[patch.crates-io]
redox_syscall = { git = "https://gitlab.redox-os.org/4lDO2/syscall.git", branch = "schemev2", features = ["std"] }
redox_syscall = { git = "https://gitlab.redox-os.org/4lDO2/syscall.git", branch = "schemev2plus", features = ["std"] }
+44 -73
View File
@@ -29,11 +29,11 @@ pub trait Resource<D: Disk> {
fn set_path(&mut self, path: &str);
fn read(&mut self, buf: &mut [u8], tx: &mut Transaction<D>) -> Result<usize>;
fn read(&mut self, buf: &mut [u8], offset: u64, tx: &mut Transaction<D>) -> Result<usize>;
fn write(&mut self, buf: &[u8], tx: &mut Transaction<D>) -> Result<usize>;
fn write(&mut self, buf: &[u8], offset: u64, tx: &mut Transaction<D>) -> Result<usize>;
fn seek(&mut self, offset: isize, whence: usize, tx: &mut Transaction<D>) -> Result<isize>;
fn fsize(&mut self, tx: &mut Transaction<D>) -> Result<u64>;
fn fmap(
&mut self,
@@ -143,7 +143,6 @@ pub struct DirResource {
parent_ptr_opt: Option<TreePtr<Node>>,
node_ptr: TreePtr<Node>,
data: Option<Vec<u8>>,
seek: isize,
uid: u32,
}
@@ -160,7 +159,6 @@ impl DirResource {
parent_ptr_opt,
node_ptr,
data,
seek: 0,
uid,
}
}
@@ -185,7 +183,6 @@ impl<D: Disk> Resource<D> for DirResource {
parent_ptr_opt: self.parent_ptr_opt,
node_ptr: self.node_ptr,
data: self.data.clone(),
seek: self.seek,
uid: self.uid,
}))
}
@@ -194,32 +191,21 @@ impl<D: Disk> Resource<D> for DirResource {
self.path = path.to_string();
}
fn read(&mut self, buf: &mut [u8], _tx: &mut Transaction<D>) -> Result<usize> {
fn read(&mut self, buf: &mut [u8], offset: u64, _tx: &mut Transaction<D>) -> Result<usize> {
let data = self.data.as_ref().ok_or(Error::new(EISDIR))?;
let size = data.len() as isize;
let mut i = 0;
while i < buf.len() && self.seek < size {
buf[i] = data[self.seek as usize];
i += 1;
self.seek += 1;
}
Ok(i)
let src = usize::try_from(offset).ok().and_then(|o| data.get(o..)).unwrap_or(&[]);
let byte_count = core::cmp::min(src.len(), buf.len());
buf[..byte_count].copy_from_slice(&src[..byte_count]);
Ok(byte_count)
}
fn write(&mut self, _buf: &[u8], _tx: &mut Transaction<D>) -> Result<usize> {
fn write(&mut self, _buf: &[u8], _offset: u64, _tx: &mut Transaction<D>) -> Result<usize> {
Err(Error::new(EBADF))
}
fn seek(&mut self, offset: isize, whence: usize, _tx: &mut Transaction<D>) -> Result<isize> {
let data = self.data.as_ref().ok_or(Error::new(EBADF))?;
let size = data.len() as isize;
self.seek = match whence {
SEEK_SET => max(0, min(size, offset)),
SEEK_CUR => max(0, min(size, self.seek + offset)),
SEEK_END => max(0, min(size, size + offset)),
_ => return Err(Error::new(EINVAL)),
};
Ok(self.seek)
fn fsize(&mut self, _tx: &mut Transaction<D>) -> Result<u64> {
Ok(self.data.as_ref().ok_or(Error::new(EBADF))?.len() as u64)
}
fn fmap(
@@ -336,7 +322,6 @@ pub struct FileResource {
parent_ptr_opt: Option<TreePtr<Node>>,
node_ptr: TreePtr<Node>,
flags: usize,
seek: isize,
uid: u32,
}
#[derive(Debug)]
@@ -370,7 +355,6 @@ impl FileResource {
parent_ptr_opt,
node_ptr,
flags,
seek: 0,
uid,
}
}
@@ -395,7 +379,6 @@ impl<D: Disk> Resource<D> for FileResource {
parent_ptr_opt: self.parent_ptr_opt,
node_ptr: self.node_ptr,
flags: self.flags,
seek: self.seek,
uid: self.uid,
}))
}
@@ -404,55 +387,43 @@ impl<D: Disk> Resource<D> for FileResource {
self.path = path.to_string();
}
fn read(&mut self, buf: &mut [u8], tx: &mut Transaction<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_RDONLY {
let atime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let count = tx.read_node(
self.node_ptr,
self.seek as u64,
buf,
atime.as_secs(),
atime.subsec_nanos(),
)?;
self.seek += count as isize;
Ok(count)
} else {
Err(Error::new(EBADF))
fn read(&mut self, buf: &mut [u8], offset: u64, tx: &mut Transaction<D>) -> Result<usize> {
if self.flags & O_ACCMODE != O_RDWR && self.flags & O_ACCMODE != O_RDONLY {
return Err(Error::new(EBADF));
}
let atime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
tx.read_node(
self.node_ptr,
offset,
buf,
atime.as_secs(),
atime.subsec_nanos(),
)
}
fn write(&mut self, buf: &[u8], tx: &mut Transaction<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
if self.flags & O_APPEND == O_APPEND {
let node = tx.read_tree(self.node_ptr)?;
self.seek = node.data().size() as isize;
}
let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let count = tx.write_node(
self.node_ptr,
self.seek as u64,
buf,
mtime.as_secs(),
mtime.subsec_nanos(),
)?;
self.seek += count as isize;
Ok(count)
} else {
Err(Error::new(EBADF))
fn write(&mut self, buf: &[u8], offset: u64, tx: &mut Transaction<D>) -> Result<usize> {
if self.flags & O_ACCMODE != O_RDWR && self.flags & O_ACCMODE != O_WRONLY {
return Err(Error::new(EBADF));
}
}
fn seek(&mut self, offset: isize, whence: usize, tx: &mut Transaction<D>) -> Result<isize> {
self.seek = match whence {
SEEK_SET => max(0, offset),
SEEK_CUR => max(0, self.seek + offset),
SEEK_END => {
let node = tx.read_tree(self.node_ptr)?;
max(0, node.data().size() as isize + offset)
}
_ => return Err(Error::new(EINVAL)),
let effective_offset = if self.flags & O_APPEND == O_APPEND {
let node = tx.read_tree(self.node_ptr)?;
node.data().size()
} else {
offset
};
Ok(self.seek)
let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
tx.write_node(
self.node_ptr,
effective_offset,
buf,
mtime.as_secs(),
mtime.subsec_nanos(),
)
}
fn fsize(&mut self, tx: &mut Transaction<D>) -> Result<u64> {
let node = tx.read_tree(self.node_ptr)?;
Ok(node.data().size())
}
fn fmap(
+17 -53
View File
@@ -12,8 +12,9 @@ use syscall::flag::{
EventFlags, MapFlags, MODE_PERM, O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_NOFOLLOW, O_RDONLY,
O_RDWR, O_STAT, O_SYMLINK, O_TRUNC, O_WRONLY,
};
use syscall::schemev2::NewFdFlags;
use syscall::{MunmapFlags, EBADFD};
use redox_scheme::SchemeMut;
use redox_scheme::{CallerCtx, OpenResult, SchemeMut};
use redox_path::{canonicalize_to_standard, canonicalize_using_cwd, canonicalize_using_scheme, scheme_path, RedoxPath};
@@ -161,7 +162,9 @@ fn dirname(path: &str) -> Option<String> {
}
impl<D: Disk> SchemeMut for FileScheme<D> {
fn open(&mut self, url: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
fn xopen(&mut self, url: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
let CallerCtx { uid, gid, .. } = *ctx;
let path = url.trim_matches('/');
// println!("Open '{}' {:X}", path, flags);
@@ -234,7 +237,7 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
&mut resolve_nodes,
)
})?;
return self.open(&resolved, flags, uid, gid);
return self.xopen(&resolved, flags, ctx);
} else if !node.data().is_symlink() && flags & O_SYMLINK == O_SYMLINK {
return Err(Error::new(EINVAL));
} else {
@@ -355,39 +358,10 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
.or_insert_with(Default::default)
.open_fds += 1;
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
self.files.insert(id, resource);
Ok(id)
}
fn chmod(&mut self, url: &str, mode: u16, uid: u32, gid: u32) -> Result<usize> {
let path = url.trim_matches('/');
// println!("Chmod '{}'", path);
let scheme_name = &self.name;
self.fs.tx(|tx| {
let mut nodes = Vec::new();
if let Some((mut node, _node_name)) =
Self::path_nodes(scheme_name, tx, path, uid, gid, &mut nodes)?
{
if node.data().uid() == uid || uid == 0 {
let old_mode = node.data().mode();
let new_mode = (old_mode & !MODE_PERM) | (mode & MODE_PERM);
if old_mode != new_mode {
node.data_mut().set_mode(new_mode);
tx.sync_tree(node)?;
}
Ok(0)
} else {
Err(Error::new(EPERM))
}
} else {
Err(Error::new(ENOENT))
}
})
Ok(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })
}
fn rmdir(&mut self, url: &str, uid: u32, gid: u32) -> Result<usize> {
@@ -497,32 +471,22 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
Ok(id)
}
#[allow(unused_variables)]
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result<usize> {
// println!("Read {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
if let Some(file) = self.files.get_mut(&id) {
self.fs.tx(|tx| file.read(buf, tx))
} else {
Err(Error::new(EBADF))
}
let file = self.files.get_mut(&id).ok_or(Error::new(EBADF))?;
self.fs.tx(|tx| file.read(buf, offset, tx))
}
fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result<usize> {
// println!("Write {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
if let Some(file) = self.files.get_mut(&id) {
self.fs.tx(|tx| file.write(buf, tx))
} else {
Err(Error::new(EBADF))
}
let file = self.files.get_mut(&id).ok_or(Error::new(EBADF))?;
self.fs.tx(|tx| file.write(buf, offset, tx))
}
fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result<isize> {
fn fsize(&mut self, id: usize) -> Result<u64> {
// println!("Seek {}, {} {}", id, pos, whence);
if let Some(file) = self.files.get_mut(&id) {
self.fs.tx(|tx| file.seek(pos, whence, tx))
} else {
Err(Error::new(EBADF))
}
let file = self.files.get_mut(&id).ok_or(Error::new(EBADF))?;
self.fs.tx(|tx| file.fsize(tx))
}
fn fchmod(&mut self, id: usize, mode: u16) -> Result<usize> {