mirror of
https://github.com/sysprog21/lkmpg.git
synced 2024-11-22 10:46:14 +08:00
Fix: blocking O_NONBLOCK process bug in sleep.c
There is a subtle bug that if the atomic flag changes between the time it was checked and the second time it was checked, sleep.c would potentially block a process that had specified O_NONBLOCK. This fixes the bug by using atomic_cmpxchg instead of atomic_read.
This commit is contained in:
parent
84cc7fee1c
commit
4adbf1dd9b
|
@ -92,12 +92,18 @@ static DECLARE_WAIT_QUEUE_HEAD(waitq);
|
|||
/* Called when the /proc file is opened */
|
||||
static int module_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
/* Try to get without blocking */
|
||||
if (!atomic_cmpxchg(&already_open, 0, 1)) {
|
||||
/* Success without blocking, allow the access */
|
||||
try_module_get(THIS_MODULE);
|
||||
return 0;
|
||||
}
|
||||
/* If the file's flags include O_NONBLOCK, it means the process does not
|
||||
* want to wait for the file. In this case, if the file is already open,
|
||||
* want to wait for the file. In this case, because the file is already open,
|
||||
* we should fail with -EAGAIN, meaning "you will have to try again",
|
||||
* instead of blocking a process which would rather stay awake.
|
||||
*/
|
||||
if ((file->f_flags & O_NONBLOCK) && atomic_read(&already_open))
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
/* This is the correct place for try_module_get(THIS_MODULE) because if
|
||||
|
|
Loading…
Reference in New Issue
Block a user