- dm-array fixes

- dm-verity forward error correction fixes
 
 - remove the flag DM_TARGET_PASSES_INTEGRITY from dm-ebs
 
 - dm-thin RCU list fix
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYIADIWIQRnH8MwLyZDhyYfesYTAyx9YGnhbQUCZ36OARQcbXBhdG9ja2FA
 cmVkaGF0LmNvbQAKCRATAyx9YGnhbQOrAP0c8fRH2lrrWr71G8SBPeAwUGAS3lh0
 Rhm4Bf9hiwVqHAD+LG0Jq9IX8zo4Ou9xeHYI3NIBvQ2M7Kum7tGKcxvlXAE=
 =Qmf0
 -----END PGP SIGNATURE-----

Merge tag 'for-6.13/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mikulas Patocka:

 - dm-array fixes

 - dm-verity forward error correction fixes

 - remove the flag DM_TARGET_PASSES_INTEGRITY from dm-ebs

 - dm-thin RCU list fix

* tag 'for-6.13/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm thin: make get_first_thin use rcu-safe list first function
  dm-ebs: don't set the flag DM_TARGET_PASSES_INTEGRITY
  dm-verity FEC: Avoid copying RS parity bytes twice.
  dm-verity FEC: Fix RS FEC repair for roots unaligned to block size (take 2)
  dm array: fix cursor index when skipping across block boundaries
  dm array: fix unreleased btree blocks on closing a faulty array cursor
  dm array: fix releasing a faulty array block twice in dm_array_cursor_end
This commit is contained in:
Linus Torvalds 2025-01-08 10:12:01 -08:00
commit 0b7958fa05
4 changed files with 45 additions and 40 deletions

View File

@ -442,7 +442,7 @@ static int ebs_iterate_devices(struct dm_target *ti,
static struct target_type ebs_target = {
.name = "ebs",
.version = {1, 0, 1},
.features = DM_TARGET_PASSES_INTEGRITY,
.features = 0,
.module = THIS_MODULE,
.ctr = ebs_ctr,
.dtr = ebs_dtr,

View File

@ -2332,10 +2332,9 @@ static struct thin_c *get_first_thin(struct pool *pool)
struct thin_c *tc = NULL;
rcu_read_lock();
if (!list_empty(&pool->active_thins)) {
tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list);
tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list);
if (tc)
thin_get(tc);
}
rcu_read_unlock();
return tc;

View File

@ -39,36 +39,24 @@ static inline u64 fec_interleave(struct dm_verity *v, u64 offset)
return offset + mod * (v->fec->rounds << v->data_dev_block_bits);
}
/*
* Decode an RS block using Reed-Solomon.
*/
static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio,
u8 *data, u8 *fec, int neras)
{
int i;
uint16_t par[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN];
for (i = 0; i < v->fec->roots; i++)
par[i] = fec[i];
return decode_rs8(fio->rs, data, par, v->fec->rsn, NULL, neras,
fio->erasures, 0, NULL);
}
/*
* Read error-correcting codes for the requested RS block. Returns a pointer
* to the data block. Caller is responsible for releasing buf.
*/
static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index,
unsigned int *offset, struct dm_buffer **buf,
unsigned short ioprio)
unsigned int *offset, unsigned int par_buf_offset,
struct dm_buffer **buf, unsigned short ioprio)
{
u64 position, block, rem;
u8 *res;
/* We have already part of parity bytes read, skip to the next block */
if (par_buf_offset)
index++;
position = (index + rsb) * v->fec->roots;
block = div64_u64_rem(position, v->fec->io_size, &rem);
*offset = (unsigned int)rem;
*offset = par_buf_offset ? 0 : (unsigned int)rem;
res = dm_bufio_read_with_ioprio(v->fec->bufio, block, buf, ioprio);
if (IS_ERR(res)) {
@ -128,11 +116,13 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
{
int r, corrected = 0, res;
struct dm_buffer *buf;
unsigned int n, i, offset;
unsigned int n, i, j, offset, par_buf_offset = 0;
uint16_t par_buf[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN];
u8 *par, *block;
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio));
par = fec_read_parity(v, rsb, block_offset, &offset,
par_buf_offset, &buf, bio_prio(bio));
if (IS_ERR(par))
return PTR_ERR(par);
@ -142,7 +132,11 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
*/
fec_for_each_buffer_rs_block(fio, n, i) {
block = fec_buffer_rs_block(v, fio, n, i);
res = fec_decode_rs8(v, fio, block, &par[offset], neras);
for (j = 0; j < v->fec->roots - par_buf_offset; j++)
par_buf[par_buf_offset + j] = par[offset + j];
/* Decode an RS block using Reed-Solomon */
res = decode_rs8(fio->rs, block, par_buf, v->fec->rsn,
NULL, neras, fio->erasures, 0, NULL);
if (res < 0) {
r = res;
goto error;
@ -155,12 +149,22 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
if (block_offset >= 1 << v->data_dev_block_bits)
goto done;
/* read the next block when we run out of parity bytes */
offset += v->fec->roots;
/* Read the next block when we run out of parity bytes */
offset += (v->fec->roots - par_buf_offset);
/* Check if parity bytes are split between blocks */
if (offset < v->fec->io_size && (offset + v->fec->roots) > v->fec->io_size) {
par_buf_offset = v->fec->io_size - offset;
for (j = 0; j < par_buf_offset; j++)
par_buf[j] = par[offset + j];
offset += par_buf_offset;
} else
par_buf_offset = 0;
if (offset >= v->fec->io_size) {
dm_bufio_release(buf);
par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio));
par = fec_read_parity(v, rsb, block_offset, &offset,
par_buf_offset, &buf, bio_prio(bio));
if (IS_ERR(par))
return PTR_ERR(par);
}
@ -724,10 +728,7 @@ int verity_fec_ctr(struct dm_verity *v)
return -E2BIG;
}
if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1))
f->io_size = 1 << v->data_dev_block_bits;
else
f->io_size = v->fec->roots << SECTOR_SHIFT;
f->io_size = 1 << v->data_dev_block_bits;
f->bufio = dm_bufio_client_create(f->dev->bdev,
f->io_size,

View File

@ -917,23 +917,27 @@ static int load_ablock(struct dm_array_cursor *c)
if (c->block)
unlock_ablock(c->info, c->block);
c->block = NULL;
c->ab = NULL;
c->index = 0;
r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le);
if (r) {
DMERR("dm_btree_cursor_get_value failed");
dm_btree_cursor_end(&c->cursor);
goto out;
} else {
r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab);
if (r) {
DMERR("get_ablock failed");
dm_btree_cursor_end(&c->cursor);
goto out;
}
}
return 0;
out:
dm_btree_cursor_end(&c->cursor);
c->block = NULL;
c->ab = NULL;
return r;
}
@ -956,10 +960,10 @@ EXPORT_SYMBOL_GPL(dm_array_cursor_begin);
void dm_array_cursor_end(struct dm_array_cursor *c)
{
if (c->block) {
if (c->block)
unlock_ablock(c->info, c->block);
dm_btree_cursor_end(&c->cursor);
}
dm_btree_cursor_end(&c->cursor);
}
EXPORT_SYMBOL_GPL(dm_array_cursor_end);
@ -999,6 +1003,7 @@ int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count)
}
count -= remaining;
c->index += (remaining - 1);
r = dm_array_cursor_next(c);
} while (!r);