Skip to content

Commit 49008f0

Browse files
committed
Merge tag 'for-5.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper updates from Mike Snitzer: - Fixes and improvements to dm btree and dm space map code in persistent-data library used by thinp and cache. - Update DM integrity to use struct_group() to zero struct journal_sector. - Update DM sysfs to use default_groups in kobj_type. * tag 'for-5.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm sysfs: use default_groups in kobj_type dm integrity: Use struct_group() to zero struct journal_sector dm space map common: add bounds check to sm_ll_lookup_bitmap() dm btree: add a defensive bounds check to insert_at() dm btree remove: change a bunch of BUG_ON() calls to proper errors dm btree spine: eliminate duplicate le32_to_cpu() in node_check() dm btree spine: remove extra node_check function declaration
2 parents c9193f4 + eaac0b5 commit 49008f0

File tree

6 files changed

+145
-65
lines changed

6 files changed

+145
-65
lines changed

drivers/md/dm-integrity.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,10 @@ struct journal_entry {
121121
#define JOURNAL_MAC_SIZE (JOURNAL_MAC_PER_SECTOR * JOURNAL_BLOCK_SECTORS)
122122

123123
struct journal_sector {
124-
__u8 entries[JOURNAL_SECTOR_DATA - JOURNAL_MAC_PER_SECTOR];
125-
__u8 mac[JOURNAL_MAC_PER_SECTOR];
124+
struct_group(sectors,
125+
__u8 entries[JOURNAL_SECTOR_DATA - JOURNAL_MAC_PER_SECTOR];
126+
__u8 mac[JOURNAL_MAC_PER_SECTOR];
127+
);
126128
commit_id_t commit_id;
127129
};
128130

@@ -2870,7 +2872,8 @@ static void init_journal(struct dm_integrity_c *ic, unsigned start_section,
28702872
wraparound_section(ic, &i);
28712873
for (j = 0; j < ic->journal_section_sectors; j++) {
28722874
struct journal_sector *js = access_journal(ic, i, j);
2873-
memset(&js->entries, 0, JOURNAL_SECTOR_DATA);
2875+
BUILD_BUG_ON(sizeof(js->sectors) != JOURNAL_SECTOR_DATA);
2876+
memset(&js->sectors, 0, sizeof(js->sectors));
28742877
js->commit_id = dm_integrity_commit_id(ic, i, j, commit_seq);
28752878
}
28762879
for (j = 0; j < ic->journal_section_entries; j++) {

drivers/md/dm-sysfs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ static struct attribute *dm_attrs[] = {
112112
&dm_attr_rq_based_seq_io_merge_deadline.attr,
113113
NULL,
114114
};
115+
ATTRIBUTE_GROUPS(dm);
115116

116117
static const struct sysfs_ops dm_sysfs_ops = {
117118
.show = dm_attr_show,
@@ -120,7 +121,7 @@ static const struct sysfs_ops dm_sysfs_ops = {
120121

121122
static struct kobj_type dm_ktype = {
122123
.sysfs_ops = &dm_sysfs_ops,
123-
.default_attrs = dm_attrs,
124+
.default_groups = dm_groups,
124125
.release = dm_kobject_release,
125126
};
126127

drivers/md/persistent-data/dm-btree-remove.c

Lines changed: 122 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#include "dm-transaction-manager.h"
1010

1111
#include <linux/export.h>
12+
#include <linux/device-mapper.h>
13+
14+
#define DM_MSG_PREFIX "btree"
1215

1316
/*
1417
* Removing an entry from a btree
@@ -79,30 +82,43 @@ static void node_shift(struct btree_node *n, int shift)
7982
}
8083
}
8184

82-
static void node_copy(struct btree_node *left, struct btree_node *right, int shift)
85+
static int node_copy(struct btree_node *left, struct btree_node *right, int shift)
8386
{
8487
uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
8588
uint32_t value_size = le32_to_cpu(left->header.value_size);
86-
BUG_ON(value_size != le32_to_cpu(right->header.value_size));
89+
if (value_size != le32_to_cpu(right->header.value_size)) {
90+
DMERR("mismatched value size");
91+
return -EILSEQ;
92+
}
8793

8894
if (shift < 0) {
8995
shift = -shift;
90-
BUG_ON(nr_left + shift > le32_to_cpu(left->header.max_entries));
96+
97+
if (nr_left + shift > le32_to_cpu(left->header.max_entries)) {
98+
DMERR("bad shift");
99+
return -EINVAL;
100+
}
101+
91102
memcpy(key_ptr(left, nr_left),
92103
key_ptr(right, 0),
93104
shift * sizeof(__le64));
94105
memcpy(value_ptr(left, nr_left),
95106
value_ptr(right, 0),
96107
shift * value_size);
97108
} else {
98-
BUG_ON(shift > le32_to_cpu(right->header.max_entries));
109+
if (shift > le32_to_cpu(right->header.max_entries)) {
110+
DMERR("bad shift");
111+
return -EINVAL;
112+
}
113+
99114
memcpy(key_ptr(right, 0),
100115
key_ptr(left, nr_left - shift),
101116
shift * sizeof(__le64));
102117
memcpy(value_ptr(right, 0),
103118
value_ptr(left, nr_left - shift),
104119
shift * value_size);
105120
}
121+
return 0;
106122
}
107123

108124
/*
@@ -170,35 +186,54 @@ static void exit_child(struct dm_btree_info *info, struct child *c)
170186
dm_tm_unlock(info->tm, c->block);
171187
}
172188

173-
static void shift(struct btree_node *left, struct btree_node *right, int count)
189+
static int shift(struct btree_node *left, struct btree_node *right, int count)
174190
{
191+
int r;
175192
uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
176193
uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
177194
uint32_t max_entries = le32_to_cpu(left->header.max_entries);
178195
uint32_t r_max_entries = le32_to_cpu(right->header.max_entries);
179196

180-
BUG_ON(max_entries != r_max_entries);
181-
BUG_ON(nr_left - count > max_entries);
182-
BUG_ON(nr_right + count > max_entries);
197+
if (max_entries != r_max_entries) {
198+
DMERR("node max_entries mismatch");
199+
return -EILSEQ;
200+
}
201+
202+
if (nr_left - count > max_entries) {
203+
DMERR("node shift out of bounds");
204+
return -EINVAL;
205+
}
206+
207+
if (nr_right + count > max_entries) {
208+
DMERR("node shift out of bounds");
209+
return -EINVAL;
210+
}
183211

184212
if (!count)
185-
return;
213+
return 0;
186214

187215
if (count > 0) {
188216
node_shift(right, count);
189-
node_copy(left, right, count);
217+
r = node_copy(left, right, count);
218+
if (r)
219+
return r;
190220
} else {
191-
node_copy(left, right, count);
221+
r = node_copy(left, right, count);
222+
if (r)
223+
return r;
192224
node_shift(right, count);
193225
}
194226

195227
left->header.nr_entries = cpu_to_le32(nr_left - count);
196228
right->header.nr_entries = cpu_to_le32(nr_right + count);
229+
230+
return 0;
197231
}
198232

199-
static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
200-
struct child *l, struct child *r)
233+
static int __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
234+
struct child *l, struct child *r)
201235
{
236+
int ret;
202237
struct btree_node *left = l->n;
203238
struct btree_node *right = r->n;
204239
uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
@@ -229,9 +264,12 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
229264
* Rebalance.
230265
*/
231266
unsigned target_left = (nr_left + nr_right) / 2;
232-
shift(left, right, nr_left - target_left);
267+
ret = shift(left, right, nr_left - target_left);
268+
if (ret)
269+
return ret;
233270
*key_ptr(parent, r->index) = right->keys[0];
234271
}
272+
return 0;
235273
}
236274

237275
static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
@@ -253,34 +291,43 @@ static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
253291
return r;
254292
}
255293

256-
__rebalance2(info, parent, &left, &right);
294+
r = __rebalance2(info, parent, &left, &right);
257295

258296
exit_child(info, &left);
259297
exit_child(info, &right);
260298

261-
return 0;
299+
return r;
262300
}
263301

264302
/*
265303
* We dump as many entries from center as possible into left, then the rest
266304
* in right, then rebalance2. This wastes some cpu, but I want something
267305
* simple atm.
268306
*/
269-
static void delete_center_node(struct dm_btree_info *info, struct btree_node *parent,
270-
struct child *l, struct child *c, struct child *r,
271-
struct btree_node *left, struct btree_node *center, struct btree_node *right,
272-
uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
307+
static int delete_center_node(struct dm_btree_info *info, struct btree_node *parent,
308+
struct child *l, struct child *c, struct child *r,
309+
struct btree_node *left, struct btree_node *center, struct btree_node *right,
310+
uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
273311
{
274312
uint32_t max_entries = le32_to_cpu(left->header.max_entries);
275313
unsigned shift = min(max_entries - nr_left, nr_center);
276314

277-
BUG_ON(nr_left + shift > max_entries);
315+
if (nr_left + shift > max_entries) {
316+
DMERR("node shift out of bounds");
317+
return -EINVAL;
318+
}
319+
278320
node_copy(left, center, -shift);
279321
left->header.nr_entries = cpu_to_le32(nr_left + shift);
280322

281323
if (shift != nr_center) {
282324
shift = nr_center - shift;
283-
BUG_ON((nr_right + shift) > max_entries);
325+
326+
if ((nr_right + shift) > max_entries) {
327+
DMERR("node shift out of bounds");
328+
return -EINVAL;
329+
}
330+
284331
node_shift(right, shift);
285332
node_copy(center, right, shift);
286333
right->header.nr_entries = cpu_to_le32(nr_right + shift);
@@ -291,18 +338,18 @@ static void delete_center_node(struct dm_btree_info *info, struct btree_node *pa
291338
r->index--;
292339

293340
dm_tm_dec(info->tm, dm_block_location(c->block));
294-
__rebalance2(info, parent, l, r);
341+
return __rebalance2(info, parent, l, r);
295342
}
296343

297344
/*
298345
* Redistributes entries among 3 sibling nodes.
299346
*/
300-
static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
301-
struct child *l, struct child *c, struct child *r,
302-
struct btree_node *left, struct btree_node *center, struct btree_node *right,
303-
uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
347+
static int redistribute3(struct dm_btree_info *info, struct btree_node *parent,
348+
struct child *l, struct child *c, struct child *r,
349+
struct btree_node *left, struct btree_node *center, struct btree_node *right,
350+
uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
304351
{
305-
int s;
352+
int s, ret;
306353
uint32_t max_entries = le32_to_cpu(left->header.max_entries);
307354
unsigned total = nr_left + nr_center + nr_right;
308355
unsigned target_right = total / 3;
@@ -317,35 +364,55 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
317364

318365
if (s < 0 && nr_center < -s) {
319366
/* not enough in central node */
320-
shift(left, center, -nr_center);
367+
ret = shift(left, center, -nr_center);
368+
if (ret)
369+
return ret;
370+
321371
s += nr_center;
322-
shift(left, right, s);
323-
nr_right += s;
324-
} else
325-
shift(left, center, s);
372+
ret = shift(left, right, s);
373+
if (ret)
374+
return ret;
326375

327-
shift(center, right, target_right - nr_right);
376+
nr_right += s;
377+
} else {
378+
ret = shift(left, center, s);
379+
if (ret)
380+
return ret;
381+
}
328382

383+
ret = shift(center, right, target_right - nr_right);
384+
if (ret)
385+
return ret;
329386
} else {
330387
s = target_right - nr_right;
331388
if (s > 0 && nr_center < s) {
332389
/* not enough in central node */
333-
shift(center, right, nr_center);
390+
ret = shift(center, right, nr_center);
391+
if (ret)
392+
return ret;
334393
s -= nr_center;
335-
shift(left, right, s);
394+
ret = shift(left, right, s);
395+
if (ret)
396+
return ret;
336397
nr_left -= s;
337-
} else
338-
shift(center, right, s);
398+
} else {
399+
ret = shift(center, right, s);
400+
if (ret)
401+
return ret;
402+
}
339403

340-
shift(left, center, nr_left - target_left);
404+
ret = shift(left, center, nr_left - target_left);
405+
if (ret)
406+
return ret;
341407
}
342408

343409
*key_ptr(parent, c->index) = center->keys[0];
344410
*key_ptr(parent, r->index) = right->keys[0];
411+
return 0;
345412
}
346413

347-
static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent,
348-
struct child *l, struct child *c, struct child *r)
414+
static int __rebalance3(struct dm_btree_info *info, struct btree_node *parent,
415+
struct child *l, struct child *c, struct child *r)
349416
{
350417
struct btree_node *left = l->n;
351418
struct btree_node *center = c->n;
@@ -357,15 +424,19 @@ static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent,
357424

358425
unsigned threshold = merge_threshold(left) * 4 + 1;
359426

360-
BUG_ON(left->header.max_entries != center->header.max_entries);
361-
BUG_ON(center->header.max_entries != right->header.max_entries);
427+
if ((left->header.max_entries != center->header.max_entries) ||
428+
(center->header.max_entries != right->header.max_entries)) {
429+
DMERR("bad btree metadata, max_entries differ");
430+
return -EILSEQ;
431+
}
432+
433+
if ((nr_left + nr_center + nr_right) < threshold) {
434+
return delete_center_node(info, parent, l, c, r, left, center, right,
435+
nr_left, nr_center, nr_right);
436+
}
362437

363-
if ((nr_left + nr_center + nr_right) < threshold)
364-
delete_center_node(info, parent, l, c, r, left, center, right,
365-
nr_left, nr_center, nr_right);
366-
else
367-
redistribute3(info, parent, l, c, r, left, center, right,
368-
nr_left, nr_center, nr_right);
438+
return redistribute3(info, parent, l, c, r, left, center, right,
439+
nr_left, nr_center, nr_right);
369440
}
370441

371442
static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
@@ -395,13 +466,13 @@ static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
395466
return r;
396467
}
397468

398-
__rebalance3(info, parent, &left, &center, &right);
469+
r = __rebalance3(info, parent, &left, &center, &right);
399470

400471
exit_child(info, &left);
401472
exit_child(info, &center);
402473
exit_child(info, &right);
403474

404-
return 0;
475+
return r;
405476
}
406477

407478
static int rebalance_children(struct shadow_spine *s,

0 commit comments

Comments
 (0)