Commit a9efc748 authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Philipp Reisner

lru_cache: consolidate lc_get and lc_try_get

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 0097f040
...@@ -308,45 +308,7 @@ static int lc_unused_element_available(struct lru_cache *lc) ...@@ -308,45 +308,7 @@ static int lc_unused_element_available(struct lru_cache *lc)
return 0; return 0;
} }
static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool may_change)
/**
* lc_get - get element by label, maybe change the active set
* @lc: the lru cache to operate on
* @enr: the label to look up
*
* Finds an element in the cache, increases its usage count,
* "touches" and returns it.
*
* In case the requested number is not present, it needs to be added to the
* cache. Therefore it is possible that an other element becomes evicted from
* the cache. In either case, the user is notified so he is able to e.g. keep
* a persistent log of the cache changes, and therefore the objects in use.
*
* Return values:
* NULL
* The cache was marked %LC_STARVING,
* or the requested label was not in the active set
* and a changing transaction is still pending (@lc was marked %LC_DIRTY).
* Or no unused or free element could be recycled (@lc will be marked as
* %LC_STARVING, blocking further lc_get() operations).
*
* pointer to the element with the REQUESTED element number.
* In this case, it can be used right away
*
* pointer to an UNUSED element with some different element number,
* where that different number may also be %LC_FREE.
*
* In this case, the cache is marked %LC_DIRTY (blocking further changes),
* and the returned element pointer is removed from the lru list and
* hash collision chains. The user now should do whatever housekeeping
* is necessary.
* Then he must call lc_changed(lc,element_pointer), to finish
* the change.
*
* NOTE: The user needs to check the lc_number on EACH use, so he recognizes
* any cache set change.
*/
struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr)
{ {
struct lc_element *e; struct lc_element *e;
...@@ -366,6 +328,8 @@ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) ...@@ -366,6 +328,8 @@ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr)
} }
++lc->misses; ++lc->misses;
if (!may_change)
RETURN(NULL);
/* In case there is nothing available and we can not kick out /* In case there is nothing available and we can not kick out
* the LRU element, we have to wait ... * the LRU element, we have to wait ...
...@@ -397,29 +361,67 @@ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) ...@@ -397,29 +361,67 @@ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr)
RETURN(e); RETURN(e);
} }
/* similar to lc_get, /**
* but only gets a new reference on an existing element. * lc_get - get element by label, maybe change the active set
* you either get the requested element, or NULL. * @lc: the lru cache to operate on
* will be consolidated into one function. * @enr: the label to look up
*
* Finds an element in the cache, increases its usage count,
* "touches" and returns it.
*
* In case the requested number is not present, it needs to be added to the
* cache. Therefore it is possible that an other element becomes evicted from
* the cache. In either case, the user is notified so he is able to e.g. keep
* a persistent log of the cache changes, and therefore the objects in use.
*
* Return values:
* NULL
* The cache was marked %LC_STARVING,
* or the requested label was not in the active set
* and a changing transaction is still pending (@lc was marked %LC_DIRTY).
* Or no unused or free element could be recycled (@lc will be marked as
* %LC_STARVING, blocking further lc_get() operations).
*
* pointer to the element with the REQUESTED element number.
* In this case, it can be used right away
*
* pointer to an UNUSED element with some different element number,
* where that different number may also be %LC_FREE.
*
* In this case, the cache is marked %LC_DIRTY (blocking further changes),
* and the returned element pointer is removed from the lru list and
* hash collision chains. The user now should do whatever housekeeping
* is necessary.
* Then he must call lc_changed(lc,element_pointer), to finish
* the change.
*
* NOTE: The user needs to check the lc_number on EACH use, so he recognizes
* any cache set change.
*/ */
struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr) struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr)
{ {
struct lc_element *e; return __lc_get(lc, enr, 1);
}
PARANOIA_ENTRY();
if (lc->flags & LC_STARVING) {
++lc->starving;
RETURN(NULL);
}
e = lc_find(lc, enr); /**
if (e) { * lc_try_get - get element by label, if present; do not change the active set
++lc->hits; * @lc: the lru cache to operate on
if (e->refcnt++ == 0) * @enr: the label to look up
lc->used++; *
list_move(&e->list, &lc->in_use); /* Not evictable... */ * Finds an element in the cache, increases its usage count,
} * "touches" and returns it.
RETURN(e); *
* Return values:
* NULL
* The cache was marked %LC_STARVING,
* or the requested label was not in the active set
*
* pointer to the element with the REQUESTED element number.
* In this case, it can be used right away
*/
struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr)
{
return __lc_get(lc, enr, 0);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment