diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 4fbbe1fb9f08..92237b6fa8cd 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -235,6 +235,7 @@ struct pool { struct pool_features pf; bool low_water_triggered:1; /* A dm event has been sent */ bool suspended:1; + bool out_of_data_space:1; struct dm_bio_prison *prison; struct dm_kcopyd_client *copier; @@ -461,9 +462,16 @@ static void cell_error_with_code(struct pool *pool, dm_bio_prison_free_cell(pool->prison, cell); } +static int get_pool_io_error_code(struct pool *pool) +{ + return pool->out_of_data_space ? -ENOSPC : -EIO; +} + static void cell_error(struct pool *pool, struct dm_bio_prison_cell *cell) { - cell_error_with_code(pool, cell, -EIO); + int error = get_pool_io_error_code(pool); + + cell_error_with_code(pool, cell, error); } static void cell_success(struct pool *pool, struct dm_bio_prison_cell *cell) @@ -622,7 +630,9 @@ static void error_retry_list_with_code(struct pool *pool, int error) static void error_retry_list(struct pool *pool) { - return error_retry_list_with_code(pool, -EIO); + int error = get_pool_io_error_code(pool); + + return error_retry_list_with_code(pool, error); } /* @@ -2419,6 +2429,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) */ if (old_mode != new_mode) notify_of_pool_mode_change_to_oods(pool); + pool->out_of_data_space = true; pool->process_bio = process_bio_read_only; pool->process_discard = process_discard_bio; pool->process_cell = process_cell_read_only; @@ -2432,6 +2443,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) case PM_WRITE: if (old_mode != new_mode) notify_of_pool_mode_change(pool, "write"); + pool->out_of_data_space = false; pool->pf.error_if_no_space = pt->requested_pf.error_if_no_space; dm_pool_metadata_read_write(pool->pmd); pool->process_bio = process_bio; @@ -2832,6 +2844,7 @@ static struct pool *pool_create(struct mapped_device *pool_md, INIT_LIST_HEAD(&pool->active_thins); pool->low_water_triggered = false; pool->suspended = true; + pool->out_of_data_space = false; pool->shared_read_ds = dm_deferred_set_create(); if (!pool->shared_read_ds) { @@ -3886,7 +3899,7 @@ static struct target_type pool_target = { .name = "thin-pool", .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | DM_TARGET_IMMUTABLE, - .version = {1, 17, 0}, + .version = {1, 18, 0}, .module = THIS_MODULE, .ctr = pool_ctr, .dtr = pool_dtr, @@ -4260,7 +4273,7 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits) static struct target_type thin_target = { .name = "thin", - .version = {1, 17, 0}, + .version = {1, 18, 0}, .module = THIS_MODULE, .ctr = thin_ctr, .dtr = thin_dtr,