summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-16 12:20:36 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-16 12:20:36 -0800
commit65cbb13fdf81832b36694a73530d346cd55a3e2c (patch)
treee571b8092cc071b6407230026ad4e04b6f6b7136
parentff2842a13dd157691dbe9f0b1498c891bef76554 (diff)
downloadsyslinux-65cbb13fdf81832b36694a73530d346cd55a3e2c.tar.gz
cache: fix _get_cache_block() return, add lock_cache_block()
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>
-rw-r--r--core/fs/cache.c29
-rw-r--r--core/include/cache.h1
2 files changed, 23 insertions, 7 deletions
diff --git a/core/fs/cache.c b/core/fs/cache.c
index 128a1248..1dc4c300 100644
--- a/core/fs/cache.c
+++ b/core/fs/cache.c
@@ -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;
}
/*
diff --git a/core/include/cache.h b/core/include/cache.h
index 0cf399af..1f451afd 100644
--- a/core/include/cache.h
+++ b/core/include/cache.h
@@ -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 */