Subject: Re: funlink() for fun!
To: NetBSD Kernel Technical Discussion List <tech-kern@NetBSD.ORG>
From: Matthias Buelow <mkb@mukappabeta.de>
List: tech-kern
Date: 07/14/2003 21:46:15
Greg A. Woods writes:

>> IMHO, the best solution (albeit outside the established Unix framework)
>> would be to fully separate operations on directories and the flat file
>> system (inodes/device-numbers or equivalents)...
>
>Yes, "file handles" as some folks call them.  They are effectively
>vnodes in the *BSD terminology.

Ok, I didn't know about file handles.  They're also not want I meant.
I wanted a handle on the directory entry (essentially the pathname) as
some kind of invariant representation of a particular directory entry
at a discrete point (originally specified by pathname).  This would
then be used instead of a pathname in open(2) etc.  That this handle
also points to a specific file (through the dir-entry's data) is a
rather less interesting detail in this context.  It's just so that the
application's got a more direct grip on the directory entry through
which a file is to be opened, for later use (such as your proposed
funlink()).  The particular entry in the directory would be marked
somehow (or locked), so if the entry gets unlinked in the meantime it
won't get reused and overwritten immediately -- something like a zombie
entry.  This would persist until the process releases the handle, or
exits.  funlink() could then be implemented as follows.  You want to
preserve atomicity for security reasons; no problem -- you could have a
system call which, instead of expecting a pathname like unlink(), would
accept such a directory entry handle, the same one convienently passed
to open() instead of a real pathname in your particular program (but it
is not necessary to open the file, of course.)  The system would know
which entry in which directory exactly was used for opening a
particular file (it would associate that information with this
handle.)  It could then unlink the entry from the directory and do the
other cleanup stuff (like decrementing the counter in the inode, etc.)
without having to fear colliding with a newly generated pathname of the
same name that was originally used to obtain the directory entry
handle.  Of course this is of theoretical nature; building an extra API
for that would be ugly, unportable and few people would use it
(especially not existing applications).  If at all, the underlying API
of open() etc. would have to be changed to this design, which is not
feasible, of course.

A second idea is that open(2) returns not only a file descriptor but
also such a handle.  Open() already compromises in dealing with
pathnames anyways, so we could be a bit relaxed about the strict
division between file (inode/devno) and a particularly directory entry
in the context of open().  The second descriptor returned could be
associated with the directory entry and be used in the manner described
above.  This would involve opening the file, of course, but that's what
most applications do anyways.  The advantage would be that it actually
could be implemented in the current semantics; maybe the existing
open(2) call could be somehow transparently enhanced, maybe a second
system call (open2(), or opend() or something) could be constructed.
If it is really necessary and how it would work out in practice I of
course don't know.

>We already have fhopen(2), fhstat(2), and fhstatfs().

They seem to be rather low-level handles for the inode, that's not what
I meant.  I basically wanted to get a hold on the directory entry that
was used for opening a particular file.

>Of course these calls (including getfh()) are currently restricted to
>the superuser because they have not had the necessary ACL semantics
>defined for them.

I don't understand why they're restricted to the superuser -- getfh()
does return EACCES when it can't access the directory of the specified
pathname and fhopen() surely checks for permissions on the file
itself.

-- 
  Matthias Buelow;  mkb@{mukappabeta.de,informatik.uni-wuerzburg.de}