Commit 532906aa7f9656209f30f08dfadd328fc1bc6912
Committed by
Mike Snitzer
1 parent
633618e335
Exists in
master
and in
16 other branches
dm cache: add remove_cblock method to policy interface
Implement policy_remove_cblock() and add remove_cblock method to the mq policy. These methods will be used by the following cache block invalidation patch which adds the 'invalidate_cblocks' message to the cache core. Also, update some comments in dm-cache-policy.h Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Showing 3 changed files with 57 additions and 4 deletions Side-by-side Diff
drivers/md/dm-cache-policy-internal.h
... | ... | @@ -64,6 +64,11 @@ |
64 | 64 | p->remove_mapping(p, oblock); |
65 | 65 | } |
66 | 66 | |
67 | +static inline int policy_remove_cblock(struct dm_cache_policy *p, dm_cblock_t cblock) | |
68 | +{ | |
69 | + return p->remove_cblock(p, cblock); | |
70 | +} | |
71 | + | |
67 | 72 | static inline void policy_force_mapping(struct dm_cache_policy *p, |
68 | 73 | dm_oblock_t current_oblock, dm_oblock_t new_oblock) |
69 | 74 | { |
drivers/md/dm-cache-policy-mq.c
... | ... | @@ -304,6 +304,15 @@ |
304 | 304 | list_add(&e->list, &ep->free); |
305 | 305 | } |
306 | 306 | |
307 | +/* | |
308 | + * Returns NULL if the entry is free. | |
309 | + */ | |
310 | +static struct entry *epool_find(struct entry_pool *ep, dm_cblock_t cblock) | |
311 | +{ | |
312 | + struct entry *e = ep->entries + from_cblock(cblock); | |
313 | + return e->hlist.pprev ? e : NULL; | |
314 | +} | |
315 | + | |
307 | 316 | static bool epool_empty(struct entry_pool *ep) |
308 | 317 | { |
309 | 318 | return list_empty(&ep->free); |
... | ... | @@ -1020,6 +1029,31 @@ |
1020 | 1029 | mutex_unlock(&mq->lock); |
1021 | 1030 | } |
1022 | 1031 | |
1032 | +static int __remove_cblock(struct mq_policy *mq, dm_cblock_t cblock) | |
1033 | +{ | |
1034 | + struct entry *e = epool_find(&mq->cache_pool, cblock); | |
1035 | + | |
1036 | + if (!e) | |
1037 | + return -ENODATA; | |
1038 | + | |
1039 | + del(mq, e); | |
1040 | + free_entry(&mq->cache_pool, e); | |
1041 | + | |
1042 | + return 0; | |
1043 | +} | |
1044 | + | |
1045 | +static int mq_remove_cblock(struct dm_cache_policy *p, dm_cblock_t cblock) | |
1046 | +{ | |
1047 | + int r; | |
1048 | + struct mq_policy *mq = to_mq_policy(p); | |
1049 | + | |
1050 | + mutex_lock(&mq->lock); | |
1051 | + r = __remove_cblock(mq, cblock); | |
1052 | + mutex_unlock(&mq->lock); | |
1053 | + | |
1054 | + return r; | |
1055 | +} | |
1056 | + | |
1023 | 1057 | static int __mq_writeback_work(struct mq_policy *mq, dm_oblock_t *oblock, |
1024 | 1058 | dm_cblock_t *cblock) |
1025 | 1059 | { |
... | ... | @@ -1139,6 +1173,7 @@ |
1139 | 1173 | mq->policy.load_mapping = mq_load_mapping; |
1140 | 1174 | mq->policy.walk_mappings = mq_walk_mappings; |
1141 | 1175 | mq->policy.remove_mapping = mq_remove_mapping; |
1176 | + mq->policy.remove_cblock = mq_remove_cblock; | |
1142 | 1177 | mq->policy.writeback_work = mq_writeback_work; |
1143 | 1178 | mq->policy.force_mapping = mq_force_mapping; |
1144 | 1179 | mq->policy.residency = mq_residency; |
drivers/md/dm-cache-policy.h
... | ... | @@ -135,9 +135,6 @@ |
135 | 135 | */ |
136 | 136 | int (*lookup)(struct dm_cache_policy *p, dm_oblock_t oblock, dm_cblock_t *cblock); |
137 | 137 | |
138 | - /* | |
139 | - * oblock must be a mapped block. Must not block. | |
140 | - */ | |
141 | 138 | void (*set_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock); |
142 | 139 | void (*clear_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock); |
143 | 140 | |
144 | 141 | |
... | ... | @@ -159,8 +156,24 @@ |
159 | 156 | void (*force_mapping)(struct dm_cache_policy *p, dm_oblock_t current_oblock, |
160 | 157 | dm_oblock_t new_oblock); |
161 | 158 | |
162 | - int (*writeback_work)(struct dm_cache_policy *p, dm_oblock_t *oblock, dm_cblock_t *cblock); | |
159 | + /* | |
160 | + * This is called via the invalidate_cblocks message. It is | |
161 | + * possible the particular cblock has already been removed due to a | |
162 | + * write io in passthrough mode. In which case this should return | |
163 | + * -ENODATA. | |
164 | + */ | |
165 | + int (*remove_cblock)(struct dm_cache_policy *p, dm_cblock_t cblock); | |
163 | 166 | |
167 | + /* | |
168 | + * Provide a dirty block to be written back by the core target. | |
169 | + * | |
170 | + * Returns: | |
171 | + * | |
172 | + * 0 and @cblock,@oblock: block to write back provided | |
173 | + * | |
174 | + * -ENODATA: no dirty blocks available | |
175 | + */ | |
176 | + int (*writeback_work)(struct dm_cache_policy *p, dm_oblock_t *oblock, dm_cblock_t *cblock); | |
164 | 177 | |
165 | 178 | /* |
166 | 179 | * How full is the cache? |