Implement a very simple cookie state machine to handle lookup, invalidation, withdrawal, relinquishment and, to be added later, commit on LRU discard. Three cache methods are provided: ->lookup_cookie() to look up and, if necessary, create a data storage object; ->withdraw_cookie() to free the resources associated with that object and potentially delete it; and ->prepare_to_write(), to do prepare for changes to the cached data to be modified locally. Changes ======= ver #3: - Fix a race between LRU discard and relinquishment whereby the former would override the latter and thus the latter would never happen[1]. ver #2: - Don't hold n_accesses elevated whilst cache is bound to a cookie, but rather add a flag that prevents the state machine from being queued when n_accesses reaches 0.
Showing the changes to include (2 of 3 files). Show all
Unified · Split
| @@ -57,6 +57,15 @@ struct fscache_cache_ops { · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | /* Free the cache's data attached to a volume */ | 58 | /* Free the cache's data attached to a volume */ |
| 59 | void (*free_volume)(struct fscache_volume *volume); | 59 | void (*free_volume)(struct fscache_volume *volume); |
| 60 | |||
| 61 | /* Look up a cookie in the cache */ | ||
| 62 | bool (*lookup_cookie)(struct fscache_cookie *cookie); | ||
| 63 | |||
| 64 | /* Withdraw an object without any cookie access counts held */ | ||
| 65 | void (*withdraw_cookie)(struct fscache_cookie *cookie); | ||
| 66 | |||
| 67 | /* Prepare to write to a live cache object */ | ||
| 68 | void (*prepare_to_write)(struct fscache_cookie *cookie); | ||
| 60 | }; | 69 | }; |
| 61 | 70 | ||
| 62 | extern struct workqueue_struct *fscache_wq; | 71 | extern struct workqueue_struct *fscache_wq; |
| @@ -72,6 +81,7 @@ extern int fscache_add_cache(struct fscache_cache *cache, · 9 unmodified lines | |||
| 72 | void *cache_priv); | 81 | void *cache_priv); |
| 73 | extern void fscache_withdraw_cache(struct fscache_cache *cache); | 82 | extern void fscache_withdraw_cache(struct fscache_cache *cache); |
| 74 | extern void fscache_withdraw_volume(struct fscache_volume *volume); | 83 | extern void fscache_withdraw_volume(struct fscache_volume *volume); |
| 84 | extern void fscache_withdraw_cookie(struct fscache_cookie *cookie); | ||
| 75 | 85 | ||
| 76 | extern void fscache_io_error(struct fscache_cache *cache); | 86 | extern void fscache_io_error(struct fscache_cache *cache); |
| 77 | 87 | ||
| @@ -85,8 +95,21 @@ extern void fscache_put_cookie(struct fscache_cookie *cookie, · 7 unmodified lines | |||
| 85 | enum fscache_cookie_trace where); | 95 | enum fscache_cookie_trace where); |
| 86 | extern void fscache_end_cookie_access(struct fscache_cookie *cookie, | 96 | extern void fscache_end_cookie_access(struct fscache_cookie *cookie, |
| 87 | enum fscache_access_trace why); | 97 | enum fscache_access_trace why); |
| 88 | extern void fscache_set_cookie_state(struct fscache_cookie *cookie, | 98 | extern void fscache_cookie_lookup_negative(struct fscache_cookie *cookie); |
| 89 | enum fscache_cookie_state state); | 99 | extern void fscache_caching_failed(struct fscache_cookie *cookie); |
| 100 | |||
| 101 | /** | ||
| 102 | * fscache_cookie_state - Read the state of a cookie | ||
| 103 | * @cookie: The cookie to query | ||
| 104 | * | ||
| 105 | * Get the state of a cookie, imposing an ordering between the cookie contents | ||
| 106 | * and the state value. Paired with fscache_set_cookie_state(). | ||
| 107 | */ | ||
| 108 | static inline | ||
| 109 | enum fscache_cookie_state fscache_cookie_state(struct fscache_cookie *cookie) | ||
| 110 | { | ||
| 111 | return smp_load_acquire(&cookie->state); | ||
| 112 | } | ||
| 90 | 113 | ||
| 91 | /** | 114 | /** |
| 92 | * fscache_get_key - Get a pointer to the cookie key | 115 | * fscache_get_key - Get a pointer to the cookie key |
| @@ -68,6 +68,8 @@ enum fscache_access_trace { · 67 unmodified lines | |||
| 68 | fscache_access_acquire_volume_end, | 68 | fscache_access_acquire_volume_end, |
| 69 | fscache_access_cache_pin, | 69 | fscache_access_cache_pin, |
| 70 | fscache_access_cache_unpin, | 70 | fscache_access_cache_unpin, |
| 71 | fscache_access_lookup_cookie_end, | ||
| 72 | fscache_access_lookup_cookie_end_failed, | ||
| 71 | fscache_access_relinquish_volume, | 73 | fscache_access_relinquish_volume, |
| 72 | fscache_access_relinquish_volume_end, | 74 | fscache_access_relinquish_volume_end, |
| 73 | fscache_access_unlive, | 75 | fscache_access_unlive, |
| @@ -124,6 +126,8 @@ enum fscache_access_trace { · 50 unmodified lines | |||
| 124 | EM(fscache_access_acquire_volume_end, "END acq_vol") \ | 126 | EM(fscache_access_acquire_volume_end, "END acq_vol") \ |
| 125 | EM(fscache_access_cache_pin, "PIN cache ") \ | 127 | EM(fscache_access_cache_pin, "PIN cache ") \ |
| 126 | EM(fscache_access_cache_unpin, "UNPIN cache ") \ | 128 | EM(fscache_access_cache_unpin, "UNPIN cache ") \ |
| 129 | EM(fscache_access_lookup_cookie_end, "END lookup ") \ | ||
| 130 | EM(fscache_access_lookup_cookie_end_failed,"END lookupf") \ | ||
| 127 | EM(fscache_access_relinquish_volume, "BEGIN rlq_vol") \ | 131 | EM(fscache_access_relinquish_volume, "BEGIN rlq_vol") \ |
| 128 | EM(fscache_access_relinquish_volume_end,"END rlq_vol") \ | 132 | EM(fscache_access_relinquish_volume_end,"END rlq_vol") \ |
| 129 | E_(fscache_access_unlive, "END unlive ") | 133 | E_(fscache_access_unlive, "END unlive ") |