[OpenAFS-devel] Re: mountpoints on linux

Andrew Deason adeason@sinenomine.net
Mon, 2 Jul 2012 18:59:34 -0500


On Fri, 29 Jun 2012 16:49:46 -0500
Andrew Deason <adeason@sinenomine.net> wrote:

> However, it is possible on Linux to have a directory, but give it a
> follow_link function, so it behaves kinda like a symlink in that it
> gets dereferenced before being accessed, and lets you point at an
> arbitrary dentry like a regular symlink. kafs does this, and just
> mounts the volume on the dir as the dereferencing operation.

I have a guess at this modification to solution "E" in gerrit 7657 (with
a couple of prereqs). It seems to work through the basic tests I've been
trying out on this issue (rmdir, rename() through weird mtpt trees,
etc). There are a few details that are incorrect; I haven't even tried
to get refcounting etc correct yet, since I'm just trying to get a
handle on the general approach.


So, there are a few things I am unsure on in the approach in that
submission as-is. I'm detailing them here since trying to have a real
discussion in gerrit is probably going to be difficult.

First of all, we have this usage in afs_mnt_follow_link:

	static const struct qstr anonstring = { .name = "" };
	newdp = d_alloc(dentry->d_parent, &anonstring);

I'm not really sure if that's valid, giving a new dentry an empty name
like that when it's not an "anonymous"/disconnected dentry. But nothing
immediately explodes when I do it.

Doing something of this sort seems necessary, though, unless we symlink
to /afs/.:mount/. Normally I am trying to 'symlink' the dir to the
existing alias dentry for the mountpoint target, so we don't need to
construct a new dentry. When there is no alias, we could in theory just
bypass the whole mntpt-symlink thing, and just return a regular dir like
we always have. However, if we rely on an alias dentry existing in
afs_mnt_follow_link, I think that creates a race. Consider:

Say we had afs_linux_lookup only direct to the afs_mnt_* operations if a
dentry alias existed for the dir. But then, by the time
afs_mnt_follow_link is called, the alias dentry no longer exists (I
assume this can happen if we flush the appropriate things, or they just
get kicked out of the relevant vfs cache). Then we are stuck again
trying to resolve our pseudo-symlink without a target dentry to point
to, so it seems like we need to d_alloc something (or point to
/afs/.:mount). So, we need to do _something_ in the case where we have
no dentry alias.


Along a similar line of thought, it seems like we can combine this
approach with the existing approach of solution "B". That is, we try the
current approach (reparent the mtpt dentry when possible), and if it's
not possible to reparent (the dentry alias cannot be invalidated), only
then do we try to create a mtpt with the follow_link function to point
at the other mtpt.

This would effectively be the current behavior where we try to get ..
pointing at the 'right' thing by reparenting. However, when we encounter
the corner cases that are currently causing deadlocks/panics, we offer
the symlink, which may get .. wrong, but at least we do not panic or do
anything else more weird. That should get us the same behavior as right
now for almost all usages.

However, I am a bit concerned about this kind of behavior for 2 reasons:

  -- The fact that we "almost always" do the current reparenting
  behavior means that if there is any mistake in the symlink/mtpt stuff,
  it will be difficult to see, reproduce, etc.

  -- The fact that mtpt access patterns dictates the definition of ..
  seems troubling, both for causing heisenbugs and from possibly a
  security standpoint. If you have something with a symlink involving ..
  (or something else that uses the 'real' ..; I think that does?), you
  could have a malicious user force .. to point at some AFS space they
  control or something. That is:

cd ~/mydir
fs mkm foomt /afs/some/scripts/dir
cd foomt
# now /afs/some/scripts/dir/.. points to ~/mydir

Of course, that (and worse) has probably always been possible, so this
is still an improvement, but I don't know if it's good enough.

So... maybe this makes solution "F" more desirable? It may 'break' usage
of .., but at least it does so in a uniform an predictable manner. But
if we are treating this as an interim solution, maybe the concessions
that must be made for solution "E" are okay.

As always, any criticisms or other possible ideas are welcomed.

-- 
Andrew Deason
adeason@sinenomine.net