On 09/09/2013 01:29 PM, Al Viro wrote:
On Mon, Sep 09, 2013 at 12:18:13PM -0400, Waiman Long wrote:+/** + * read_seqbegin_or_lock - begin a sequence number check or locking block + * lock: sequence lock + * seq : sequence number to be checked + * + * First try it once optimistically without taking the lock. If that fails, + * take the lock. The sequence number is also used as a marker for deciding + * whether to be a reader (even) or writer (odd). + * N.B. seq must be initialized to an even number to begin with. + */ +static inline void read_seqbegin_or_lock(seqlock_t *lock, int *seq) +{ + if (!(*seq& 1)) { /* Even */ + *seq = read_seqbegin(lock); + rcu_read_lock(); + } else /* Odd */ + write_seqlock(lock); +} +static inline int read_seqretry_or_unlock(seqlock_t *lock, int *seq) +{ + if (!(*seq& 1)) { /* Even */ + rcu_read_unlock(); + if (read_seqretry(lock, *seq)) { + (*seq)++; /* Take writer lock */ + return 1; + } + } else /* Odd */ + write_sequnlock(lock); + return 0; +}I'm not sure I like mixing rcu_read_lock() into that - d_path() and friends can do that themselves just fine (it needs to be taken when seq is even), and e.g. d_walk() doesn't need it at all. Other than that, I'm OK with this variant.
I think rcu_read_lock() is needed to make sure that the dentry won't be freed as we don't take d_lock now.
-Longman -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/

