I was thinking about how to implement services in MetaFS. Services are sort of like sub-directories/files of inodes (any inode) that provide a more useful way to interact with them. (The canonical example is chdir()ing into a tarball and poking around.)
But, all of MetaFS has the strict invariant that locking must happen starting at the root of the tree and going down. So I'm thinking "OK, if the file and its service both need to be locked, the file has to be locked first, since the service is the child of the file.".
But that's not how it appears to the end user. If you hypothetically do an ls on a file and its service, you'd see something like:
-rw------- 1 condor condor 26K Feb 26 2004 myfile.tar drwx------ 2 condor condor 176 Jun 14 21:07 myfile.tar#tar/
Both the file and service are children of the parent directory.
The locking problem had a head-on collision with this fact just now. So instead of having locking the service be dependent on locking the file (to preserve the locking invariant), I've decided I can, in fact, do it the other way around, which makes more sense anyway.
The user's going to perform some operation (say, a readdir()) on the service, so we need to lock it. OK, now the service needs to look into the tarball for the information, so we need to lock that. And since they're both children of the directory (instead of trying to make the service a child of the file, which logically makes sense but doesn't work), we can still safely preserve the invariant.
All this, of course, requires that MetaFS be able to handle silly things like "mv myfile.tar myfile.tar#tar/" without locking both of them, but that should be fairly trivial. Ordinarily, "myfile.tar" would get locked first, followed by "myfile.tar#tar", which is exactly backwards and thus causes deadlocks.
I'm sure you're all thoroughly confused now.