Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / drivers / md / dm-cache-metadata.c
index f6543f3..3970cda 100644 (file)
@@ -867,18 +867,55 @@ static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd,
        return 0;
 }
 
-#define WRITE_LOCK(cmd) \
-       if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
-               return -EINVAL; \
-       down_write(&cmd->root_lock)
+static bool cmd_write_lock(struct dm_cache_metadata *cmd)
+{
+       down_write(&cmd->root_lock);
+       if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) {
+               up_write(&cmd->root_lock);
+               return false;
+       }
+       return true;
+}
+
+#define WRITE_LOCK(cmd)                                \
+       do {                                    \
+               if (!cmd_write_lock((cmd)))     \
+                       return -EINVAL;         \
+       } while(0)
 
-#define WRITE_LOCK_VOID(cmd) \
-       if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \
-               return; \
-       down_write(&cmd->root_lock)
+#define WRITE_LOCK_VOID(cmd)                   \
+       do {                                    \
+               if (!cmd_write_lock((cmd)))     \
+                       return;                 \
+       } while(0)
 
 #define WRITE_UNLOCK(cmd) \
-       up_write(&cmd->root_lock)
+       up_write(&(cmd)->root_lock)
+
+static bool cmd_read_lock(struct dm_cache_metadata *cmd)
+{
+       down_read(&cmd->root_lock);
+       if (cmd->fail_io) {
+               up_read(&cmd->root_lock);
+               return false;
+       }
+       return true;
+}
+
+#define READ_LOCK(cmd)                         \
+       do {                                    \
+               if (!cmd_read_lock((cmd)))      \
+                       return -EINVAL;         \
+       } while(0)
+
+#define READ_LOCK_VOID(cmd)                    \
+       do {                                    \
+               if (!cmd_read_lock((cmd)))      \
+                       return;                 \
+       } while(0)
+
+#define READ_UNLOCK(cmd) \
+       up_read(&(cmd)->root_lock)
 
 int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size)
 {
@@ -1015,22 +1052,20 @@ int dm_cache_load_discards(struct dm_cache_metadata *cmd,
 {
        int r;
 
-       down_read(&cmd->root_lock);
+       READ_LOCK(cmd);
        r = __load_discards(cmd, fn, context);
-       up_read(&cmd->root_lock);
+       READ_UNLOCK(cmd);
 
        return r;
 }
 
-dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd)
+int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result)
 {
-       dm_cblock_t r;
-
-       down_read(&cmd->root_lock);
-       r = cmd->cache_blocks;
-       up_read(&cmd->root_lock);
+       READ_LOCK(cmd);
+       *result = cmd->cache_blocks;
+       READ_UNLOCK(cmd);
 
-       return r;
+       return 0;
 }
 
 static int __remove(struct dm_cache_metadata *cmd, dm_cblock_t cblock)
@@ -1188,9 +1223,9 @@ int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
 {
        int r;
 
-       down_read(&cmd->root_lock);
+       READ_LOCK(cmd);
        r = __load_mappings(cmd, policy, fn, context);
-       up_read(&cmd->root_lock);
+       READ_UNLOCK(cmd);
 
        return r;
 }
@@ -1215,18 +1250,18 @@ static int __dump_mappings(struct dm_cache_metadata *cmd)
 
 void dm_cache_dump(struct dm_cache_metadata *cmd)
 {
-       down_read(&cmd->root_lock);
+       READ_LOCK_VOID(cmd);
        __dump_mappings(cmd);
-       up_read(&cmd->root_lock);
+       READ_UNLOCK(cmd);
 }
 
 int dm_cache_changed_this_transaction(struct dm_cache_metadata *cmd)
 {
        int r;
 
-       down_read(&cmd->root_lock);
+       READ_LOCK(cmd);
        r = cmd->changed;
-       up_read(&cmd->root_lock);
+       READ_UNLOCK(cmd);
 
        return r;
 }
@@ -1276,9 +1311,9 @@ int dm_cache_set_dirty(struct dm_cache_metadata *cmd,
 void dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd,
                                 struct dm_cache_statistics *stats)
 {
-       down_read(&cmd->root_lock);
+       READ_LOCK_VOID(cmd);
        *stats = cmd->stats;
-       up_read(&cmd->root_lock);
+       READ_UNLOCK(cmd);
 }
 
 void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
@@ -1312,9 +1347,9 @@ int dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd,
 {
        int r = -EINVAL;
 
-       down_read(&cmd->root_lock);
+       READ_LOCK(cmd);
        r = dm_sm_get_nr_free(cmd->metadata_sm, result);
-       up_read(&cmd->root_lock);
+       READ_UNLOCK(cmd);
 
        return r;
 }
@@ -1324,9 +1359,9 @@ int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd,
 {
        int r = -EINVAL;
 
-       down_read(&cmd->root_lock);
+       READ_LOCK(cmd);
        r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
-       up_read(&cmd->root_lock);
+       READ_UNLOCK(cmd);
 
        return r;
 }
@@ -1417,7 +1452,13 @@ int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *
 
 int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result)
 {
-       return blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result);
+       int r;
+
+       READ_LOCK(cmd);
+       r = blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result);
+       READ_UNLOCK(cmd);
+
+       return r;
 }
 
 void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd)
@@ -1440,10 +1481,7 @@ int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd)
        struct dm_block *sblock;
        struct cache_disk_superblock *disk_super;
 
-       /*
-        * We ignore fail_io for this function.
-        */
-       down_write(&cmd->root_lock);
+       WRITE_LOCK(cmd);
        set_bit(NEEDS_CHECK, &cmd->flags);
 
        r = superblock_lock(cmd, &sblock);
@@ -1458,19 +1496,17 @@ int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd)
        dm_bm_unlock(sblock);
 
 out:
-       up_write(&cmd->root_lock);
+       WRITE_UNLOCK(cmd);
        return r;
 }
 
-bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd)
+int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result)
 {
-       bool needs_check;
+       READ_LOCK(cmd);
+       *result = !!test_bit(NEEDS_CHECK, &cmd->flags);
+       READ_UNLOCK(cmd);
 
-       down_read(&cmd->root_lock);
-       needs_check = !!test_bit(NEEDS_CHECK, &cmd->flags);
-       up_read(&cmd->root_lock);
-
-       return needs_check;
+       return 0;
 }
 
 int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)