Skip to content

Commit 4134455

Browse files
Mikulas Patockasnitm
authored andcommitted
dm writecache: fix writing beyond end of underlying device when shrinking
Do not attempt to write any data beyond the end of the underlying data device while shrinking it. The DM writecache device must be suspended when the underlying data device is shrunk. Signed-off-by: Mikulas Patocka <[email protected]> Cc: [email protected] Signed-off-by: Mike Snitzer <[email protected]>
1 parent cccb493 commit 4134455

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

drivers/md/dm-writecache.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ struct dm_writecache {
148148
size_t metadata_sectors;
149149
size_t n_blocks;
150150
uint64_t seq_count;
151+
sector_t data_device_sectors;
151152
void *block_start;
152153
struct wc_entry *entries;
153154
unsigned block_size;
@@ -977,6 +978,8 @@ static void writecache_resume(struct dm_target *ti)
977978

978979
wc_lock(wc);
979980

981+
wc->data_device_sectors = i_size_read(wc->dev->bdev->bd_inode) >> SECTOR_SHIFT;
982+
980983
if (WC_MODE_PMEM(wc)) {
981984
persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size);
982985
} else {
@@ -1646,6 +1649,10 @@ static bool wc_add_block(struct writeback_struct *wb, struct wc_entry *e, gfp_t
16461649
void *address = memory_data(wc, e);
16471650

16481651
persistent_memory_flush_cache(address, block_size);
1652+
1653+
if (unlikely(bio_end_sector(&wb->bio) >= wc->data_device_sectors))
1654+
return true;
1655+
16491656
return bio_add_page(&wb->bio, persistent_memory_page(address),
16501657
block_size, persistent_memory_page_offset(address)) != 0;
16511658
}
@@ -1717,6 +1724,9 @@ static void __writecache_writeback_pmem(struct dm_writecache *wc, struct writeba
17171724
if (writecache_has_error(wc)) {
17181725
bio->bi_status = BLK_STS_IOERR;
17191726
bio_endio(bio);
1727+
} else if (unlikely(!bio_sectors(bio))) {
1728+
bio->bi_status = BLK_STS_OK;
1729+
bio_endio(bio);
17201730
} else {
17211731
submit_bio(bio);
17221732
}
@@ -1760,6 +1770,14 @@ static void __writecache_writeback_ssd(struct dm_writecache *wc, struct writebac
17601770
e = f;
17611771
}
17621772

1773+
if (unlikely(to.sector + to.count > wc->data_device_sectors)) {
1774+
if (to.sector >= wc->data_device_sectors) {
1775+
writecache_copy_endio(0, 0, c);
1776+
continue;
1777+
}
1778+
from.count = to.count = wc->data_device_sectors - to.sector;
1779+
}
1780+
17631781
dm_kcopyd_copy(wc->dm_kcopyd, &from, 1, &to, 0, writecache_copy_endio, c);
17641782

17651783
__writeback_throttle(wc, wbl);

0 commit comments

Comments
 (0)