This is a note to let you know that I've just added the patch titled dm thin metadata: use pool locking at end of dm_pool_metadata_close to the 5.5-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: dm-thin-metadata-use-pool-locking-at-end-of-dm_pool_metadata_close.patch and it can be found in the queue-5.5 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 44d8ebf436399a40fcd10dd31b29d37823d62fcc Mon Sep 17 00:00:00 2001 From: Mike Snitzer <snitzer@xxxxxxxxxx> Date: Mon, 13 Jan 2020 11:18:51 -0500 Subject: dm thin metadata: use pool locking at end of dm_pool_metadata_close From: Mike Snitzer <snitzer@xxxxxxxxxx> commit 44d8ebf436399a40fcd10dd31b29d37823d62fcc upstream. Ensure that the pool is locked during calls to __commit_transaction and __destroy_persistent_data_objects. Just being consistent with locking, but reality is dm_pool_metadata_close is called once pool is being destroyed so access to pool shouldn't be contended. Also, use pmd_write_lock_in_core rather than __pmd_write_lock in dm_pool_commit_metadata and rename __pmd_write_lock to pmd_write_lock_in_core -- there was no need for the alias. In addition, verify that the pool is locked in __commit_transaction(). Fixes: 873f258becca ("dm thin metadata: do not write metadata if no changes occurred") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/md/dm-thin-metadata.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c @@ -387,16 +387,15 @@ static int subtree_equal(void *context, * Variant that is used for in-core only changes or code that * shouldn't put the pool in service on its own (e.g. commit). */ -static inline void __pmd_write_lock(struct dm_pool_metadata *pmd) +static inline void pmd_write_lock_in_core(struct dm_pool_metadata *pmd) __acquires(pmd->root_lock) { down_write(&pmd->root_lock); } -#define pmd_write_lock_in_core(pmd) __pmd_write_lock((pmd)) static inline void pmd_write_lock(struct dm_pool_metadata *pmd) { - __pmd_write_lock(pmd); + pmd_write_lock_in_core(pmd); if (unlikely(!pmd->in_service)) pmd->in_service = true; } @@ -831,6 +830,7 @@ static int __commit_transaction(struct d * We need to know if the thin_disk_superblock exceeds a 512-byte sector. */ BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512); + BUG_ON(!rwsem_is_locked(&pmd->root_lock)); if (unlikely(!pmd->in_service)) return 0; @@ -953,6 +953,7 @@ int dm_pool_metadata_close(struct dm_poo return -EBUSY; } + pmd_write_lock_in_core(pmd); if (!dm_bm_is_read_only(pmd->bm) && !pmd->fail_io) { r = __commit_transaction(pmd); if (r < 0) @@ -961,6 +962,7 @@ int dm_pool_metadata_close(struct dm_poo } if (!pmd->fail_io) __destroy_persistent_data_objects(pmd); + pmd_write_unlock(pmd); kfree(pmd); return 0; @@ -1841,7 +1843,7 @@ int dm_pool_commit_metadata(struct dm_po * Care is taken to not have commit be what * triggers putting the thin-pool in-service. */ - __pmd_write_lock(pmd); + pmd_write_lock_in_core(pmd); if (pmd->fail_io) goto out; Patches currently in stable-queue which might be from snitzer@xxxxxxxxxx are queue-5.5/dm-crypt-fix-benbi-iv-constructor-crash-if-used-in-authenticated-mode.patch queue-5.5/dm-fix-potential-for-q-make_request_fn-null-pointer.patch queue-5.5/dm-crypt-fix-gfp-flags-passed-to-skcipher_request_alloc.patch queue-5.5/dm-writecache-fix-incorrect-flush-sequence-when-doing-ssd-mode-commit.patch queue-5.5/dm-thin-metadata-use-pool-locking-at-end-of-dm_pool_metadata_close.patch queue-5.5/dm-thin-fix-use-after-free-in-metadata_pre_commit_callback.patch queue-5.5/dm-zoned-support-zone-sizes-smaller-than-128mib.patch queue-5.5/dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch