I’m currently writing a simple “multicaster” module.
Only one process can open a proc filesystem file for writing, and the rest can open it for reading.
To do so i use the inode_operation .permission callback, I check the operation and when i detect someone open a file for writing I set a flag ON.
i need a way to detect if a process that opened a file for writing has decided to close the file so i can set the flag OFF, so someone else can open for writing.
Currently in case someone is open for writing i save the current->pid of that process and when the .close callback is called I check if that process is the one I saved earlier.
Is there a better way to do that? Without saving the pid, perhaps checking the files that the current process has opened and it’s permission…
Thanks!
No, it’s not safe. Consider a few scenarios:
Process A opens the file for writing, and then
fork()s, creating process B. Now both A and B have the file open for writing. When Process A closes it, you set the flag to 0 but process B still has it open for writing.Process A has multiple threads. Thread X opens the file for writing, but Thread Y closes it. Now the flag is stuck at 1. (Remember that
->pidin kernel space is actually the userspace thread ID).Rather than doing things at the inode level, you should be doing things in the
.openand.releasemethods of yourfile_operationsstruct.Your inode’s private data should contain a
struct file *current_writer;, initialised toNULL. In thefile_operations.openmethod, if it’s being opened for write then check thecurrent_writer; if it’s NULL, set it to thestruct file *being opened, otherwise fail the open withEPERM. In thefile_operations.releasemethod, check if thestruct file *being released is equal to the inode’scurrent_writer– if so, setcurrent_writerback toNULL.PS: Bandan is also correct that you need locking, but the using the inode’s existing
i_mutexshould suffice to protect thecurrent_writer.