- Fix a couple DM snapshot target crashes exposed by user-error.
- Fix DM integrity target to not use discard optimization, introduced during 5.13 merge, when recalulating. - Fix some sparse warnings in DM integrity target. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEJfWUX4UqZ4x1O2wixSPxCi2dA1oFAmCmu68ACgkQxSPxCi2d A1qlXwf/W8l0T+2/NBggl4Hhld7+4+3u7B2UrSpXQ5TbnPEUyfplG80MukbtM7KN uwQAgOLWMEfqcRyFbbj3nUaUU216lEA00ooCt5YnLdDMPi+oNa1BL/YksUqC0gka X8dYA/Uz1q6R+XMlCpJVFda+lkiR2eLLvo1URaKYwWhe3IsEgSvtW3qG+WRrSKs5 H7J7Gu5qh0L7LYyQswgpvzQIKdIStWQ6cN7HGPOmNesV8lX/XrnPC+IkWCgzhDJx ZpcoR47ViIgTEd7giume1n8Ky8Jnu8WbiAHMQBuvtc2IGg8Jdw0Co6ll3ezsFprf 0YFivO8yUujdUrmQ0Hzi5S5826tQ7A== =lKDE -----END PGP SIGNATURE----- Merge tag 'for-5.13/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 couple DM snapshot target crashes exposed by user-error. - Fix DM integrity target to not use discard optimization, introduced during 5.13 merge, when recalulating. - Fix some sparse warnings in DM integrity target. * tag 'for-5.13/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm integrity: fix sparse warnings dm integrity: revert to not using discard filler when recalulating dm snapshot: fix crash with transient storage and zero chunk size dm snapshot: fix a crash when an origin has no snapshots
This commit is contained in:
commit
a0eb553b6f
|
@ -66,14 +66,14 @@ struct superblock {
|
|||
__u8 magic[8];
|
||||
__u8 version;
|
||||
__u8 log2_interleave_sectors;
|
||||
__u16 integrity_tag_size;
|
||||
__u32 journal_sections;
|
||||
__u64 provided_data_sectors; /* userspace uses this value */
|
||||
__u32 flags;
|
||||
__le16 integrity_tag_size;
|
||||
__le32 journal_sections;
|
||||
__le64 provided_data_sectors; /* userspace uses this value */
|
||||
__le32 flags;
|
||||
__u8 log2_sectors_per_block;
|
||||
__u8 log2_blocks_per_bitmap_bit;
|
||||
__u8 pad[2];
|
||||
__u64 recalc_sector;
|
||||
__le64 recalc_sector;
|
||||
__u8 pad2[8];
|
||||
__u8 salt[SALT_SIZE];
|
||||
};
|
||||
|
@ -86,16 +86,16 @@ struct superblock {
|
|||
|
||||
#define JOURNAL_ENTRY_ROUNDUP 8
|
||||
|
||||
typedef __u64 commit_id_t;
|
||||
typedef __le64 commit_id_t;
|
||||
#define JOURNAL_MAC_PER_SECTOR 8
|
||||
|
||||
struct journal_entry {
|
||||
union {
|
||||
struct {
|
||||
__u32 sector_lo;
|
||||
__u32 sector_hi;
|
||||
__le32 sector_lo;
|
||||
__le32 sector_hi;
|
||||
} s;
|
||||
__u64 sector;
|
||||
__le64 sector;
|
||||
} u;
|
||||
commit_id_t last_bytes[];
|
||||
/* __u8 tag[0]; */
|
||||
|
@ -806,7 +806,7 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result
|
|||
}
|
||||
|
||||
if (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) {
|
||||
uint64_t section_le;
|
||||
__le64 section_le;
|
||||
|
||||
r = crypto_shash_update(desc, (__u8 *)&ic->sb->salt, SALT_SIZE);
|
||||
if (unlikely(r < 0)) {
|
||||
|
@ -1640,7 +1640,7 @@ static void integrity_end_io(struct bio *bio)
|
|||
static void integrity_sector_checksum(struct dm_integrity_c *ic, sector_t sector,
|
||||
const char *data, char *result)
|
||||
{
|
||||
__u64 sector_le = cpu_to_le64(sector);
|
||||
__le64 sector_le = cpu_to_le64(sector);
|
||||
SHASH_DESC_ON_STACK(req, ic->internal_hash);
|
||||
int r;
|
||||
unsigned digest_size;
|
||||
|
@ -2689,30 +2689,26 @@ next_chunk:
|
|||
if (unlikely(dm_integrity_failed(ic)))
|
||||
goto err;
|
||||
|
||||
if (!ic->discard) {
|
||||
io_req.bi_op = REQ_OP_READ;
|
||||
io_req.bi_op_flags = 0;
|
||||
io_req.mem.type = DM_IO_VMA;
|
||||
io_req.mem.ptr.addr = ic->recalc_buffer;
|
||||
io_req.notify.fn = NULL;
|
||||
io_req.client = ic->io;
|
||||
io_loc.bdev = ic->dev->bdev;
|
||||
io_loc.sector = get_data_sector(ic, area, offset);
|
||||
io_loc.count = n_sectors;
|
||||
io_req.bi_op = REQ_OP_READ;
|
||||
io_req.bi_op_flags = 0;
|
||||
io_req.mem.type = DM_IO_VMA;
|
||||
io_req.mem.ptr.addr = ic->recalc_buffer;
|
||||
io_req.notify.fn = NULL;
|
||||
io_req.client = ic->io;
|
||||
io_loc.bdev = ic->dev->bdev;
|
||||
io_loc.sector = get_data_sector(ic, area, offset);
|
||||
io_loc.count = n_sectors;
|
||||
|
||||
r = dm_io(&io_req, 1, &io_loc, NULL);
|
||||
if (unlikely(r)) {
|
||||
dm_integrity_io_error(ic, "reading data", r);
|
||||
goto err;
|
||||
}
|
||||
r = dm_io(&io_req, 1, &io_loc, NULL);
|
||||
if (unlikely(r)) {
|
||||
dm_integrity_io_error(ic, "reading data", r);
|
||||
goto err;
|
||||
}
|
||||
|
||||
t = ic->recalc_tags;
|
||||
for (i = 0; i < n_sectors; i += ic->sectors_per_block) {
|
||||
integrity_sector_checksum(ic, logical_sector + i, ic->recalc_buffer + (i << SECTOR_SHIFT), t);
|
||||
t += ic->tag_size;
|
||||
}
|
||||
} else {
|
||||
t = ic->recalc_tags + (n_sectors >> ic->sb->log2_sectors_per_block) * ic->tag_size;
|
||||
t = ic->recalc_tags;
|
||||
for (i = 0; i < n_sectors; i += ic->sectors_per_block) {
|
||||
integrity_sector_checksum(ic, logical_sector + i, ic->recalc_buffer + (i << SECTOR_SHIFT), t);
|
||||
t += ic->tag_size;
|
||||
}
|
||||
|
||||
metadata_block = get_metadata_sector_and_offset(ic, area, offset, &metadata_offset);
|
||||
|
@ -3826,7 +3822,7 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
|
|||
for (i = 0; i < ic->journal_sections; i++) {
|
||||
struct scatterlist sg;
|
||||
struct skcipher_request *section_req;
|
||||
__u32 section_le = cpu_to_le32(i);
|
||||
__le32 section_le = cpu_to_le32(i);
|
||||
|
||||
memset(crypt_iv, 0x00, ivsize);
|
||||
memset(crypt_data, 0x00, crypt_len);
|
||||
|
@ -4368,13 +4364,11 @@ try_smaller_buffer:
|
|||
goto bad;
|
||||
}
|
||||
INIT_WORK(&ic->recalc_work, integrity_recalc);
|
||||
if (!ic->discard) {
|
||||
ic->recalc_buffer = vmalloc(RECALC_SECTORS << SECTOR_SHIFT);
|
||||
if (!ic->recalc_buffer) {
|
||||
ti->error = "Cannot allocate buffer for recalculating";
|
||||
r = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
ic->recalc_buffer = vmalloc(RECALC_SECTORS << SECTOR_SHIFT);
|
||||
if (!ic->recalc_buffer) {
|
||||
ti->error = "Cannot allocate buffer for recalculating";
|
||||
r = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
ic->recalc_tags = kvmalloc_array(RECALC_SECTORS >> ic->sb->log2_sectors_per_block,
|
||||
ic->tag_size, GFP_KERNEL);
|
||||
|
@ -4383,9 +4377,6 @@ try_smaller_buffer:
|
|||
r = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
if (ic->discard)
|
||||
memset(ic->recalc_tags, DISCARD_FILLER,
|
||||
(RECALC_SECTORS >> ic->sb->log2_sectors_per_block) * ic->tag_size);
|
||||
} else {
|
||||
if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) {
|
||||
ti->error = "Recalculate can only be specified with internal_hash";
|
||||
|
@ -4579,7 +4570,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
|
|||
|
||||
static struct target_type integrity_target = {
|
||||
.name = "integrity",
|
||||
.version = {1, 9, 0},
|
||||
.version = {1, 10, 0},
|
||||
.module = THIS_MODULE,
|
||||
.features = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY,
|
||||
.ctr = dm_integrity_ctr,
|
||||
|
|
|
@ -855,12 +855,11 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new)
|
|||
static uint32_t __minimum_chunk_size(struct origin *o)
|
||||
{
|
||||
struct dm_snapshot *snap;
|
||||
unsigned chunk_size = 0;
|
||||
unsigned chunk_size = rounddown_pow_of_two(UINT_MAX);
|
||||
|
||||
if (o)
|
||||
list_for_each_entry(snap, &o->snapshots, list)
|
||||
chunk_size = min_not_zero(chunk_size,
|
||||
snap->store->chunk_size);
|
||||
chunk_size = min(chunk_size, snap->store->chunk_size);
|
||||
|
||||
return (uint32_t) chunk_size;
|
||||
}
|
||||
|
@ -1409,6 +1408,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
|
||||
if (!s->store->chunk_size) {
|
||||
ti->error = "Chunk size not set";
|
||||
r = -EINVAL;
|
||||
goto bad_read_metadata;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue