|
@@ -1,3 +1,5 @@
|
|
|
+use core::sync::atomic::AtomicI32;
|
|
|
+
|
|
|
use alloc::sync::{Arc, Weak};
|
|
|
|
|
|
use crate::{
|
|
@@ -6,13 +8,12 @@ use crate::{
|
|
|
vfs::{core::generate_inode_id, file::FileMode, FileType, IndexNode, Metadata, PollStatus},
|
|
|
},
|
|
|
include::bindings::bindings::{vfs_file_operations_t, vfs_file_t, vfs_index_node_t, ENOTSUP},
|
|
|
- kdebug,
|
|
|
- libs::spinlock::SpinLock,
|
|
|
+ libs::rwlock::RwLock,
|
|
|
time::TimeSpec,
|
|
|
};
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
-pub struct LockedPS2KeyBoardInode(SpinLock<PS2KeyBoardInode>);
|
|
|
+pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>, AtomicI32); // self.1 用来记录有多少个文件打开了这个inode
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
pub struct PS2KeyBoardInode {
|
|
@@ -53,8 +54,11 @@ impl LockedPS2KeyBoardInode {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
- let result = Arc::new(LockedPS2KeyBoardInode(SpinLock::new(inode)));
|
|
|
- result.0.lock().self_ref = Arc::downgrade(&result);
|
|
|
+ let result = Arc::new(LockedPS2KeyBoardInode(
|
|
|
+ RwLock::new(inode),
|
|
|
+ AtomicI32::new(0),
|
|
|
+ ));
|
|
|
+ result.0.write().self_ref = Arc::downgrade(&result);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
@@ -62,7 +66,7 @@ impl LockedPS2KeyBoardInode {
|
|
|
|
|
|
impl DeviceINode for LockedPS2KeyBoardInode {
|
|
|
fn set_fs(&self, fs: Weak<DevFS>) {
|
|
|
- self.0.lock().fs = fs;
|
|
|
+ self.0.write().fs = fs;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -80,7 +84,7 @@ impl IndexNode for LockedPS2KeyBoardInode {
|
|
|
buf: &mut [u8],
|
|
|
_data: &mut crate::filesystem::vfs::FilePrivateData,
|
|
|
) -> Result<usize, i32> {
|
|
|
- let guard = self.0.lock();
|
|
|
+ let guard = self.0.read();
|
|
|
let func = guard.f_ops.read.unwrap();
|
|
|
let r = unsafe {
|
|
|
func(
|
|
@@ -108,16 +112,24 @@ impl IndexNode for LockedPS2KeyBoardInode {
|
|
|
_data: &mut crate::filesystem::vfs::FilePrivateData,
|
|
|
_mode: &FileMode,
|
|
|
) -> Result<(), i32> {
|
|
|
- let guard = self.0.lock();
|
|
|
- let func = guard.f_ops.open.unwrap();
|
|
|
- let _ = unsafe { func(0 as *mut vfs_index_node_t, 0 as *mut vfs_file_t) };
|
|
|
+ let prev_ref_count = self.1.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
|
|
|
+ if prev_ref_count == 0 {
|
|
|
+ // 第一次打开,需要初始化
|
|
|
+ let guard = self.0.write();
|
|
|
+ let func = guard.f_ops.open.unwrap();
|
|
|
+ let _ = unsafe { func(0 as *mut vfs_index_node_t, 0 as *mut vfs_file_t) };
|
|
|
+ }
|
|
|
return Ok(());
|
|
|
}
|
|
|
|
|
|
fn close(&self, _data: &mut crate::filesystem::vfs::FilePrivateData) -> Result<(), i32> {
|
|
|
- let guard = self.0.lock();
|
|
|
- let func = guard.f_ops.close.unwrap();
|
|
|
- let _ = unsafe { func(0 as *mut vfs_index_node_t, 0 as *mut vfs_file_t) };
|
|
|
+ let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
|
|
|
+ if prev_ref_count == 1 {
|
|
|
+ // 最后一次关闭,需要释放
|
|
|
+ let guard = self.0.write();
|
|
|
+ let func = guard.f_ops.close.unwrap();
|
|
|
+ let _ = unsafe { func(0 as *mut vfs_index_node_t, 0 as *mut vfs_file_t) };
|
|
|
+ }
|
|
|
return Ok(());
|
|
|
}
|
|
|
|
|
@@ -128,11 +140,11 @@ impl IndexNode for LockedPS2KeyBoardInode {
|
|
|
}
|
|
|
|
|
|
fn metadata(&self) -> Result<Metadata, i32> {
|
|
|
- return Ok(self.0.lock().metadata.clone());
|
|
|
+ return Ok(self.0.read().metadata.clone());
|
|
|
}
|
|
|
|
|
|
fn set_metadata(&self, metadata: &Metadata) -> Result<(), i32> {
|
|
|
- let mut inode = self.0.lock();
|
|
|
+ let mut inode = self.0.write();
|
|
|
inode.metadata.atime = metadata.atime;
|
|
|
inode.metadata.mtime = metadata.mtime;
|
|
|
inode.metadata.ctime = metadata.ctime;
|
|
@@ -144,7 +156,7 @@ impl IndexNode for LockedPS2KeyBoardInode {
|
|
|
}
|
|
|
|
|
|
fn fs(&self) -> alloc::sync::Arc<dyn crate::filesystem::vfs::FileSystem> {
|
|
|
- return self.0.lock().fs.upgrade().unwrap();
|
|
|
+ return self.0.read().fs.upgrade().unwrap();
|
|
|
}
|
|
|
|
|
|
fn as_any_ref(&self) -> &dyn core::any::Any {
|