dm cache: add remove_cblock method to policy interface
authorJoe Thornber <ejt@redhat.com>
Fri, 8 Nov 2013 16:36:17 +0000 (16:36 +0000)
committerMike Snitzer <snitzer@redhat.com>
Mon, 11 Nov 2013 16:37:50 +0000 (11:37 -0500)
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>
drivers/md/dm-cache-policy-internal.h
drivers/md/dm-cache-policy-mq.c
drivers/md/dm-cache-policy.h

index a75f7e7498ebc5e68b026e818e3722d01dd8f0f9..2256a1f24f73e1e3fc0271f0fbd39b1f4c1b67b0 100644 (file)
@@ -64,6 +64,11 @@ static inline void policy_remove_mapping(struct dm_cache_policy *p, dm_oblock_t
        p->remove_mapping(p, oblock);
 }
 
+static inline int policy_remove_cblock(struct dm_cache_policy *p, dm_cblock_t cblock)
+{
+       return p->remove_cblock(p, cblock);
+}
+
 static inline void policy_force_mapping(struct dm_cache_policy *p,
                                        dm_oblock_t current_oblock, dm_oblock_t new_oblock)
 {
index 782bf854666ab361503df8c1e29a60f17132ded3..7209fab8b8edade7a57e85e4da2c727b59e58d9e 100644 (file)
@@ -304,6 +304,15 @@ static void free_entry(struct entry_pool *ep, struct entry *e)
        list_add(&e->list, &ep->free);
 }
 
+/*
+ * Returns NULL if the entry is free.
+ */
+static struct entry *epool_find(struct entry_pool *ep, dm_cblock_t cblock)
+{
+       struct entry *e = ep->entries + from_cblock(cblock);
+       return e->hlist.pprev ? e : NULL;
+}
+
 static bool epool_empty(struct entry_pool *ep)
 {
        return list_empty(&ep->free);
@@ -1020,6 +1029,31 @@ static void mq_remove_mapping(struct dm_cache_policy *p, dm_oblock_t oblock)
        mutex_unlock(&mq->lock);
 }
 
+static int __remove_cblock(struct mq_policy *mq, dm_cblock_t cblock)
+{
+       struct entry *e = epool_find(&mq->cache_pool, cblock);
+
+       if (!e)
+               return -ENODATA;
+
+       del(mq, e);
+       free_entry(&mq->cache_pool, e);
+
+       return 0;
+}
+
+static int mq_remove_cblock(struct dm_cache_policy *p, dm_cblock_t cblock)
+{
+       int r;
+       struct mq_policy *mq = to_mq_policy(p);
+
+       mutex_lock(&mq->lock);
+       r = __remove_cblock(mq, cblock);
+       mutex_unlock(&mq->lock);
+
+       return r;
+}
+
 static int __mq_writeback_work(struct mq_policy *mq, dm_oblock_t *oblock,
                              dm_cblock_t *cblock)
 {
@@ -1139,6 +1173,7 @@ static void init_policy_functions(struct mq_policy *mq)
        mq->policy.load_mapping = mq_load_mapping;
        mq->policy.walk_mappings = mq_walk_mappings;
        mq->policy.remove_mapping = mq_remove_mapping;
+       mq->policy.remove_cblock = mq_remove_cblock;
        mq->policy.writeback_work = mq_writeback_work;
        mq->policy.force_mapping = mq_force_mapping;
        mq->policy.residency = mq_residency;
index 33369ca9614f978ae0481e0d79677c980660f42d..052c00a84a5c63a616b24ed0dd156681c880f0c4 100644 (file)
@@ -135,9 +135,6 @@ struct dm_cache_policy {
         */
        int (*lookup)(struct dm_cache_policy *p, dm_oblock_t oblock, dm_cblock_t *cblock);
 
-       /*
-        * oblock must be a mapped block.  Must not block.
-        */
        void (*set_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock);
        void (*clear_dirty)(struct dm_cache_policy *p, dm_oblock_t oblock);
 
@@ -159,8 +156,24 @@ struct dm_cache_policy {
        void (*force_mapping)(struct dm_cache_policy *p, dm_oblock_t current_oblock,
                              dm_oblock_t new_oblock);
 
-       int (*writeback_work)(struct dm_cache_policy *p, dm_oblock_t *oblock, dm_cblock_t *cblock);
+       /*
+        * This is called via the invalidate_cblocks message.  It is
+        * possible the particular cblock has already been removed due to a
+        * write io in passthrough mode.  In which case this should return
+        * -ENODATA.
+        */
+       int (*remove_cblock)(struct dm_cache_policy *p, dm_cblock_t cblock);
 
+       /*
+        * Provide a dirty block to be written back by the core target.
+        *
+        * Returns:
+        *
+        * 0 and @cblock,@oblock: block to write back provided
+        *
+        * -ENODATA: no dirty blocks available
+        */
+       int (*writeback_work)(struct dm_cache_policy *p, dm_oblock_t *oblock, dm_cblock_t *cblock);
 
        /*
         * How full is the cache?