Skip to content

Commit d90accf

Browse files
mingnusgregkh
authored andcommitted
dm cache: fix concurrent write failure in passthrough mode
[ Upstream commit e4f6634 ] When bio prison cell lock acquisition fails due to concurrent writes to the same block in passthrough mode, dm-cache incorrectly returns an I/O error instead of properly handling the concurrency. This can occur in both process and workqueue contexts when invalidate_lock() is called for exclusive access to a data block. Fix this by deferring the write bios to ensure proper block device behavior. Reproduce steps: 1. Create a cache device dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 262144 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 262144 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" 2. Promote the first data block into cache fio --filename=/dev/mapper/cache --name=populate --rw=write --bs=4k \ --direct=1 --size=64k 3. Reload the cache into passthrough mode dmsetup suspend cache dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 passthrough smq 0" dmsetup resume cache 4. Write to the first cached block concurrently. Sometimes one of the processes will receive I/O errors. fio --filename=/dev/mapper/cache --name test --rw=randwrite --bs=4k \ --randrepeat=0 --direct=1 --numjobs=2 --size 64k <snip> fio-3.41 fio: io_u error on file /dev/mapper/cache: Input/output error: write offset=4096, buflen=4096 fio: pid=106, err=5/file:io_u.c:2008, func=io_u error, error=Input/output error test: (groupid=0, jobs=1): err= 0: pid=105 test: (groupid=0, jobs=1): err= 5 (file:io_u.c:2008, func=io_u error, error=Input/output error): pid=106 <snip> Fixes: b29d498 ("dm cache: significant rework to leverage dm-bio-prison-v2") Signed-off-by: Ming-Hung Tsai <mtsai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent ac5ee99 commit d90accf

1 file changed

Lines changed: 9 additions & 0 deletions

File tree

drivers/md/dm-cache-target.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,15 @@ static int invalidate_lock(struct dm_cache_migration *mg)
15571557
READ_WRITE_LOCK_LEVEL, prealloc, &mg->cell);
15581558
if (r < 0) {
15591559
free_prison_cell(cache, prealloc);
1560+
1561+
/* Defer the bio for retrying the cell lock */
1562+
if (mg->overwrite_bio) {
1563+
struct bio *bio = mg->overwrite_bio;
1564+
1565+
mg->overwrite_bio = NULL;
1566+
defer_bio(cache, bio);
1567+
}
1568+
15601569
invalidate_complete(mg, false);
15611570
return r;
15621571
}

0 commit comments

Comments
 (0)