Skip to content

Commit 64f799f

Browse files
committed
Merge tag 'for-6.9/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: - Fix a memory leak in DM integrity recheck code that was added during the 6.9 merge. Also fix the recheck code to ensure it issues bios with proper alignment. - Fix DM snapshot's dm_exception_table_exit() to schedule while handling an large exception table during snapshot device shutdown. * tag 'for-6.9/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm-integrity: align the outgoing bio in integrity_recheck dm snapshot: fix lockup in dm_exception_table_exit dm-integrity: fix a memory leak when rechecking the data
2 parents ff9c18e + b4d78cf commit 64f799f

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

drivers/md/dm-integrity.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,6 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
16991699
struct bio_vec bv;
17001700
sector_t sector, logical_sector, area, offset;
17011701
struct page *page;
1702-
void *buffer;
17031702

17041703
get_area_and_offset(ic, dio->range.logical_sector, &area, &offset);
17051704
dio->metadata_block = get_metadata_sector_and_offset(ic, area, offset,
@@ -1708,13 +1707,14 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
17081707
logical_sector = dio->range.logical_sector;
17091708

17101709
page = mempool_alloc(&ic->recheck_pool, GFP_NOIO);
1711-
buffer = page_to_virt(page);
17121710

17131711
__bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) {
17141712
unsigned pos = 0;
17151713

17161714
do {
1715+
sector_t alignment;
17171716
char *mem;
1717+
char *buffer = page_to_virt(page);
17181718
int r;
17191719
struct dm_io_request io_req;
17201720
struct dm_io_region io_loc;
@@ -1727,6 +1727,14 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
17271727
io_loc.sector = sector;
17281728
io_loc.count = ic->sectors_per_block;
17291729

1730+
/* Align the bio to logical block size */
1731+
alignment = dio->range.logical_sector | bio_sectors(bio) | (PAGE_SIZE >> SECTOR_SHIFT);
1732+
alignment &= -alignment;
1733+
io_loc.sector = round_down(io_loc.sector, alignment);
1734+
io_loc.count += sector - io_loc.sector;
1735+
buffer += (sector - io_loc.sector) << SECTOR_SHIFT;
1736+
io_loc.count = round_up(io_loc.count, alignment);
1737+
17301738
r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
17311739
if (unlikely(r)) {
17321740
dio->bi_status = errno_to_blk_status(r);
@@ -1848,12 +1856,12 @@ static void integrity_metadata(struct work_struct *w)
18481856
r = dm_integrity_rw_tag(ic, checksums, &dio->metadata_block, &dio->metadata_offset,
18491857
checksums_ptr - checksums, dio->op == REQ_OP_READ ? TAG_CMP : TAG_WRITE);
18501858
if (unlikely(r)) {
1859+
if (likely(checksums != checksums_onstack))
1860+
kfree(checksums);
18511861
if (r > 0) {
1852-
integrity_recheck(dio, checksums);
1862+
integrity_recheck(dio, checksums_onstack);
18531863
goto skip_io;
18541864
}
1855-
if (likely(checksums != checksums_onstack))
1856-
kfree(checksums);
18571865
goto error;
18581866
}
18591867

drivers/md/dm-snap.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,8 +684,10 @@ static void dm_exception_table_exit(struct dm_exception_table *et,
684684
for (i = 0; i < size; i++) {
685685
slot = et->table + i;
686686

687-
hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list)
687+
hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) {
688688
kmem_cache_free(mem, ex);
689+
cond_resched();
690+
}
689691
}
690692

691693
kvfree(et->table);

0 commit comments

Comments
 (0)