Bug Summary

File:fcache.c
Location:line 35, column 1
Description:Dereference of null pointer

Annotated Source Code

1/*-
2 * Copyright (c) 2007 Aaron L. Meihm
3 * Copyright (c) 2007 Christian S.J. Peron
4 * All rights reserved.
5 *
6 * $Id: conf.c,v 1.15 2007/04/13 14:45:12 csjp Exp $
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30#include "includes.h"
31
32static int fcache_cmp(struct fcache *, struct fcache *);
33
34RB_PROTOTYPE(btree, fcache, f_glue, fcache_cmp)void btree_RB_INSERT_COLOR(struct btree *, struct fcache *); void
btree_RB_REMOVE_COLOR(struct btree *, struct fcache *, struct
fcache *); struct fcache *btree_RB_REMOVE(struct btree *, struct
fcache *); struct fcache *btree_RB_INSERT(struct btree *, struct
fcache *); struct fcache *btree_RB_FIND(struct btree *, struct
fcache *); struct fcache *btree_RB_NFIND(struct btree *, struct
fcache *); struct fcache *btree_RB_NEXT(struct fcache *); struct
fcache *btree_RB_PREV(struct fcache *); struct fcache *btree_RB_MINMAX
(struct btree *, int);
;
35RB_GENERATE(btree, fcache, f_glue, fcache_cmp)void btree_RB_INSERT_COLOR(struct btree *head, struct fcache *
elm) { struct fcache *parent, *gparent, *tmp; while ((parent =
(elm)->f_glue.rbe_parent) != ((void *)0) && (parent
)->f_glue.rbe_color == 1) { gparent = (parent)->f_glue.
rbe_parent; if (parent == (gparent)->f_glue.rbe_left) { tmp
= (gparent)->f_glue.rbe_right; if (tmp && (tmp)->
f_glue.rbe_color == 1) { (tmp)->f_glue.rbe_color = 0; do {
(parent)->f_glue.rbe_color = 0; (gparent)->f_glue.rbe_color
= 1; } while ( 0); elm = gparent; continue; } if ((parent)->
f_glue.rbe_right == elm) { do { (tmp) = (parent)->f_glue.rbe_right
; if (((parent)->f_glue.rbe_right = (tmp)->f_glue.rbe_left
) != ((void *)0)) { ((tmp)->f_glue.rbe_left)->f_glue.rbe_parent
= (parent); } do {} while (0); if (((tmp)->f_glue.rbe_parent
= (parent)->f_glue.rbe_parent) != ((void *)0)) { if ((parent
) == ((parent)->f_glue.rbe_parent)->f_glue.rbe_left) ((
parent)->f_glue.rbe_parent)->f_glue.rbe_left = (tmp); else
((parent)->f_glue.rbe_parent)->f_glue.rbe_right = (tmp
); } else (head)->rbh_root = (tmp); (tmp)->f_glue.rbe_left
= (parent); (parent)->f_glue.rbe_parent = (tmp); do {} while
(0); if (((tmp)->f_glue.rbe_parent)) do {} while (0); } while
( 0); tmp = parent; parent = elm; elm = tmp; } do { (parent)
->f_glue.rbe_color = 0; (gparent)->f_glue.rbe_color = 1
; } while ( 0); do { (tmp) = (gparent)->f_glue.rbe_left; if
(((gparent)->f_glue.rbe_left = (tmp)->f_glue.rbe_right
) != ((void *)0)) { ((tmp)->f_glue.rbe_right)->f_glue.rbe_parent
= (gparent); } do {} while (0); if (((tmp)->f_glue.rbe_parent
= (gparent)->f_glue.rbe_parent) != ((void *)0)) { if ((gparent
) == ((gparent)->f_glue.rbe_parent)->f_glue.rbe_left) (
(gparent)->f_glue.rbe_parent)->f_glue.rbe_left = (tmp);
else ((gparent)->f_glue.rbe_parent)->f_glue.rbe_right =
(tmp); } else (head)->rbh_root = (tmp); (tmp)->f_glue.
rbe_right = (gparent); (gparent)->f_glue.rbe_parent = (tmp
); do {} while (0); if (((tmp)->f_glue.rbe_parent)) do {} while
(0); } while ( 0); } else { tmp = (gparent)->f_glue.rbe_left
; if (tmp && (tmp)->f_glue.rbe_color == 1) { (tmp)
->f_glue.rbe_color = 0; do { (parent)->f_glue.rbe_color
= 0; (gparent)->f_glue.rbe_color = 1; } while ( 0); elm =
gparent; continue; } if ((parent)->f_glue.rbe_left == elm
) { do { (tmp) = (parent)->f_glue.rbe_left; if (((parent)->
f_glue.rbe_left = (tmp)->f_glue.rbe_right) != ((void *)0))
{ ((tmp)->f_glue.rbe_right)->f_glue.rbe_parent = (parent
); } do {} while (0); if (((tmp)->f_glue.rbe_parent = (parent
)->f_glue.rbe_parent) != ((void *)0)) { if ((parent) == ((
parent)->f_glue.rbe_parent)->f_glue.rbe_left) ((parent)
->f_glue.rbe_parent)->f_glue.rbe_left = (tmp); else ((parent
)->f_glue.rbe_parent)->f_glue.rbe_right = (tmp); } else
(head)->rbh_root = (tmp); (tmp)->f_glue.rbe_right = (parent
); (parent)->f_glue.rbe_parent = (tmp); do {} while (0); if
(((tmp)->f_glue.rbe_parent)) do {} while (0); } while ( 0
); tmp = parent; parent = elm; elm = tmp; } do { (parent)->
f_glue.rbe_color = 0; (gparent)->f_glue.rbe_color = 1; } while
( 0); do { (tmp) = (gparent)->f_glue.rbe_right; if (((gparent
)->f_glue.rbe_right = (tmp)->f_glue.rbe_left) != ((void
*)0)) { ((tmp)->f_glue.rbe_left)->f_glue.rbe_parent = (
gparent); } do {} while (0); if (((tmp)->f_glue.rbe_parent
= (gparent)->f_glue.rbe_parent) != ((void *)0)) { if ((gparent
) == ((gparent)->f_glue.rbe_parent)->f_glue.rbe_left) (
(gparent)->f_glue.rbe_parent)->f_glue.rbe_left = (tmp);
else ((gparent)->f_glue.rbe_parent)->f_glue.rbe_right =
(tmp); } else (head)->rbh_root = (tmp); (tmp)->f_glue.
rbe_left = (gparent); (gparent)->f_glue.rbe_parent = (tmp)
; do {} while (0); if (((tmp)->f_glue.rbe_parent)) do {} while
(0); } while ( 0); } } (head->rbh_root)->f_glue.rbe_color
= 0; } void btree_RB_REMOVE_COLOR(struct btree *head, struct
fcache *parent, struct fcache *elm) { struct fcache *tmp; while
((elm == ((void *)0) || (elm)->f_glue.rbe_color == 0) &&
elm != (head)->rbh_root) { if ((parent)->f_glue.rbe_left
== elm) { tmp = (parent)->f_glue.rbe_right; if ((tmp)->
f_glue.rbe_color == 1) { do { (tmp)->f_glue.rbe_color = 0;
(parent)->f_glue.rbe_color = 1; } while ( 0); do { (tmp) =
(parent)->f_glue.rbe_right; if (((parent)->f_glue.rbe_right
= (tmp)->f_glue.rbe_left) != ((void *)0)) { ((tmp)->f_glue
.rbe_left)->f_glue.rbe_parent = (parent); } do {} while (0
); if (((tmp)->f_glue.rbe_parent = (parent)->f_glue.rbe_parent
) != ((void *)0)) { if ((parent) == ((parent)->f_glue.rbe_parent
)->f_glue.rbe_left) ((parent)->f_glue.rbe_parent)->f_glue
.rbe_left = (tmp); else ((parent)->f_glue.rbe_parent)->
f_glue.rbe_right = (tmp); } else (head)->rbh_root = (tmp);
(tmp)->f_glue.rbe_left = (parent); (parent)->f_glue.rbe_parent
= (tmp); do {} while (0); if (((tmp)->f_glue.rbe_parent))
do {} while (0); } while ( 0); tmp = (parent)->f_glue.rbe_right
; } if (((tmp)->f_glue.rbe_left == ((void *)0) || ((tmp)->
f_glue.rbe_left)->f_glue.rbe_color == 0) && ((tmp)
->f_glue.rbe_right == ((void *)0) || ((tmp)->f_glue.rbe_right
)->f_glue.rbe_color == 0)) { (tmp)->f_glue.rbe_color = 1
; elm = parent; parent = (elm)->f_glue.rbe_parent; } else {
if ((tmp)->f_glue.rbe_right == ((void *)0) || ((tmp)->
f_glue.rbe_right)->f_glue.rbe_color == 0) { struct fcache *
oleft; if ((oleft = (tmp)->f_glue.rbe_left) != ((void *)0)
) (oleft)->f_glue.rbe_color = 0; (tmp)->f_glue.rbe_color
= 1; do { (oleft) = (tmp)->f_glue.rbe_left; if (((tmp)->
f_glue.rbe_left = (oleft)->f_glue.rbe_right) != ((void *)0
)) { ((oleft)->f_glue.rbe_right)->f_glue.rbe_parent = (
tmp); } do {} while (0); if (((oleft)->f_glue.rbe_parent =
(tmp)->f_glue.rbe_parent) != ((void *)0)) { if ((tmp) == (
(tmp)->f_glue.rbe_parent)->f_glue.rbe_left) ((tmp)->
f_glue.rbe_parent)->f_glue.rbe_left = (oleft); else ((tmp)
->f_glue.rbe_parent)->f_glue.rbe_right = (oleft); } else
(head)->rbh_root = (oleft); (oleft)->f_glue.rbe_right =
(tmp); (tmp)->f_glue.rbe_parent = (oleft); do {} while (0
); if (((oleft)->f_glue.rbe_parent)) do {} while (0); } while
( 0); tmp = (parent)->f_glue.rbe_right; } (tmp)->f_glue
.rbe_color = (parent)->f_glue.rbe_color; (parent)->f_glue
.rbe_color = 0; if ((tmp)->f_glue.rbe_right) ((tmp)->f_glue
.rbe_right)->f_glue.rbe_color = 0; do { (tmp) = (parent)->
f_glue.rbe_right; if (((parent)->f_glue.rbe_right = (tmp)->
f_glue.rbe_left) != ((void *)0)) { ((tmp)->f_glue.rbe_left
)->f_glue.rbe_parent = (parent); } do {} while (0); if (((
tmp)->f_glue.rbe_parent = (parent)->f_glue.rbe_parent) !=
((void *)0)) { if ((parent) == ((parent)->f_glue.rbe_parent
)->f_glue.rbe_left) ((parent)->f_glue.rbe_parent)->f_glue
.rbe_left = (tmp); else ((parent)->f_glue.rbe_parent)->
f_glue.rbe_right = (tmp); } else (head)->rbh_root = (tmp);
(tmp)->f_glue.rbe_left = (parent); (parent)->f_glue.rbe_parent
= (tmp); do {} while (0); if (((tmp)->f_glue.rbe_parent))
do {} while (0); } while ( 0); elm = (head)->rbh_root; break
; } } else { tmp = (parent)->f_glue.rbe_left; if ((tmp)->
f_glue.rbe_color == 1) { do { (tmp)->f_glue.rbe_color = 0;
(parent)->f_glue.rbe_color = 1; } while ( 0); do { (tmp) =
(parent)->f_glue.rbe_left; if (((parent)->f_glue.rbe_left
= (tmp)->f_glue.rbe_right) != ((void *)0)) { ((tmp)->f_glue
.rbe_right)->f_glue.rbe_parent = (parent); } do {} while (
0); if (((tmp)->f_glue.rbe_parent = (parent)->f_glue.rbe_parent
) != ((void *)0)) { if ((parent) == ((parent)->f_glue.rbe_parent
)->f_glue.rbe_left) ((parent)->f_glue.rbe_parent)->f_glue
.rbe_left = (tmp); else ((parent)->f_glue.rbe_parent)->
f_glue.rbe_right = (tmp); } else (head)->rbh_root = (tmp);
(tmp)->f_glue.rbe_right = (parent); (parent)->f_glue.rbe_parent
= (tmp); do {} while (0); if (((tmp)->f_glue.rbe_parent))
do {} while (0); } while ( 0); tmp = (parent)->f_glue.rbe_left
; } if (((tmp)->f_glue.rbe_left == ((void *)0) || ((tmp)->
f_glue.rbe_left)->f_glue.rbe_color == 0) && ((tmp)
->f_glue.rbe_right == ((void *)0) || ((tmp)->f_glue.rbe_right
)->f_glue.rbe_color == 0)) { (tmp)->f_glue.rbe_color = 1
; elm = parent; parent = (elm)->f_glue.rbe_parent; } else {
if ((tmp)->f_glue.rbe_left == ((void *)0) || ((tmp)->f_glue
.rbe_left)->f_glue.rbe_color == 0) { struct fcache *oright
; if ((oright = (tmp)->f_glue.rbe_right) != ((void *)0)) (
oright)->f_glue.rbe_color = 0; (tmp)->f_glue.rbe_color =
1; do { (oright) = (tmp)->f_glue.rbe_right; if (((tmp)->
f_glue.rbe_right = (oright)->f_glue.rbe_left) != ((void *)
0)) { ((oright)->f_glue.rbe_left)->f_glue.rbe_parent = (
tmp); } do {} while (0); if (((oright)->f_glue.rbe_parent =
(tmp)->f_glue.rbe_parent) != ((void *)0)) { if ((tmp) == (
(tmp)->f_glue.rbe_parent)->f_glue.rbe_left) ((tmp)->
f_glue.rbe_parent)->f_glue.rbe_left = (oright); else ((tmp
)->f_glue.rbe_parent)->f_glue.rbe_right = (oright); } else
(head)->rbh_root = (oright); (oright)->f_glue.rbe_left
= (tmp); (tmp)->f_glue.rbe_parent = (oright); do {} while
(0); if (((oright)->f_glue.rbe_parent)) do {} while (0); }
while ( 0); tmp = (parent)->f_glue.rbe_left; } (tmp)->
f_glue.rbe_color = (parent)->f_glue.rbe_color; (parent)->
f_glue.rbe_color = 0; if ((tmp)->f_glue.rbe_left) ((tmp)->
f_glue.rbe_left)->f_glue.rbe_color = 0; do { (tmp) = (parent
)->f_glue.rbe_left; if (((parent)->f_glue.rbe_left = (tmp
)->f_glue.rbe_right) != ((void *)0)) { ((tmp)->f_glue.rbe_right
)->f_glue.rbe_parent = (parent); } do {} while (0); if (((
tmp)->f_glue.rbe_parent = (parent)->f_glue.rbe_parent) !=
((void *)0)) { if ((parent) == ((parent)->f_glue.rbe_parent
)->f_glue.rbe_left) ((parent)->f_glue.rbe_parent)->f_glue
.rbe_left = (tmp); else ((parent)->f_glue.rbe_parent)->
f_glue.rbe_right = (tmp); } else (head)->rbh_root = (tmp);
(tmp)->f_glue.rbe_right = (parent); (parent)->f_glue.rbe_parent
= (tmp); do {} while (0); if (((tmp)->f_glue.rbe_parent))
do {} while (0); } while ( 0); elm = (head)->rbh_root; break
; } } } if (elm) (elm)->f_glue.rbe_color = 0; } struct fcache
* btree_RB_REMOVE(struct btree *head, struct fcache *elm) { struct
fcache *child, *parent, *old = elm; int color; if ((elm)->
f_glue.rbe_left == ((void *)0)) child = (elm)->f_glue.rbe_right
; else if ((elm)->f_glue.rbe_right == ((void *)0)) child =
(elm)->f_glue.rbe_left; else { struct fcache *left; elm =
(elm)->f_glue.rbe_right; while ((left = (elm)->f_glue.
rbe_left) != ((void *)0)) elm = left; child = (elm)->f_glue
.rbe_right; parent = (elm)->f_glue.rbe_parent; color = (elm
)->f_glue.rbe_color; if (child) (child)->f_glue.rbe_parent
= parent; if (parent) { if ((parent)->f_glue.rbe_left == elm
) (parent)->f_glue.rbe_left = child; else (parent)->f_glue
.rbe_right = child; do {} while (0); } else (head)->rbh_root
= child; if ((elm)->f_glue.rbe_parent == old) parent = elm
; (elm)->f_glue = (old)->f_glue; if ((old)->f_glue.rbe_parent
) { if (((old)->f_glue.rbe_parent)->f_glue.rbe_left == old
) ((old)->f_glue.rbe_parent)->f_glue.rbe_left = elm; else
((old)->f_glue.rbe_parent)->f_glue.rbe_right = elm; do
{} while (0); } else (head)->rbh_root = elm; ((old)->f_glue
.rbe_left)->f_glue.rbe_parent = elm; if ((old)->f_glue.
rbe_right) ((old)->f_glue.rbe_right)->f_glue.rbe_parent
= elm; if (parent) { left = parent; do { do {} while (0); } while
((left = (left)->f_glue.rbe_parent) != ((void *)0)); } goto
color; } parent = (elm)->f_glue.rbe_parent; color = (elm)
->f_glue.rbe_color; if (child) (child)->f_glue.rbe_parent
= parent; if (parent) { if ((parent)->f_glue.rbe_left == elm
) (parent)->f_glue.rbe_left = child; else (parent)->f_glue
.rbe_right = child; do {} while (0); } else (head)->rbh_root
= child; color: if (color == 0) btree_RB_REMOVE_COLOR(head, parent
, child); return (old); } struct fcache * btree_RB_INSERT(struct
btree *head, struct fcache *elm) { struct fcache *tmp; struct
fcache *parent = ((void *)0); int comp = 0; tmp = (head)->
rbh_root; while (tmp) { parent = tmp; comp = (fcache_cmp)(elm
, parent); if (comp < 0) tmp = (tmp)->f_glue.rbe_left; else
if (comp > 0) tmp = (tmp)->f_glue.rbe_right; else return
(tmp); } do { (elm)->f_glue.rbe_parent = parent; (elm)->
f_glue.rbe_left = (elm)->f_glue.rbe_right = ((void *)0); (
elm)->f_glue.rbe_color = 1; } while ( 0); if (parent != ((
void *)0)) { if (comp < 0) (parent)->f_glue.rbe_left = elm
; else (parent)->f_glue.rbe_right = elm; do {} while (0); }
else (head)->rbh_root = elm; btree_RB_INSERT_COLOR(head, elm
); return (((void *)0)); } struct fcache * btree_RB_FIND(struct
btree *head, struct fcache *elm) { struct fcache *tmp = (head
)->rbh_root; int comp; while (tmp) { comp = fcache_cmp(elm
, tmp); if (comp < 0) tmp = (tmp)->f_glue.rbe_left; else
if (comp > 0) tmp = (tmp)->f_glue.rbe_right; else return
(tmp); } return (((void *)0)); } struct fcache * btree_RB_NFIND
(struct btree *head, struct fcache *elm) { struct fcache *tmp
= (head)->rbh_root; struct fcache *res = ((void *)0); int
comp; while (tmp) { comp = fcache_cmp(elm, tmp); if (comp <
0) { res = tmp; tmp = (tmp)->f_glue.rbe_left; } else if (
comp > 0) tmp = (tmp)->f_glue.rbe_right; else return (tmp
); } return (res); } struct fcache * btree_RB_NEXT(struct fcache
*elm) { if ((elm)->f_glue.rbe_right) { elm = (elm)->f_glue
.rbe_right; while ((elm)->f_glue.rbe_left) elm = (elm)->
f_glue.rbe_left; } else { if ((elm)->f_glue.rbe_parent &&
(elm == ((elm)->f_glue.rbe_parent)->f_glue.rbe_left)) elm
= (elm)->f_glue.rbe_parent; else { while ((elm)->f_glue
.rbe_parent && (elm == ((elm)->f_glue.rbe_parent)->
f_glue.rbe_right)) elm = (elm)->f_glue.rbe_parent; elm = (
elm)->f_glue.rbe_parent; } } return (elm); } struct fcache
* btree_RB_PREV(struct fcache *elm) { if ((elm)->f_glue.rbe_left
) { elm = (elm)->f_glue.rbe_left; while ((elm)->f_glue.
rbe_right) elm = (elm)->f_glue.rbe_right; } else { if ((elm
)->f_glue.rbe_parent && (elm == ((elm)->f_glue.
rbe_parent)->f_glue.rbe_right)) elm = (elm)->f_glue.rbe_parent
; else { while ((elm)->f_glue.rbe_parent && (elm ==
((elm)->f_glue.rbe_parent)->f_glue.rbe_left)) elm = (elm
)->f_glue.rbe_parent; elm = (elm)->f_glue.rbe_parent; }
} return (elm); } struct fcache * btree_RB_MINMAX(struct btree
*head, int val) { struct fcache *tmp = (head)->rbh_root; struct
fcache *parent = ((void *)0); while (tmp) { parent = tmp; if
(val < 0) tmp = (tmp)->f_glue.rbe_left; else tmp = (tmp
)->f_glue.rbe_right; } return (parent); }
;
Within the expansion of the macro 'RB_GENERATE':
a
Assuming 'elm' is not equal to null
b
Value assigned to field 'rbe_left'
c
Assuming pointer value is null
d
Null pointer value stored to 'tmp'
e
Dereference of null pointer
36TAILQ_HEAD(tailhead, dev_list)struct tailhead { struct dev_list *tqh_first; struct dev_list
**tqh_last; }
cache_head = TAILQ_HEAD_INITIALIZER(cache_head){ ((void *)0), &(cache_head).tqh_first, };
37
38static int
39fcache_cmp(struct fcache *fc1, struct fcache *fc2)
40{
41
42 if (fc1->f_inode > fc2->f_inode)
43 return (1);
44 if (fc1->f_inode < fc2->f_inode)
45 return (-1);
46 return (0);
47}
48
49void
50fcache_destroy(void)
51{
52 struct fcache *fcp, *next_fcp;
53 struct dev_list *dp, *dp2;
54
55 TAILQ_FOREACH_SAFE(dp, &cache_head, d_glue, dp2)for ((dp) = (((&cache_head))->tqh_first); (dp) &&
((dp2) = (((dp))->d_glue.tqe_next), 1); (dp) = (dp2))
{
56 for (fcp = RB_MIN(btree, &dp->d_btree)btree_RB_MINMAX(&dp->d_btree, -1); fcp != NULL((void *)0);
57 fcp = next_fcp) {
58 next_fcp = RB_NEXT(btree, &dp->d_btree, fcp)btree_RB_NEXT(fcp);
59 RB_REMOVE(btree, &dp->d_btree, fcp)btree_RB_REMOVE(&dp->d_btree, fcp);
60 free(fcp);
61 }
62 TAILQ_REMOVE(&cache_head, dp, d_glue)do {;;;; if (((((dp))->d_glue.tqe_next)) != ((void *)0)) (
((dp))->d_glue.tqe_next)->d_glue.tqe_prev = (dp)->d_glue
.tqe_prev; else { (&cache_head)->tqh_last = (dp)->d_glue
.tqe_prev;; } *(dp)->d_glue.tqe_prev = (((dp))->d_glue.
tqe_next);;;; } while (0)
;
63 free(dp);
64 }
65}
66
67void
68fcache_init(void)
69{
70
71 TAILQ_INIT(&cache_head)do { (((&cache_head))->tqh_first) = ((void *)0); (&
cache_head)->tqh_last = &(((&cache_head))->tqh_first
);; } while (0)
;
72}
73
74static struct dev_list *
75fcache_locate(dev_t device)
76{
77 struct dev_list *dp;
78
79 TAILQ_FOREACH(dp, &cache_head, d_glue)for ((dp) = (((&cache_head))->tqh_first); (dp); (dp) =
(((dp))->d_glue.tqe_next))
80 if (dp->d_device == device)
81 return (dp);
82 dp = malloc(sizeof(*dp));
83 if (dp == NULL((void *)0))
84 return (NULL((void *)0));
85 dp->d_device = device;
86 RB_INIT(&dp->d_btree)do { (&dp->d_btree)->rbh_root = ((void *)0); } while
( 0)
;
87 TAILQ_INSERT_HEAD(&cache_head, dp, d_glue)do {; if (((((dp))->d_glue.tqe_next) = (((&cache_head)
)->tqh_first)) != ((void *)0)) (((&cache_head))->tqh_first
)->d_glue.tqe_prev = &(((dp))->d_glue.tqe_next); else
(&cache_head)->tqh_last = &(((dp))->d_glue.tqe_next
); (((&cache_head))->tqh_first) = (dp); (dp)->d_glue
.tqe_prev = &(((&cache_head))->tqh_first);;; } while
(0)
;
88 return (dp);
89}
90
91char *
92fcache_search(dev_t device, ino_t inode)
93{
94 struct fcache fc, *fcp;
95 struct dev_list *dp;
96
97 dp = fcache_locate(device);
98 if (dp == NULL((void *)0))
99 return (NULL((void *)0));
100 fc.f_inode = inode;
101 fcp = RB_FIND(btree, &dp->d_btree, &fc)btree_RB_FIND(&dp->d_btree, &fc);
102 if (fcp == NULL((void *)0))
103 return (NULL((void *)0));
104 return (fcp->f_pathname);
105}
106
107void
108fcache_add_entry(dev_t device, ino_t inode, char *pathname)
109{
110 struct dev_list *dp;
111 struct fcache *fcp;
112 char *ret;
113
114 ret = fcache_search(device, inode);
115 if (ret != NULL((void *)0))
116 return;
117 dp = fcache_locate(device);
118 if (dp == NULL((void *)0)) {
119 (void) fprintf(stderr__stderrp, "failed to allocate cache\n");
120 return;
121 }
122 fcp = malloc(sizeof(*fcp));
123 if (fcp == NULL((void *)0)) {
124 (void) fprintf(stderr__stderrp, "failed to allocate cache object\n");
125 return;
126 }
127 fcp->f_inode = inode;
128 fcp->f_pathname = strdup(pathname);
129 if (RB_INSERT(btree, &dp->d_btree, fcp)btree_RB_INSERT(&dp->d_btree, fcp) != 0)
130 printf("item already existed\n");
131}
132