Skip to content

Commit

Permalink
dm thin: fix missing out-of-data-space to write mode transition if bl…
Browse files Browse the repository at this point in the history
…ocks are released

Discard bios and thin device deletion have the potential to release data
blocks.  If the thin-pool is in out-of-data-space mode, and blocks were
released, transition the thin-pool back to full write mode.

The correct time to do this is just after the thin-pool metadata commit.
It cannot be done before the commit because the space maps will not
allow immediate reuse of the data blocks in case there's a rollback
following power failure.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Cc: stable@vger.kernel.org
  • Loading branch information
Joe Thornber authored and Mike Snitzer committed Dec 17, 2014
1 parent 45ec9bd commit 2c43fd2
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions drivers/md/dm-thin.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,24 @@ static void schedule_external_copy(struct thin_c *tc, dm_block_t virt_block,
schedule_zero(tc, virt_block, data_dest, cell, bio);
}

static void set_pool_mode(struct pool *pool, enum pool_mode new_mode);

static void check_for_space(struct pool *pool)
{
int r;
dm_block_t nr_free;

if (get_pool_mode(pool) != PM_OUT_OF_DATA_SPACE)
return;

r = dm_pool_get_free_block_count(pool->pmd, &nr_free);
if (r)
return;

if (nr_free)
set_pool_mode(pool, PM_WRITE);
}

/*
* A non-zero return indicates read_only or fail_io mode.
* Many callers don't care about the return value.
Expand All @@ -1141,6 +1159,8 @@ static int commit(struct pool *pool)
r = dm_pool_commit_metadata(pool->pmd);
if (r)
metadata_operation_failed(pool, "dm_pool_commit_metadata", r);
else
check_for_space(pool);

return r;
}
Expand All @@ -1159,8 +1179,6 @@ static void check_low_water_mark(struct pool *pool, dm_block_t free_blocks)
}
}

static void set_pool_mode(struct pool *pool, enum pool_mode new_mode);

static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
{
int r;
Expand Down

0 comments on commit 2c43fd2

Please sign in to comment.