]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - misc-utils/lsblk-devtree.c
6 void lsblk_reset_iter(struct lsblk_iter
*itr
, int direction
)
9 direction
= itr
->direction
;
11 memset(itr
, 0, sizeof(*itr
));
12 itr
->direction
= direction
;
15 struct lsblk_device
*lsblk_new_device(struct lsblk_devtree
*tree
)
17 struct lsblk_device
*dev
;
19 dev
= calloc(1, sizeof(*dev
));
26 lsblk_ref_devtree(dev
->tree
);
28 INIT_LIST_HEAD(&dev
->deps
);
29 INIT_LIST_HEAD(&dev
->ls_roots
);
30 INIT_LIST_HEAD(&dev
->ls_devices
);
32 DBG(DEV
, ul_debugobj(dev
, "alloc"));
36 void lsblk_ref_device(struct lsblk_device
*dev
)
43 static int device_remove_dependence(struct lsblk_device
*dev
, struct lsblk_devdep
*dep
)
45 if (!dev
|| !dep
|| !list_empty(&dev
->deps
))
48 DBG(DEV
, ul_debugobj(dev
, " remove-deallocate dependence 0x%p", dep
));
49 list_del_init(&dep
->ls_deps
);
50 lsblk_unref_device(dep
->child
);
55 static int device_remove_dependences(struct lsblk_device
*dev
)
60 DBG(DEV
, ul_debugobj(dev
, "remove all depencences"));
61 while (!list_empty(&dev
->deps
)) {
62 struct lsblk_devdep
*dp
= list_entry(dev
->deps
.next
,
63 struct lsblk_devdep
, ls_deps
);
64 device_remove_dependence(dev
, dp
);
69 void lsblk_unref_device(struct lsblk_device
*dev
)
74 if (--dev
->refcount
<= 0) {
75 DBG(DEV
, ul_debugobj(dev
, "dealloc"));
77 device_remove_dependences(dev
);
78 lsblk_device_free_properties(dev
->properties
);
80 list_del_init(&dev
->ls_roots
);
81 list_del_init(&dev
->ls_devices
);
86 free(dev
->mountpoint
);
88 ul_unref_path(dev
->sysfs
);
89 lsblk_ref_devtree(dev
->tree
);
95 struct lsblk_devdep
*lsblk_device_new_dependence(struct lsblk_device
*parent
, struct lsblk_device
*child
)
97 struct lsblk_devdep
*dp
;
99 if (!parent
|| !child
) {
104 dp
= calloc(1, sizeof(*dp
));
108 INIT_LIST_HEAD(&dp
->ls_deps
);
110 lsblk_ref_device(child
);
113 DBG(DEV
, ul_debugobj(parent
, "add dependence 0x%p [%s->%s]", dp
, parent
->name
, child
->name
));
114 list_add_tail(&dp
->ls_deps
, &parent
->deps
);
119 int lsblk_device_next_child(struct lsblk_device
*dev
,
120 struct lsblk_iter
*itr
,
121 struct lsblk_device
**child
)
125 if (!dev
|| !itr
|| !child
)
130 LSBLK_ITER_INIT(itr
, &dev
->deps
);
131 if (itr
->p
!= itr
->head
) {
132 struct lsblk_devdep
*dp
= NULL
;
134 LSBLK_ITER_ITERATE(itr
, dp
, struct lsblk_devdep
, ls_deps
);
143 struct lsblk_devtree
*lsblk_new_devtree()
145 struct lsblk_devtree
*tr
;
147 tr
= calloc(1, sizeof(*tr
));
153 INIT_LIST_HEAD(&tr
->roots
);
154 INIT_LIST_HEAD(&tr
->devices
);
156 DBG(TREE
, ul_debugobj(tr
, "alloc"));
160 void lsblk_ref_devtree(struct lsblk_devtree
*tr
)
166 void lsblk_unref_devtree(struct lsblk_devtree
*tr
)
171 if (--tr
->refcount
<= 0) {
172 DBG(TREE
, ul_debugobj(tr
, "dealloc"));
174 while (!list_empty(&tr
->roots
)) {
175 struct lsblk_device
*dev
= list_entry(tr
->roots
.next
,
176 struct lsblk_device
, ls_roots
);
177 lsblk_unref_device(dev
);
179 while (!list_empty(&tr
->devices
)) {
180 struct lsblk_device
*dev
= list_entry(tr
->devices
.next
,
181 struct lsblk_device
, ls_devices
);
182 lsblk_unref_device(dev
);
188 int lsblk_devtree_add_root(struct lsblk_devtree
*tr
, struct lsblk_device
*dev
)
190 lsblk_ref_device(dev
);
192 DBG(TREE
, ul_debugobj(tr
, "add root device 0x%p [%s]", dev
, dev
->name
));
193 list_add_tail(&dev
->ls_roots
, &tr
->roots
);
197 int lsblk_devtree_next_root(struct lsblk_devtree
*tr
,
198 struct lsblk_iter
*itr
,
199 struct lsblk_device
**dev
)
203 if (!tr
|| !itr
|| !dev
)
207 LSBLK_ITER_INIT(itr
, &tr
->roots
);
208 if (itr
->p
!= itr
->head
) {
209 LSBLK_ITER_ITERATE(itr
, *dev
, struct lsblk_device
, ls_roots
);
215 int lsblk_devtree_add_device(struct lsblk_devtree
*tr
, struct lsblk_device
*dev
)
217 lsblk_ref_device(dev
);
219 DBG(TREE
, ul_debugobj(tr
, "add device 0x%p [%s]", dev
, dev
->name
));
220 list_add_tail(&dev
->ls_devices
, &tr
->devices
);
224 int lsblk_devtree_next_device(struct lsblk_devtree
*tr
,
225 struct lsblk_iter
*itr
,
226 struct lsblk_device
**dev
)
230 if (!tr
|| !itr
|| !dev
)
234 LSBLK_ITER_INIT(itr
, &tr
->devices
);
235 if (itr
->p
!= itr
->head
) {
236 LSBLK_ITER_ITERATE(itr
, *dev
, struct lsblk_device
, ls_devices
);
242 struct lsblk_device
*lsblk_devtree_get_device(struct lsblk_devtree
*tr
, const char *name
)
244 struct lsblk_device
*dev
= NULL
;
245 struct lsblk_iter itr
;
247 lsblk_reset_iter(&itr
, LSBLK_ITER_FORWARD
);
249 while (lsblk_devtree_next_device(tr
, &itr
, &dev
) == 0) {
250 if (strcmp(name
, dev
->name
) == 0)