[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFC: [PATCH] trans/fakeroot.c

From: Samuel Thibault
Subject: Re: RFC: [PATCH] trans/fakeroot.c
Date: Mon, 12 Oct 2015 00:35:51 +0200
User-agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30)

Svante Signell, le Sun 11 Oct 2015 23:02:16 +0200, a écrit :
> > We also see from the printout that
> > nn->openmodes = 2 = O_WRITE and
> > newmodes = 1 = O_READ i.e. no intersecting sets.
> > 
> The above condition is really happening when building (patched to
> build, not related to fakeroot) gpsd.

Ok. It makes complete sense: we've been writing to a file, and now we
are reading from it.

>  --- a/trans/fakeroot.c.orig  2015-10-08 22:32:09.000000000 +0200
> +++ b/trans/fakeroot.c        2015-10-08 22:34:47.000000000 +0200
> @@ -216,9 +216,9 @@
>      {
>        /* The user wants openmodes we haven't tried before.  */
> -      if (file != MACH_PORT_NULL && (nn->openmodes & ~newmodes))
> +      if (file != MACH_PORT_NULL && (nn->openmodes & newmodes))
>       {
> -       /* Intersecting sets with no inclusion. `file' doesn't fit
> either,
> +       /* Intersecting sets. `file' doesn't fit either,

But this doesn't make sense!  Let me explain in detail what
check_openmodes does:

- we have an existing node, nn, which contains an opened file nn->file,
  opened with modes nn->openmodes.
- we want to have it opened with nn->openmodes | newmodes.
- the 'file' port parameter happens to be that file opened with


- either nn->openmodes already contains the newmodes bits, nn->file is
thus already the file opened with modes nn->openmodes | newmodes
- or it doesn't, and so we have to do something:
  - if newmodes actually contains all the nn->openmodes bit, then the
  'file' port is just what we need, and there is no need to reopen the
  - otherwise the 'file' port is useless, so we should just close it,
  and really reopen the file with nn->openmodes | newmodes.

So the condition for closing the file and making it null is
"nn->openmodes has bits that newmodes doesn't have".  That happens to
translate to "nn->openmodes & ~newmodes".  If I'm wrong somewhere in my
reasoning (which can probably be very true), please tell me where.

Just saying "that testcase works with my patch" is not enough to
convince me to apply it, because there are so many other cases. In the
testcase you mention above:

> > nn->openmodes = 2 = O_WRITE and
> > newmodes = 1 = O_READ i.e. no intersecting sets.

(nn->openmodes & ~newmodes) will be O_WRITE, which shows that we have an
existing file opened with O_WRITE, but the provided 'file' port doesn't
have it (as announced by newmodes). And thus we *have* to destroy the
'file' port and not use it, and instead reopen the file to really get
O_WRITE|O_READ: otherwise we wouldn't have O_WRITE any more, which will
pose problem whenever we want to write to it again.

In the other testcase you mentioned in your previous mail:

> nn->openmodes = 1 = O_READ and
> newmodes = 3 = O_READ | O_WRITE,

We have an existing file opened in O_READ, and now we want
O_READ|O_WRITE. The existing file is not enough, it's missing O_WRITE
(newmodes &~ nn->openmodes returns O_WRITE), but the provided 'file'
port has both O_READ|O_WRITE, so we can just use it, there is no need to
reopen the file, it'll cover both the original need (O_READ) as tested
by nn->openmodes & ~newmodes being 0, and the new need (O_READ|O_WRITE).

> I told you, the test should be inclusive, not exclusive :)

You didn't prove why. Testcases are good when they cover all cases.
Otherwise they are just an indication of something is going wrong, not
that the proposed fix is always right.

Either what I said above is wrong at some point, or the bug is somewhere
else (see the previous changes we had to make in netfs_attempt_chmod for
instance).  What call *actually* produces the permission denied error,
BTW?  In our previous exchange it was actually the reopen operation.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]