我目前正在编写一个简单的“多人”模块。
只有一个进程可以打开proc文件系统文件进行写入,其余进程可以打开它进行读取。 为此我使用inode_operation .permission回调,我检查操作,当我检测到有人打开文件进行写入时,我将标志设置为ON。
我需要一种方法来检测打开文件进行写入的进程是否已决定关闭文件,以便我可以将标志设置为OFF,这样其他人就可以打开进行写入了。
目前如果有人开放写作,我会保存该进程的 current-> pid ,并且当调用.close回调时,我会检查该进程是否是我之前保存的进程。 / p>
有没有更好的方法呢?不保存pid,也许检查当前进程已打开的文件及其权限......
谢谢!
答案 0 :(得分:2)
不,这不安全。考虑几个场景:
进程A打开文件进行写入,然后fork()
,创建进程B.现在A和B都打开文件进行写入。当进程A关闭它时,您将标志设置为0,但进程B仍然打开它进行写入。
进程A有多个线程。线程X打开文件进行写入,但线程Y将其关闭。现在标志位于1.(请记住,内核空间中的->pid
实际上是用户空间线程 ID。
您应该使用.open
结构的.release
和file_operations
方法执行操作,而不是在inode级别执行操作。
您的inode的私人数据应包含struct file *current_writer;
,初始化为NULL
。在file_operations.open
方法中,如果要将其打开以进行写入,请检查current_writer
;如果它为NULL,则将其设置为正在打开的struct file *
,否则将使用EPERM
打开。在file_operations.release
方法中,检查被释放的struct file *
是否等于inode的current_writer
- 如果是,请将current_writer
设置回NULL
。
PS:Bandan也是正确的,你需要锁定,但使用inode的现有i_mutex
应该足以保护current_writer
。
答案 1 :(得分:0)
我希望我能正确理解你的问题:当有人想写你的proc文件时,你将一个名为flag的变量设置为1,并将current-> pid保存在一个全局变量中。然后,当调用任何close()入口点时,检查close()实例的current-> pid并将其与保存的值进行比较。如果匹配,则将标志设置为关闭。对 ?
考虑这种情况:进程A想要写入您的proc资源,因此您检查权限回调。您看到该标志为0,因此您可以为进程A将其设置为1.但是在那一刻,调度程序发现进程A已经用完了它的时间共享并选择了另一个进程来运行(标志仍然是o!)。过了一段时间,进程B也想要写入你的proc资源,检查标志是否为0,将其设置为1,然后继续写入文件。不幸的是,此时,进程A被安排再次运行,因为它认为标志为0(记住,在调度程序抢占之前,标志为0),因此将其设置为1并继续写入文件。最终结果:proc资源中的数据损坏。
您应该使用内核提供的良好锁定机制来进行此类操作,并根据您的要求,我认为RCU是最好的:看看RCU locking mechanism