OSDN Git Service

dm cache metadata: fail operations if fail_io mode has been established
authorMike Snitzer <snitzer@redhat.com>
Fri, 5 May 2017 18:40:13 +0000 (14:40 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 May 2017 12:30:08 +0000 (14:30 +0200)
commit 10add84e276432d9dd8044679a1028dd4084117e upstream.

Otherwise it is possible to trigger crashes due to the metadata being
inaccessible yet these methods don't safely account for that possibility
without these checks.

Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/md/dm-cache-metadata.c

index 3970cda..d3c55d7 100644 (file)
@@ -1326,17 +1326,19 @@ void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
 
 int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown)
 {
-       int r;
+       int r = -EINVAL;
        flags_mutator mutator = (clean_shutdown ? set_clean_shutdown :
                                 clear_clean_shutdown);
 
        WRITE_LOCK(cmd);
+       if (cmd->fail_io)
+               goto out;
+
        r = __commit_transaction(cmd, mutator);
        if (r)
                goto out;
 
        r = __begin_transaction(cmd);
-
 out:
        WRITE_UNLOCK(cmd);
        return r;
@@ -1348,7 +1350,8 @@ int dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd,
        int r = -EINVAL;
 
        READ_LOCK(cmd);
-       r = dm_sm_get_nr_free(cmd->metadata_sm, result);
+       if (!cmd->fail_io)
+               r = dm_sm_get_nr_free(cmd->metadata_sm, result);
        READ_UNLOCK(cmd);
 
        return r;
@@ -1360,7 +1363,8 @@ int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd,
        int r = -EINVAL;
 
        READ_LOCK(cmd);
-       r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
+       if (!cmd->fail_io)
+               r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
        READ_UNLOCK(cmd);
 
        return r;