On Mon, Sep 09, 2013 at 07:06:04PM +0100, Al Viro wrote: > I like my proposal for the set of primitives better: > > static inline bool seqretry_and_lock(seqlock_t *lock, unsigned *seq): > { > if ((*seq & 1) || !read_seqretry(lock, *seq)) > return true; > *seq |= 1; > write_seqlock(lock); > return false; > } > > static inline void seqretry_done(seqlock_t *lock, unsigned seq) > { > if (seq & 1) > write_sequnlock(lock); > } > > with the prepend_path() and friends becoming > > rcu_read_lock(); > seq = read_seqbegin(&rename_lock); > again: > .... > if (!seqretry_and_lock(&rename_lock, seq)) > goto again; /* now as writer */ > seqretry_done(&rename_lock, seq); > rcu_read_unlock(); Actually, it's better for prepend_path() as well, because it's actually rcu_read_lock(); seq = read_seqbegin(&rename_lock); again: .... if (error) goto done; .... if (!seqretry_and_lock(&rename_lock, seq)) goto again; /* now as writer */ done: seqretry_done(&rename_lock, seq); rcu_read_unlock(); Posted variant will sometimes hit the following path: * seq_readlock() * start generating the output * hit an error [another process has taken and released rename_lock for some reason] * hit read_seqretry_and_unlock(), which returns 1. * retry everything with seq_writelock(), despite the error. It's not too horrible (we won't be looping indefinitely, ignoring error all along), but it's certainly subtle enough... -- 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