xref: /linux/include/linux/klist.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1  /* SPDX-License-Identifier: GPL-2.0-only */
2  /*
3   *	klist.h - Some generic list helpers, extending struct list_head a bit.
4   *
5   *	Implementations are found in lib/klist.c
6   *
7   *	Copyright (C) 2005 Patrick Mochel
8   */
9  
10  #ifndef _LINUX_KLIST_H
11  #define _LINUX_KLIST_H
12  
13  #include <linux/spinlock.h>
14  #include <linux/kref.h>
15  #include <linux/list.h>
16  
17  struct klist_node;
18  struct klist {
19  	spinlock_t		k_lock;
20  	struct list_head	k_list;
21  	void			(*get)(struct klist_node *);
22  	void			(*put)(struct klist_node *);
23  } __attribute__ ((aligned (sizeof(void *))));
24  
25  #define KLIST_INIT(_name, _get, _put)					\
26  	{ .k_lock	= __SPIN_LOCK_UNLOCKED(_name.k_lock),		\
27  	  .k_list	= LIST_HEAD_INIT(_name.k_list),			\
28  	  .get		= _get,						\
29  	  .put		= _put, }
30  
31  #define DEFINE_KLIST(_name, _get, _put)					\
32  	struct klist _name = KLIST_INIT(_name, _get, _put)
33  
34  extern void klist_init(struct klist *k, void (*get)(struct klist_node *),
35  		       void (*put)(struct klist_node *));
36  
37  struct klist_node {
38  	void			*n_klist;	/* never access directly */
39  	struct list_head	n_node;
40  	struct kref		n_ref;
41  };
42  
43  extern void klist_add_tail(struct klist_node *n, struct klist *k);
44  extern void klist_add_head(struct klist_node *n, struct klist *k);
45  extern void klist_add_behind(struct klist_node *n, struct klist_node *pos);
46  extern void klist_add_before(struct klist_node *n, struct klist_node *pos);
47  
48  extern void klist_del(struct klist_node *n);
49  extern void klist_remove(struct klist_node *n);
50  
51  extern int klist_node_attached(struct klist_node *n);
52  
53  
54  struct klist_iter {
55  	struct klist		*i_klist;
56  	struct klist_node	*i_cur;
57  };
58  
59  
60  extern void klist_iter_init(struct klist *k, struct klist_iter *i);
61  extern void klist_iter_init_node(struct klist *k, struct klist_iter *i,
62  				 struct klist_node *n);
63  extern void klist_iter_exit(struct klist_iter *i);
64  extern struct klist_node *klist_prev(struct klist_iter *i);
65  extern struct klist_node *klist_next(struct klist_iter *i);
66  
67  #endif
68