From: Ian Abbott <abbotti@mev.co.uk>
To: Hartley Sweeten <HartleyS@visionengravers.com>,
"driverdev-devel@linuxdriverproject.org"
<driverdev-devel@linuxdriverproject.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 4/7] staging: comedi: don't allow read() on async command set up for "write"
Date: Thu, 30 Oct 2014 21:00:29 +0000 [thread overview]
Message-ID: <5452A6ED.8090007@mev.co.uk> (raw)
In-Reply-To: <DC148C5AA1CEBA4E87973D432B1C2D8826017050@P3PWEX4MB008.ex4.secureserver.net>
On 30/10/14 20:45, Hartley Sweeten wrote:
> On Thursday, October 30, 2014 1:28 PM, Ian Abbott wrote:
>> On 30/10/14 18:05, Hartley Sweeten wrote:
>>> On Thursday, October 30, 2014 5:42 AM, Ian Abbott wrote:
>> [snip]
>>>> add_wait_queue(&async->wait_head, &wait);
>>>> while (nbytes > 0 && !retval) {
>>>> @@ -2249,6 +2253,10 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
>>>> retval = -EACCES;
>>>> break;
>>>> }
>>>> + if (async->cmd.flags & CMDF_WRITE) {
>>>> + retval = -EINVAL;
>>>> + break;
>>>> + }
>>>
>>> Is this second test really needed in the while() loop?
>>>
>>> For that matter, are the s->busy tests needed in the while() loop?
>>
>> To answer your second question, some other thread using the same file
>> object might have cancelled the asynchronous command, causing the
>> current thread to see that the command is no longer active when it wakes up.
>>
>> To answer your first question, that other thread might have managed to
>> set up another asynchronous command in before we wake up, and it might
>> have been set up as a "write" command (if the subdevice supports
>> commands in both directions). This doesn't detect the case when the
>> other thread has managed to set up another "read" command, but since the
>> current read() call hasn't read any data yet, we can just pretend we
>> didn't know about the original command and read data from the new
>> command instead. (After all, the calling thread can't prove the read()
>> started before the first command was cancelled, so we can just pretend
>> it didn't.)
>
> But when the command is first started by do_cmd_ioctl() we have this sequence:
>
> if (s->busy)
> return -EBUSY;
> ...
> s->busy = file;
> ret = s->do_cmd(dev, s);
>
> From then on the s->busy pointer can only be cleared in do_become_nonbusy()
> (by way of a (*cancel)). So another command cannot be started until the current
> command is completed.
The other thread could do its own read() after it cancelled the command,
which would clear the busy condition (once it returns 0 to indicate
end-of-file), so the current thread's read() still needs to check it.
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=-
-=( Web: http://www.mev.co.uk/ )=-
next prev parent reply other threads:[~2014-10-30 21:00 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-30 12:42 [PATCH 0/7] staging: comedi: enforce data transfer direction Ian Abbott
2014-10-30 12:42 ` [PATCH 1/7] staging: comedi: maybe force CMDF_WRITE command flag Ian Abbott
2014-10-30 12:42 ` [PATCH 2/7] staging: comedi: me4000: don't clobber command flags Ian Abbott
2014-10-30 12:42 ` [PATCH 3/7] staging: comedi: ni_mio_common: don't change CMDF_WRITE flag Ian Abbott
2014-10-30 12:42 ` [PATCH 4/7] staging: comedi: don't allow read() on async command set up for "write" Ian Abbott
2014-10-30 18:05 ` Hartley Sweeten
2014-10-30 20:27 ` Ian Abbott
2014-10-30 20:45 ` Hartley Sweeten
2014-10-30 21:00 ` Ian Abbott [this message]
2014-10-30 12:42 ` [PATCH 5/7] staging: comedi: don't allow write() on async command set up for "read" Ian Abbott
2014-10-30 18:07 ` Hartley Sweeten
2014-10-30 20:29 ` Ian Abbott
2014-10-30 12:42 ` [PATCH 6/7] staging: comedi: check command direction in poll() file operation Ian Abbott
2014-10-30 12:42 ` [PATCH 7/7] staging: comedi: check actual data direction for COMEDI_BUFINFO ioctl Ian Abbott
2014-10-30 21:29 ` [PATCH 0/7] staging: comedi: enforce data transfer direction Hartley Sweeten
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5452A6ED.8090007@mev.co.uk \
--to=abbotti@mev.co.uk \
--cc=HartleyS@visionengravers.com \
--cc=driverdev-devel@linuxdriverproject.org \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.