Linux kernel 文件操作问题,我如何知道打开文件进行写入的进程是否决定关闭它?

Linux kernel 文件操作问题,我如何知道打开文件进行写入的进程是否决定关闭它?,linux-kernel,kernel,kernel-module,Linux Kernel,Kernel,Kernel Module,我目前正在编写一个简单的“Multicast”模块 只有一个进程可以打开proc文件系统文件进行写入,其余进程可以打开它进行读取。 为此,我使用inode_操作.permission回调,检查操作,当我检测到有人打开文件进行写入时,我设置一个标记 我需要一种方法来检测打开文件进行写入的进程是否已决定关闭该文件,以便我可以关闭该标志,以便其他人可以打开进行写入 当前,如果有人打开进行写入,我将保存该进程的当前->pid,当调用.close回调时,我将检查该进程是否是我先前保存的进程 有更好的方法吗

我目前正在编写一个简单的“Multicast”模块

只有一个进程可以打开proc文件系统文件进行写入,其余进程可以打开它进行读取。 为此,我使用inode_操作.permission回调,检查操作,当我检测到有人打开文件进行写入时,我设置一个标记

我需要一种方法来检测打开文件进行写入的进程是否已决定关闭该文件,以便我可以关闭该标志,以便其他人可以打开进行写入

当前,如果有人打开进行写入,我将保存该进程的当前->pid,当调用.close回调时,我将检查该进程是否是我先前保存的进程

有更好的方法吗?如果不保存pid,可能会检查当前进程已打开的文件及其权限


谢谢

我希望我正确理解了您的问题:当有人想写入您的proc文件时,您将一个名为flag的变量设置为1,并将当前->pid保存在一个全局变量中。然后,当调用任何close()入口点时,检查close()实例的current->pid,并将其与保存的值进行比较。如果匹配,则将标志关闭。对吧?

考虑这种情况:进程A想要写入您的进程资源,因此您需要检查权限回调。您可以看到标志是0,因此您可以为进程A将其设置为1。但此时,调度程序发现进程A已用完其时间共享,并选择另一个进程运行(标志仍然是o!)。过了一段时间,进程B也想写入您的proc资源,检查标志是否为0,将其设置为1,然后开始写入文件。不幸的是,此时,进程A被安排再次运行,因为它认为标志是0(记住,在调度程序抢占它之前,标志是0),所以将其设置为1并开始写入文件。最终结果:proc资源中的数据损坏


对于这种类型的操作,您应该使用内核提供的良好锁定机制,并且根据您的要求,我认为RCU是最好的:查看一下

不,它不安全。考虑以下几种情况:

  • 进程A打开文件进行写入,然后
    fork()
    s创建进程B。现在,A和B都打开文件进行写入。当进程A将其关闭时,您将标志设置为0,但进程B仍将其打开以进行写入

  • 进程A有多个线程。线程X打开文件进行写入,但线程Y将其关闭。现在旗帜被固定在1。(请记住,内核空间中的
    ->pid
    实际上是用户空间线程ID)

您不应该在inode级别执行操作,而应该在
文件操作的
结构的
.open
.release
方法中执行操作

inode的私有数据应该包含一个
struct file*current\u writer,初始化为
NULL
。在
file_operations.open
方法中,如果要将其打开以进行写入,则检查
当前_writer
;如果为空,请将其设置为正在打开的
struct file*
,否则,请使用
EPERM
使打开失败。在
file\u operations.release
方法中,检查正在释放的
struct file*
是否等于inode的
current\u writer
——如果是,将
current\u writer
设置回
NULL


PS:Bandan同样正确,您需要锁定,但是使用inode现有的
i\u互斥体
应该足以保护
当前写入程序

上下文开关不取决于代码中的内容。尽管如此,它还是会发生的。很抱歉,如果我的回答不够清楚,但我说的是用锁替换实现中的“标志”。如果你愿意,让我知道,我可以在答案中添加一个例子。同意,这是一个更好的场景,更可能发生。