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 <[email protected]>
---
 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


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to