Re: [PATCH 1/2] vfs: make real_lookup do dentry revalidation with i_mutex held

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> > 
> > 	http://marc.info/?l=linux-fsdevel&m=123831685111213&w=2
> > 
> > Looking over it, the 
> > 
> > +		unsigned int lock_held = mutex_is_locked(&dir->i_mutex);
> > ...
> > +		if (lock_held) {
> > +			/* Already pending, send to ->lookup() */
> > +			d_drop(dentry);
> > 
> > bit looks highly suspect.  I'm guessing revalidate should never sleep, and 
> > always kick things off to ->lookup() (to do any waiting on upcall 
> > completion or whatever else) if the dentry isn't valid now...?
> 
> Yeah, I've heard that before, ;)
> 
> And that maybe the case, but that was what I first had.
> 
> Sending everything to ->lookup() might be possible but it certainly
> isn't that simple.
> 
> Waiting in ->d_revaidate() isn't that different to waiting in ->lookup()
> anyway as that must always be done without the directory mutex held. If
> the lock isn't held when in ->d_revalidate() I can't really see any
> reason not to handle that right their, possibly preventing the need to
> go to ->lookup().

IIRC, the fundamental problem was that if ->d_revalidate() can be called 
either with or without the dir mutex, you won't know whether the mutex is 
locked by the caller or by some other thread (mutex_is_locked() doesn't 
tell you _who_ locked the mutex).  And if waiting in d_revalidate means 
unlocking the mutex, that can't work, because you won't know if that's 
safe.  Thus, no waiting allowed in revalidate?

> There are several cases I need to deal with, apart from path walks
> initiated by the daemon which don't cause any call backs, and so are
> largely handled by trivially returning success. The cases are, an
> expiring dentry that will go away which ->lookup() can't yet handle, an
> expiring dentry that won't go away which ->lookup() should be able to
> handle already, and a straight out mount request which ->lookup() should
> also be able to handle. The tail end of the expire cases can progress
> concurrently with a mount, which is further complicated by the two cases
> of going away or not, so it's all a bit tricky.

It sounds to me like revalidate should only return success in the trivial, 
non-blocking case.  And the ->lookup() should be able to handle all 
(other) cases.  I.e., things should still work correctly (perhaps more 
slowly) without any d_revalidate() at all.  (It still looks like the main 
change needed is for lookup to use d_obtain_alias, instead of returning 
NULL unconditionally...)

> In any case I need to get this to work without the change you proposed,
> except for cases that result from the locking change, and I'm using
> printks to track incorrect returns to identify those cases. So what I
> need right now is consistent behaviour and I'm not quite there. Once I
> have that I'll work on any issues resulting from the locking change.

I suspect you want to work with the real_lookup patch applied... I don't 
think you can get consistent behavior without it. The whole goal here is 
to remove the wait-in-revalidate workaround that was compensating for that 
bug; without either the fix or the workaround you'll get occasional 
-ENOENT.

sage
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux