Fwd: [LAST ROUND] fifo/pipe merge code

Giovanni Trematerra gianni at freebsd.org
Wed Feb 8 21:14:50 UTC 2012


On Wed, Feb 8, 2012 at 6:49 AM, Bruce Evans <brde at optusnet.com.au> wrote:
> On Tue, 7 Feb 2012, Giovanni Trematerra wrote:
>
>
> It looks quite good now.  I see only a few minor style bugs:

Hi Bruce,
Thank you to have found time to review the patch again.

I updated the patch and I hope I fixed all the minor style bugs
that you pointed out.

here the new one:
http://www.trematerra.net/patches/pipefifo_merge.4.4.patch

>
> % diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
> % index 94a2713..0d35877 100644
> % --- a/sys/fs/fifofs/fifo_vnops.c
> % +++ b/sys/fs/fifofs/fifo_vnops.c
> % ...
> % +int
> % +fifo_iseof(struct file *fp)
> % ...
> % +     KASSERT(fp->f_vnode != NULL, ("fifo_iseof: no vnode info."));
> % +     KASSERT(fp->f_vnode->v_fifoinfo != NULL, ("fifo_iseof: no
> fifoinfo."));
>
>
> I wonder if you can assert that some suitable lock is held here.
>
> % +     fip = fp->f_vnode->v_fifoinfo;
> % +     return (fp->f_seqcount == fip->fi_wgen);
> %  }
> % ...

Now I changed fifo_open to remove global fifo_mtx mutex, using PIPE_MTX,
and assert to be held in fifo_iseof.
I stress tested the patch with WITNESS and INVARIANT on and got no a panic
and no LOR.

>
> % @@ -1284,6 +1348,17 @@ pipe_ioctl(fp, cmd, data, active_cred, td)
> %               break;
> % %     case FIONREAD:
> % +
> % +             /*
> % +              * FIONREAD will return 0 for non-readable descriptors, and
> % +              * the results of FIONREAD on the read pipe for readable
> % +              * descriptors.
> % +              */
> % +             if (!(fp->f_flag & FREAD)) {
> % +                     *(int *)data = 0;
> % +                     PIPE_UNLOCK(mpipe);
> % +                     return (0);
> % +             }
> %               if (mpipe->pipe_state & PIPE_DIRECTW)
> %                       *(int *)data = mpipe->pipe_map.cnt;
> %               else

I completely removed that comment now. The code is clear enough.

>
> Urk, now I see many major style bugs:
>
> % @@ -1333,47 +1408,55 @@ pipe_poll(fp, events, active_cred, td)
> %       int error;
> %  #endif
> % % -   wpipe = rpipe->pipe_peer;
> % +     wpipe = PIPE_PEER(rpipe);
> %       PIPE_LOCK(rpipe);
> %  #ifdef MAC
> %       error = mac_pipe_check_poll(active_cred, rpipe->pipe_pair);
> %       if (error)
> %               goto locked_error;
> %  #endif
> % -     if (events & (POLLIN | POLLRDNORM))
> % -             if ((rpipe->pipe_state & PIPE_DIRECTW) ||
> % -                 (rpipe->pipe_buffer.cnt > 0))
> % -                     revents |= events & (POLLIN | POLLRDNORM);
> % -
> % -     if (events & (POLLOUT | POLLWRNORM))
> % -             if (wpipe->pipe_present != PIPE_ACTIVE ||
> % -                 (wpipe->pipe_state & PIPE_EOF) ||
> % -                 (((wpipe->pipe_state & PIPE_DIRECTW) == 0) &&
> % -                  ((wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >=
> PIPE_BUF ||
> % -                      wpipe->pipe_buffer.size == 0)))
> % -                     revents |= events & (POLLOUT | POLLWRNORM);
> % -
> % -     if ((events & POLLINIGNEOF) == 0) {
> % -             if (rpipe->pipe_state & PIPE_EOF) {
> % -                     revents |= (events & (POLLIN | POLLRDNORM));
> % -                     if (wpipe->pipe_present != PIPE_ACTIVE ||
> % -                         (wpipe->pipe_state & PIPE_EOF))
> % -                             revents |= POLLHUP;
> % +     if (fp->f_flag & FREAD) {
> % +             if (events & (POLLIN | POLLRDNORM))
> % +                     if ((rpipe->pipe_state & PIPE_DIRECTW) ||
> % +                         (rpipe->pipe_buffer.cnt > 0))
> % +                             revents |= events & (POLLIN | POLLRDNORM);
> % +
>
> This part of the patch is still unreadable since it indents everything to
> add FREAD and FWRITE checks.  I don't like those anyway (they should
> probably produce POLLERR POLLNVAL instead of ignoring the error -- see
> previous mail), but they are needed for now for compatibility in the
> FIFO case (hopefully they don't break compatibility for the plain pipe
> case).

I tried to make this part of the patch more readable, I hope I did.
Talking about returning POLLERR/POLLNVAL as I said previously,
I like to work on that and on making pipe/fifo implementation more POSIX
compliant just after the patch will be merge the tree.


> To avoid churning this code for them now and later when the
> behaviour is fixed, they should be added in a non-invasive way like the
> old fifo code did.  That involved using && instead of a nested if.  In
> the old code, everything was under the combined && if.  Now there are
> 3 nested ifs.  This logic change seems to be non-null and give bugs (1).
>
> % +             if (rpipe->pipe_state & PIPE_NAMED)
> % +                     if (fifo_iseof(fp))
>
> Here the (unrelated) nested if is just a style bug.  It gives verboseness
> and extra indentation.
>
> % +                             events |= POLLINIGNEOF;
> % +
>
> (1) In the old code, POLLINIGNEOF was only set here if we are polling for
> some input condition (and this is valid).  Now it is set if the file is
> just open for input.  Either way could be right, but this is a change.  If
> we are not polling for input, we don't care about it, but POSIX requires
> POLLHUP to be set in some cases, and this affects whether we return or
> block, and POLLINIGNEOF interacts with this subtly.  There may also be
> a problem not going through here to set POLLINIGNEOF in the !FREAD case.

Fixed. Thank you.

While I hope I didn't introduced new bugs, do you agree that at this point
the patch is in such a shape that makes it committable?

--
Gianni


More information about the freebsd-arch mailing list