summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-thin.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-thin.c')
-rw-r--r--drivers/md/dm-thin.c72
1 files changed, 37 insertions, 35 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 0bd8d498b3b9..dadd9696340c 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -195,7 +195,7 @@ static void throttle_unlock(struct throttle *t)
195struct dm_thin_new_mapping; 195struct dm_thin_new_mapping;
196 196
197/* 197/*
198 * The pool runs in 4 modes. Ordered in degraded order for comparisons. 198 * The pool runs in various modes. Ordered in degraded order for comparisons.
199 */ 199 */
200enum pool_mode { 200enum pool_mode {
201 PM_WRITE, /* metadata may be changed */ 201 PM_WRITE, /* metadata may be changed */
@@ -282,9 +282,38 @@ struct pool {
282 mempool_t mapping_pool; 282 mempool_t mapping_pool;
283}; 283};
284 284
285static enum pool_mode get_pool_mode(struct pool *pool);
286static void metadata_operation_failed(struct pool *pool, const char *op, int r); 285static void metadata_operation_failed(struct pool *pool, const char *op, int r);
287 286
287static enum pool_mode get_pool_mode(struct pool *pool)
288{
289 return pool->pf.mode;
290}
291
292static void notify_of_pool_mode_change(struct pool *pool)
293{
294 const char *descs[] = {
295 "write",
296 "out-of-data-space",
297 "read-only",
298 "read-only",
299 "fail"
300 };
301 const char *extra_desc = NULL;
302 enum pool_mode mode = get_pool_mode(pool);
303
304 if (mode == PM_OUT_OF_DATA_SPACE) {
305 if (!pool->pf.error_if_no_space)
306 extra_desc = " (queue IO)";
307 else
308 extra_desc = " (error IO)";
309 }
310
311 dm_table_event(pool->ti->table);
312 DMINFO("%s: switching pool to %s%s mode",
313 dm_device_name(pool->pool_md),
314 descs[(int)mode], extra_desc ? : "");
315}
316
288/* 317/*
289 * Target context for a pool. 318 * Target context for a pool.
290 */ 319 */
@@ -2351,8 +2380,6 @@ static void do_waker(struct work_struct *ws)
2351 queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD); 2380 queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD);
2352} 2381}
2353 2382
2354static void notify_of_pool_mode_change_to_oods(struct pool *pool);
2355
2356/* 2383/*
2357 * We're holding onto IO to allow userland time to react. After the 2384 * We're holding onto IO to allow userland time to react. After the
2358 * timeout either the pool will have been resized (and thus back in 2385 * timeout either the pool will have been resized (and thus back in
@@ -2365,7 +2392,7 @@ static void do_no_space_timeout(struct work_struct *ws)
2365 2392
2366 if (get_pool_mode(pool) == PM_OUT_OF_DATA_SPACE && !pool->pf.error_if_no_space) { 2393 if (get_pool_mode(pool) == PM_OUT_OF_DATA_SPACE && !pool->pf.error_if_no_space) {
2367 pool->pf.error_if_no_space = true; 2394 pool->pf.error_if_no_space = true;
2368 notify_of_pool_mode_change_to_oods(pool); 2395 notify_of_pool_mode_change(pool);
2369 error_retry_list_with_code(pool, BLK_STS_NOSPC); 2396 error_retry_list_with_code(pool, BLK_STS_NOSPC);
2370 } 2397 }
2371} 2398}
@@ -2433,26 +2460,6 @@ static void noflush_work(struct thin_c *tc, void (*fn)(struct work_struct *))
2433 2460
2434/*----------------------------------------------------------------*/ 2461/*----------------------------------------------------------------*/
2435 2462
2436static enum pool_mode get_pool_mode(struct pool *pool)
2437{
2438 return pool->pf.mode;
2439}
2440
2441static void notify_of_pool_mode_change(struct pool *pool, const char *new_mode)
2442{
2443 dm_table_event(pool->ti->table);
2444 DMINFO("%s: switching pool to %s mode",
2445 dm_device_name(pool->pool_md), new_mode);
2446}
2447
2448static void notify_of_pool_mode_change_to_oods(struct pool *pool)
2449{
2450 if (!pool->pf.error_if_no_space)
2451 notify_of_pool_mode_change(pool, "out-of-data-space (queue IO)");
2452 else
2453 notify_of_pool_mode_change(pool, "out-of-data-space (error IO)");
2454}
2455
2456static bool passdown_enabled(struct pool_c *pt) 2463static bool passdown_enabled(struct pool_c *pt)
2457{ 2464{
2458 return pt->adjusted_pf.discard_passdown; 2465 return pt->adjusted_pf.discard_passdown;
@@ -2501,8 +2508,6 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
2501 2508
2502 switch (new_mode) { 2509 switch (new_mode) {
2503 case PM_FAIL: 2510 case PM_FAIL:
2504 if (old_mode != new_mode)
2505 notify_of_pool_mode_change(pool, "failure");
2506 dm_pool_metadata_read_only(pool->pmd); 2511 dm_pool_metadata_read_only(pool->pmd);
2507 pool->process_bio = process_bio_fail; 2512 pool->process_bio = process_bio_fail;
2508 pool->process_discard = process_bio_fail; 2513 pool->process_discard = process_bio_fail;
@@ -2516,8 +2521,6 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
2516 2521
2517 case PM_OUT_OF_METADATA_SPACE: 2522 case PM_OUT_OF_METADATA_SPACE:
2518 case PM_READ_ONLY: 2523 case PM_READ_ONLY:
2519 if (!is_read_only_pool_mode(old_mode))
2520 notify_of_pool_mode_change(pool, "read-only");
2521 dm_pool_metadata_read_only(pool->pmd); 2524 dm_pool_metadata_read_only(pool->pmd);
2522 pool->process_bio = process_bio_read_only; 2525 pool->process_bio = process_bio_read_only;
2523 pool->process_discard = process_bio_success; 2526 pool->process_discard = process_bio_success;
@@ -2538,8 +2541,6 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
2538 * alarming rate. Adjust your low water mark if you're 2541 * alarming rate. Adjust your low water mark if you're
2539 * frequently seeing this mode. 2542 * frequently seeing this mode.
2540 */ 2543 */
2541 if (old_mode != new_mode)
2542 notify_of_pool_mode_change_to_oods(pool);
2543 pool->out_of_data_space = true; 2544 pool->out_of_data_space = true;
2544 pool->process_bio = process_bio_read_only; 2545 pool->process_bio = process_bio_read_only;
2545 pool->process_discard = process_discard_bio; 2546 pool->process_discard = process_discard_bio;
@@ -2552,8 +2553,6 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
2552 break; 2553 break;
2553 2554
2554 case PM_WRITE: 2555 case PM_WRITE:
2555 if (old_mode != new_mode)
2556 notify_of_pool_mode_change(pool, "write");
2557 if (old_mode == PM_OUT_OF_DATA_SPACE) 2556 if (old_mode == PM_OUT_OF_DATA_SPACE)
2558 cancel_delayed_work_sync(&pool->no_space_timeout); 2557 cancel_delayed_work_sync(&pool->no_space_timeout);
2559 pool->out_of_data_space = false; 2558 pool->out_of_data_space = false;
@@ -2573,6 +2572,9 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
2573 * doesn't cause an unexpected mode transition on resume. 2572 * doesn't cause an unexpected mode transition on resume.
2574 */ 2573 */
2575 pt->adjusted_pf.mode = new_mode; 2574 pt->adjusted_pf.mode = new_mode;
2575
2576 if (old_mode != new_mode)
2577 notify_of_pool_mode_change(pool);
2576} 2578}
2577 2579
2578static void abort_transaction(struct pool *pool) 2580static void abort_transaction(struct pool *pool)
@@ -4023,7 +4025,7 @@ static struct target_type pool_target = {
4023 .name = "thin-pool", 4025 .name = "thin-pool",
4024 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | 4026 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
4025 DM_TARGET_IMMUTABLE, 4027 DM_TARGET_IMMUTABLE,
4026 .version = {1, 20, 0}, 4028 .version = {1, 21, 0},
4027 .module = THIS_MODULE, 4029 .module = THIS_MODULE,
4028 .ctr = pool_ctr, 4030 .ctr = pool_ctr,
4029 .dtr = pool_dtr, 4031 .dtr = pool_dtr,
@@ -4397,7 +4399,7 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
4397 4399
4398static struct target_type thin_target = { 4400static struct target_type thin_target = {
4399 .name = "thin", 4401 .name = "thin",
4400 .version = {1, 20, 0}, 4402 .version = {1, 21, 0},
4401 .module = THIS_MODULE, 4403 .module = THIS_MODULE,
4402 .ctr = thin_ctr, 4404 .ctr = thin_ctr,
4403 .dtr = thin_dtr, 4405 .dtr = thin_dtr,