Skip to content

Commit 0b7958f

Browse files
committed
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
2 parents 09a0fa9 + 80f130b commit 0b7958f

File tree

4 files changed

+45
-40
lines changed

4 files changed

+45
-40
lines changed

drivers/md/dm-ebs-target.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ static int ebs_iterate_devices(struct dm_target *ti,
442442
static struct target_type ebs_target = {
443443
.name = "ebs",
444444
.version = {1, 0, 1},
445-
.features = DM_TARGET_PASSES_INTEGRITY,
445+
.features = 0,
446446
.module = THIS_MODULE,
447447
.ctr = ebs_ctr,
448448
.dtr = ebs_dtr,

drivers/md/dm-thin.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,10 +2332,9 @@ static struct thin_c *get_first_thin(struct pool *pool)
23322332
struct thin_c *tc = NULL;
23332333

23342334
rcu_read_lock();
2335-
if (!list_empty(&pool->active_thins)) {
2336-
tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list);
2335+
tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list);
2336+
if (tc)
23372337
thin_get(tc);
2338-
}
23392338
rcu_read_unlock();
23402339

23412340
return tc;

drivers/md/dm-verity-fec.c

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,36 +39,24 @@ static inline u64 fec_interleave(struct dm_verity *v, u64 offset)
3939
return offset + mod * (v->fec->rounds << v->data_dev_block_bits);
4040
}
4141

42-
/*
43-
* Decode an RS block using Reed-Solomon.
44-
*/
45-
static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio,
46-
u8 *data, u8 *fec, int neras)
47-
{
48-
int i;
49-
uint16_t par[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN];
50-
51-
for (i = 0; i < v->fec->roots; i++)
52-
par[i] = fec[i];
53-
54-
return decode_rs8(fio->rs, data, par, v->fec->rsn, NULL, neras,
55-
fio->erasures, 0, NULL);
56-
}
57-
5842
/*
5943
* Read error-correcting codes for the requested RS block. Returns a pointer
6044
* to the data block. Caller is responsible for releasing buf.
6145
*/
6246
static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index,
63-
unsigned int *offset, struct dm_buffer **buf,
64-
unsigned short ioprio)
47+
unsigned int *offset, unsigned int par_buf_offset,
48+
struct dm_buffer **buf, unsigned short ioprio)
6549
{
6650
u64 position, block, rem;
6751
u8 *res;
6852

53+
/* We have already part of parity bytes read, skip to the next block */
54+
if (par_buf_offset)
55+
index++;
56+
6957
position = (index + rsb) * v->fec->roots;
7058
block = div64_u64_rem(position, v->fec->io_size, &rem);
71-
*offset = (unsigned int)rem;
59+
*offset = par_buf_offset ? 0 : (unsigned int)rem;
7260

7361
res = dm_bufio_read_with_ioprio(v->fec->bufio, block, buf, ioprio);
7462
if (IS_ERR(res)) {
@@ -128,11 +116,13 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
128116
{
129117
int r, corrected = 0, res;
130118
struct dm_buffer *buf;
131-
unsigned int n, i, offset;
119+
unsigned int n, i, j, offset, par_buf_offset = 0;
120+
uint16_t par_buf[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN];
132121
u8 *par, *block;
133122
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
134123

135-
par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio));
124+
par = fec_read_parity(v, rsb, block_offset, &offset,
125+
par_buf_offset, &buf, bio_prio(bio));
136126
if (IS_ERR(par))
137127
return PTR_ERR(par);
138128

@@ -142,7 +132,11 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
142132
*/
143133
fec_for_each_buffer_rs_block(fio, n, i) {
144134
block = fec_buffer_rs_block(v, fio, n, i);
145-
res = fec_decode_rs8(v, fio, block, &par[offset], neras);
135+
for (j = 0; j < v->fec->roots - par_buf_offset; j++)
136+
par_buf[par_buf_offset + j] = par[offset + j];
137+
/* Decode an RS block using Reed-Solomon */
138+
res = decode_rs8(fio->rs, block, par_buf, v->fec->rsn,
139+
NULL, neras, fio->erasures, 0, NULL);
146140
if (res < 0) {
147141
r = res;
148142
goto error;
@@ -155,12 +149,22 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_io *io,
155149
if (block_offset >= 1 << v->data_dev_block_bits)
156150
goto done;
157151

158-
/* read the next block when we run out of parity bytes */
159-
offset += v->fec->roots;
152+
/* Read the next block when we run out of parity bytes */
153+
offset += (v->fec->roots - par_buf_offset);
154+
/* Check if parity bytes are split between blocks */
155+
if (offset < v->fec->io_size && (offset + v->fec->roots) > v->fec->io_size) {
156+
par_buf_offset = v->fec->io_size - offset;
157+
for (j = 0; j < par_buf_offset; j++)
158+
par_buf[j] = par[offset + j];
159+
offset += par_buf_offset;
160+
} else
161+
par_buf_offset = 0;
162+
160163
if (offset >= v->fec->io_size) {
161164
dm_bufio_release(buf);
162165

163-
par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio));
166+
par = fec_read_parity(v, rsb, block_offset, &offset,
167+
par_buf_offset, &buf, bio_prio(bio));
164168
if (IS_ERR(par))
165169
return PTR_ERR(par);
166170
}
@@ -724,10 +728,7 @@ int verity_fec_ctr(struct dm_verity *v)
724728
return -E2BIG;
725729
}
726730

727-
if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1))
728-
f->io_size = 1 << v->data_dev_block_bits;
729-
else
730-
f->io_size = v->fec->roots << SECTOR_SHIFT;
731+
f->io_size = 1 << v->data_dev_block_bits;
731732

732733
f->bufio = dm_bufio_client_create(f->dev->bdev,
733734
f->io_size,

drivers/md/persistent-data/dm-array.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -917,23 +917,27 @@ static int load_ablock(struct dm_array_cursor *c)
917917
if (c->block)
918918
unlock_ablock(c->info, c->block);
919919

920-
c->block = NULL;
921-
c->ab = NULL;
922920
c->index = 0;
923921

924922
r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le);
925923
if (r) {
926924
DMERR("dm_btree_cursor_get_value failed");
927-
dm_btree_cursor_end(&c->cursor);
925+
goto out;
928926

929927
} else {
930928
r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab);
931929
if (r) {
932930
DMERR("get_ablock failed");
933-
dm_btree_cursor_end(&c->cursor);
931+
goto out;
934932
}
935933
}
936934

935+
return 0;
936+
937+
out:
938+
dm_btree_cursor_end(&c->cursor);
939+
c->block = NULL;
940+
c->ab = NULL;
937941
return r;
938942
}
939943

@@ -956,10 +960,10 @@ EXPORT_SYMBOL_GPL(dm_array_cursor_begin);
956960

957961
void dm_array_cursor_end(struct dm_array_cursor *c)
958962
{
959-
if (c->block) {
963+
if (c->block)
960964
unlock_ablock(c->info, c->block);
961-
dm_btree_cursor_end(&c->cursor);
962-
}
965+
966+
dm_btree_cursor_end(&c->cursor);
963967
}
964968
EXPORT_SYMBOL_GPL(dm_array_cursor_end);
965969

@@ -999,6 +1003,7 @@ int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count)
9991003
}
10001004

10011005
count -= remaining;
1006+
c->index += (remaining - 1);
10021007
r = dm_array_cursor_next(c);
10031008

10041009
} while (!r);

0 commit comments

Comments
 (0)