Merge branch 'no_seek' into 'master'
Replace seek() with fsize(). See merge request redox-os/ramfs!8
This commit is contained in:
Generated
+8
-8
@@ -4,15 +4,15 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
@@ -47,9 +47,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a4d4161697395d7cc9b182a14a753b2ba0243dcf622e278e644c6e7f74904c1"
|
||||
checksum = "2148c23b7ed5bf1cc3919b4830e4bf2a674a5d3691c619317624ccd78d13a3ac"
|
||||
dependencies = [
|
||||
"libredox",
|
||||
"redox_syscall",
|
||||
@@ -57,9 +57,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.1"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
|
||||
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ description = "In-memory filesystem for Redox, which is useful for early logging
|
||||
[dependencies]
|
||||
redox-daemon = "0.1.2"
|
||||
redox_syscall = "0.5.1"
|
||||
redox-scheme = "0.2"
|
||||
redox-scheme = "0.2.1"
|
||||
libredox = "0.1.3"
|
||||
|
||||
+14
-6
@@ -11,29 +11,37 @@ fn main() {
|
||||
let scheme_name = env::args().nth(1).expect("Usage:\n\tramfs SCHEME_NAME");
|
||||
|
||||
redox_daemon::Daemon::new(move |daemon| {
|
||||
let socket = redox_scheme::Socket::create(&scheme_name).expect("ramfs: failed to create socket");
|
||||
let socket = redox_scheme::Socket::<redox_scheme::V2>::create(&scheme_name)
|
||||
.expect("ramfs: failed to create socket");
|
||||
|
||||
let mut scheme = Scheme::new(scheme_name).expect("ramfs: failed to initialize scheme");
|
||||
|
||||
libredox::call::setrens(0, 0).expect("ramfs: failed to enter null namespace");
|
||||
|
||||
daemon.ready().expect("ramfs: failed to mark daemon as ready");
|
||||
daemon
|
||||
.ready()
|
||||
.expect("ramfs: failed to mark daemon as ready");
|
||||
|
||||
loop {
|
||||
let Some(request) = socket.next_request(SignalBehavior::Restart).expect("ramfs: failed to get next scheme request") else {
|
||||
let Some(request) = socket
|
||||
.next_request(SignalBehavior::Restart)
|
||||
.expect("ramfs: failed to get next scheme request")
|
||||
else {
|
||||
break;
|
||||
};
|
||||
match request.kind() {
|
||||
RequestKind::Call(call) => {
|
||||
let response = call.handle_scheme_mut(&mut scheme);
|
||||
|
||||
socket.write_responses(&[response], SignalBehavior::Restart).expect("ramfs: failed to write next scheme response");
|
||||
socket
|
||||
.write_responses(&[response], SignalBehavior::Restart)
|
||||
.expect("ramfs: failed to write next scheme response");
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
process::exit(0);
|
||||
}).expect("ramfs: failed to create daemon");
|
||||
})
|
||||
.expect("ramfs: failed to create daemon");
|
||||
}
|
||||
|
||||
+44
-43
@@ -10,18 +10,19 @@ use syscall::error::{
|
||||
use syscall::flag::{
|
||||
O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_STAT, O_TRUNC, O_WRONLY,
|
||||
};
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
use syscall::{Error, EventFlags, Map, Result, Stat, StatVfs, TimeSpec};
|
||||
use syscall::{MODE_DIR, MODE_FILE, MODE_PERM, MODE_TYPE, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
|
||||
use redox_scheme::SchemeMut;
|
||||
use redox_scheme::{CallerCtx, OpenResult, SchemeMut};
|
||||
|
||||
use crate::filesystem::{self, DirEntry, File, FileData, Filesystem};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Handle {
|
||||
inode: usize,
|
||||
offset: usize,
|
||||
|
||||
// TODO: fcntl_flags?
|
||||
opened_as_read: bool, // opened with O_RDONLY or O_RDWR
|
||||
opened_as_write: bool, // opened with O_WRONLY or O_RDWR
|
||||
|
||||
@@ -167,7 +168,6 @@ impl Scheme {
|
||||
|
||||
Ok(Handle {
|
||||
inode,
|
||||
offset: 0,
|
||||
opened_as_read,
|
||||
opened_as_write,
|
||||
current_perm,
|
||||
@@ -176,14 +176,14 @@ impl Scheme {
|
||||
}
|
||||
|
||||
impl SchemeMut for Scheme {
|
||||
fn open(&mut self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
|
||||
fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
|
||||
let exists = self.filesystem.resolve(path.as_bytes(), 0, 0).is_ok();
|
||||
if flags & O_CREAT != 0 && flags & O_EXCL != 0 && exists {
|
||||
return Err(Error::new(EEXIST));
|
||||
}
|
||||
|
||||
let handle = if flags & O_CREAT != 0 && exists {
|
||||
self.open_existing(path.as_bytes(), flags, uid, gid)?
|
||||
self.open_existing(path.as_bytes(), flags, ctx.uid, ctx.gid)?
|
||||
} else if flags & O_CREAT != 0 {
|
||||
if flags & O_STAT != 0 {
|
||||
return Err(Error::new(EINVAL));
|
||||
@@ -191,7 +191,7 @@ impl SchemeMut for Scheme {
|
||||
|
||||
let (parent_dir_inode, new_name) =
|
||||
self.filesystem
|
||||
.resolve_except_last(path.as_bytes(), uid, gid)?;
|
||||
.resolve_except_last(path.as_bytes(), ctx.uid, ctx.gid)?;
|
||||
let new_name = new_name.ok_or(Error::new(EINVAL))?; // cannot mkdir /
|
||||
|
||||
let current_time = filesystem::current_time();
|
||||
@@ -213,8 +213,8 @@ impl SchemeMut for Scheme {
|
||||
crtime: current_time,
|
||||
ctime: current_time,
|
||||
mtime: current_time,
|
||||
gid,
|
||||
uid,
|
||||
gid: ctx.gid,
|
||||
uid: ctx.uid,
|
||||
ino: new_inode_number,
|
||||
mode,
|
||||
nlink: 2, // parent entry, "."
|
||||
@@ -234,8 +234,8 @@ impl SchemeMut for Scheme {
|
||||
crtime: current_time,
|
||||
ctime: current_time,
|
||||
mtime: current_time,
|
||||
gid,
|
||||
uid,
|
||||
gid: ctx.gid,
|
||||
uid: ctx.uid,
|
||||
ino: new_inode_number,
|
||||
mode,
|
||||
nlink: 1,
|
||||
@@ -243,7 +243,7 @@ impl SchemeMut for Scheme {
|
||||
open_handles: 1,
|
||||
}
|
||||
};
|
||||
let current_perm = current_perm(&new_inode, uid, gid);
|
||||
let current_perm = current_perm(&new_inode, ctx.uid, ctx.gid);
|
||||
check_permissions(flags, current_perm)?;
|
||||
|
||||
self.filesystem.files.insert(new_inode_number, new_inode);
|
||||
@@ -263,13 +263,12 @@ impl SchemeMut for Scheme {
|
||||
|
||||
Handle {
|
||||
inode: new_inode_number,
|
||||
offset: 0,
|
||||
opened_as_read: flags & O_ACCMODE == O_RDONLY || flags & O_ACCMODE == O_RDWR,
|
||||
opened_as_write: flags & O_ACCMODE == O_WRONLY || flags & O_ACCMODE == O_RDWR,
|
||||
current_perm,
|
||||
}
|
||||
} else {
|
||||
self.open_existing(path.as_bytes(), flags, uid, gid)?
|
||||
self.open_existing(path.as_bytes(), flags, ctx.uid, ctx.gid)?
|
||||
};
|
||||
|
||||
let fd = self.next_fd;
|
||||
@@ -277,7 +276,10 @@ impl SchemeMut for Scheme {
|
||||
|
||||
self.handles.insert(fd, handle);
|
||||
|
||||
Ok(fd)
|
||||
Ok(OpenResult::ThisScheme {
|
||||
number: fd,
|
||||
flags: NewFdFlags::POSITIONED,
|
||||
})
|
||||
}
|
||||
fn rmdir(&mut self, path: &str, uid: u32, gid: u32) -> Result<usize> {
|
||||
self.remove_dentry(path.as_bytes(), uid, gid, true)
|
||||
@@ -298,8 +300,11 @@ impl SchemeMut for Scheme {
|
||||
self.handles.insert(fd, handle);
|
||||
Ok(fd)
|
||||
}
|
||||
fn read(&mut self, fd: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
fn read(&mut self, fd: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result<usize> {
|
||||
let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?;
|
||||
let Ok(offset) = usize::try_from(offset) else {
|
||||
return Ok(0);
|
||||
};
|
||||
let file = self
|
||||
.filesystem
|
||||
.files
|
||||
@@ -316,15 +321,13 @@ impl SchemeMut for Scheme {
|
||||
return Err(Error::new(EBADFD));
|
||||
}
|
||||
|
||||
if handle.offset >= bytes.len() {
|
||||
if offset >= bytes.len() {
|
||||
return Ok(0);
|
||||
}
|
||||
let bytes_to_read =
|
||||
cmp::min(bytes.len(), buf.len() + handle.offset) - handle.offset;
|
||||
buf[..bytes_to_read]
|
||||
.copy_from_slice(&bytes[handle.offset..handle.offset + bytes_to_read]);
|
||||
handle.offset += bytes_to_read;
|
||||
Ok(bytes_to_read)
|
||||
let src = buf.get(..offset).unwrap_or(&[]);
|
||||
let to_copy = src.len().min(buf.len());
|
||||
buf[..to_copy].copy_from_slice(&bytes[offset..][..to_copy]);
|
||||
Ok(to_copy)
|
||||
}
|
||||
FileData::Directory(ref entries) => {
|
||||
if file.mode & MODE_TYPE != MODE_DIR {
|
||||
@@ -335,7 +338,7 @@ impl SchemeMut for Scheme {
|
||||
return Err(Error::new(EBADF));
|
||||
}
|
||||
|
||||
let mut bytes_to_skip = handle.offset;
|
||||
let mut bytes_to_skip = offset;
|
||||
let mut bytes_left_to_read = buf.len();
|
||||
let mut bytes_read = 0;
|
||||
|
||||
@@ -361,14 +364,16 @@ impl SchemeMut for Scheme {
|
||||
buf[bytes_read + bytes_to_read - 1] = b'\n';
|
||||
bytes_left_to_read -= bytes_to_read;
|
||||
bytes_read += bytes_to_read;
|
||||
handle.offset += bytes_read;
|
||||
}
|
||||
Ok(bytes_read)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn write(&mut self, fd: usize, buf: &[u8]) -> Result<usize> {
|
||||
fn write(&mut self, fd: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result<usize> {
|
||||
let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?;
|
||||
let Ok(offset) = usize::try_from(offset) else {
|
||||
return Ok(0);
|
||||
};
|
||||
let file = self
|
||||
.filesystem
|
||||
.files
|
||||
@@ -381,21 +386,20 @@ impl SchemeMut for Scheme {
|
||||
}
|
||||
|
||||
// if there's a seek hole, fill it with 0 and continue writing.
|
||||
let end_off = handle.offset.checked_add(buf.len()).ok_or(Error::new(EOVERFLOW))?;
|
||||
let end_off = offset.checked_add(buf.len()).ok_or(Error::new(EOVERFLOW))?;
|
||||
if end_off > bytes.len() {
|
||||
let additional = end_off - bytes.len();
|
||||
bytes.try_reserve(additional).or(Err(Error::new(ENOMEM)))?;
|
||||
bytes.resize(end_off, 0u8);
|
||||
}
|
||||
bytes[handle.offset..][..buf.len()].copy_from_slice(buf);
|
||||
handle.offset = end_off;
|
||||
bytes[offset..][..buf.len()].copy_from_slice(buf);
|
||||
|
||||
Ok(buf.len())
|
||||
} else {
|
||||
Err(Error::new(EISDIR))
|
||||
}
|
||||
}
|
||||
fn seek(&mut self, fd: usize, pos: isize, whence: usize) -> Result<isize> {
|
||||
fn fsize(&mut self, fd: usize) -> Result<u64> {
|
||||
let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?;
|
||||
let file = self
|
||||
.filesystem
|
||||
@@ -403,19 +407,10 @@ impl SchemeMut for Scheme {
|
||||
.get_mut(&handle.inode)
|
||||
.ok_or(Error::new(EBADFD))?;
|
||||
|
||||
handle.offset = match whence {
|
||||
SEEK_SET => cmp::max(0, pos),
|
||||
SEEK_CUR => cmp::max(
|
||||
0,
|
||||
pos + isize::try_from(handle.offset).or(Err(Error::new(EOVERFLOW)))?,
|
||||
),
|
||||
SEEK_END => cmp::max(
|
||||
0,
|
||||
pos + isize::try_from(file.data.size()).or(Err(Error::new(EOVERFLOW)))?,
|
||||
),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
Ok(handle.offset as isize)
|
||||
file.data
|
||||
.size()
|
||||
.try_into()
|
||||
.map_err(|_| Error::new(EOVERFLOW))
|
||||
}
|
||||
fn fchmod(&mut self, fd: usize, mode: u16) -> Result<usize> {
|
||||
let handle = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?;
|
||||
@@ -462,7 +457,13 @@ impl SchemeMut for Scheme {
|
||||
}
|
||||
Err(Error::new(ENOSYS))
|
||||
}
|
||||
fn mmap_prep(&mut self, fd: usize, _offset: u64, _size: usize, _flags: syscall::MapFlags) -> Result<usize> {
|
||||
fn mmap_prep(
|
||||
&mut self,
|
||||
fd: usize,
|
||||
_offset: u64,
|
||||
_size: usize,
|
||||
_flags: syscall::MapFlags,
|
||||
) -> Result<usize> {
|
||||
if !self.handles.contains_key(&fd) {
|
||||
return Err(Error::new(EBADF));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user