aboutsummaryrefslogtreecommitdiffstats
path: root/cache.c
blob: 6fdbd25ac13e5635d96707d42d9427f389c892df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "cache.h"
#include <stdio.h>
#include <fcntl.h>
#include <malloc.h>


/*
 * Each CachePtr contains:
 * - Block pointer
 * - LRU previous pointer
 * - LRU next pointer
 * - Block data buffer address
 * The first entry is the head node of the list
 */
struct cache_struct cache[CACHE_ENTRIES + 1] = {0,};

extern int blk_size;

/**
 * cache_init:
 *
 * Initialize the cache data structres.
 *
 */
void cache_init(void)
{
        struct cache_struct *prev, *cur;
        int i;
        
        cur = cache;
        prev = &cache[CACHE_ENTRIES];

        for ( i = 0; i < CACHE_ENTRIES + 1; i++ ) {
                cur->block = 0;
                cur->prev  = prev;
                prev->next = cur;
                cur->data  = NULL;
                
                prev = cur; 
                cur  = &cache[i+1];
        }
}




/**
 * get_cache_block:
 *
 * Check for a particular BLOCK in the block cache, 
 * and if it is already there, just do nothing and return;
 * otherwise load it and updata the relative cache
 * structre with data pointer.
 *
 * @param: block, the block number we want check.
 * @retrun: return the most recent cache structure pointer
 *
 */
struct cache_struct * get_cache_block(__u32 block)
{
        struct cache_struct *cs = &cache[1];
        struct cache_struct *head,  *last;
        int i;

        for ( i = 0; i < CACHE_ENTRIES; i ++ ) {
                if ( cs->block == block )
                        goto hit;
                else
                        cs = &cache[i + 1];
        }

        /* we missed it here, so we need to load it */
 miss:
        /* store it at head of real cache */
        cs = cache[0].next;
        
        cs->block = block;
        cs->data = (void*)getoneblk(block);

 hit:
        /* remove cs from current position in list */
        cs->prev->next = cs->next;
        cs->next->prev = cs->prev;
        
        
        /* add to just before head node */
        last = cache[0].prev;
        head = cache;

        last->next = cs;
        cs->prev = last;
        head->prev = cs;
        cs->next = head;

        return cs;
}