forked from Minki/linux
- Two stable@ fixes for the verity target's FEC support
- A stable@ fix for raid target's raid1 support (when no bitmap is used) - A 4.11 cache metadata v2 format fix to properly test blocks are clean -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJY56smAAoJEMUj8QotnQNa3xYH/39l25eGzam0cnITa31cX9uu lb+oWnqbgvbd65HZr2QPu9RO8LQMK9wxw40wapyYTEnkDfgeW+hmwYo3BUZ0IpdT Ry39KGCGaxk3L3cATSgtZT18AsWRHmKqlHLf6y98RdeFLVb3lyUFllkLF9r3M2ep 1Ga2MiMJYffaiTsSKxwZQG3XG7mq9MNfRnCehGAQwjGgWL3EsYHNsq+Hosn/tdtZ 2D7BvAMr2X+3xEUVevqL2dFmJ1D2tbJjtedeAKVOccErV/BofwWPUvTOFX8202+Y CUC9pW+hDQqpCm15Pr4N6oU4TeC4mHMwGK0SLWmoXkl3VDPbUUO3qC5AwKxsepA= =cWkE -----END PGP SIGNATURE----- Merge tag 'dm-4.11-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm Pull device mapper fixes from Mike Snitzer: - two stable fixes for the verity target's FEC support - a stable fix for raid target's raid1 support (when no bitmap is used) - a 4.11 cache metadata v2 format fix to properly test blocks are clean * tag 'dm-4.11-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm verity fec: fix bufio leaks dm raid: fix NULL pointer dereference for raid1 without bitmap dm cache metadata: fix metadata2 format's blocks_are_clean_separate_dirty dm verity fec: limit error correction recursion
This commit is contained in:
commit
81d4bab4ce
@ -932,7 +932,7 @@ static int blocks_are_clean_separate_dirty(struct dm_cache_metadata *cmd,
|
||||
*result = true;
|
||||
|
||||
r = dm_bitset_cursor_begin(&cmd->dirty_info, cmd->dirty_root,
|
||||
from_cblock(begin), &cmd->dirty_cursor);
|
||||
from_cblock(cmd->cache_blocks), &cmd->dirty_cursor);
|
||||
if (r) {
|
||||
DMERR("%s: dm_bitset_cursor_begin for dirty failed", __func__);
|
||||
return r;
|
||||
@ -959,14 +959,16 @@ static int blocks_are_clean_separate_dirty(struct dm_cache_metadata *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
begin = to_cblock(from_cblock(begin) + 1);
|
||||
if (begin == end)
|
||||
break;
|
||||
|
||||
r = dm_bitset_cursor_next(&cmd->dirty_cursor);
|
||||
if (r) {
|
||||
DMERR("%s: dm_bitset_cursor_next for dirty failed", __func__);
|
||||
dm_bitset_cursor_end(&cmd->dirty_cursor);
|
||||
return r;
|
||||
}
|
||||
|
||||
begin = to_cblock(from_cblock(begin) + 1);
|
||||
}
|
||||
|
||||
dm_bitset_cursor_end(&cmd->dirty_cursor);
|
||||
|
@ -3726,7 +3726,7 @@ static int raid_preresume(struct dm_target *ti)
|
||||
return r;
|
||||
|
||||
/* Resize bitmap to adjust to changed region size (aka MD bitmap chunksize) */
|
||||
if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) &&
|
||||
if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && mddev->bitmap &&
|
||||
mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)) {
|
||||
r = bitmap_resize(mddev->bitmap, mddev->dev_sectors,
|
||||
to_bytes(rs->requested_bitmap_chunk_sectors), 0);
|
||||
|
@ -146,8 +146,6 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio,
|
||||
block = fec_buffer_rs_block(v, fio, n, i);
|
||||
res = fec_decode_rs8(v, fio, block, &par[offset], neras);
|
||||
if (res < 0) {
|
||||
dm_bufio_release(buf);
|
||||
|
||||
r = res;
|
||||
goto error;
|
||||
}
|
||||
@ -172,6 +170,8 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio,
|
||||
done:
|
||||
r = corrected;
|
||||
error:
|
||||
dm_bufio_release(buf);
|
||||
|
||||
if (r < 0 && neras)
|
||||
DMERR_LIMIT("%s: FEC %llu: failed to correct: %d",
|
||||
v->data_dev->name, (unsigned long long)rsb, r);
|
||||
@ -269,7 +269,7 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io,
|
||||
&is_zero) == 0) {
|
||||
/* skip known zero blocks entirely */
|
||||
if (is_zero)
|
||||
continue;
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* skip if we have already found the theoretical
|
||||
@ -439,6 +439,13 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
|
||||
if (!verity_fec_is_enabled(v))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (fio->level >= DM_VERITY_FEC_MAX_RECURSION) {
|
||||
DMWARN_LIMIT("%s: FEC: recursion too deep", v->data_dev->name);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
fio->level++;
|
||||
|
||||
if (type == DM_VERITY_BLOCK_TYPE_METADATA)
|
||||
block += v->data_blocks;
|
||||
|
||||
@ -470,7 +477,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
|
||||
if (r < 0) {
|
||||
r = fec_decode_rsb(v, io, fio, rsb, offset, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (dest)
|
||||
@ -480,6 +487,8 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
|
||||
r = verity_for_bv_block(v, io, iter, fec_bv_copy);
|
||||
}
|
||||
|
||||
done:
|
||||
fio->level--;
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -520,6 +529,7 @@ void verity_fec_init_io(struct dm_verity_io *io)
|
||||
memset(fio->bufs, 0, sizeof(fio->bufs));
|
||||
fio->nbufs = 0;
|
||||
fio->output = NULL;
|
||||
fio->level = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -27,6 +27,9 @@
|
||||
#define DM_VERITY_FEC_BUF_MAX \
|
||||
(1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS))
|
||||
|
||||
/* maximum recursion level for verity_fec_decode */
|
||||
#define DM_VERITY_FEC_MAX_RECURSION 4
|
||||
|
||||
#define DM_VERITY_OPT_FEC_DEV "use_fec_from_device"
|
||||
#define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks"
|
||||
#define DM_VERITY_OPT_FEC_START "fec_start"
|
||||
@ -58,6 +61,7 @@ struct dm_verity_fec_io {
|
||||
unsigned nbufs; /* number of buffers allocated */
|
||||
u8 *output; /* buffer for corrected output */
|
||||
size_t output_pos;
|
||||
unsigned level; /* recursion level */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DM_VERITY_FEC
|
||||
|
Loading…
Reference in New Issue
Block a user