aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2013-11-08 11:36:17 -0500
committerMike Snitzer <snitzer@redhat.com>2013-11-11 11:37:50 -0500
commit532906aa7f9656209f30f08dfadd328fc1bc6912 (patch)
treed8af8f44e38894c97a0d891152723d5b7184edc5 /drivers/md
parent633618e3353f8953e43d989d08302f5dcd51d8be (diff)
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>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-cache-policy-internal.h5
-rw-r--r--drivers/md/dm-cache-policy-mq.c35
-rw-r--r--drivers/md/dm-cache-policy.h21
3 files changed, 57 insertions, 4 deletions
diff --git a/drivers/md/dm-cache-policy-internal.h b/drivers/md/dm-cache-policy-internal.h
index a75f7e7498eb..2256a1f24f73 100644
--- a/drivers/md/dm-cache-policy-internal.h
+++ b/drivers/md/dm-cache-policy-internal.h
@@ -64,6 +64,11 @@ static inline void policy_remove_mapping(struct dm_cache_policy *p, dm_oblock_t
64 p->remove_mapping(p, oblock); 64 p->remove_mapping(p, oblock);
65} 65}
66 66
67static inline int policy_remove_cblock(struct dm_cache_policy *p, dm_cblock_t cblock)
68{
69 return p->remove_cblock(p, cblock);
70}
71
67static inline void policy_force_mapping(struct dm_cache_policy *p, 72static inline void policy_force_mapping(struct dm_cache_policy *p,
68 dm_oblock_t current_oblock, dm_oblock_t new_oblock) 73 dm_oblock_t current_oblock, dm_oblock_t new_oblock)
69{ 74{
diff --git a/drivers/md/dm-cache-policy-mq.c b/drivers/md/dm-cache-policy-mq.c
index 782bf854666a..7209fab8b8ed 100644
--- a/drivers/md/dm-cache-policy-mq.c
+++ b/drivers/md/dm-cache-policy-mq.c
@@ -304,6 +304,15 @@ static void free_entry(struct entry_pool *ep, struct entry *e)
304 list_add(&e->list, &ep->free); 304 list_add(&e->list, &ep->free);
305} 305}
306 306
307/*
308 * Returns NULL if the entry is free.
309 */
310static 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
307static bool epool_empty(struct entry_pool *ep) 316static bool epool_empty(struct entry_pool *ep)
308{ 317{
309 return list_empty(&ep->free); 318 return list_empty(&ep->free);
@@ -1020,6 +1029,31 @@ static void mq_remove_mapping(struct dm_cache_policy *p, dm_oblock_t oblock)
1020 mutex_unlock(&mq->lock); 1029 mutex_unlock(&mq->lock);
1021} 1030}
1022 1031
1032static 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
1045static 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
1023static int __mq_writeback_work(struct mq_policy *mq, dm_oblock_t *oblock, 1057static int __mq_writeback_work(struct mq_policy *mq, dm_oblock_t *oblock,
1024 dm_cblock_t *cblock) 1058 dm_cblock_t *cblock)
1025{ 1059{
@@ -1139,6 +1173,7 @@ static void init_policy_functions(struct mq_policy *mq)
1139 mq->policy.load_mapping = mq_load_mapping; 1173 mq->policy.load_mapping = mq_load_mapping;
1140 mq->policy.walk_mappings = mq_walk_mappings; 1174 mq->policy.walk_mappings = mq_walk_mappings;
1141 mq->policy.remove_mapping = mq_remove_mapping; 1175 mq->policy.remove_mapping = mq_remove_mapping;
1176 mq->policy.remove_cblock = mq_remove_cblock;
1142 mq->policy.writeback_work = mq_writeback_work; 1177 mq->policy.writeback_work = mq_writeback_work;
1143 mq->policy.force_mapping = mq_force_mapping; 1178 mq->policy.force_mapping = mq_force_mapping;
1144 mq->policy.residency = mq_residency; 1179 mq->policy.residency = mq_residency;
diff --git a/drivers/md/dm-cache-policy.h b/drivers/md/dm-cache-policy.h
index 33369ca9614f..052c00a84a5c 100644
--- a/drivers/md/dm-cache-policy.h
+++ b/drivers/md/dm-cache-policy.h
@@ -135,9 +135,6 @@ struct dm_cache_policy {
135 */ 135 */
136 int (*lookup)(struct dm_cache_policy *p, dm_oblock_t oblock, dm_cblock_t *cblock); 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 void (*set_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock); 138 void (*set_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock);
142 void (*clear_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock); 139 void (*clear_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock);
143 140
@@ -159,8 +156,24 @@ struct dm_cache_policy {
159 void (*force_mapping)(struct dm_cache_policy *p, dm_oblock_t current_oblock, 156 void (*force_mapping)(struct dm_cache_policy *p, dm_oblock_t current_oblock,
160 dm_oblock_t new_oblock); 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 * How full is the cache? 179 * How full is the cache?