mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 20:46:48 +02:00
- 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:
commit
0b7958fa05
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user