Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

klist: implement klist_prev()

klist_prev() gets the previous element in the list. It is useful to traverse
through the list in reverse order, for example, to provide LIFO (last in first
out) variant of access.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Andy Shevchenko and committed by
Lee Jones
2e0fed7f ddef08dd

+42
+1
include/linux/klist.h
··· 63 63 extern void klist_iter_init_node(struct klist *k, struct klist_iter *i, 64 64 struct klist_node *n); 65 65 extern void klist_iter_exit(struct klist_iter *i); 66 + extern struct klist_node *klist_prev(struct klist_iter *i); 66 67 extern struct klist_node *klist_next(struct klist_iter *i); 67 68 68 69 #endif
+41
lib/klist.c
··· 324 324 } 325 325 326 326 /** 327 + * klist_prev - Ante up prev node in list. 328 + * @i: Iterator structure. 329 + * 330 + * First grab list lock. Decrement the reference count of the previous 331 + * node, if there was one. Grab the prev node, increment its reference 332 + * count, drop the lock, and return that prev node. 333 + */ 334 + struct klist_node *klist_prev(struct klist_iter *i) 335 + { 336 + void (*put)(struct klist_node *) = i->i_klist->put; 337 + struct klist_node *last = i->i_cur; 338 + struct klist_node *prev; 339 + 340 + spin_lock(&i->i_klist->k_lock); 341 + 342 + if (last) { 343 + prev = to_klist_node(last->n_node.prev); 344 + if (!klist_dec_and_del(last)) 345 + put = NULL; 346 + } else 347 + prev = to_klist_node(i->i_klist->k_list.prev); 348 + 349 + i->i_cur = NULL; 350 + while (prev != to_klist_node(&i->i_klist->k_list)) { 351 + if (likely(!knode_dead(prev))) { 352 + kref_get(&prev->n_ref); 353 + i->i_cur = prev; 354 + break; 355 + } 356 + prev = to_klist_node(prev->n_node.prev); 357 + } 358 + 359 + spin_unlock(&i->i_klist->k_lock); 360 + 361 + if (put && last) 362 + put(last); 363 + return i->i_cur; 364 + } 365 + EXPORT_SYMBOL_GPL(klist_prev); 366 + 367 + /** 327 368 * klist_next - Ante up next node in list. 328 369 * @i: Iterator structure. 329 370 *