aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorDamien Le Moal2018-10-17 18:05:08 +0900
committerMike Snitzer2018-10-18 15:17:03 -0400
commit3d4e738311327bc4ba1d55fbe2f1da3de4a475f9 (patch)
treead665b95dd90cf7fdadce080ebbee76379c1cf8e /block
parent33c2865f8d011a2ca9f67124ddab9dc89382e9f1 (diff)
dm zoned: fix various dmz_get_mblock() issues
dmz_fetch_mblock() called from dmz_get_mblock() has a race since the allocation of the new metadata block descriptor and its insertion in the cache rbtree with the READING state is not atomic. Two different contexts requesting the same block may end up each adding two different descriptors of the same block to the cache. Another problem for this function is that the BIO for processing the block read is allocated after the metadata block descriptor is inserted in the cache rbtree. If the BIO allocation fails, the metadata block descriptor is freed without first being removed from the rbtree. Fix the first problem by checking again if the requested block is not in the cache right before inserting the newly allocated descriptor, atomically under the mblk_lock spinlock. The second problem is fixed by simply allocating the BIO before inserting the new block in the cache. Finally, since dmz_fetch_mblock() also increments a block reference counter, rename the function to dmz_get_mblock_slow(). To be symmetric and clear, also rename dmz_lookup_mblock() to dmz_get_mblock_fast() and increment the block reference counter directly in that function rather than in dmz_get_mblock(). Fixes: 3b1a94c88b79 ("dm zoned: drive-managed zoned block device target") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'block')
0 files changed, 0 insertions, 0 deletions