#ifndef CACHE_H #define CACHE_H #include #define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) #include "hashtable.h" #include "netclient.h" MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Anemone Memory Client"); #define KERNEL_SECTOR_SIZE 512 #define CACHE_SIZE 4096 /* 16M */ #define PAGE_OUT_OVER_NET 1 #define PAGE_IN_OVER_NET 2 #define MAX_PREFETCH 256 //#define TRACE extern atomic64_t outstanding_reqs; extern ulong cache_size; extern ulong water_low, water_high; extern bool water_weight; /* Percentages, not # requests */ #define WATER_LOW 90 #define WATER_HIGH 96 //#define WATER extern ulong cache_hits; extern ulong cache_reads; /* Cache Structures */ typedef struct cache { kmem_cache_t *page_cache; spinlock_t *lock; int (*replacement)(struct cache *); void (*retrieve_finish)(void *); void *dev; /* very specific, only for use in returning to * retrieve finish */ int stored_pages; int stored_write_pages; int cache_size; int cache_write_limit; list_head lh; list_head list_free; HashTable ht; /* Points to itself */ struct cache *cache; } Cache; struct cache_entry { struct list_head queue; /* points to the linked list that makes up the cache */ ulong offset; /* Offset of page */ u8 *page; /* the page */ int write; struct sk_buff *skb; /* This may or may not point to an sk_buff. If it does, * then the cache must take care to call kfree_skb when the * page is kicked out of memory (this is to avoid a memcpy). */ ulong use_count; /* maintains a counter of how many uses this entry has */ int answered; int swapped; /* added to support asynchronous write status */ int prefetch; /* added to support prefetch read status */ }; /* Hashing Function */ ulong cache_hash(void *); /* Equal Function */ bool cache_entry_equal(void *, void *); /* Cache Functions */ int cache_init(Cache *cache, int cacheSize, int (*rep)(Cache *), \ void (*retrieve_finish)(void *), void *dev, \ spinlock_t *lock, struct request_queue * queue); int cache_cleanup(Cache *); int cache_add(Cache *, ulong, ulong, void *); void *cache_retrieve(Cache *, ulong, void *); void *cache_retrieve_no_net(Cache *, ulong); void cache_retrieve_finish(void *, struct sk_buff *, ulong, bool, void *); int cache_remove(Cache *, ulong); int cache_remove_and_dec(Cache *, ulong); /* MRU Replacement Policy */ int mru_replace(struct cache *cache); void mru_finish(void *cache, void *r, bool success); #endif