Re: Linux device drivers: O_NONBLOCK in fops->open ...

From: Scott McPeak (smcpeak@EECS.Berkeley.EDU)
Date: 10/09/00


From: "Scott McPeak" <smcpeak@EECS.Berkeley.EDU>
Date: Mon, 9 Oct 2000 17:10:51 -0700 (PDT)
Subject: Re: Linux device drivers: O_NONBLOCK in fops->open ...
Message-ID: <Pine.LNX.4.21.0010091654490.6331-100000@yzermann.pasture.cow>


> Here's the question: Is the driver writer allowed to put a process
> to sleep (= block) in the open method if the O_NONBLOCK flag is
> set?

I don't see why not, regardless of the flag's setting.  You can put
the process to sleep whenever you want to, other caveats
notwithstanding (e.g. see below).  The only issue is whether the
client software can deal with it, but since it presumably knows what
device it's talking to etc. it just has to understand that driver's
behavior.  And lacking such understanding, blocking is safer than
returning -EAGAIN and hoping the client happens to check.

But one caveat on blocking write() -- there's a semaphore "down" just
before fops->write gets called, and a corresponding "up" on return
(see fs/read_write.c/sys_write()).  Thus, if you put the process to
sleep inside write(), you won't be able to field any more write()
requests on that device until the sleeping process wakes up.  Worse,
you won't even be able to kill (-9) the process that blocked while
down-ing the semaphore (!) until it unblocks.

My guess is someone decided most people can't implement concurrent
write() properly so they just made it disabled by default. 

The solution used in fs/pipe.c (and two other places) is to "up" the
semaphore on entry to write and "down" it before leaving.

(There's actually a bug in drivers/sound/emu10k1/audio.c, where they
do this on *read* as well as write, which up's the semaphore to 2,
almost certainly not what was intended.)

-Scott



This archive was generated by hypermail 2b30 : 11/04/02 PST