Skip to content

Commit 884cdcc

Browse files
committed
refactor(fd): lock all ObjectInterfaces externally
1 parent 4711272 commit 884cdcc

File tree

11 files changed

+203
-82
lines changed

11 files changed

+203
-82
lines changed

src/fd/mod.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ pub(crate) trait ObjectInterface: Sync + Send + core::fmt::Debug {
233233

234234
/// `accept` a connection on a socket
235235
#[cfg(any(feature = "net", feature = "vsock"))]
236-
async fn accept(&self) -> io::Result<(Arc<dyn ObjectInterface>, Endpoint)> {
236+
async fn accept(&self) -> io::Result<(Arc<async_lock::RwLock<dyn ObjectInterface>>, Endpoint)> {
237237
Err(Errno::Inval)
238238
}
239239

@@ -337,19 +337,19 @@ pub(crate) fn read(fd: FileDescriptor, buf: &mut [u8]) -> io::Result<usize> {
337337
return Ok(0);
338338
}
339339

340-
block_on(obj.read(buf), None)
340+
block_on(async { obj.read().await.read(buf).await }, None)
341341
}
342342

343343
pub(crate) fn lseek(fd: FileDescriptor, offset: isize, whence: SeekWhence) -> io::Result<isize> {
344344
let obj = get_object(fd)?;
345345

346-
block_on(obj.lseek(offset, whence), None)
346+
block_on(async { obj.read().await.lseek(offset, whence).await }, None)
347347
}
348348

349349
pub(crate) fn chmod(fd: FileDescriptor, mode: AccessPermission) -> io::Result<()> {
350350
let obj = get_object(fd)?;
351351

352-
block_on(obj.chmod(mode), None)
352+
block_on(async { obj.read().await.chmod(mode).await }, None)
353353
}
354354

355355
pub(crate) fn write(fd: FileDescriptor, buf: &[u8]) -> io::Result<usize> {
@@ -359,12 +359,12 @@ pub(crate) fn write(fd: FileDescriptor, buf: &[u8]) -> io::Result<usize> {
359359
return Ok(0);
360360
}
361361

362-
block_on(obj.write(buf), None)
362+
block_on(async { obj.read().await.write(buf).await }, None)
363363
}
364364

365365
pub(crate) fn truncate(fd: FileDescriptor, length: usize) -> io::Result<()> {
366366
let obj = get_object(fd)?;
367-
block_on(obj.truncate(length), None)
367+
block_on(async { obj.read().await.truncate(length).await }, None)
368368
}
369369

370370
async fn poll_fds(fds: &mut [PollFd]) -> io::Result<u64> {
@@ -375,7 +375,7 @@ async fn poll_fds(fds: &mut [PollFd]) -> io::Result<u64> {
375375
let fd = i.fd;
376376
i.revents = PollEvent::empty();
377377
if let Ok(obj) = core_scheduler().get_object(fd) {
378-
let mut pinned = core::pin::pin!(obj.poll(i.events));
378+
let mut pinned = core::pin::pin!(async { obj.read().await.poll(i.events).await });
379379
if let Ready(Ok(e)) = pinned.as_mut().poll(cx)
380380
&& !e.is_empty()
381381
{
@@ -416,7 +416,7 @@ pub fn poll(fds: &mut [PollFd], timeout: Option<Duration>) -> io::Result<u64> {
416416

417417
pub fn fstat(fd: FileDescriptor) -> io::Result<FileAttr> {
418418
let obj = get_object(fd)?;
419-
block_on(obj.fstat(), None)
419+
block_on(async { obj.read().await.fstat().await }, None)
420420
}
421421

422422
/// Wait for some event on a file descriptor.
@@ -440,16 +440,20 @@ pub fn fstat(fd: FileDescriptor) -> io::Result<FileAttr> {
440440
pub fn eventfd(initval: u64, flags: EventFlags) -> io::Result<FileDescriptor> {
441441
let obj = self::eventfd::EventFd::new(initval, flags);
442442

443-
let fd = core_scheduler().insert_object(Arc::new(obj))?;
443+
let fd = core_scheduler().insert_object(Arc::new(async_lock::RwLock::new(obj)))?;
444444

445445
Ok(fd)
446446
}
447447

448-
pub(crate) fn get_object(fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
448+
pub(crate) fn get_object(
449+
fd: FileDescriptor,
450+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
449451
core_scheduler().get_object(fd)
450452
}
451453

452-
pub(crate) fn insert_object(obj: Arc<dyn ObjectInterface>) -> io::Result<FileDescriptor> {
454+
pub(crate) fn insert_object(
455+
obj: Arc<async_lock::RwLock<dyn ObjectInterface>>,
456+
) -> io::Result<FileDescriptor> {
453457
core_scheduler().insert_object(obj)
454458
}
455459

@@ -465,11 +469,13 @@ pub(crate) fn dup_object2(fd1: FileDescriptor, fd2: FileDescriptor) -> io::Resul
465469
core_scheduler().dup_object2(fd1, fd2)
466470
}
467471

468-
pub(crate) fn remove_object(fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
472+
pub(crate) fn remove_object(
473+
fd: FileDescriptor,
474+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
469475
core_scheduler().remove_object(fd)
470476
}
471477

472478
pub(crate) fn isatty(fd: FileDescriptor) -> io::Result<bool> {
473479
let obj = get_object(fd)?;
474-
block_on(obj.isatty(), None)
480+
block_on(async { obj.read().await.isatty().await }, None)
475481
}

src/fd/socket/tcp.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,12 @@ impl ObjectInterface for async_lock::RwLock<Socket> {
496496
self.read().await.connect(endpoint).await
497497
}
498498

499-
async fn accept(&self) -> io::Result<(Arc<dyn ObjectInterface>, Endpoint)> {
499+
async fn accept(&self) -> io::Result<(Arc<async_lock::RwLock<dyn ObjectInterface>>, Endpoint)> {
500500
let (socket, endpoint) = self.write().await.accept().await?;
501-
Ok((Arc::new(async_lock::RwLock::new(socket)), endpoint))
501+
Ok((
502+
Arc::new(async_lock::RwLock::new(async_lock::RwLock::new(socket))),
503+
endpoint,
504+
))
502505
}
503506

504507
async fn getpeername(&self) -> io::Result<Option<Endpoint>> {

src/fd/socket/vsock.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,9 @@ impl ObjectInterface for async_lock::RwLock<Socket> {
442442
self.write().await.connect(endpoint).await
443443
}
444444

445-
async fn accept(&self) -> io::Result<(Arc<dyn ObjectInterface>, Endpoint)> {
445+
async fn accept(&self) -> io::Result<(Arc<async_lock::RwLock<dyn ObjectInterface>>, Endpoint)> {
446446
let (handle, endpoint) = self.write().await.accept().await?;
447-
Ok((Arc::new(handle), endpoint))
447+
Ok((Arc::new(async_lock::RwLock::new(handle)), endpoint))
448448
}
449449

450450
async fn getpeername(&self) -> io::Result<Option<Endpoint>> {

src/fs/fuse.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,8 +1123,10 @@ impl VfsNode for FuseDirectory {
11231123
Ok(self.attr)
11241124
}
11251125

1126-
fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
1127-
Ok(Arc::new(FuseDirectoryHandle::new(self.prefix.clone())))
1126+
fn get_object(&self) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
1127+
Ok(Arc::new(async_lock::RwLock::new(FuseDirectoryHandle::new(
1128+
self.prefix.clone(),
1129+
))))
11281130
}
11291131

11301132
fn traverse_readdir(&self, components: &mut Vec<&str>) -> io::Result<Vec<DirectoryEntry>> {
@@ -1253,7 +1255,7 @@ impl VfsNode for FuseDirectory {
12531255
components: &mut Vec<&str>,
12541256
opt: OpenOption,
12551257
mode: AccessPermission,
1256-
) -> io::Result<Arc<dyn ObjectInterface>> {
1258+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
12571259
let path = self.traversal_path(components);
12581260

12591261
debug!("FUSE open: {path:#?}, {opt:?} {mode:?}");
@@ -1275,7 +1277,9 @@ impl VfsNode for FuseDirectory {
12751277
if attr.st_mode.contains(AccessPermission::S_IFDIR) {
12761278
let mut path = path.into_string().unwrap();
12771279
path.remove(0);
1278-
Ok(Arc::new(FuseDirectoryHandle::new(Some(path))))
1280+
Ok(Arc::new(async_lock::RwLock::new(FuseDirectoryHandle::new(
1281+
Some(path),
1282+
))))
12791283
} else {
12801284
Err(Errno::Notdir)
12811285
}
@@ -1320,7 +1324,7 @@ impl VfsNode for FuseDirectory {
13201324

13211325
drop(file_guard);
13221326

1323-
Ok(Arc::new(file))
1327+
Ok(Arc::new(async_lock::RwLock::new(file)))
13241328
}
13251329
}
13261330

src/fs/mem.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,10 @@ impl VfsNode for RomFile {
294294
NodeKind::File
295295
}
296296

297-
fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
298-
Ok(Arc::new(RomFileInterface::new(self.data.clone())))
297+
fn get_object(&self) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
298+
Ok(Arc::new(async_lock::RwLock::new(RomFileInterface::new(
299+
self.data.clone(),
300+
))))
299301
}
300302

301303
fn get_file_attributes(&self) -> io::Result<FileAttr> {
@@ -348,8 +350,10 @@ impl VfsNode for RamFile {
348350
NodeKind::File
349351
}
350352

351-
fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
352-
Ok(Arc::new(RamFileInterface::new(self.data.clone())))
353+
fn get_object(&self) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
354+
Ok(Arc::new(async_lock::RwLock::new(RamFileInterface::new(
355+
self.data.clone(),
356+
))))
353357
}
354358

355359
fn get_file_attributes(&self) -> io::Result<FileAttr> {
@@ -502,7 +506,7 @@ impl MemDirectory {
502506
components: &mut Vec<&str>,
503507
opt: OpenOption,
504508
mode: AccessPermission,
505-
) -> io::Result<Arc<dyn ObjectInterface>> {
509+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
506510
if let Some(component) = components.pop() {
507511
let node_name = String::from(component);
508512

@@ -523,7 +527,9 @@ impl MemDirectory {
523527
} else if opt.contains(OpenOption::O_CREAT) {
524528
let file = Box::new(RamFile::new(mode));
525529
guard.insert(node_name, file.clone());
526-
return Ok(Arc::new(RamFileInterface::new(file.data.clone())));
530+
return Ok(Arc::new(async_lock::RwLock::new(RamFileInterface::new(
531+
file.data.clone(),
532+
))));
527533
} else {
528534
return Err(Errno::Noent);
529535
}
@@ -543,8 +549,10 @@ impl VfsNode for MemDirectory {
543549
NodeKind::Directory
544550
}
545551

546-
fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
547-
Ok(Arc::new(MemDirectoryInterface::new(self.inner.clone())))
552+
fn get_object(&self) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
553+
Ok(Arc::new(async_lock::RwLock::new(
554+
MemDirectoryInterface::new(self.inner.clone()),
555+
)))
548556
}
549557

550558
fn get_file_attributes(&self) -> io::Result<FileAttr> {
@@ -735,7 +743,7 @@ impl VfsNode for MemDirectory {
735743
components: &mut Vec<&str>,
736744
opt: OpenOption,
737745
mode: AccessPermission,
738-
) -> io::Result<Arc<dyn ObjectInterface>> {
746+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
739747
block_on(self.async_traverse_open(components, opt, mode), None)
740748
}
741749

src/fs/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub(crate) trait VfsNode: core::fmt::Debug {
5959
}
6060

6161
/// Determine the syscall interface
62-
fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
62+
fn get_object(&self) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
6363
Err(Errno::Nosys)
6464
}
6565

@@ -112,7 +112,7 @@ pub(crate) trait VfsNode: core::fmt::Debug {
112112
_components: &mut Vec<&str>,
113113
_option: OpenOption,
114114
_mode: AccessPermission,
115-
) -> io::Result<Arc<dyn ObjectInterface>> {
115+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
116116
Err(Errno::Nosys)
117117
}
118118

@@ -162,7 +162,7 @@ impl Filesystem {
162162
path: &str,
163163
opt: OpenOption,
164164
mode: AccessPermission,
165-
) -> io::Result<Arc<dyn ObjectInterface>> {
165+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
166166
debug!("Open file {path} with {opt:?}");
167167
let mut components: Vec<&str> = path.split('/').collect();
168168

@@ -205,9 +205,11 @@ impl Filesystem {
205205
self.root.traverse_mkdir(&mut components, mode)
206206
}
207207

208-
pub fn opendir(&self, path: &str) -> io::Result<Arc<dyn ObjectInterface>> {
208+
pub fn opendir(&self, path: &str) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
209209
debug!("Open directory {path}");
210-
Ok(Arc::new(DirectoryReader::new(self.readdir(path)?)))
210+
Ok(Arc::new(async_lock::RwLock::new(DirectoryReader::new(
211+
self.readdir(path)?,
212+
))))
211213
}
212214

213215
/// List given directory
@@ -447,7 +449,7 @@ pub fn truncate(name: &str, size: usize) -> io::Result<()> {
447449
with_relative_filename(name, |name| {
448450
let fs = FILESYSTEM.get().ok_or(Errno::Inval)?;
449451
if let Ok(file) = fs.open(name, OpenOption::O_TRUNC, AccessPermission::empty()) {
450-
block_on(file.truncate(size), None)
452+
block_on(async { file.read().await.truncate(size).await }, None)
451453
} else {
452454
Err(Errno::Badf)
453455
}

src/fs/uhyve.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl VfsNode for UhyveDirectory {
171171
components: &mut Vec<&str>,
172172
opt: OpenOption,
173173
mode: AccessPermission,
174-
) -> io::Result<Arc<dyn ObjectInterface>> {
174+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
175175
let path = self.traversal_path(components);
176176

177177
let mut open_params = OpenParams {
@@ -187,7 +187,9 @@ impl VfsNode for UhyveDirectory {
187187
uhyve_hypercall(Hypercall::FileOpen(&mut open_params));
188188

189189
if open_params.ret > 0 {
190-
Ok(Arc::new(UhyveFileHandle::new(open_params.ret)))
190+
Ok(Arc::new(async_lock::RwLock::new(UhyveFileHandle::new(
191+
open_params.ret,
192+
))))
191193
} else {
192194
Err(Errno::Io)
193195
}

src/scheduler/mod.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,11 @@ struct NewTask {
220220
prio: Priority,
221221
core_id: CoreId,
222222
stacks: TaskStacks,
223-
object_map: Arc<RwSpinLock<HashMap<FileDescriptor, Arc<dyn ObjectInterface>, RandomState>>>,
223+
object_map: Arc<
224+
RwSpinLock<
225+
HashMap<FileDescriptor, Arc<async_lock::RwLock<dyn ObjectInterface>>, RandomState>,
226+
>,
227+
>,
224228
}
225229

226230
impl From<NewTask> for Task {
@@ -457,14 +461,21 @@ impl PerCoreScheduler {
457461
#[inline]
458462
pub fn get_current_task_object_map(
459463
&self,
460-
) -> Arc<RwSpinLock<HashMap<FileDescriptor, Arc<dyn ObjectInterface>, RandomState>>> {
464+
) -> Arc<
465+
RwSpinLock<
466+
HashMap<FileDescriptor, Arc<async_lock::RwLock<dyn ObjectInterface>>, RandomState>,
467+
>,
468+
> {
461469
without_interrupts(|| self.current_task.borrow().object_map.clone())
462470
}
463471

464472
/// Map a file descriptor to their IO interface and returns
465473
/// the shared reference
466474
#[inline]
467-
pub fn get_object(&self, fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
475+
pub fn get_object(
476+
&self,
477+
fd: FileDescriptor,
478+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
468479
without_interrupts(|| {
469480
let current_task = self.current_task.borrow();
470481
let object_map = current_task.object_map.read();
@@ -477,9 +488,11 @@ impl PerCoreScheduler {
477488
#[cfg(feature = "common-os")]
478489
#[cfg_attr(not(target_arch = "x86_64"), expect(dead_code))]
479490
pub fn recreate_objmap(&self) -> io::Result<()> {
480-
let mut map = HashMap::<FileDescriptor, Arc<dyn ObjectInterface>, RandomState>::with_hasher(
481-
RandomState::with_seeds(0, 0, 0, 0),
482-
);
491+
let mut map = HashMap::<
492+
FileDescriptor,
493+
Arc<async_lock::RwLock<dyn ObjectInterface>>,
494+
RandomState,
495+
>::with_hasher(RandomState::with_seeds(0, 0, 0, 0));
483496

484497
without_interrupts(|| {
485498
let mut current_task = self.current_task.borrow_mut();
@@ -501,7 +514,10 @@ impl PerCoreScheduler {
501514

502515
/// Insert a new IO interface and returns a file descriptor as
503516
/// identifier to this object
504-
pub fn insert_object(&self, obj: Arc<dyn ObjectInterface>) -> io::Result<FileDescriptor> {
517+
pub fn insert_object(
518+
&self,
519+
obj: Arc<async_lock::RwLock<dyn ObjectInterface>>,
520+
) -> io::Result<FileDescriptor> {
505521
without_interrupts(|| {
506522
let current_task = self.current_task.borrow();
507523
let mut object_map = current_task.object_map.write();
@@ -576,7 +592,10 @@ impl PerCoreScheduler {
576592
}
577593

578594
/// Remove a IO interface, which is named by the file descriptor
579-
pub fn remove_object(&self, fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
595+
pub fn remove_object(
596+
&self,
597+
fd: FileDescriptor,
598+
) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
580599
without_interrupts(|| {
581600
let current_task = self.current_task.borrow();
582601
let mut object_map = current_task.object_map.write();

0 commit comments

Comments
 (0)