Changeset 7ef5ea2 in mainline
- Timestamp:
- 2025-06-29T23:21:19Z (3 months ago)
- Children:
- 640250b
- Parents:
- b81ae12
- Location:
- uspace/srv/bd/hr/metadata/foreign/md
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/hr/metadata/foreign/md/hr_md.c
rb81ae12 r7ef5ea2 55 55 /* not exposed */ 56 56 static void *meta_md_alloc_struct(void); 57 /* static void meta_md_encode(void *, void *); */ 57 static void meta_md_encode(void *, void *); 58 58 static errno_t meta_md_decode(const void *, void *); 59 59 static errno_t meta_md_get_block(service_id_t, void **); 60 /* static errno_t meta_md_write_block(service_id_t, const void *); */ 60 static errno_t meta_md_write_block(service_id_t, const void *); 61 61 62 62 static errno_t meta_md_probe(service_id_t, void **); … … 190 190 vol->strip_size = main_meta->chunksize * 512; 191 191 192 vol->in_mem_md = calloc( 1, MD_SIZE * 512);192 vol->in_mem_md = calloc(vol->extent_no, MD_SIZE * 512); 193 193 if (vol->in_mem_md == NULL) 194 194 return ENOMEM; 195 memcpy(vol->in_mem_md, main_meta, MD_SIZE * 512); 196 195 196 size_t i = 0; 197 197 list_foreach(*list, link, struct dev_list_member, iter) { 198 198 struct mdp_superblock_1 *iter_meta = iter->md; … … 200 200 uint8_t index = iter_meta->dev_roles[iter_meta->dev_number]; 201 201 202 struct mdp_superblock_1 *p = (struct mdp_superblock_1 *) 203 (((char *)vol->in_mem_md) + MD_SIZE * 512 * index); 204 memcpy(p, iter_meta, MD_SIZE * 512); 205 202 206 vol->extents[index].svc_id = iter->svc_id; 203 207 iter->fini = false; 204 208 205 if (iter_meta->events == max_events && index < vol->extent_no) 209 bool invalidate = false; 210 211 if (iter_meta->events != max_events) 212 invalidate = true; 213 214 if (iter_meta->feature_map & MD_DISK_SYNC) 215 invalidate = true; 216 217 if (!invalidate) 206 218 vol->extents[index].state = HR_EXT_ONLINE; 207 219 else 208 220 vol->extents[index].state = HR_EXT_INVALID; 221 222 i++; 223 if (i == vol->extent_no) 224 break; 209 225 } 210 226 … … 240 256 fibril_mutex_lock(&vol->md_lock); 241 257 242 struct mdp_superblock_1 *md = vol->in_mem_md; 243 244 md->events++; 258 for (size_t d = 0; d < vol->extent_no; d++) { 259 struct mdp_superblock_1 *md = (struct mdp_superblock_1 *) 260 (((uint8_t *)vol->in_mem_md) + MD_SIZE * 512 * d); 261 md->events++; 262 } 245 263 246 264 fibril_mutex_unlock(&vol->md_lock); … … 251 269 HR_DEBUG("%s()", __func__); 252 270 253 return ENOTSUP; 271 fibril_rwlock_read_lock(&vol->extents_lock); 272 273 for (size_t i = 0; i < vol->extent_no; i++) 274 meta_md_save_ext(vol, i, with_state_callback); 275 276 fibril_rwlock_read_unlock(&vol->extents_lock); 277 278 return EOK; 254 279 } 255 280 … … 259 284 HR_DEBUG("%s()", __func__); 260 285 261 return ENOTSUP; 286 assert(fibril_rwlock_is_locked(&vol->extents_lock)); 287 288 void *md_block = hr_calloc_waitok(1, MD_SIZE * 512); 289 290 struct mdp_superblock_1 *md = (struct mdp_superblock_1 *) 291 (((uint8_t *)vol->in_mem_md) + MD_SIZE * 512 * ext_idx); 292 293 hr_extent_t *ext = &vol->extents[ext_idx]; 294 295 fibril_rwlock_read_lock(&vol->states_lock); 296 hr_ext_state_t s = ext->state; 297 fibril_rwlock_read_unlock(&vol->states_lock); 298 299 if (s != HR_EXT_ONLINE && s != HR_EXT_REBUILD) { 300 return EINVAL; 301 } 302 303 fibril_mutex_lock(&vol->md_lock); 304 305 if (s == HR_EXT_REBUILD) { 306 md->resync_offset = vol->rebuild_blk; 307 md->feature_map = MD_DISK_SYNC; 308 } else { 309 md->resync_offset = 0; 310 md->feature_map = 0; 311 } 312 313 meta_md_encode(md, md_block); 314 errno_t rc = meta_md_write_block(ext->svc_id, md_block); 315 if (rc != EOK && with_state_callback) 316 vol->hr_ops.ext_state_cb(vol, ext_idx, rc); 317 318 fibril_mutex_unlock(&vol->md_lock); 319 320 if (with_state_callback) 321 vol->hr_ops.vol_state_eval(vol); 322 323 free(md_block); 324 325 return EOK; 262 326 } 263 327 … … 353 417 printf("dev_number: %" PRIu32 "\n", md->dev_number); 354 418 355 printf("cnt_corrected_read: %" PRIu32 "\n", md->cnt_corrected_read);356 357 419 printf("device_uuid: "); 358 420 bytefield_print(md->device_uuid, 16); 359 421 printf("\n"); 360 361 printf("devflags: 0x%" PRIx8 "\n", md->devflags);362 422 363 423 printf("events: %" PRIu64 "\n", md->events); … … 367 427 else 368 428 printf("resync_offset: %" PRIu64 "\n", md->resync_offset); 369 370 printf("sb_csum: 0x%" PRIx32 "\n", md->sb_csum);371 429 372 430 printf("max_dev: %" PRIu32 "\n", md->max_dev); … … 387 445 } 388 446 389 #if 0390 447 static void meta_md_encode(void *md_v, void *block) 391 448 { 392 449 HR_DEBUG("%s()", __func__); 393 450 394 (void)md_v; 395 (void)block; 396 } 397 #endif 451 memcpy(block, md_v, meta_md_get_size() * 512); 452 453 struct mdp_superblock_1 *md = block; 454 455 md->magic = host2uint32_t_le(md->magic); 456 md->major_version = host2uint32_t_le(md->major_version); 457 md->feature_map = host2uint32_t_le(md->feature_map); 458 md->level = host2uint32_t_le(md->level); 459 md->layout = host2uint32_t_le(md->layout); 460 md->size = host2uint64_t_le(md->size); 461 md->chunksize = host2uint32_t_le(md->chunksize); 462 md->raid_disks = host2uint32_t_le(md->raid_disks); 463 md->data_offset = host2uint64_t_le(md->data_offset); 464 md->data_size = host2uint64_t_le(md->data_size); 465 md->super_offset = host2uint64_t_le(md->super_offset); 466 md->dev_number = host2uint32_t_le(md->dev_number); 467 md->events = host2uint64_t_le(md->events); 468 md->resync_offset = host2uint64_t_le(md->resync_offset); 469 md->max_dev = host2uint32_t_le(md->max_dev); 470 for (uint32_t d = 0; d < md->max_dev; d++) 471 md->dev_roles[d] = host2uint16_t_le(md->dev_roles[d]); 472 473 md->sb_csum = calc_sb_1_csum(md); 474 } 398 475 399 476 static errno_t meta_md_decode(const void *block, void *md_v) … … 404 481 struct mdp_superblock_1 *md = md_v; 405 482 406 struct mdp_superblock_1 *scratch_md = meta_md_alloc_struct(); 407 if (scratch_md == NULL) 408 return ENOMEM; 409 410 memcpy(scratch_md, block, meta_md_get_size() * 512); 411 412 md->magic = uint32_t_le2host(scratch_md->magic); 483 /* 484 * Do in-place decoding to cpu byte order. 485 * We do it like this because: 486 * 1) we do not know what is after the 256 bytes 487 * of the struct, so we write back what was there 488 * previously, 489 * 2) we do not want to deal unused fields such 490 * as unions and so on. 491 */ 492 memcpy(md, block, meta_md_get_size() * 512); 493 494 md->magic = uint32_t_le2host(md->magic); 413 495 if (md->magic != MD_MAGIC) { 414 496 rc = EINVAL; … … 416 498 } 417 499 418 md->major_version = uint32_t_le2host( scratch_md->major_version);500 md->major_version = uint32_t_le2host(md->major_version); 419 501 if (md->major_version != 1) { 420 502 HR_DEBUG("unsupported metadata version\n"); … … 423 505 } 424 506 425 md->feature_map = uint32_t_le2host(scratch_md->feature_map); 507 md->feature_map = uint32_t_le2host(md->feature_map); 508 /* XXX: do not even support MD_DISK_SYNC here */ 426 509 if (md->feature_map != 0x0) { 427 510 HR_DEBUG("unsupported feature map bits\n"); … … 430 513 } 431 514 432 memcpy(md->set_uuid, scratch_md->set_uuid, 16); 433 434 memcpy(md->set_name, scratch_md->set_name, 32); 435 436 md->ctime = uint64_t_le2host(scratch_md->ctime); 437 438 md->level = uint32_t_le2host(scratch_md->level); 515 md->level = uint32_t_le2host(md->level); 439 516 switch (md->level) { 440 517 case 0: … … 449 526 } 450 527 451 md->layout = uint32_t_le2host( scratch_md->layout);528 md->layout = uint32_t_le2host(md->layout); 452 529 if (md->level == 5) { 453 530 switch (md->layout) { … … 469 546 } 470 547 471 md->size = uint64_t_le2host( scratch_md->size);472 473 md->chunksize = uint32_t_le2host( scratch_md->chunksize);474 475 md->raid_disks = uint32_t_le2host( scratch_md->raid_disks);548 md->size = uint64_t_le2host(md->size); 549 550 md->chunksize = uint32_t_le2host(md->chunksize); 551 552 md->raid_disks = uint32_t_le2host(md->raid_disks); 476 553 if (md->raid_disks > HR_MAX_EXTENTS) { 477 554 rc = EINVAL; … … 479 556 } 480 557 481 md->data_offset = uint64_t_le2host( scratch_md->data_offset);482 483 md->data_size = uint64_t_le2host( scratch_md->data_size);558 md->data_offset = uint64_t_le2host(md->data_offset); 559 560 md->data_size = uint64_t_le2host(md->data_size); 484 561 if (md->data_size != md->size) { 485 562 rc = EINVAL; … … 487 564 } 488 565 489 md->super_offset = uint64_t_le2host( scratch_md->super_offset);566 md->super_offset = uint64_t_le2host(md->super_offset); 490 567 if (md->super_offset != MD_OFFSET) { 491 568 rc = EINVAL; … … 493 570 } 494 571 495 md->dev_number = uint32_t_le2host(scratch_md->dev_number); 496 497 md->cnt_corrected_read = 498 uint32_t_le2host(scratch_md->cnt_corrected_read); 499 500 memcpy(md->device_uuid, scratch_md->device_uuid, 16); 501 502 md->devflags = scratch_md->devflags; 503 504 md->bblog_shift = scratch_md->bblog_shift; 505 506 md->bblog_size = uint16_t_le2host(scratch_md->bblog_size); 507 508 md->bblog_offset = uint32_t_le2host(scratch_md->bblog_offset); 509 510 md->utime = uint64_t_le2host(scratch_md->utime); 511 512 md->events = uint64_t_le2host(scratch_md->events); 513 514 md->resync_offset = uint64_t_le2host(scratch_md->resync_offset); 515 if (md->resync_offset != ~(0ULL)) { 516 rc = EINVAL; 517 goto error; 518 } 519 520 md->sb_csum = uint32_t_le2host(scratch_md->sb_csum); 521 522 md->max_dev = uint32_t_le2host(scratch_md->max_dev); 572 md->dev_number = uint32_t_le2host(md->dev_number); 573 574 md->events = uint64_t_le2host(md->events); 575 576 md->resync_offset = uint64_t_le2host(md->resync_offset); 577 if (md->feature_map == 0 && md->resync_offset != ~(0ULL)) { 578 rc = EINVAL; 579 goto error; 580 } 581 582 md->max_dev = uint32_t_le2host(md->max_dev); 523 583 if (md->max_dev > 256 + 128) { 524 584 rc = EINVAL; … … 527 587 528 588 for (uint32_t d = 0; d < md->max_dev; d++) 529 md->dev_roles[d] = uint16_t_le2host( scratch_md->dev_roles[d]);589 md->dev_roles[d] = uint16_t_le2host(md->dev_roles[d]); 530 590 531 591 error: 532 free(scratch_md);533 534 592 return rc; 535 593 } … … 575 633 } 576 634 577 #if 0578 635 static errno_t meta_md_write_block(service_id_t dev, const void *block) 579 636 { … … 602 659 return rc; 603 660 } 604 #endif605 661 606 662 /** @} -
uspace/srv/bd/hr/metadata/foreign/md/md_p.h
rb81ae12 r7ef5ea2 33 33 34 34 #define MD_MAGIC 0xa92b4efc 35 36 #define MD_DISK_SYNC 2 35 37 36 38 /* … … 130 132 }; 131 133 132 /* from mdadm.h */ 134 /* 135 * mdadm - manage Linux "md" devices aka RAID arrays. 136 * 137 * Copyright (C) 2001-2016 Neil Brown <neilb@suse.com> 138 * 139 * 140 * This program is free software; you can redistribute it and/or modify 141 * it under the terms of the GNU General Public License as published by 142 * the Free Software Foundation; either version 2 of the License, or 143 * (at your option) any later version. 144 * 145 * This program is distributed in the hope that it will be useful, 146 * but WITHOUT ANY WARRANTY; without even the implied warranty of 147 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 148 * GNU General Public License for more details. 149 * 150 * You should have received a copy of the GNU General Public License 151 * along with this program; if not, write to the Free Software 152 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 153 * 154 * Author: Neil Brown 155 * Email: <neilb@suse.de> 156 */ 157 158 /* from mdadm - mdadm.h*/ 133 159 #define ALGORITHM_LEFT_ASYMMETRIC 0 134 160 #define ALGORITHM_RIGHT_ASYMMETRIC 1 135 161 #define ALGORITHM_LEFT_SYMMETRIC 2 162 163 /* from mdadm - super1.c */ 164 static inline unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) 165 { 166 unsigned int disk_csum, csum; 167 unsigned long long newcsum; 168 int size = sizeof(*sb) + uint32_t_le2host(sb->max_dev)*2; 169 unsigned int *isuper = (unsigned int *)sb; 170 171 /* make sure I can count... */ 172 if (offsetof(struct mdp_superblock_1,data_offset) != 128 || 173 offsetof(struct mdp_superblock_1, utime) != 192 || 174 sizeof(struct mdp_superblock_1) != 256) { 175 fprintf(stderr, "WARNING - superblock isn't sized correctly\n"); 176 } 177 178 disk_csum = sb->sb_csum; 179 sb->sb_csum = 0; 180 newcsum = 0; 181 for (; size >= 4; size -= 4) { 182 newcsum += uint32_t_le2host(*isuper); 183 isuper++; 184 } 185 186 if (size == 2) 187 newcsum += uint32_t_le2host(*(unsigned short*) isuper); 188 189 csum = (newcsum & 0xffffffff) + (newcsum >> 32); 190 sb->sb_csum = disk_csum; 191 return host2uint32_t_le(csum); 192 } 136 193 137 194 #endif
Note:
See TracChangeset
for help on using the changeset viewer.