[设计问题] SocketInode多余的引用计数问题

对于 inet socket,不需要引用计数来维护 SocketInode,raw udp完全不需要,而 tcp accept的新 “socket” 会有额外的 SocketInode;即使有dup等,其inode的open-close也应由外部统一维护而非内部进行引用计数。
对于 unix socket,观察到其确实有对同一socket多次open的行为(其引用计数会>1)。然而,

  1. 其open-close的维护仍然由外部统一维护,并不会出错
  2. 根据以下,也不存在资源泄露的问题,包括其自身close行为不做任何事。

因此我提议移除 SocketInode 多余的引用计数设计

SocketInode 相关代码段简化为以下部分,运行正常:

/// # Socket在文件系统中的inode封装
#[derive(Debug)]
pub struct SocketInode(SpinLock<Box<dyn Socket>>);

impl SocketInode {
    pub fn new(socket: Box<dyn Socket>) -> Arc<Self> {
        Arc::new(Self(SpinLock::new(socket)))
    }

    #[inline]
    pub fn inner(&self) -> SpinLockGuard<Box<dyn Socket>> {
        self.0.lock()
    }

    pub unsafe fn inner_no_preempt(&self) -> SpinLockGuard<Box<dyn Socket>> {
        self.0.lock_no_preempt()
    }
}

impl IndexNode for SocketInode {
    fn open(
        &self,
        _data: SpinLockGuard<FilePrivateData>,
        _mode: &FileMode,
    ) -> Result<(), SystemError> {
        Ok(())
    }

    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
        let mut socket = self.0.lock_irqsave();

        if socket.metadata().socket_type == SocketType::Unix {
            return Ok(());
        }

        if let Some(Endpoint::Ip(Some(ip))) = socket.endpoint() {
            PORT_MANAGER.unbind_port(socket.metadata().socket_type, ip.port);
        }

        socket.clear_epoll()?;

        HANDLE_MAP
            .write_irqsave()
            .remove(&socket.socket_handle())
            .unwrap();
        socket.close();

        Ok(())
    }
    // 剩下的内容省略

此处是抛砖引玉,我希望尽可能多地知道socket各方面设计的原因()

这个我熟,是我设计的
当时是为了在fork产生的多进程环境下确保所有进程都close了这个inode再关闭socket
你可以在github里翻翻我的pr(直接看文件历史可能找不到,我移动过这部分文件