Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull device mapper updates from Mike Snitzer:

- Improve scalability of DM's device hash by switching to rbtree

- Extend DM ioctl's DM_LIST_DEVICES_CMD handling to include UUID and
allow filtering based on name or UUID prefix.

- Various small fixes for typos, warnings, unused function, or
needlessly exported interfaces.

- Remove needless request_queue NULL pointer checks in DM thin and
cache targets.

- Remove unnecessary loop in DM core's __split_and_process_bio().

- Remove DM core's dm_vcalloc() and just use kvcalloc or kvmalloc_array
instead (depending whether zeroing is useful).

- Fix request-based DM's double free of blk_mq_tag_set in device remove
after table load fails.

- Improve DM persistent data performance on non-x86 by fixing packed
structs to have a stated alignment. Also remove needless extra work
from redundant calls to sm_disk_get_nr_free() and a paranoid BUG_ON()
that caused duplicate checksum calculation.

- Fix missing goto in DM integrity's bitmap_flush_interval error
handling.

- Add "reset_recalculate" feature flag to DM integrity.

- Improve DM integrity by leveraging discard support to avoid needless
re-writing of metadata and also use discard support to improve hash
recalculation.

- Fix race with DM raid target's reshape and MD raid4/5/6 resync that
resulted in inconsistant reshape state during table reloads.

- Update DM raid target to temove unnecessary discard limits for raid0
and raid10 now that MD has optimized discard handling for both raid
levels.

* tag 'for-5.13/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (26 commits)
dm raid: remove unnecessary discard limits for raid0 and raid10
dm rq: fix double free of blk_mq_tag_set in dev remove after table load fails
dm integrity: use discard support when recalculating
dm integrity: increase RECALC_SECTORS to improve recalculate speed
dm integrity: don't re-write metadata if discarding same blocks
dm raid: fix inconclusive reshape layout on fast raid4/5/6 table reload sequences
dm raid: fix fall-through warning in rs_check_takeover() for Clang
dm clone metadata: remove unused function
dm integrity: fix missing goto in bitmap_flush_interval error handling
dm: replace dm_vcalloc()
dm space map common: fix division bug in sm_ll_find_free_block()
dm persistent data: packed struct should have an aligned() attribute too
dm btree spine: remove paranoid node_check call in node_prep_for_write()
dm space map disk: remove redundant calls to sm_disk_get_nr_free()
dm integrity: add the "reset_recalculate" feature flag
dm persistent data: remove unused return from exit_shadow_spine()
dm cache: remove needless request_queue NULL pointer checks
dm thin: remove needless request_queue NULL pointer check
dm: unexport dm_{get,put}_table_device
dm ebs: fix a few typos
...

+371 -270
+1 -1
drivers/md/dm-cache-target.c
··· 3387 3387 { 3388 3388 struct request_queue *q = bdev_get_queue(origin_bdev); 3389 3389 3390 - return q && blk_queue_discard(q); 3390 + return blk_queue_discard(q); 3391 3391 } 3392 3392 3393 3393 /*
-6
drivers/md/dm-clone-metadata.c
··· 276 276 return dm_bm_read_lock(cmd->bm, SUPERBLOCK_LOCATION, &sb_validator, sblock); 277 277 } 278 278 279 - static inline int superblock_write_lock(struct dm_clone_metadata *cmd, 280 - struct dm_block **sblock) 281 - { 282 - return dm_bm_write_lock(cmd->bm, SUPERBLOCK_LOCATION, &sb_validator, sblock); 283 - } 284 - 285 279 static inline int superblock_write_lock_zero(struct dm_clone_metadata *cmd, 286 280 struct dm_block **sblock) 287 281 {
+3 -3
drivers/md/dm-ebs-target.c
··· 28 28 spinlock_t lock; /* Guard bios input list above. */ 29 29 sector_t start; /* <start> table line argument, see ebs_ctr below. */ 30 30 unsigned int e_bs; /* Emulated block size in sectors exposed to upper layer. */ 31 - unsigned int u_bs; /* Underlying block size in sectors retrievd from/set on lower layer device. */ 31 + unsigned int u_bs; /* Underlying block size in sectors retrieved from/set on lower layer device. */ 32 32 unsigned char block_shift; /* bitshift sectors -> blocks used in dm-bufio API. */ 33 33 bool u_bs_set:1; /* Flag to indicate underlying block size is set on table line. */ 34 34 }; ··· 43 43 return sector & (bs - 1); 44 44 } 45 45 46 - /* Return number of blocks for a bio, accounting for misalignement of start and end sectors. */ 46 + /* Return number of blocks for a bio, accounting for misalignment of start and end sectors. */ 47 47 static inline unsigned int __nr_blocks(struct ebs_c *ec, struct bio *bio) 48 48 { 49 49 sector_t end_sector = __block_mod(bio->bi_iter.bi_sector, ec->u_bs) + bio_sectors(bio); ··· 171 171 dm_bufio_forget_buffers(ec->bufio, __sector_to_block(ec, sector), blocks); 172 172 } 173 173 174 - /* Worker funtion to process incoming bios. */ 174 + /* Worker function to process incoming bios. */ 175 175 static void __ebs_process_bios(struct work_struct *ws) 176 176 { 177 177 int r;
+55 -30
drivers/md/dm-integrity.c
··· 35 35 #define MIN_LOG2_INTERLEAVE_SECTORS 3 36 36 #define MAX_LOG2_INTERLEAVE_SECTORS 31 37 37 #define METADATA_WORKQUEUE_MAX_ACTIVE 16 38 - #define RECALC_SECTORS 8192 38 + #define RECALC_SECTORS 32768 39 39 #define RECALC_WRITE_SUPER 16 40 40 #define BITMAP_BLOCK_SIZE 4096 /* don't change it */ 41 41 #define BITMAP_FLUSH_INTERVAL (10 * HZ) ··· 262 262 bool journal_uptodate; 263 263 bool just_formatted; 264 264 bool recalculate_flag; 265 + bool reset_recalculate_flag; 265 266 bool discard; 266 267 bool fix_padding; 267 268 bool fix_hmac; ··· 1429 1428 if (op == TAG_READ) { 1430 1429 memcpy(tag, dp, to_copy); 1431 1430 } else if (op == TAG_WRITE) { 1432 - memcpy(dp, tag, to_copy); 1433 - dm_bufio_mark_partial_buffer_dirty(b, *metadata_offset, *metadata_offset + to_copy); 1431 + if (memcmp(dp, tag, to_copy)) { 1432 + memcpy(dp, tag, to_copy); 1433 + dm_bufio_mark_partial_buffer_dirty(b, *metadata_offset, *metadata_offset + to_copy); 1434 + } 1434 1435 } else { 1435 1436 /* e.g.: op == TAG_CMP */ 1436 1437 ··· 2689 2686 if (unlikely(dm_integrity_failed(ic))) 2690 2687 goto err; 2691 2688 2692 - io_req.bi_op = REQ_OP_READ; 2693 - io_req.bi_op_flags = 0; 2694 - io_req.mem.type = DM_IO_VMA; 2695 - io_req.mem.ptr.addr = ic->recalc_buffer; 2696 - io_req.notify.fn = NULL; 2697 - io_req.client = ic->io; 2698 - io_loc.bdev = ic->dev->bdev; 2699 - io_loc.sector = get_data_sector(ic, area, offset); 2700 - io_loc.count = n_sectors; 2689 + if (!ic->discard) { 2690 + io_req.bi_op = REQ_OP_READ; 2691 + io_req.bi_op_flags = 0; 2692 + io_req.mem.type = DM_IO_VMA; 2693 + io_req.mem.ptr.addr = ic->recalc_buffer; 2694 + io_req.notify.fn = NULL; 2695 + io_req.client = ic->io; 2696 + io_loc.bdev = ic->dev->bdev; 2697 + io_loc.sector = get_data_sector(ic, area, offset); 2698 + io_loc.count = n_sectors; 2701 2699 2702 - r = dm_io(&io_req, 1, &io_loc, NULL); 2703 - if (unlikely(r)) { 2704 - dm_integrity_io_error(ic, "reading data", r); 2705 - goto err; 2706 - } 2700 + r = dm_io(&io_req, 1, &io_loc, NULL); 2701 + if (unlikely(r)) { 2702 + dm_integrity_io_error(ic, "reading data", r); 2703 + goto err; 2704 + } 2707 2705 2708 - t = ic->recalc_tags; 2709 - for (i = 0; i < n_sectors; i += ic->sectors_per_block) { 2710 - integrity_sector_checksum(ic, logical_sector + i, ic->recalc_buffer + (i << SECTOR_SHIFT), t); 2711 - t += ic->tag_size; 2706 + t = ic->recalc_tags; 2707 + for (i = 0; i < n_sectors; i += ic->sectors_per_block) { 2708 + integrity_sector_checksum(ic, logical_sector + i, ic->recalc_buffer + (i << SECTOR_SHIFT), t); 2709 + t += ic->tag_size; 2710 + } 2711 + } else { 2712 + t = ic->recalc_tags + (n_sectors >> ic->sb->log2_sectors_per_block) * ic->tag_size; 2712 2713 } 2713 2714 2714 2715 metadata_block = get_metadata_sector_and_offset(ic, area, offset, &metadata_offset); ··· 3141 3134 rw_journal_sectors(ic, REQ_OP_READ, 0, 0, 3142 3135 ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL); 3143 3136 if (ic->mode == 'B') { 3144 - if (ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit) { 3137 + if (ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit && 3138 + !ic->reset_recalculate_flag) { 3145 3139 block_bitmap_copy(ic, ic->recalc_bitmap, ic->journal); 3146 3140 block_bitmap_copy(ic, ic->may_write_bitmap, ic->journal); 3147 3141 if (!block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, ··· 3164 3156 } 3165 3157 } else { 3166 3158 if (!(ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit && 3167 - block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_TEST_ALL_CLEAR))) { 3159 + block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_TEST_ALL_CLEAR)) || 3160 + ic->reset_recalculate_flag) { 3168 3161 ic->sb->flags |= cpu_to_le32(SB_FLAG_RECALCULATING); 3169 3162 ic->sb->recalc_sector = cpu_to_le64(0); 3170 3163 } ··· 3178 3169 dm_integrity_io_error(ic, "writing superblock", r); 3179 3170 } else { 3180 3171 replay_journal(ic); 3172 + if (ic->reset_recalculate_flag) { 3173 + ic->sb->flags |= cpu_to_le32(SB_FLAG_RECALCULATING); 3174 + ic->sb->recalc_sector = cpu_to_le64(0); 3175 + } 3181 3176 if (ic->mode == 'B') { 3182 3177 ic->sb->flags |= cpu_to_le32(SB_FLAG_DIRTY_BITMAP); 3183 3178 ic->sb->log2_blocks_per_bitmap_bit = ic->log2_blocks_per_bitmap_bit; ··· 3255 3242 arg_count += !!ic->meta_dev; 3256 3243 arg_count += ic->sectors_per_block != 1; 3257 3244 arg_count += !!(ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)); 3245 + arg_count += ic->reset_recalculate_flag; 3258 3246 arg_count += ic->discard; 3259 3247 arg_count += ic->mode == 'J'; 3260 3248 arg_count += ic->mode == 'J'; ··· 3275 3261 DMEMIT(" block_size:%u", ic->sectors_per_block << SECTOR_SHIFT); 3276 3262 if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) 3277 3263 DMEMIT(" recalculate"); 3264 + if (ic->reset_recalculate_flag) 3265 + DMEMIT(" reset_recalculate"); 3278 3266 if (ic->discard) 3279 3267 DMEMIT(" allow_discards"); 3280 3268 DMEMIT(" journal_sectors:%u", ic->initial_sectors - SB_SECTORS); ··· 3930 3914 unsigned extra_args; 3931 3915 struct dm_arg_set as; 3932 3916 static const struct dm_arg _args[] = { 3933 - {0, 17, "Invalid number of feature args"}, 3917 + {0, 18, "Invalid number of feature args"}, 3934 3918 }; 3935 3919 unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; 3936 3920 bool should_write_sb; ··· 4055 4039 if (val >= (uint64_t)UINT_MAX * 1000 / HZ) { 4056 4040 r = -EINVAL; 4057 4041 ti->error = "Invalid bitmap_flush_interval argument"; 4042 + goto bad; 4058 4043 } 4059 4044 ic->bitmap_flush_interval = msecs_to_jiffies(val); 4060 4045 } else if (!strncmp(opt_string, "internal_hash:", strlen("internal_hash:"))) { ··· 4075 4058 goto bad; 4076 4059 } else if (!strcmp(opt_string, "recalculate")) { 4077 4060 ic->recalculate_flag = true; 4061 + } else if (!strcmp(opt_string, "reset_recalculate")) { 4062 + ic->recalculate_flag = true; 4063 + ic->reset_recalculate_flag = true; 4078 4064 } else if (!strcmp(opt_string, "allow_discards")) { 4079 4065 ic->discard = true; 4080 4066 } else if (!strcmp(opt_string, "fix_padding")) { ··· 4368 4348 goto bad; 4369 4349 } 4370 4350 INIT_WORK(&ic->recalc_work, integrity_recalc); 4371 - ic->recalc_buffer = vmalloc(RECALC_SECTORS << SECTOR_SHIFT); 4372 - if (!ic->recalc_buffer) { 4373 - ti->error = "Cannot allocate buffer for recalculating"; 4374 - r = -ENOMEM; 4375 - goto bad; 4351 + if (!ic->discard) { 4352 + ic->recalc_buffer = vmalloc(RECALC_SECTORS << SECTOR_SHIFT); 4353 + if (!ic->recalc_buffer) { 4354 + ti->error = "Cannot allocate buffer for recalculating"; 4355 + r = -ENOMEM; 4356 + goto bad; 4357 + } 4376 4358 } 4377 4359 ic->recalc_tags = kvmalloc_array(RECALC_SECTORS >> ic->sb->log2_sectors_per_block, 4378 4360 ic->tag_size, GFP_KERNEL); ··· 4383 4361 r = -ENOMEM; 4384 4362 goto bad; 4385 4363 } 4364 + if (ic->discard) 4365 + memset(ic->recalc_tags, DISCARD_FILLER, 4366 + (RECALC_SECTORS >> ic->sb->log2_sectors_per_block) * ic->tag_size); 4386 4367 } else { 4387 4368 if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) { 4388 4369 ti->error = "Recalculate can only be specified with internal_hash"; ··· 4579 4554 4580 4555 static struct target_type integrity_target = { 4581 4556 .name = "integrity", 4582 - .version = {1, 7, 0}, 4557 + .version = {1, 9, 0}, 4583 4558 .module = THIS_MODULE, 4584 4559 .features = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY, 4585 4560 .ctr = dm_integrity_ctr,
+184 -112
drivers/md/dm-ioctl.c
··· 14 14 #include <linux/init.h> 15 15 #include <linux/wait.h> 16 16 #include <linux/slab.h> 17 + #include <linux/rbtree.h> 17 18 #include <linux/dm-ioctl.h> 18 19 #include <linux/hdreg.h> 19 20 #include <linux/compat.h> ··· 37 36 * name or uuid. 38 37 *---------------------------------------------------------------*/ 39 38 struct hash_cell { 40 - struct list_head name_list; 41 - struct list_head uuid_list; 39 + struct rb_node name_node; 40 + struct rb_node uuid_node; 41 + bool name_set; 42 + bool uuid_set; 42 43 43 44 char *name; 44 45 char *uuid; ··· 56 53 }; 57 54 58 55 59 - #define NUM_BUCKETS 64 60 - #define MASK_BUCKETS (NUM_BUCKETS - 1) 61 - static struct list_head _name_buckets[NUM_BUCKETS]; 62 - static struct list_head _uuid_buckets[NUM_BUCKETS]; 56 + static struct rb_root name_rb_tree = RB_ROOT; 57 + static struct rb_root uuid_rb_tree = RB_ROOT; 63 58 64 59 static void dm_hash_remove_all(bool keep_open_devices, bool mark_deferred, bool only_deferred); 65 60 ··· 71 70 */ 72 71 static DEFINE_MUTEX(dm_hash_cells_mutex); 73 72 74 - static void init_buckets(struct list_head *buckets) 75 - { 76 - unsigned int i; 77 - 78 - for (i = 0; i < NUM_BUCKETS; i++) 79 - INIT_LIST_HEAD(buckets + i); 80 - } 81 - 82 - static int dm_hash_init(void) 83 - { 84 - init_buckets(_name_buckets); 85 - init_buckets(_uuid_buckets); 86 - return 0; 87 - } 88 - 89 73 static void dm_hash_exit(void) 90 74 { 91 75 dm_hash_remove_all(false, false, false); 92 - } 93 - 94 - /*----------------------------------------------------------------- 95 - * Hash function: 96 - * We're not really concerned with the str hash function being 97 - * fast since it's only used by the ioctl interface. 98 - *---------------------------------------------------------------*/ 99 - static unsigned int hash_str(const char *str) 100 - { 101 - const unsigned int hash_mult = 2654435387U; 102 - unsigned int h = 0; 103 - 104 - while (*str) 105 - h = (h + (unsigned int) *str++) * hash_mult; 106 - 107 - return h & MASK_BUCKETS; 108 76 } 109 77 110 78 /*----------------------------------------------------------------- ··· 81 111 *---------------------------------------------------------------*/ 82 112 static struct hash_cell *__get_name_cell(const char *str) 83 113 { 84 - struct hash_cell *hc; 85 - unsigned int h = hash_str(str); 114 + struct rb_node *n = name_rb_tree.rb_node; 86 115 87 - list_for_each_entry (hc, _name_buckets + h, name_list) 88 - if (!strcmp(hc->name, str)) { 116 + while (n) { 117 + struct hash_cell *hc = container_of(n, struct hash_cell, name_node); 118 + int c = strcmp(hc->name, str); 119 + if (!c) { 89 120 dm_get(hc->md); 90 121 return hc; 91 122 } 123 + n = c >= 0 ? n->rb_left : n->rb_right; 124 + } 92 125 93 126 return NULL; 94 127 } 95 128 96 129 static struct hash_cell *__get_uuid_cell(const char *str) 97 130 { 98 - struct hash_cell *hc; 99 - unsigned int h = hash_str(str); 131 + struct rb_node *n = uuid_rb_tree.rb_node; 100 132 101 - list_for_each_entry (hc, _uuid_buckets + h, uuid_list) 102 - if (!strcmp(hc->uuid, str)) { 133 + while (n) { 134 + struct hash_cell *hc = container_of(n, struct hash_cell, uuid_node); 135 + int c = strcmp(hc->uuid, str); 136 + if (!c) { 103 137 dm_get(hc->md); 104 138 return hc; 105 139 } 140 + n = c >= 0 ? n->rb_left : n->rb_right; 141 + } 106 142 107 143 return NULL; 144 + } 145 + 146 + static void __unlink_name(struct hash_cell *hc) 147 + { 148 + if (hc->name_set) { 149 + hc->name_set = false; 150 + rb_erase(&hc->name_node, &name_rb_tree); 151 + } 152 + } 153 + 154 + static void __unlink_uuid(struct hash_cell *hc) 155 + { 156 + if (hc->uuid_set) { 157 + hc->uuid_set = false; 158 + rb_erase(&hc->uuid_node, &uuid_rb_tree); 159 + } 160 + } 161 + 162 + static void __link_name(struct hash_cell *new_hc) 163 + { 164 + struct rb_node **n, *parent; 165 + 166 + __unlink_name(new_hc); 167 + 168 + new_hc->name_set = true; 169 + 170 + n = &name_rb_tree.rb_node; 171 + parent = NULL; 172 + 173 + while (*n) { 174 + struct hash_cell *hc = container_of(*n, struct hash_cell, name_node); 175 + int c = strcmp(hc->name, new_hc->name); 176 + BUG_ON(!c); 177 + parent = *n; 178 + n = c >= 0 ? &hc->name_node.rb_left : &hc->name_node.rb_right; 179 + } 180 + 181 + rb_link_node(&new_hc->name_node, parent, n); 182 + rb_insert_color(&new_hc->name_node, &name_rb_tree); 183 + } 184 + 185 + static void __link_uuid(struct hash_cell *new_hc) 186 + { 187 + struct rb_node **n, *parent; 188 + 189 + __unlink_uuid(new_hc); 190 + 191 + new_hc->uuid_set = true; 192 + 193 + n = &uuid_rb_tree.rb_node; 194 + parent = NULL; 195 + 196 + while (*n) { 197 + struct hash_cell *hc = container_of(*n, struct hash_cell, uuid_node); 198 + int c = strcmp(hc->uuid, new_hc->uuid); 199 + BUG_ON(!c); 200 + parent = *n; 201 + n = c > 0 ? &hc->uuid_node.rb_left : &hc->uuid_node.rb_right; 202 + } 203 + 204 + rb_link_node(&new_hc->uuid_node, parent, n); 205 + rb_insert_color(&new_hc->uuid_node, &uuid_rb_tree); 108 206 } 109 207 110 208 static struct hash_cell *__get_dev_cell(uint64_t dev) ··· 223 185 } 224 186 } 225 187 226 - INIT_LIST_HEAD(&hc->name_list); 227 - INIT_LIST_HEAD(&hc->uuid_list); 188 + hc->name_set = hc->uuid_set = false; 228 189 hc->md = md; 229 190 hc->new_map = NULL; 230 191 return hc; ··· 263 226 goto bad; 264 227 } 265 228 266 - list_add(&cell->name_list, _name_buckets + hash_str(name)); 229 + __link_name(cell); 267 230 268 231 if (uuid) { 269 232 hc = __get_uuid_cell(uuid); 270 233 if (hc) { 271 - list_del(&cell->name_list); 234 + __unlink_name(cell); 272 235 dm_put(hc->md); 273 236 goto bad; 274 237 } 275 - list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); 238 + __link_uuid(cell); 276 239 } 277 240 dm_get(md); 278 241 mutex_lock(&dm_hash_cells_mutex); ··· 293 256 struct dm_table *table; 294 257 int srcu_idx; 295 258 296 - /* remove from the dev hash */ 297 - list_del(&hc->uuid_list); 298 - list_del(&hc->name_list); 259 + /* remove from the dev trees */ 260 + __unlink_name(hc); 261 + __unlink_uuid(hc); 299 262 mutex_lock(&dm_hash_cells_mutex); 300 263 dm_set_mdptr(hc->md, NULL); 301 264 mutex_unlock(&dm_hash_cells_mutex); ··· 316 279 317 280 static void dm_hash_remove_all(bool keep_open_devices, bool mark_deferred, bool only_deferred) 318 281 { 319 - int i, dev_skipped; 282 + int dev_skipped; 283 + struct rb_node *n; 320 284 struct hash_cell *hc; 321 285 struct mapped_device *md; 322 286 struct dm_table *t; ··· 327 289 328 290 down_write(&_hash_lock); 329 291 330 - for (i = 0; i < NUM_BUCKETS; i++) { 331 - list_for_each_entry(hc, _name_buckets + i, name_list) { 332 - md = hc->md; 333 - dm_get(md); 292 + for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) { 293 + hc = container_of(n, struct hash_cell, name_node); 294 + md = hc->md; 295 + dm_get(md); 334 296 335 - if (keep_open_devices && 336 - dm_lock_for_deletion(md, mark_deferred, only_deferred)) { 337 - dm_put(md); 338 - dev_skipped++; 339 - continue; 340 - } 341 - 342 - t = __hash_remove(hc); 343 - 344 - up_write(&_hash_lock); 345 - 346 - if (t) { 347 - dm_sync_table(md); 348 - dm_table_destroy(t); 349 - } 297 + if (keep_open_devices && 298 + dm_lock_for_deletion(md, mark_deferred, only_deferred)) { 350 299 dm_put(md); 351 - if (likely(keep_open_devices)) 352 - dm_destroy(md); 353 - else 354 - dm_destroy_immediate(md); 355 - 356 - /* 357 - * Some mapped devices may be using other mapped 358 - * devices, so repeat until we make no further 359 - * progress. If a new mapped device is created 360 - * here it will also get removed. 361 - */ 362 - goto retry; 300 + dev_skipped++; 301 + continue; 363 302 } 303 + 304 + t = __hash_remove(hc); 305 + 306 + up_write(&_hash_lock); 307 + 308 + if (t) { 309 + dm_sync_table(md); 310 + dm_table_destroy(t); 311 + } 312 + dm_put(md); 313 + if (likely(keep_open_devices)) 314 + dm_destroy(md); 315 + else 316 + dm_destroy_immediate(md); 317 + 318 + /* 319 + * Some mapped devices may be using other mapped 320 + * devices, so repeat until we make no further 321 + * progress. If a new mapped device is created 322 + * here it will also get removed. 323 + */ 324 + goto retry; 364 325 } 365 326 366 327 up_write(&_hash_lock); ··· 377 340 hc->uuid = new_uuid; 378 341 mutex_unlock(&dm_hash_cells_mutex); 379 342 380 - list_add(&hc->uuid_list, _uuid_buckets + hash_str(new_uuid)); 343 + __link_uuid(hc); 381 344 } 382 345 383 346 /* ··· 391 354 /* 392 355 * Rename and move the name cell. 393 356 */ 394 - list_del(&hc->name_list); 357 + __unlink_name(hc); 395 358 old_name = hc->name; 396 359 397 360 mutex_lock(&dm_hash_cells_mutex); 398 361 hc->name = new_name; 399 362 mutex_unlock(&dm_hash_cells_mutex); 400 363 401 - list_add(&hc->name_list, _name_buckets + hash_str(new_name)); 364 + __link_name(hc); 402 365 403 366 return old_name; 404 367 } ··· 540 503 return ((void *) param) + param->data_start; 541 504 } 542 505 506 + static bool filter_device(struct hash_cell *hc, const char *pfx_name, const char *pfx_uuid) 507 + { 508 + const char *val; 509 + size_t val_len, pfx_len; 510 + 511 + val = hc->name; 512 + val_len = strlen(val); 513 + pfx_len = strnlen(pfx_name, DM_NAME_LEN); 514 + if (pfx_len > val_len) 515 + return false; 516 + if (memcmp(val, pfx_name, pfx_len)) 517 + return false; 518 + 519 + val = hc->uuid ? hc->uuid : ""; 520 + val_len = strlen(val); 521 + pfx_len = strnlen(pfx_uuid, DM_UUID_LEN); 522 + if (pfx_len > val_len) 523 + return false; 524 + if (memcmp(val, pfx_uuid, pfx_len)) 525 + return false; 526 + 527 + return true; 528 + } 529 + 543 530 static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_size) 544 531 { 545 - unsigned int i; 532 + struct rb_node *n; 546 533 struct hash_cell *hc; 547 534 size_t len, needed = 0; 548 535 struct gendisk *disk; ··· 579 518 * Loop through all the devices working out how much 580 519 * space we need. 581 520 */ 582 - for (i = 0; i < NUM_BUCKETS; i++) { 583 - list_for_each_entry (hc, _name_buckets + i, name_list) { 584 - needed += align_val(offsetof(struct dm_name_list, name) + strlen(hc->name) + 1); 585 - needed += align_val(sizeof(uint32_t)); 586 - } 521 + for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) { 522 + hc = container_of(n, struct hash_cell, name_node); 523 + if (!filter_device(hc, param->name, param->uuid)) 524 + continue; 525 + needed += align_val(offsetof(struct dm_name_list, name) + strlen(hc->name) + 1); 526 + needed += align_val(sizeof(uint32_t) * 2); 527 + if (param->flags & DM_UUID_FLAG && hc->uuid) 528 + needed += align_val(strlen(hc->uuid) + 1); 587 529 } 588 530 589 531 /* ··· 604 540 /* 605 541 * Now loop through filling out the names. 606 542 */ 607 - for (i = 0; i < NUM_BUCKETS; i++) { 608 - list_for_each_entry (hc, _name_buckets + i, name_list) { 609 - if (old_nl) 610 - old_nl->next = (uint32_t) ((void *) nl - 611 - (void *) old_nl); 612 - disk = dm_disk(hc->md); 613 - nl->dev = huge_encode_dev(disk_devt(disk)); 614 - nl->next = 0; 615 - strcpy(nl->name, hc->name); 543 + for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) { 544 + void *uuid_ptr; 545 + hc = container_of(n, struct hash_cell, name_node); 546 + if (!filter_device(hc, param->name, param->uuid)) 547 + continue; 548 + if (old_nl) 549 + old_nl->next = (uint32_t) ((void *) nl - 550 + (void *) old_nl); 551 + disk = dm_disk(hc->md); 552 + nl->dev = huge_encode_dev(disk_devt(disk)); 553 + nl->next = 0; 554 + strcpy(nl->name, hc->name); 616 555 617 - old_nl = nl; 618 - event_nr = align_ptr(nl->name + strlen(hc->name) + 1); 619 - *event_nr = dm_get_event_nr(hc->md); 620 - nl = align_ptr(event_nr + 1); 556 + old_nl = nl; 557 + event_nr = align_ptr(nl->name + strlen(hc->name) + 1); 558 + event_nr[0] = dm_get_event_nr(hc->md); 559 + event_nr[1] = 0; 560 + uuid_ptr = align_ptr(event_nr + 2); 561 + if (param->flags & DM_UUID_FLAG) { 562 + if (hc->uuid) { 563 + event_nr[1] |= DM_NAME_LIST_FLAG_HAS_UUID; 564 + strcpy(uuid_ptr, hc->uuid); 565 + uuid_ptr = align_ptr(uuid_ptr + strlen(hc->uuid) + 1); 566 + } else { 567 + event_nr[1] |= DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID; 568 + } 621 569 } 570 + nl = uuid_ptr; 622 571 } 623 572 /* 624 573 * If mismatch happens, security may be compromised due to buffer ··· 2068 1991 { 2069 1992 int r; 2070 1993 2071 - r = dm_hash_init(); 2072 - if (r) 2073 - return r; 2074 - 2075 1994 r = misc_register(&_dm_misc); 2076 1995 if (r) { 2077 1996 DMERR("misc_register failed for control device"); 2078 - dm_hash_exit(); 2079 1997 return r; 2080 1998 } 2081 1999
+29 -15
drivers/md/dm-raid.c
··· 1853 1853 ((mddev->layout == ALGORITHM_PARITY_N && mddev->new_layout == ALGORITHM_PARITY_N) || 1854 1854 __within_range(mddev->new_layout, ALGORITHM_LEFT_ASYMMETRIC, ALGORITHM_RIGHT_SYMMETRIC))) 1855 1855 return 0; 1856 + break; 1856 1857 1857 1858 default: 1858 1859 break; ··· 1869 1868 return rs->md.new_level != rs->md.level; 1870 1869 } 1871 1870 1871 + /* True if layout is set to reshape. */ 1872 + static bool rs_is_layout_change(struct raid_set *rs, bool use_mddev) 1873 + { 1874 + return (use_mddev ? rs->md.delta_disks : rs->delta_disks) || 1875 + rs->md.new_layout != rs->md.layout || 1876 + rs->md.new_chunk_sectors != rs->md.chunk_sectors; 1877 + } 1878 + 1872 1879 /* True if @rs is requested to reshape by ctr */ 1873 1880 static bool rs_reshape_requested(struct raid_set *rs) 1874 1881 { ··· 1889 1880 if (rs_is_raid0(rs)) 1890 1881 return false; 1891 1882 1892 - change = mddev->new_layout != mddev->layout || 1893 - mddev->new_chunk_sectors != mddev->chunk_sectors || 1894 - rs->delta_disks; 1883 + change = rs_is_layout_change(rs, false); 1895 1884 1896 1885 /* Historical case to support raid1 reshape without delta disks */ 1897 1886 if (rs_is_raid1(rs)) { ··· 2824 2817 } 2825 2818 2826 2819 /* 2827 - * 2820 + * Reshape: 2828 2821 * - change raid layout 2829 2822 * - change chunk size 2830 2823 * - add disks ··· 2931 2924 rdev->sectors += reshape_sectors; 2932 2925 2933 2926 return r; 2927 + } 2928 + 2929 + /* 2930 + * If the md resync thread has updated superblock with max reshape position 2931 + * at the end of a reshape but not (yet) reset the layout configuration 2932 + * changes -> reset the latter. 2933 + */ 2934 + static void rs_reset_inconclusive_reshape(struct raid_set *rs) 2935 + { 2936 + if (!rs_is_reshaping(rs) && rs_is_layout_change(rs, true)) { 2937 + rs_set_cur(rs); 2938 + rs->md.delta_disks = 0; 2939 + rs->md.reshape_backwards = 0; 2940 + } 2934 2941 } 2935 2942 2936 2943 /* ··· 3233 3212 if (r) 3234 3213 goto bad; 3235 3214 3215 + /* Catch any inconclusive reshape superblock content. */ 3216 + rs_reset_inconclusive_reshape(rs); 3217 + 3236 3218 /* Start raid set read-only and assumed clean to change in raid_resume() */ 3237 3219 rs->md.ro = 1; 3238 3220 rs->md.in_sync = 1; 3239 3221 3240 - /* Keep array frozen */ 3222 + /* Keep array frozen until resume. */ 3241 3223 set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery); 3242 3224 3243 3225 /* Has to be held on running the array */ ··· 3254 3230 } 3255 3231 3256 3232 r = md_start(&rs->md); 3257 - 3258 3233 if (r) { 3259 3234 ti->error = "Failed to start raid array"; 3260 3235 mddev_unlock(&rs->md); ··· 3750 3727 3751 3728 blk_limits_io_min(limits, chunk_size_bytes); 3752 3729 blk_limits_io_opt(limits, chunk_size_bytes * mddev_data_stripes(rs)); 3753 - 3754 - /* 3755 - * RAID0 and RAID10 personalities require bio splitting, 3756 - * RAID1/4/5/6 don't and process large discard bios properly. 3757 - */ 3758 - if (rs_is_raid0(rs) || rs_is_raid10(rs)) { 3759 - limits->discard_granularity = chunk_size_bytes; 3760 - limits->max_discard_sectors = rs->md.chunk_sectors; 3761 - } 3762 3730 } 3763 3731 3764 3732 static void raid_postsuspend(struct dm_target *ti)
+2
drivers/md/dm-rq.c
··· 569 569 blk_mq_free_tag_set(md->tag_set); 570 570 out_kfree_tag_set: 571 571 kfree(md->tag_set); 572 + md->tag_set = NULL; 572 573 573 574 return err; 574 575 } ··· 579 578 if (md->tag_set) { 580 579 blk_mq_free_tag_set(md->tag_set); 581 580 kfree(md->tag_set); 581 + md->tag_set = NULL; 582 582 } 583 583 } 584 584
+3 -3
drivers/md/dm-snap-persistent.c
··· 596 596 free_area(ps); 597 597 598 598 /* Allocated in persistent_read_metadata */ 599 - vfree(ps->callbacks); 599 + kvfree(ps->callbacks); 600 600 601 601 kfree(ps); 602 602 } ··· 621 621 */ 622 622 ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) / 623 623 sizeof(struct disk_exception); 624 - ps->callbacks = dm_vcalloc(ps->exceptions_per_area, 625 - sizeof(*ps->callbacks)); 624 + ps->callbacks = kvcalloc(ps->exceptions_per_area, 625 + sizeof(*ps->callbacks), GFP_KERNEL); 626 626 if (!ps->callbacks) 627 627 return -ENOMEM; 628 628
+3 -2
drivers/md/dm-snap.c
··· 663 663 664 664 et->hash_shift = hash_shift; 665 665 et->hash_mask = size - 1; 666 - et->table = dm_vcalloc(size, sizeof(struct hlist_bl_head)); 666 + et->table = kvmalloc_array(size, sizeof(struct hlist_bl_head), 667 + GFP_KERNEL); 667 668 if (!et->table) 668 669 return -ENOMEM; 669 670 ··· 690 689 kmem_cache_free(mem, ex); 691 690 } 692 691 693 - vfree(et->table); 692 + kvfree(et->table); 694 693 } 695 694 696 695 static uint32_t exception_hash(struct dm_exception_table *et, chunk_t chunk)
+6 -24
drivers/md/dm-table.c
··· 94 94 return 0; 95 95 } 96 96 97 - void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size) 98 - { 99 - unsigned long size; 100 - void *addr; 101 - 102 - /* 103 - * Check that we're not going to overflow. 104 - */ 105 - if (nmemb > (ULONG_MAX / elem_size)) 106 - return NULL; 107 - 108 - size = nmemb * elem_size; 109 - addr = vzalloc(size); 110 - 111 - return addr; 112 - } 113 - EXPORT_SYMBOL(dm_vcalloc); 114 - 115 97 /* 116 98 * highs, and targets are managed as dynamic arrays during a 117 99 * table load. ··· 106 124 /* 107 125 * Allocate both the target array and offset array at once. 108 126 */ 109 - n_highs = (sector_t *) dm_vcalloc(num, sizeof(struct dm_target) + 110 - sizeof(sector_t)); 127 + n_highs = kvcalloc(num, sizeof(struct dm_target) + sizeof(sector_t), 128 + GFP_KERNEL); 111 129 if (!n_highs) 112 130 return -ENOMEM; 113 131 114 132 n_targets = (struct dm_target *) (n_highs + num); 115 133 116 134 memset(n_highs, -1, sizeof(*n_highs) * num); 117 - vfree(t->highs); 135 + kvfree(t->highs); 118 136 119 137 t->num_allocated = num; 120 138 t->highs = n_highs; ··· 180 198 181 199 /* free the indexes */ 182 200 if (t->depth >= 2) 183 - vfree(t->index[t->depth - 2]); 201 + kvfree(t->index[t->depth - 2]); 184 202 185 203 /* free the targets */ 186 204 for (i = 0; i < t->num_targets; i++) { ··· 192 210 dm_put_target_type(tgt->type); 193 211 } 194 212 195 - vfree(t->highs); 213 + kvfree(t->highs); 196 214 197 215 /* free the device list */ 198 216 free_devices(&t->devices, t->md); ··· 1059 1077 total += t->counts[i]; 1060 1078 } 1061 1079 1062 - indexes = (sector_t *) dm_vcalloc(total, (unsigned long) NODE_SIZE); 1080 + indexes = kvcalloc(total, NODE_SIZE, GFP_KERNEL); 1063 1081 if (!indexes) 1064 1082 return -ENOMEM; 1065 1083
+1 -1
drivers/md/dm-thin.c
··· 2816 2816 { 2817 2817 struct request_queue *q = bdev_get_queue(pt->data_dev->bdev); 2818 2818 2819 - return q && blk_queue_discard(q); 2819 + return blk_queue_discard(q); 2820 2820 } 2821 2821 2822 2822 static bool is_factor(sector_t block_size, uint32_t n)
+29 -11
drivers/md/dm-verity-target.c
··· 893 893 return r; 894 894 } 895 895 896 + static inline bool verity_is_verity_mode(const char *arg_name) 897 + { 898 + return (!strcasecmp(arg_name, DM_VERITY_OPT_LOGGING) || 899 + !strcasecmp(arg_name, DM_VERITY_OPT_RESTART) || 900 + !strcasecmp(arg_name, DM_VERITY_OPT_PANIC)); 901 + } 902 + 903 + static int verity_parse_verity_mode(struct dm_verity *v, const char *arg_name) 904 + { 905 + if (v->mode) 906 + return -EINVAL; 907 + 908 + if (!strcasecmp(arg_name, DM_VERITY_OPT_LOGGING)) 909 + v->mode = DM_VERITY_MODE_LOGGING; 910 + else if (!strcasecmp(arg_name, DM_VERITY_OPT_RESTART)) 911 + v->mode = DM_VERITY_MODE_RESTART; 912 + else if (!strcasecmp(arg_name, DM_VERITY_OPT_PANIC)) 913 + v->mode = DM_VERITY_MODE_PANIC; 914 + 915 + return 0; 916 + } 917 + 896 918 static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, 897 919 struct dm_verity_sig_opts *verify_args) 898 920 { ··· 938 916 arg_name = dm_shift_arg(as); 939 917 argc--; 940 918 941 - if (!strcasecmp(arg_name, DM_VERITY_OPT_LOGGING)) { 942 - v->mode = DM_VERITY_MODE_LOGGING; 943 - continue; 944 - 945 - } else if (!strcasecmp(arg_name, DM_VERITY_OPT_RESTART)) { 946 - v->mode = DM_VERITY_MODE_RESTART; 947 - continue; 948 - 949 - } else if (!strcasecmp(arg_name, DM_VERITY_OPT_PANIC)) { 950 - v->mode = DM_VERITY_MODE_PANIC; 919 + if (verity_is_verity_mode(arg_name)) { 920 + r = verity_parse_verity_mode(v, arg_name); 921 + if (r) { 922 + ti->error = "Conflicting error handling parameters"; 923 + return r; 924 + } 951 925 continue; 952 926 953 927 } else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) { ··· 1260 1242 1261 1243 static struct target_type verity_target = { 1262 1244 .name = "verity", 1263 - .version = {1, 7, 0}, 1245 + .version = {1, 8, 0}, 1264 1246 .module = THIS_MODULE, 1265 1247 .ctr = verity_ctr, 1266 1248 .dtr = verity_dtr,
+1 -1
drivers/md/dm-writecache.c
··· 73 73 }; 74 74 __le64 padding[8]; 75 75 }; 76 - struct wc_memory_entry entries[0]; 76 + struct wc_memory_entry entries[]; 77 77 }; 78 78 79 79 struct wc_entry {
+27 -32
drivers/md/dm.c
··· 840 840 *result = &td->dm_dev; 841 841 return 0; 842 842 } 843 - EXPORT_SYMBOL_GPL(dm_get_table_device); 844 843 845 844 void dm_put_table_device(struct mapped_device *md, struct dm_dev *d) 846 845 { ··· 853 854 } 854 855 mutex_unlock(&md->table_devices_lock); 855 856 } 856 - EXPORT_SYMBOL(dm_put_table_device); 857 857 858 858 static void free_table_devices(struct list_head *devices) 859 859 { ··· 1639 1641 } else { 1640 1642 ci.bio = bio; 1641 1643 ci.sector_count = bio_sectors(bio); 1642 - while (ci.sector_count && !error) { 1643 - error = __split_and_process_non_flush(&ci); 1644 - if (ci.sector_count && !error) { 1645 - /* 1646 - * Remainder must be passed to submit_bio_noacct() 1647 - * so that it gets handled *after* bios already submitted 1648 - * have been completely processed. 1649 - * We take a clone of the original to store in 1650 - * ci.io->orig_bio to be used by end_io_acct() and 1651 - * for dec_pending to use for completion handling. 1652 - */ 1653 - struct bio *b = bio_split(bio, bio_sectors(bio) - ci.sector_count, 1654 - GFP_NOIO, &md->queue->bio_split); 1655 - ci.io->orig_bio = b; 1644 + error = __split_and_process_non_flush(&ci); 1645 + if (ci.sector_count && !error) { 1646 + /* 1647 + * Remainder must be passed to submit_bio_noacct() 1648 + * so that it gets handled *after* bios already submitted 1649 + * have been completely processed. 1650 + * We take a clone of the original to store in 1651 + * ci.io->orig_bio to be used by end_io_acct() and 1652 + * for dec_pending to use for completion handling. 1653 + */ 1654 + struct bio *b = bio_split(bio, bio_sectors(bio) - ci.sector_count, 1655 + GFP_NOIO, &md->queue->bio_split); 1656 + ci.io->orig_bio = b; 1656 1657 1657 - /* 1658 - * Adjust IO stats for each split, otherwise upon queue 1659 - * reentry there will be redundant IO accounting. 1660 - * NOTE: this is a stop-gap fix, a proper fix involves 1661 - * significant refactoring of DM core's bio splitting 1662 - * (by eliminating DM's splitting and just using bio_split) 1663 - */ 1664 - part_stat_lock(); 1665 - __dm_part_stat_sub(dm_disk(md)->part0, 1666 - sectors[op_stat_group(bio_op(bio))], ci.sector_count); 1667 - part_stat_unlock(); 1658 + /* 1659 + * Adjust IO stats for each split, otherwise upon queue 1660 + * reentry there will be redundant IO accounting. 1661 + * NOTE: this is a stop-gap fix, a proper fix involves 1662 + * significant refactoring of DM core's bio splitting 1663 + * (by eliminating DM's splitting and just using bio_split) 1664 + */ 1665 + part_stat_lock(); 1666 + __dm_part_stat_sub(dm_disk(md)->part0, 1667 + sectors[op_stat_group(bio_op(bio))], ci.sector_count); 1668 + part_stat_unlock(); 1668 1669 1669 - bio_chain(b, bio); 1670 - trace_block_split(b, bio->bi_iter.bi_sector); 1671 - ret = submit_bio_noacct(bio); 1672 - break; 1673 - } 1670 + bio_chain(b, bio); 1671 + trace_block_split(b, bio->bi_iter.bi_sector); 1672 + ret = submit_bio_noacct(bio); 1674 1673 } 1675 1674 } 1676 1675
+3 -3
drivers/md/persistent-data/dm-btree-internal.h
··· 34 34 __le32 max_entries; 35 35 __le32 value_size; 36 36 __le32 padding; 37 - } __packed; 37 + } __attribute__((packed, aligned(8))); 38 38 39 39 struct btree_node { 40 40 struct node_header header; 41 41 __le64 keys[]; 42 - } __packed; 42 + } __attribute__((packed, aligned(8))); 43 43 44 44 45 45 /* ··· 83 83 }; 84 84 85 85 void init_shadow_spine(struct shadow_spine *s, struct dm_btree_info *info); 86 - int exit_shadow_spine(struct shadow_spine *s); 86 + void exit_shadow_spine(struct shadow_spine *s); 87 87 88 88 int shadow_step(struct shadow_spine *s, dm_block_t b, 89 89 struct dm_btree_value_type *vt);
+2 -6
drivers/md/persistent-data/dm-btree-spine.c
··· 30 30 h->csum = cpu_to_le32(dm_bm_checksum(&h->flags, 31 31 block_size - sizeof(__le32), 32 32 BTREE_CSUM_XOR)); 33 - 34 - BUG_ON(node_check(v, b, 4096)); 35 33 } 36 34 37 35 static int node_check(struct dm_block_validator *v, ··· 181 183 s->count = 0; 182 184 } 183 185 184 - int exit_shadow_spine(struct shadow_spine *s) 186 + void exit_shadow_spine(struct shadow_spine *s) 185 187 { 186 - int r = 0, i; 188 + int i; 187 189 188 190 for (i = 0; i < s->count; i++) { 189 191 unlock_block(s->info, s->nodes[i]); 190 192 } 191 - 192 - return r; 193 193 } 194 194 195 195 int shadow_step(struct shadow_spine *s, dm_block_t b,
+2
drivers/md/persistent-data/dm-space-map-common.c
··· 339 339 */ 340 340 begin = do_div(index_begin, ll->entries_per_block); 341 341 end = do_div(end, ll->entries_per_block); 342 + if (end == 0) 343 + end = ll->entries_per_block; 342 344 343 345 for (i = index_begin; i < index_end; i++, begin = 0) { 344 346 struct dm_block *blk;
+4 -4
drivers/md/persistent-data/dm-space-map-common.h
··· 33 33 __le64 blocknr; 34 34 __le32 nr_free; 35 35 __le32 none_free_before; 36 - } __packed; 36 + } __attribute__ ((packed, aligned(8))); 37 37 38 38 39 39 #define MAX_METADATA_BITMAPS 255 ··· 43 43 __le64 blocknr; 44 44 45 45 struct disk_index_entry index[MAX_METADATA_BITMAPS]; 46 - } __packed; 46 + } __attribute__ ((packed, aligned(8))); 47 47 48 48 struct ll_disk; 49 49 ··· 86 86 __le64 nr_allocated; 87 87 __le64 bitmap_root; 88 88 __le64 ref_count_root; 89 - } __packed; 89 + } __attribute__ ((packed, aligned(8))); 90 90 91 91 #define ENTRIES_PER_BYTE 4 92 92 ··· 94 94 __le32 csum; 95 95 __le32 not_used; 96 96 __le64 blocknr; 97 - } __packed; 97 + } __attribute__ ((packed, aligned(8))); 98 98 99 99 enum allocation_event { 100 100 SM_NONE,
-9
drivers/md/persistent-data/dm-space-map-disk.c
··· 187 187 static int sm_disk_commit(struct dm_space_map *sm) 188 188 { 189 189 int r; 190 - dm_block_t nr_free; 191 190 struct sm_disk *smd = container_of(sm, struct sm_disk, sm); 192 - 193 - r = sm_disk_get_nr_free(sm, &nr_free); 194 - if (r) 195 - return r; 196 191 197 192 r = sm_ll_commit(&smd->ll); 198 193 if (r) ··· 196 201 memcpy(&smd->old_ll, &smd->ll, sizeof(smd->old_ll)); 197 202 smd->begin = 0; 198 203 smd->nr_allocated_this_transaction = 0; 199 - 200 - r = sm_disk_get_nr_free(sm, &nr_free); 201 - if (r) 202 - return r; 203 204 204 205 return 0; 205 206 }
-5
include/linux/device-mapper.h
··· 574 574 */ 575 575 void dm_destroy_keyslot_manager(struct blk_keyslot_manager *ksm); 576 576 577 - /* 578 - * A wrapper around vmalloc. 579 - */ 580 - void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); 581 - 582 577 /*----------------------------------------------------------------- 583 578 * Macros. 584 579 *---------------------------------------------------------------*/
+16 -2
include/uapi/linux/dm-ioctl.h
··· 193 193 __u32 next; /* offset to the next record from 194 194 the _start_ of this */ 195 195 char name[0]; 196 + 197 + /* 198 + * The following members can be accessed by taking a pointer that 199 + * points immediately after the terminating zero character in "name" 200 + * and aligning this pointer to next 8-byte boundary. 201 + * Uuid is present if the flag DM_NAME_LIST_FLAG_HAS_UUID is set. 202 + * 203 + * __u32 event_nr; 204 + * __u32 flags; 205 + * char uuid[0]; 206 + */ 196 207 }; 208 + 209 + #define DM_NAME_LIST_FLAG_HAS_UUID 1 210 + #define DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID 2 197 211 198 212 /* 199 213 * Used to retrieve the target versions ··· 286 272 #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) 287 273 288 274 #define DM_VERSION_MAJOR 4 289 - #define DM_VERSION_MINOR 44 275 + #define DM_VERSION_MINOR 45 290 276 #define DM_VERSION_PATCHLEVEL 0 291 - #define DM_VERSION_EXTRA "-ioctl (2021-02-01)" 277 + #define DM_VERSION_EXTRA "-ioctl (2021-03-22)" 292 278 293 279 /* Status bits */ 294 280 #define DM_READONLY_FLAG (1 << 0) /* In/Out */