tmpfs: fix non-unique instance bug
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 14 Jun 2019 19:22:35 +0000 (15:22 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 11 Jul 2019 18:29:21 +0000 (14:29 -0400)
commit6f38e5adfad0b08531fb4327f1e122193121db92
tree6883d5b5b498a69ccb761a6b2f1930b5bc6c1470
parente5d5883667cbd780fba36913fecc68fef420159e
tmpfs: fix non-unique instance bug

tmpfs cleans itself up when it disappears.  QIDs within an instance were
unique, starting from 0.  However, QIDs *between* instances were not
unique!  Multiple instances would be separate TFSs, but they were
reusing QIDs.

Where's the problem with that?  Walk and whatnot happen in the tree file
code.  Don't forget about mount/bind!  If you bind another device onto a
tmpfs file, then other tmpfs instances in your namespace will also have
that device mounted!  For example:

cd -P \#tmpfs
mkdir pipe-or-whatever # QID 1
/bin/bind \#pipe pipe-or-whatever
cd / # destroys tmpfs

cd -P \#tmpfs # new tmpfs
ls pipe-or-whatever # still bound!

Someone else could be the one that saw that too.  Any file with that QID
(e.g. a file, not a directory) could also have that bind!  That's
because the namespace mount-detecting code uses chan equality, which is
qid.path equality (within a device) (for the most part - also checks
type (directory/file/etc)).

The fix is to have unique instances of tmpfs, and encode that in the
QID.  You have to put it in the path, not the vers, since all callers of
eqchan() that we care about are 'pathonly', meaning they don't care
about the version.

I used an arena to exercise the code a bit.  A u16_pool would be
simpler.  Though it doesn't have a destructor (yet).  Arguably we should
only use the u16_pool when performance is important, if at all.  That's
only used in #mnt.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/dev/tmpfs.c