Changeset 0277ec2 in mainline
- Timestamp:
- 2025-04-01T08:51:52Z (6 weeks ago)
- Children:
- 4200735
- Parents:
- a5ec426
- Location:
- uspace/srv/bd/hr
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/hr/hr.c
ra5ec426 r0277ec2 142 142 goto error; 143 143 144 rc = hr_write_meta_to_vol(new_volume); 144 rc = hr_metadata_init(new_volume, new_volume->in_mem_md); 145 if (rc != EOK) 146 goto error; 147 148 rc = hr_metadata_save(new_volume); 145 149 if (rc != EOK) 146 150 goto error; -
uspace/srv/bd/hr/raid1.c
ra5ec426 r0277ec2 540 540 fibril_rwlock_write_unlock(&vol->states_lock); 541 541 542 /* 543 * For now write metadata at the end, because 544 * we don't sync metada accross extents yet. 545 */ 546 hr_write_meta_to_ext(vol, rebuild_idx); 542 rc = hr_metadata_save(vol); 543 547 544 end: 548 545 if (rc != EOK) { -
uspace/srv/bd/hr/raid5.c
ra5ec426 r0277ec2 842 842 843 843 hr_update_ext_status(vol, bad, HR_EXT_ONLINE); 844 /* 845 * For now write metadata at the end, because 846 * we don't sync metada accross extents yet. 847 */ 848 hr_write_meta_to_ext(vol, bad); 844 845 rc = hr_metadata_save(vol); 846 849 847 end: 850 848 (void)hr_raid5_update_vol_status(vol); -
uspace/srv/bd/hr/superblock.c
ra5ec426 r0277ec2 50 50 #include "var.h" 51 51 52 static errno_t read_metadata(service_id_t, hr_metadata_t *); 53 static errno_t hr_fill_meta_from_vol(hr_volume_t *, hr_metadata_t *); 54 55 errno_t hr_write_meta_to_vol(hr_volume_t *vol) 56 { 57 HR_DEBUG("%s()", __func__); 58 59 errno_t rc; 60 size_t i; 61 hr_metadata_t *metadata; 52 errno_t hr_metadata_init(hr_volume_t *vol, hr_metadata_t *md) 53 { 54 HR_DEBUG("%s()", __func__); 55 56 str_cpy(md->magic, HR_MAGIC_SIZE, HR_MAGIC_STR); 57 58 md->version = HR_METADATA_VERSION; 59 vol->metadata_version = md->version; 60 61 md->counter = 0; 62 vol->counter = md->counter; 63 62 64 uuid_t uuid; 63 64 metadata = calloc(1, HR_META_SIZE * vol->bsize);65 if (metadata == NULL)66 return ENOMEM;67 68 rc = hr_fill_meta_from_vol(vol, metadata);69 if (rc != EOK)70 goto error;71 72 65 /* rndgen */ 73 66 fibril_usleep(1000); 74 rc = uuid_generate(&uuid);75 if (rc != EOK) 76 goto error;67 errno_t rc = uuid_generate(&uuid); 68 if (rc != EOK) 69 return rc; 77 70 78 71 /* XXX: for now we just copy byte by byte as "encoding" */ 79 memcpy(m etadata->uuid, &uuid, HR_UUID_LEN);72 memcpy(md->uuid, &uuid, HR_UUID_LEN); 80 73 /* uuid_encode(&uuid, metadata->uuid); */ 81 74 82 for (i = 0; i < vol->extent_no; i++) { 83 metadata->index = host2uint32_t_le(i); 84 85 rc = block_write_direct(vol->extents[i].svc_id, 86 vol->extents[i].blkno - 1, HR_META_SIZE, metadata); 75 md->nblocks = vol->nblocks; 76 md->data_blkno = vol->data_blkno; 77 md->truncated_blkno = vol->truncated_blkno; 78 md->data_offset = vol->data_offset; 79 md->extent_no = vol->extent_no; 80 md->level = vol->level; 81 md->layout = vol->layout; 82 md->strip_size = vol->strip_size; 83 md->bsize = vol->bsize; 84 memcpy(md->devname, vol->devname, HR_DEVNAME_LEN); 85 86 return EOK; 87 } 88 89 errno_t hr_metadata_save(hr_volume_t *vol) 90 { 91 HR_DEBUG("%s()", __func__); 92 93 errno_t rc = EOK; 94 95 void *md_block = calloc(1, vol->bsize); 96 if (md_block == NULL) 97 return ENOMEM; 98 99 for (size_t i = 0; i < vol->extent_no; i++) { 100 hr_extent_t *ext = &vol->extents[i]; 101 102 /* TODO: special case for REBUILD */ 103 if (ext->status != HR_EXT_ONLINE) 104 continue; 105 106 vol->in_mem_md->index = i; 107 hr_encode_metadata_to_block(vol->in_mem_md, md_block); 108 rc = hr_write_metadata_block(ext->svc_id, md_block); 109 /* 110 * XXX: here maybe call vol status event or the state 111 * callback inside, same with read_block... 112 * 113 * also think about using FGE here... maybe a bit more 114 * code, but faster and gratis state callback :-) 115 */ 87 116 if (rc != EOK) 88 117 goto error; 89 90 118 } 91 119 92 memcpy(vol->in_mem_md, metadata, sizeof(hr_metadata_t));93 120 error: 94 free(m etadata);121 free(md_block); 95 122 return rc; 96 123 } 97 124 98 errno_t hr_write_meta_to_ext(hr_volume_t *vol, size_t ext)99 {100 HR_DEBUG("%s()", __func__);101 102 errno_t rc;103 hr_metadata_t *metadata;104 105 /* XXX: use scratchpad */106 metadata = calloc(1, HR_META_SIZE * vol->bsize);107 if (metadata == NULL)108 return ENOMEM;109 110 rc = hr_fill_meta_from_vol(vol, metadata);111 if (rc != EOK)112 goto error;113 114 metadata->index = host2uint32_t_le(ext);115 116 rc = block_write_direct(vol->extents[ext].svc_id,117 vol->extents[ext].blkno - 1, HR_META_SIZE, metadata);118 if (rc != EOK)119 goto error;120 121 error:122 free(metadata);123 return rc;124 }125 126 /*127 * Fill metadata members from128 * specified volume.129 *130 * Does not fill extent index and UUID.131 */132 static errno_t hr_fill_meta_from_vol(hr_volume_t *vol, hr_metadata_t *metadata)133 {134 HR_DEBUG("%s()", __func__);135 136 size_t meta_blkno = HR_META_SIZE;137 138 if (vol->level != HR_LVL_1)139 meta_blkno *= vol->extent_no;140 141 if (vol->nblocks < meta_blkno) {142 HR_ERROR("hr_fill_meta_from_vol(): volume \"%s\" does not "143 " have enough space to store metada, aborting\n",144 vol->devname);145 return EINVAL;146 } else if (vol->nblocks == meta_blkno) {147 HR_ERROR("hr_fill_meta_from_vol(): volume \"%s\" would have "148 "zero data blocks after writing metadata, aborting\n",149 vol->devname);150 return EINVAL;151 }152 153 /* XXX: use scratchpad */154 str_cpy(metadata->magic, HR_MAGIC_SIZE, HR_MAGIC_STR);155 metadata->nblocks = host2uint64_t_le(vol->nblocks);156 metadata->data_blkno = host2uint64_t_le(vol->data_blkno);157 metadata->truncated_blkno = host2uint64_t_le(vol->truncated_blkno);158 metadata->data_offset = host2uint64_t_le(vol->data_offset);159 metadata->counter = host2uint64_t_le(~(0UL)); /* XXX: unused */160 metadata->version = host2uint32_t_le(~(0U)); /* XXX: unused */161 metadata->extent_no = host2uint32_t_le(vol->extent_no);162 /* index filled separately for each extent */163 metadata->level = host2uint32_t_le(vol->level);164 metadata->layout = host2uint32_t_le(vol->layout);165 metadata->strip_size = host2uint32_t_le(vol->strip_size);166 metadata->bsize = host2uint32_t_le(vol->bsize);167 str_cpy(metadata->devname, HR_DEVNAME_LEN, vol->devname);168 169 return EOK;170 }171 172 125 bool hr_valid_md_magic(hr_metadata_t *md) 173 126 { 127 HR_DEBUG("%s()", __func__); 128 174 129 if (str_lcmp(md->magic, HR_MAGIC_STR, HR_MAGIC_SIZE) != 0) 175 130 return false; … … 178 133 } 179 134 180 errno_t hr_ fill_vol_from_meta(hr_volume_t *vol)135 errno_t hr_write_metadata_block(service_id_t dev, const void *block) 181 136 { 182 137 HR_DEBUG("%s()", __func__); 183 138 184 139 errno_t rc; 185 hr_metadata_t *metadata; 186 187 metadata = calloc(1, HR_META_SIZE * vol->bsize); 188 if (metadata == NULL) 189 return ENOMEM; 190 191 service_id_t assembly_svc_id_order[HR_MAX_EXTENTS] = { 0 }; 192 for (size_t i = 0; i < vol->extent_no; i++) 193 assembly_svc_id_order[i] = vol->extents[i].svc_id; 194 140 uint64_t blkno; 141 size_t bsize; 142 143 rc = block_get_bsize(dev, &bsize); 144 if (rc != EOK) 145 return rc; 146 147 if (bsize < sizeof(hr_metadata_t)) 148 return EINVAL; 149 150 rc = block_get_nblocks(dev, &blkno); 151 if (rc != EOK) 152 return rc; 153 154 if (blkno < HR_META_SIZE) 155 return EINVAL; 156 157 rc = block_write_direct(dev, blkno - 1, HR_META_SIZE, block); 195 158 /* 196 * XXX: sanitize metadata, for example if truncated_blkno <= extent.blkno 197 * or bsize == extent.bsize 159 * XXX: here maybe call vol status event or the state callback... 160 * 161 * but need to pass vol pointer 198 162 */ 199 163 200 size_t md_order_indices[HR_MAX_EXTENTS] = { 0 };201 for (size_t i = 0; i < vol->extent_no; i++) {202 if (assembly_svc_id_order[i] == 0) {203 /* set invalid index */204 md_order_indices[i] = vol->extent_no;205 continue;206 }207 rc = read_metadata(assembly_svc_id_order[i], metadata);208 if (rc != EOK)209 goto end;210 if (!hr_valid_md_magic(metadata))211 goto end;212 md_order_indices[i] = uint32_t_le2host(metadata->index);213 }214 215 for (size_t i = 0; i < vol->extent_no; i++) {216 vol->extents[i].svc_id = 0;217 vol->extents[i].status = HR_EXT_MISSING;218 }219 220 /* sort */221 for (size_t i = 0; i < vol->extent_no; i++) {222 for (size_t j = 0; j < vol->extent_no; j++) {223 if (i == md_order_indices[j]) {224 vol->extents[i].svc_id =225 assembly_svc_id_order[j];226 vol->extents[i].status = HR_EXT_ONLINE;227 }228 }229 }230 231 /*232 * still assume metadata are in sync across extents233 */234 235 if (vol->extent_no != uint32_t_le2host(metadata->extent_no)) {236 HR_ERROR("number of divices in array differ: specified %zu, "237 "metadata states %u",238 vol->extent_no, uint32_t_le2host(metadata->extent_no));239 rc = EINVAL;240 goto end;241 }242 243 /* TODO: handle version */244 vol->level = uint32_t_le2host(metadata->level);245 vol->layout = (uint8_t)uint32_t_le2host(metadata->layout);246 vol->strip_size = uint32_t_le2host(metadata->strip_size);247 vol->nblocks = uint64_t_le2host(metadata->nblocks);248 vol->data_blkno = uint64_t_le2host(metadata->data_blkno);249 vol->data_offset = uint64_t_le2host(metadata->data_offset);250 vol->bsize = uint32_t_le2host(metadata->bsize);251 vol->counter = uint64_t_le2host(0x00); /* unused */252 253 if (str_cmp(metadata->devname, vol->devname) != 0) {254 HR_WARN("devname on metadata (%s) and config (%s) differ, "255 "using config", metadata->devname, vol->devname);256 }257 end:258 free(metadata);259 164 return rc; 260 165 } 261 166 262 /* XXX: rewrite with read_metadata_block() */263 static errno_t read_metadata(service_id_t dev, hr_metadata_t *metadata)264 {265 errno_t rc;266 uint64_t nblocks;267 268 rc = block_get_nblocks(dev, &nblocks);269 if (rc != EOK)270 return rc;271 272 if (nblocks < HR_META_SIZE)273 return EINVAL;274 275 rc = block_read_direct(dev, nblocks - 1, HR_META_SIZE, metadata);276 if (rc != EOK)277 return rc;278 279 return EOK;280 }281 282 167 errno_t hr_get_metadata_block(service_id_t dev, void **rblock) 283 168 { 284 169 HR_DEBUG("%s()", __func__); 170 285 171 errno_t rc; 286 172 uint64_t blkno; … … 307 193 308 194 rc = block_read_direct(dev, blkno - 1, HR_META_SIZE, block); 195 /* 196 * XXX: here maybe call vol status event or the state callback... 197 * 198 * but need to pass vol pointer 199 */ 309 200 if (rc != EOK) { 310 201 free(block); … … 321 212 } 322 213 323 void hr_decode_metadata_from_block(void *block, hr_metadata_t *metadata) 324 { 214 void hr_encode_metadata_to_block(hr_metadata_t *metadata, void *block) 215 { 216 HR_DEBUG("%s()", __func__); 217 218 /* 219 * Use scratch metadata for easier encoding without the need 220 * for manualy specifying offsets. 221 */ 222 hr_metadata_t scratch_md; 223 224 memcpy(scratch_md.magic, metadata->magic, HR_MAGIC_SIZE); 225 memcpy(scratch_md.uuid, metadata->uuid, HR_UUID_LEN); 226 /* uuid_decode((uint8_t *)scratch_md.uuid, (uuid_t *)metadata->uuid); */ 227 228 scratch_md.nblocks = host2uint64_t_le(metadata->nblocks); 229 scratch_md.data_blkno = host2uint64_t_le(metadata->data_blkno); 230 scratch_md.truncated_blkno = host2uint64_t_le( 231 metadata->truncated_blkno); 232 scratch_md.data_offset = host2uint64_t_le(metadata->data_offset); 233 scratch_md.counter = host2uint64_t_le(metadata->counter); 234 scratch_md.version = host2uint32_t_le(metadata->version); 235 scratch_md.extent_no = host2uint32_t_le(metadata->extent_no); 236 scratch_md.index = host2uint32_t_le(metadata->index); 237 scratch_md.level = host2uint32_t_le(metadata->level); 238 scratch_md.layout = host2uint32_t_le(metadata->layout); 239 scratch_md.strip_size = host2uint32_t_le(metadata->strip_size); 240 scratch_md.bsize = host2uint32_t_le(metadata->bsize); 241 memcpy(scratch_md.devname, metadata->devname, HR_DEVNAME_LEN); 242 243 memcpy(block, &scratch_md, sizeof(hr_metadata_t)); 244 } 245 246 void hr_decode_metadata_from_block(const void *block, hr_metadata_t *metadata) 247 { 248 HR_DEBUG("%s()", __func__); 249 325 250 /* 326 251 * Use scratch metadata for easier decoding without the need … … 352 277 void hr_metadata_dump(hr_metadata_t *metadata) 353 278 { 279 HR_DEBUG("%s()", __func__); 280 354 281 printf("\tmagic: %s\n", metadata->magic); 355 282 printf("\tUUID: "); -
uspace/srv/bd/hr/superblock.h
ra5ec426 r0277ec2 48 48 #define HR_MAGIC_SIZE 16 49 49 #define HR_UUID_LEN 16 50 /* #define HR_METADATA_VERSION 0 */ 50 #define HR_METADATA_VERSION 1 51 51 52 52 typedef struct hr_metadata hr_metadata_t; … … 79 79 } __attribute__((packed)); 80 80 81 extern errno_t hr_ write_meta_to_vol(hr_volume_t *);82 extern errno_t hr_ write_meta_to_ext(hr_volume_t *, size_t);83 extern errno_t hr_ fill_vol_from_meta(hr_volume_t*);81 extern errno_t hr_metadata_init(hr_volume_t *, hr_metadata_t *); 82 extern errno_t hr_metadata_save(hr_volume_t *); 83 extern errno_t hr_write_metadata_block(service_id_t, const void *); 84 84 extern errno_t hr_get_metadata_block(service_id_t, void **); 85 extern void hr_decode_metadata_from_block(void *, hr_metadata_t *); 85 extern void hr_encode_metadata_to_block(hr_metadata_t *, void *); 86 extern void hr_decode_metadata_from_block(const void *, hr_metadata_t *); 86 87 extern void hr_metadata_dump(hr_metadata_t *); 87 88 extern bool hr_valid_md_magic(hr_metadata_t *); -
uspace/srv/bd/hr/util.c
ra5ec426 r0277ec2 773 773 774 774 list_foreach(*list, link, struct svc_id_linked, iter) { 775 hr_metadata_dump(iter->md);775 /* hr_metadata_dump(iter->md); */ 776 776 if (iter->md->counter >= max_counter_val) { 777 777 max_counter_val = iter->md->counter;
Note:
See TracChangeset
for help on using the changeset viewer.