Use positioned IO scheme interface.
This commit is contained in:
Generated
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user