Hello, I would like to start a discussion about some basic details implementation of the unionmount project.
Firstly, the implementation was suggested in two ways: as a stand-alone translator and as a series of extensions to lib{net,disk}fs libraries. These two approaches have there advantages and disadvantages. Implementing unionmount functionality in a stand-alone translator will involve an extra layer of translation (which would often mean an extra context switch in each operation), but will be more flexible in the meaning that to modify parts of functionality will require rebuilding a single translator. OTOH, implementing unionmount as extensions to translator libraries would mean faster operation and automatic inclusion of the functionality in *every* existing translators, but modifying something would require more effort. I am generally inclined to implement the functionality as a stand-alone translator first (though things might well show that this variant of implementation would be best (my personal opinion)), and moving things to lib{net,disk}fs later on. Let me first expose my understanding of the term ``unionmount functionality''. Usually (when doing settrans) the translator being set on a node (directory) foo/ obscures the directory structure lying under foo/. The essence of the unionmount idea here is to mount the translator is such a way that the filesystem the translator makes public *merge* with the underlying filesystem. As far as the stand-alone implementation is concerned, I think we should borrow as much ideas as possible from unionfs. Firstly, unionmount should most probably be a libnetfs-based translator. Now let us go further: unionmount is expected to merge the filesystem on which it sits with the filesystem exposed by the translator it is asked to start in unionmount mode (further referred to as ``the Translator''). When unionmount is starting, it has (of course) a port to the underlying node, which means that it has full access to its underlying filesystem. Now, it can create a shadow node, mirroring the underlying node and then set the Translator on this shadow node. The purpose of this is to keep the Translator away from the real underlying node, giving it at the same time all the information it should require. One of the advantages of this approach is that it reuses the ideas implemented in unionfs to the maximum: actually, only the startup part should differ from the one in unionfs. Probably, I could even kind of fork off the unionfs code base, modify the starting sequence and obtain the unionmount translator. Taking into consideration that unionfs has some features of which we are in no need and that it doesn't (yet) build on my (QEMU) Debian/Hurd, I could spend a day on tailoring unionfs to our needs and another day (at most) on modifying the resulting translator to act like unionmount. This advantage could make the stand-alone approach cheap to implement, at least as a proof-of-concept thing. Also this is why consider it necessary to pay this approach worthy attention. The second approach (about modifying the translator libraries) may prove trickier. First of all, I don't really know the internals of libdiskfs, so I will base my reasoning about the second approach on libnetfs, hoping that libdiskfs will not prove very much different. The idea is to modify the default implementation of netfs_S_dir_lookup in such a way that it will yield control to the user-defined netfs_attempt_lookup only in the case the requested file name could not be found under the underlying node. (Obviously, netfs_attempt_lookup can have priority instead, thus allowing the translator to obscure some of the underlying nodes). This approach will require adding some user-modifiable flag to the corresponding translator library that will allow to switch on and off this functionality, because not all translators would be happy running in unionmount mode. The problem of this approach is that we go away from modularity, loading lib{net,disk}fs with functionality for which they were not initially designed. The immediate problem I can see is that the attempt to rebuild an existing translator against a modified library will not always be a trivial task (at least in the case of libnetfs): many libnetfs-based translators override the default functionality of netfs_S_dir_lookup, so making them union-mount-aware will result in modifying the corresponding sections of their code. As I have already mentioned, I am personally more inclined to implement the unionmount functionality as a stand-alone translator first, because this approach preserves modularity. I am aware of the performance issue about extra context switches, but if the unionmount translator will not give off ports to its own nodes, but ports to *external* nodes (underlying filesystem nodes or those published by the Translator), it will not take part in the frequent (and most time-critical) I/O operations and act as an initial source of ports only. I think it is reasonable for unionmount not to create proxy nodes (in nsmux terminology), because I cannot presently invent a use case where it will need control over the ports it gave off to the client. Regards, scolobb