Skip to content
Snippets Groups Projects
Verified Commit 8a31d1b6 authored by Jacob Lorentzon's avatar Jacob Lorentzon
Browse files

Use positioned IO scheme interface.

parent 3800bf15
No related branches found
No related tags found
No related merge requests found
......@@ -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",
]
......
......@@ -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"] }
......@@ -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));
}
let effective_offset = if self.flags & O_APPEND == O_APPEND {
let node = tx.read_tree(self.node_ptr)?;
node.data().size()
} else {
offset
};
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 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)),
};
Ok(self.seek)
fn fsize(&mut self, tx: &mut Transaction<D>) -> Result<u64> {
let node = tx.read_tree(self.node_ptr)?;
Ok(node.data().size())
}
fn fmap(
......
......@@ -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> {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment