cache: fix _get_cache_block() return, add lock_cache_block()
authorH. Peter Anvin <hpa@zytor.com>
Tue, 16 Feb 2010 20:20:36 +0000 (12:20 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 16 Feb 2010 20:20:36 +0000 (12:20 -0800)
Correct the return value from _get_cache_block(), and add a method for
locking a block permanently in the cache.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
core/fs/cache.c
core/include/cache.h

index 128a124..1dc4c30 100644 (file)
@@ -58,6 +58,17 @@ void cache_init(struct device *dev, int block_size_shift)
 }
 
 /*
+ * Lock a block permanently in the cache
+ */
+void cache_lock_block(struct cache *cs)
+{
+    cs->prev->next = cs->next;
+    cs->next->prev = cs->prev;
+
+    cs->next = cs->prev = NULL;
+}
+
+/*
  * Check for a particular BLOCK in the block cache, 
  * and if it is already there, just do nothing and return;
  * otherwise pick a victim block and update the LRU link.
@@ -79,15 +90,19 @@ struct cache *_get_cache_block(struct device *dev, block_t block)
     /* Not found, pick a victim */
     cs = head->next;
 
-    /* Add to just before head node */
 found:
-    cs->prev->next = cs->next;
-    cs->next->prev = cs->prev;
+    /* Move to the end of the LRU chain, unless the block is already locked */
+    if (cs->next) {
+       cs->prev->next = cs->next;
+       cs->next->prev = cs->prev;
+       
+       cs->prev = head->prev;
+       head->prev->next = cs;
+       cs->next = head;
+       head->prev = cs;
+    }
 
-    cs->prev = head->prev;
-    head->prev->next = cs;
-    cs->next = head;
-    head->prev = cs;
+    return cs;
 }    
 
 /*
index 0cf399a..1f451af 100644 (file)
@@ -18,5 +18,6 @@ struct cache {
 void cache_init(struct device *, int);
 const void *get_cache(struct device *, block_t);
 struct cache *_get_cache_block(struct device *, block_t);
+void cache_lock_block(struct cache *);
 
 #endif /* cache.h */