Merge branch 'no_seek' into 'master'

Replace seek() with fsize().

See merge request redox-os/ramfs!8
This commit is contained in:
Jeremy Soller
2024-08-30 21:35:38 +00:00
4 changed files with 67 additions and 58 deletions
Generated
+8 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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));
}