1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef _FSCACHE
6 #define _FSCACHE
7 
8 #define CLEAN 0
9 #define DIRTY_NEW 1  // from a new write_TFS
10 #define DIRTY_OLD 2  // from an overwrite
11 
12 // Values for the flags field in the Cache structure
13 #define CACHE_DIRTY (1 << 0)
14 
15 #define SET_DIRTY_NEW(C, ent) {    \
16     if (C) {                       \
17         (ent)->state = DIRTY_NEW;  \
18         (C)->flags |= CACHE_DIRTY; \
19     }                              \
20 }
21 
22 #define SET_DIRTY_OLD(C, ent) { \
23     (ent)->state = DIRTY_OLD;   \
24     (C)->flags |= CACHE_DIRTY;  \
25 }
26 
27 typedef struct cache_entry FcEntry;
28 struct cache_entry {
29     FcEntry* next_lru;   // next and prev for the LRU list is
30     FcEntry* prev_lru;   // a double linked list
31     FcEntry* next_hash;  // next and prev for the hash list is
32     FcEntry* prev_hash;  // a double linked list
33     FcEntry** hash_head; // pointer to head of hash table list
34     ui8* data;           // pointer to cached data
35     ui8* dirty_map;      // dirty bitmap of pages in sector
36     void* file_ptr;      // pointer to file control information
37     ui32 sect_num;       // sector number in actual medium
38     ui16 pin_cnt;        // pin counter: 0 = unpinned, > 0 pinned
39     ui16 state;          // clean, dirty_new, dirty_old flag
40 };
41 
42 typedef int (*MedWFunc)(FcEntry* entry, int update, void* vol_ptr);
43 typedef int (*MedRFunc)(void* head, ui32 sect_num, void* vol_ptr);
44 
45 typedef struct {
46     FcEntry* pool;       // array containing all cache entries
47     FcEntry** hash_tbl;  // hash table to point to pool
48     FcEntry* lru_head;   // head of the LRU list
49     FcEntry* lru_tail;   // tail of the LRU list
50     ui32 pool_size;      // number of cache entries
51     ui32 sector_number;  // current sector being worked on
52     MedWFunc wr_sect;    // write function to write sector back
53     MedWFunc wr_page;    // write function to write page back
54     MedRFunc rd_sect;    // read function to read sector
55     ui32 block_sects;    // num sects in memory block
56     ui32 flags;          // cache flags
57     ui32 meta_ents;      // number of non-file data sector entries
58     ui32 meta_threshold; // min # of non-file data sector entries
59     ui32 sector_pages;   // number of pages in sector
60     ui32 tot_access;     // number of get requests
61     ui32 hit_access;     // number of hits on get requests
62     ui32 ram_used;       // RAM used by cache in bytes
63     void* vol_ptr;       // FS volume cache belongs to
64 } Cache;
65 
66 int FcInit(Cache* C, ui32 pool_size, MedWFunc wrf, MedRFunc rdf, ui32 sect_sz, ui32 tmp_ents,
67            ui32 block_sects, void* volp);
68 int FcInitMeta(Cache* C, ui32 pool_size, ui32 meta_threshold, MedWFunc wr_sect, MedWFunc wr_page,
69                MedRFunc rd_sect, ui32 sect_sz, ui32 pg_sz, ui32 tmp_ents, void* volp);
70 void FcReinit(Cache* C, ui32 entry_size);
71 void FcDestroy(Cache* C);
72 void FcRmvEntry(Cache* C, ui32 entry_number);
73 FcEntry* FcGetEntry(Cache* C, ui32 ent_number, int skip_rd, void* filep);
74 void FcFreeEntry(Cache* C, FcEntry** entry);
75 int FcFlush(Cache* C);
76 void FcUpdateEntry(Cache* C, FcEntry* entry, ui32 entry_number);
77 FcEntry* FcInCache(const Cache* C, ui32 entry_number);
78 void FcSetDirtyNewPgs(Cache* C, FcEntry* ent, ui32 start, ui32 n);
79 int FcHitsPercent(const Cache* C);
80 int FcWriteSect(const Cache* C, FcEntry* ent, int update);
81 int FcHash(uint sector_number, uint size);
82 void FcRmvFmLRU(Cache* C, FcEntry* entry);
83 ui32 FcRAM(const Cache* C);
84 void FcDiag(Cache* C);
85 
86 #endif // _FSCACHE
87