diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-10-23 18:23:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-10-23 18:23:52 -0400 |
commit | 35df017c4d5571ee6f3061964d1445aae250219c (patch) | |
tree | 90023fc44a9660a7e506c1ba7b7f44f8af5a141e | |
parent | ea1ee5ff1b500ccdc64782ecef13d276afb08f14 (diff) | |
parent | 3201ac452e84a8a368197d648c9b7011e061804a (diff) |
Merge tag 'dm-4.3-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer:
"Three stable fixes (two in btree code used by DM thinp and one to
properly store flags in DM cache metadata's superblock)"
* tag 'dm-4.3-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm cache: the CLEAN_SHUTDOWN flag was not being set
dm btree: fix leak of bufio-backed block in btree_split_beneath error path
dm btree remove: fix a bug when rebalancing nodes after removal
-rw-r--r-- | drivers/md/dm-cache-metadata.c | 2 | ||||
-rw-r--r-- | drivers/md/persistent-data/dm-btree-remove.c | 17 | ||||
-rw-r--r-- | drivers/md/persistent-data/dm-btree.c | 2 |
3 files changed, 13 insertions, 8 deletions
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 20cc36b01b77..0a17d1b91a81 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c | |||
@@ -634,10 +634,10 @@ static int __commit_transaction(struct dm_cache_metadata *cmd, | |||
634 | 634 | ||
635 | disk_super = dm_block_data(sblock); | 635 | disk_super = dm_block_data(sblock); |
636 | 636 | ||
637 | disk_super->flags = cpu_to_le32(cmd->flags); | ||
637 | if (mutator) | 638 | if (mutator) |
638 | update_flags(disk_super, mutator); | 639 | update_flags(disk_super, mutator); |
639 | 640 | ||
640 | disk_super->flags = cpu_to_le32(cmd->flags); | ||
641 | disk_super->mapping_root = cpu_to_le64(cmd->root); | 641 | disk_super->mapping_root = cpu_to_le64(cmd->root); |
642 | disk_super->hint_root = cpu_to_le64(cmd->hint_root); | 642 | disk_super->hint_root = cpu_to_le64(cmd->hint_root); |
643 | disk_super->discard_root = cpu_to_le64(cmd->discard_root); | 643 | disk_super->discard_root = cpu_to_le64(cmd->discard_root); |
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c index 421a36c593e3..2e4c4cb79e4d 100644 --- a/drivers/md/persistent-data/dm-btree-remove.c +++ b/drivers/md/persistent-data/dm-btree-remove.c | |||
@@ -301,11 +301,16 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent, | |||
301 | { | 301 | { |
302 | int s; | 302 | int s; |
303 | uint32_t max_entries = le32_to_cpu(left->header.max_entries); | 303 | uint32_t max_entries = le32_to_cpu(left->header.max_entries); |
304 | unsigned target = (nr_left + nr_center + nr_right) / 3; | 304 | unsigned total = nr_left + nr_center + nr_right; |
305 | BUG_ON(target > max_entries); | 305 | unsigned target_right = total / 3; |
306 | unsigned remainder = (target_right * 3) != total; | ||
307 | unsigned target_left = target_right + remainder; | ||
308 | |||
309 | BUG_ON(target_left > max_entries); | ||
310 | BUG_ON(target_right > max_entries); | ||
306 | 311 | ||
307 | if (nr_left < nr_right) { | 312 | if (nr_left < nr_right) { |
308 | s = nr_left - target; | 313 | s = nr_left - target_left; |
309 | 314 | ||
310 | if (s < 0 && nr_center < -s) { | 315 | if (s < 0 && nr_center < -s) { |
311 | /* not enough in central node */ | 316 | /* not enough in central node */ |
@@ -316,10 +321,10 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent, | |||
316 | } else | 321 | } else |
317 | shift(left, center, s); | 322 | shift(left, center, s); |
318 | 323 | ||
319 | shift(center, right, target - nr_right); | 324 | shift(center, right, target_right - nr_right); |
320 | 325 | ||
321 | } else { | 326 | } else { |
322 | s = target - nr_right; | 327 | s = target_right - nr_right; |
323 | if (s > 0 && nr_center < s) { | 328 | if (s > 0 && nr_center < s) { |
324 | /* not enough in central node */ | 329 | /* not enough in central node */ |
325 | shift(center, right, nr_center); | 330 | shift(center, right, nr_center); |
@@ -329,7 +334,7 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent, | |||
329 | } else | 334 | } else |
330 | shift(center, right, s); | 335 | shift(center, right, s); |
331 | 336 | ||
332 | shift(left, center, nr_left - target); | 337 | shift(left, center, nr_left - target_left); |
333 | } | 338 | } |
334 | 339 | ||
335 | *key_ptr(parent, c->index) = center->keys[0]; | 340 | *key_ptr(parent, c->index) = center->keys[0]; |
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c index b6cec258cc21..0e09aef43998 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c | |||
@@ -523,7 +523,7 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key) | |||
523 | 523 | ||
524 | r = new_block(s->info, &right); | 524 | r = new_block(s->info, &right); |
525 | if (r < 0) { | 525 | if (r < 0) { |
526 | /* FIXME: put left */ | 526 | unlock_block(s->info, left); |
527 | return r; | 527 | return r; |
528 | } | 528 | } |
529 | 529 | ||