Until this commit the assumed length of all cache entries has been exactly one page. To make other sizes possible, the length is now stored in struct cache_entry. Note that cache_search may return a pointer in the middle of a cache buffer. Signed-off-by: Petr Tesarik <ptesarik at suse.cz> --- cache.c | 12 ++++++++---- cache.h | 3 ++- makedumpfile.c | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cache.c b/cache.c index ccd67ca..938eda6 100644 --- a/cache.c +++ b/cache.c @@ -79,17 +79,20 @@ remove_entry(struct cache *cache, struct cache_entry *entry) } void * -cache_search(unsigned long long paddr) +cache_search(unsigned long long paddr, unsigned long length) { struct cache_entry *entry; - for (entry = used.head; entry; entry = entry->next) - if (entry->paddr == paddr) { + for (entry = used.head; entry; entry = entry->next) { + size_t off = paddr - entry->paddr; + if (off < entry->buflen && + length <= entry->buflen - off) { if (entry != used.head) { remove_entry(&used, entry); add_entry(&used, entry); } - return entry->bufptr; + return entry->bufptr + off; } + } return NULL; /* cache miss */ } @@ -111,6 +114,7 @@ cache_alloc(unsigned long long paddr) idx = entry - entries; entry->paddr = paddr; entry->bufptr = cachebuf + idx * info->page_size; + entry->buflen = info->page_size; add_entry(&pending, entry); return entry; diff --git a/cache.h b/cache.h index 0e65f97..792ba6c 100644 --- a/cache.h +++ b/cache.h @@ -22,11 +22,12 @@ struct cache_entry { unsigned long long paddr; void *bufptr; + unsigned long buflen; struct cache_entry *next, *prev; }; int cache_init(void); -void *cache_search(unsigned long long paddr); +void *cache_search(unsigned long long paddr, unsigned long length); struct cache_entry *cache_alloc(unsigned long long paddr); void cache_add(struct cache_entry *entry); void cache_free(struct cache_entry *entry); diff --git a/makedumpfile.c b/makedumpfile.c index d778139..f1aad08 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -647,7 +647,7 @@ next_page: read_size = MIN(info->page_size - PAGEOFFSET(paddr), size); pgaddr = PAGEBASE(paddr); - pgbuf = cache_search(pgaddr); + pgbuf = cache_search(pgaddr, read_size); if (!pgbuf) { ++cache_miss; cached = cache_alloc(pgaddr); -- 1.8.4.5