Otherwise, just loading a thin-pool and then removing it will cause its metadata to be changed (e.g. superblock written) -- even without any thin devices being made active or metadata snapshot being manipulated. Add 'in_service' flag to struct dm_pool_metadata and use a new dm_pool_set_in_service() interface to set it if either a thin device is activated or a message is sent to the thin-pool. Once 'in_service' is set it is never cleared. __commit_transaction() will return 0 if 'in_service' is not set. Also fix dm_pool_commit_metadata() to open the next transaction if the return from __commit_transaction() is 0. Not seeing why the early return ever made since for a return of 0 given that dm-io's async_io(), as used by bufio, always returns 0. Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> --- drivers/md/dm-thin-metadata.c | 23 ++++++++++++++++++++++- drivers/md/dm-thin-metadata.h | 2 ++ drivers/md/dm-thin.c | 9 +++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 7381e477a945..fcff30fc07cd 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c @@ -201,6 +201,13 @@ struct dm_pool_metadata { */ bool fail_io:1; + /* + * Set once a thin-pool has been accessed through one of the interfaces + * that imply the pool is in-service (e.g. thin devices created/deleted, + * thin-pool message, metadata snapshots, etc). + */ + bool in_service:1; + /* * Reading the space map roots can fail, so we read it into these * buffers before the superblock is locked and updated. @@ -790,6 +797,9 @@ static int __commit_transaction(struct dm_pool_metadata *pmd) */ BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512); + if (unlikely(!pmd->in_service)) + return 0; + r = __write_changed_details(pmd); if (r < 0) return r; @@ -853,6 +863,7 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, pmd->time = 0; INIT_LIST_HEAD(&pmd->thin_devices); pmd->fail_io = false; + pmd->in_service = false; pmd->bdev = bdev; pmd->data_block_size = data_block_size; @@ -1727,6 +1738,16 @@ int dm_pool_dec_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_ return r; } +void dm_pool_set_in_service(struct dm_pool_metadata *pmd) +{ + if (!pmd->in_service) { + down_write(&pmd->root_lock); + if (!pmd->in_service) + pmd->in_service = true; + up_write(&pmd->root_lock); + } +} + bool dm_thin_changed_this_transaction(struct dm_thin_device *td) { int r; @@ -1787,7 +1808,7 @@ int dm_pool_commit_metadata(struct dm_pool_metadata *pmd) goto out; r = __commit_transaction(pmd); - if (r <= 0) + if (r < 0) goto out; /* diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index f6be0d733c20..8192530984be 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h @@ -47,6 +47,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, int dm_pool_metadata_close(struct dm_pool_metadata *pmd); +void dm_pool_set_in_service(struct dm_pool_metadata *pmd); + /* * Compat feature flags. Any incompat flags beyond the ones * specified below will prevent use of the thin metadata. diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index fcd887703f95..b6dbbdfc9118 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3822,6 +3822,13 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv, return -EOPNOTSUPP; } + /* + * Any message sent to a thin-pool warrants putting it in-service + * (even if the message is malformed, it speaks to a user + * attempting to interface with the thin-pool) + */ + dm_pool_set_in_service(pool->pmd); + if (!strcasecmp(argv[0], "create_thin")) r = process_create_thin_mesg(argc, argv, pool); @@ -4222,6 +4229,8 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) goto bad_pool; } + dm_pool_set_in_service(tc->pool->pmd); + r = dm_pool_open_thin_device(tc->pool->pmd, tc->dev_id, &tc->td); if (r) { ti->error = "Couldn't open thin internal device"; -- 2.18.0 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel