aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2017-05-05 14:40:13 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-25 09:44:33 -0400
commite69242436b6b086a6f342f715c68389596a9a7ac (patch)
tree47cfa34818b4c84ca627d4dd5647008a2783ca65
parent042d8dbf69c6ca0d542eaf41480d9303c36c56a9 (diff)
dm cache metadata: fail operations if fail_io mode has been established
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>
-rw-r--r--drivers/md/dm-cache-metadata.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
index 695577812cf6..6937ca42be8c 100644
--- a/drivers/md/dm-cache-metadata.c
+++ b/drivers/md/dm-cache-metadata.c
@@ -1383,17 +1383,19 @@ void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
1383 1383
1384int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown) 1384int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown)
1385{ 1385{
1386 int r; 1386 int r = -EINVAL;
1387 flags_mutator mutator = (clean_shutdown ? set_clean_shutdown : 1387 flags_mutator mutator = (clean_shutdown ? set_clean_shutdown :
1388 clear_clean_shutdown); 1388 clear_clean_shutdown);
1389 1389
1390 WRITE_LOCK(cmd); 1390 WRITE_LOCK(cmd);
1391 if (cmd->fail_io)
1392 goto out;
1393
1391 r = __commit_transaction(cmd, mutator); 1394 r = __commit_transaction(cmd, mutator);
1392 if (r) 1395 if (r)
1393 goto out; 1396 goto out;
1394 1397
1395 r = __begin_transaction(cmd); 1398 r = __begin_transaction(cmd);
1396
1397out: 1399out:
1398 WRITE_UNLOCK(cmd); 1400 WRITE_UNLOCK(cmd);
1399 return r; 1401 return r;
@@ -1405,7 +1407,8 @@ int dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd,
1405 int r = -EINVAL; 1407 int r = -EINVAL;
1406 1408
1407 READ_LOCK(cmd); 1409 READ_LOCK(cmd);
1408 r = dm_sm_get_nr_free(cmd->metadata_sm, result); 1410 if (!cmd->fail_io)
1411 r = dm_sm_get_nr_free(cmd->metadata_sm, result);
1409 READ_UNLOCK(cmd); 1412 READ_UNLOCK(cmd);
1410 1413
1411 return r; 1414 return r;
@@ -1417,7 +1420,8 @@ int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd,
1417 int r = -EINVAL; 1420 int r = -EINVAL;
1418 1421
1419 READ_LOCK(cmd); 1422 READ_LOCK(cmd);
1420 r = dm_sm_get_nr_blocks(cmd->metadata_sm, result); 1423 if (!cmd->fail_io)
1424 r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
1421 READ_UNLOCK(cmd); 1425 READ_UNLOCK(cmd);
1422 1426
1423 return r; 1427 return r;