|
@@ -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,
|