Subject: Re: Unionfs write problem with RO bottom layer.
To: Martin S. Weber <Ephaeton@gmx.net>
From: Thor Lancelot Simon <tls@rek.tjls.com>
List: tech-kern
Date: 11/28/2007 10:13:53
On Wed, Nov 28, 2007 at 01:24:53PM +0100, Martin S. Weber wrote:
> On Tue, Nov 27, 2007 at 08:08:49PM -0500, Thor Lancelot Simon wrote:
> > (...)
> > To reproduce:
> >
> > 1) Mount /l0 read-write
> > 2) touch /l0/foo
> > 3) Remount /l0 read-only
> > 4) Mount /l1 read-write
> > 4) Union mount /l1 over /l0: mount_union /l1 /l0
> > 5) cat > /l0/foo or cat >> /l0/foo (either will fail with EROFS).
>
> It is, imho because it initializes the union vnodes in a wrong way,
> effectively nulling permissions et al instead of copying them up
> from the lower layer.
It looks to me as if union_access with a read-only lower layer has always
had this bug (checking permissions of lower-layer vnode if upper-layer
node doesn't exist; never creating a new upper-layer node as union_open
does, thus finding lower layers only) for ever. And since vn_open has
always had two calls to VOP_ACCESS() before theV VOP_OPEN, I can't see
why it ever worked.
Basically, when you land in union_access trying to write a node that
presently exists only in the lower layer, it appears to me that un_uppervp
will always be NULLVP. The permission checks will then be passed through
to the lower-layer filesystem via the VOP_CALL of lowervp's VOP_ACCESS,
which is wrong, since if lowervp is on a read only filesystem this will
give EROFS even though if there were an attempt to create uppervp via
union_open(), it would in fact succeed.
If you have a patch that makes this work, I'd love to see it. If you
think it worked in 4.0, I'm confused as to how, since AFAICT none of
the relevant code has changed. Though I, too, could swear I used union
with a read-only lower layer before -- it was cd9660, not ffs, in my
case as well, but I don't see why that should matter.
The instructions I gave for reproducing the bug work with FFS. What
happens if you follow those exact steps with CD9660?
Thor