On Dec 20, 2005, at 2:15 PM, Rob Ross wrote:
I thought we wanted (3,4) before (2)?
Hmm..I thought we had agreed to go down the rmdirent path if the
lookup and getattr wouldn't hit the caches. Remember that the
disadvantage of putting 3 (the actual over-the-wire getattr) before 2
(rmdirent) is that we also have to do the lookup to get the object.
So in the case where the dirent_count == 0, we end up with an extra
roundrip (we do a name lookup twice basically, once with lookup and
again with rmdirent).
-sam
Rob
Sam Lang wrote:
So I have something that does what I think we want for remove. It
basically does the following steps. Note that the difference from
before is that steps 1 and 4 have been added:
1. check ncache and acache for name/attr and then check
dirent_count != 0 -> return ENOTEMPTY.
2. rmdirent(name) => object
3. getattr(object) => attr
4. if attr.dirent_count != 0, do crdirent and return ENOTEMPTY
5. remove(object) => if returns ENOTEMPTY, do crdirent and return
ENOTEMPTY
Also, the directory name => object mapping was getting invalidated
in the name cache at cleanup even with ENOTEMPTY. I've added a
check to only invalidate if we're not returning ENOTEMPTY.
Does this look reasonable to everyone?
-sam
On Dec 19, 2005, at 10:33 PM, Rob Ross wrote:
Ok, I was missing your point before, but I get it now -- if we
were to put the new getattr in before the rmdirent, there is a
possibility that someone could remove the last entry in the
directory after the getattr but before the rmdirent could happen.
It's not a race though. A race has to have unexpected results
based on relative timing. In our case, the situation you
describe is indistinguishable from the case where the final
removal occurs just as the rmdir returns, which is fine.
This new scheme does still leave open the possibility that we
remove a directory's dirent when there is something in the
directory (and then we recreate the dirent). We're just reducing
the opportunities for this being seen.
It is also not the case that vtags would help here, because the
directory's dirent (which is what we remove first) is not part of
the directory itself (which is what we'd have the vtag for). I'm
batting like 100 or so tonight, so I think I'll quit writing
emails after this one and go to sleep or something.
Rob
Rob Ross wrote:
Sam Lang wrote:
The race that's an issue seems to be if the getattr tells me
the directory is not empty, in which case I just return
ENOTEMPTY back to the caller, but in the meantime someone else
could have removed all the entries (in which case the remove
should have succeeded). I'm not sure that's much of an issue
for our users though.
That's not a race. First thing that happens on a file removal
is that the directory entry is removed, so if something is being
removed, it won't be in the directory.
Right now our caching scheme is under-the-covers so to speak,
where we always continue with the operation if the cache
misses. It seems like we could make a decision based on a
cache hit. In other words, if I know the name and attribute
are cached, I can save time by checking if the directory is not
empty. If its not cached, I can just go down the rmdirent path
like we do now. Doing lookup/getattr will add an extra
roundtrip in most cases (where the directory is empty) if
things aren't being cached. Overkill?
I don't like caching negative entries without consistency, so I
like the idea of going down the path if we don't have any
directory contents cached.
Rob
_______________________________________________
PVFS2-developers mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-
developers
_______________________________________________
PVFS2-developers mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers