[dm-devel] [PATCH] dm thin: fix pool target flags that control discard
Joe Thornber
thornber at redhat.com
Mon Mar 26 15:34:39 UTC 2012
On Mon, Mar 26, 2012 at 03:15:21PM +0100, Joe Thornber wrote:
> > o disallow disabling discards if a pool was already configured with
> > discards enabled (the default)
> > - justification is inlined in the code
> > - required pool_ctr knowing whether pool was created or not; so added
> > 'created' flag to __pool_find()
>
> ack, this needs fixing.
The following patch prevents people changing the top-level discard
flag when reloading a pool target.
I'll push this test in a bit (dm-cache changes holding things up).
# we don't allow people to change their minds about top level
# discard support.
def test_change_discard_with_reload_fails
with_standard_pool(@size, :discard => true) do |pool|
assert_raise(ExitError) do
table = Table.new(ThinPool.new(@size, @metadata_dev, @data_dev,
@data_block_size, @low_water_mark, false, false, false))
pool.load(table)
end
end
with_standard_pool(@size, :discard => false) do |pool|
assert_raise(ExitError) do
table = Table.new(ThinPool.new(@size, @metadata_dev, @data_dev,
@data_block_size, @low_water_mark, false, true, false))
pool.load(table)
end
end
end
- Joe
commit 9f075e7f5330039addba213a0f512ab7c0ea3ecf
Author: Joe Thornber <ejt at redhat.com>
Date: Mon Mar 26 16:26:33 2012 +0100
dm-thin: don't allow the top level discard flag to be changed on reload.
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index e8fe5db..e5a6ed4 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -1445,10 +1445,12 @@ static void __pool_dec(struct pool *pool)
static struct pool *__pool_find(struct mapped_device *pool_md,
struct block_device *metadata_dev,
- unsigned long block_size, char **error)
+ unsigned long block_size, char **error,
+ int *created)
{
struct pool *pool = __pool_table_lookup_metadata_dev(metadata_dev);
+ *created = 0;
if (pool) {
if (pool->pool_md != pool_md)
return ERR_PTR(-EBUSY);
@@ -1461,8 +1463,10 @@ static struct pool *__pool_find(struct mapped_device *pool_md,
return ERR_PTR(-EINVAL);
__pool_inc(pool);
- } else
+ } else {
pool = pool_create(pool_md, metadata_dev, block_size, error);
+ *created = 1;
+ }
}
return pool;
@@ -1542,7 +1546,7 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
*/
static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
{
- int r;
+ int r, pool_created;
struct pool_c *pt;
struct pool *pool;
struct pool_features pf;
@@ -1617,12 +1621,24 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
}
pool = __pool_find(dm_table_get_md(ti->table), metadata_dev->bdev,
- block_size, &ti->error);
+ block_size, &ti->error, &pool_created);
if (IS_ERR(pool)) {
r = PTR_ERR(pool);
goto out_free_pt;
}
+ /*
+ * 'pool_created' reflects whether this is the first table load.
+ * Top level discard support is not allowed to be changed after
+ * initial load. This would require a pool reload to trigger thin
+ * device changes.
+ */
+ if (!pool_created && pf.discard_enabled != pool->pf.discard_enabled) {
+ ti->error = "Discard support cannot be changed once enabled";
+ r = -EINVAL;
+ goto out_flags_changed;
+ }
+
pt->pool = pool;
pt->ti = ti;
pt->metadata_dev = metadata_dev;
@@ -1643,6 +1659,8 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
return 0;
+out_flags_changed:
+ __pool_dec(pool);
out_free_pt:
kfree(pt);
out:
More information about the dm-devel
mailing list