Changeset 50603405 in mainline
- Timestamp:
- 2025-04-20T10:09:26Z (4 weeks ago)
- Children:
- 14394141
- Parents:
- 6f41c21f
- git-author:
- Miroslav Cimerman <mc@…> (2025-04-20 09:56:29)
- git-committer:
- Miroslav Cimerman <mc@…> (2025-04-20 10:09:26)
- Location:
- uspace/srv/bd/hr
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/hr/hr.c
r6f41c21f r50603405 79 79 size_t i, size; 80 80 hr_config_t *cfg; 81 hr_volume_t * new_volume;81 hr_volume_t *vol; 82 82 ipc_call_t call; 83 83 … … 127 127 } 128 128 129 rc = hr_create_vol_struct(&new_volume, cfg->level, cfg->devname); 129 rc = hr_create_vol_struct(&vol, cfg->level, cfg->devname, 130 HR_METADATA_NATIVE); 130 131 if (rc != EOK) { 131 132 free(cfg); … … 134 135 } 135 136 136 rc = hr_init_extents_from_cfg( new_volume, cfg);137 if (rc != EOK) 138 goto error; 139 140 new_volume->hr_ops.init(new_volume);141 if (rc != EOK) 142 goto error; 143 144 rc = hr_metadata_init(new_volume, new_volume->in_mem_md);145 if (rc != EOK) 146 goto error; 147 148 rc = new_volume->hr_ops.create(new_volume);149 if (rc != EOK) 150 goto error; 151 152 rc = hr_metadata_save(new_volume, WITH_STATE_CALLBACK);153 if (rc != EOK) 154 goto error; 155 156 rc = hr_register_volume( new_volume);137 rc = hr_init_extents_from_cfg(vol, cfg); 138 if (rc != EOK) 139 goto error; 140 141 vol->hr_ops.init(vol); 142 if (rc != EOK) 143 goto error; 144 145 rc = vol->meta_ops->init_vol2meta(vol, vol->in_mem_md); 146 if (rc != EOK) 147 goto error; 148 149 rc = vol->hr_ops.create(vol); 150 if (rc != EOK) 151 goto error; 152 153 rc = vol->meta_ops->save(vol, WITH_STATE_CALLBACK); 154 if (rc != EOK) 155 goto error; 156 157 rc = hr_register_volume(vol); 157 158 if (rc != EOK) 158 159 goto error; 159 160 160 161 fibril_rwlock_write_lock(&hr_volumes_lock); 161 list_append(& new_volume->lvolumes, &hr_volumes);162 list_append(&vol->lvolumes, &hr_volumes); 162 163 fibril_rwlock_write_unlock(&hr_volumes_lock); 163 164 164 HR_DEBUG("created volume \"%s\" (%" PRIun ")\n", new_volume->devname,165 new_volume->svc_id);165 HR_DEBUG("created volume \"%s\" (%" PRIun ")\n", vol->devname, 166 vol->svc_id); 166 167 167 168 free(cfg); … … 170 171 error: 171 172 free(cfg); 172 hr_destroy_vol_struct( new_volume);173 hr_destroy_vol_struct(vol); 173 174 async_answer_0(icall, rc); 174 175 } -
uspace/srv/bd/hr/meson.build
r6f41c21f r50603405 32 32 'hr.c', 33 33 'io.c', 34 'metadata/native.c', 34 35 'raid0.c', 35 36 'raid1.c', -
uspace/srv/bd/hr/raid0.c
r6f41c21f r50603405 124 124 vol->truncated_blkno = truncated_blkno; 125 125 vol->nblocks = total_blkno; 126 vol->data_offset = HR_DATA_OFF;126 vol->data_offset = vol->meta_ops->get_data_offset(); 127 127 128 128 vol->data_blkno = total_blkno; 129 vol->data_blkno -= HR_META_SIZE * vol->extent_no; /* count md blocks */ 129 /* count md blocks */ 130 vol->data_blkno -= vol->meta_ops->get_size() * vol->extent_no; 130 131 131 132 vol->strip_size = HR_STRIP_SIZE; … … 200 201 fibril_mutex_lock(&vol->md_lock); 201 202 202 /* XXX: will be wrapped in md specific fcn ptrs */203 vol->in_mem_md->counter++;203 vol->meta_ops->inc_counter(vol->in_mem_md); 204 /* TODO: save right away */ 204 205 205 206 fibril_mutex_unlock(&vol->md_lock); -
uspace/srv/bd/hr/raid1.c
r6f41c21f r50603405 34 34 */ 35 35 36 #include <abi/ipc/ipc.h> 36 37 #include <bd_srv.h> 37 38 #include <block.h> … … 137 138 vol->truncated_blkno = truncated_blkno; 138 139 vol->nblocks = truncated_blkno; 139 vol->data_offset = HR_DATA_OFF;140 vol->data_blkno = truncated_blkno - HR_META_SIZE;140 vol->data_offset = vol->meta_ops->get_data_offset(); 141 vol->data_blkno = truncated_blkno - vol->meta_ops->get_size(); 141 142 vol->strip_size = 0; 142 143 … … 227 228 fibril_mutex_lock(&vol->md_lock); 228 229 229 /* XXX: will be wrapped in md specific fcn ptrs */230 vol->in_mem_md->counter++;230 vol->meta_ops->inc_counter(vol->in_mem_md); 231 /* XXX: save right away */ 231 232 232 233 fibril_mutex_unlock(&vol->md_lock); … … 550 551 fibril_rwlock_write_unlock(&vol->states_lock); 551 552 552 rc = hr_metadata_save(vol, WITH_STATE_CALLBACK);553 rc = vol->meta_ops->save(vol, WITH_STATE_CALLBACK); 553 554 554 555 end: -
uspace/srv/bd/hr/raid5.c
r6f41c21f r50603405 139 139 vol->truncated_blkno = truncated_blkno; 140 140 vol->nblocks = total_blkno; 141 vol->data_offset = HR_DATA_OFF;141 vol->data_offset = vol->meta_ops->get_data_offset(); 142 142 143 143 vol->data_blkno = total_blkno; 144 vol->data_blkno -= HR_META_SIZE * vol->extent_no; /* count md blocks */ 144 /* count md blocks */ 145 vol->data_blkno -= vol->meta_ops->get_size() * vol->extent_no; 145 146 vol->data_blkno -= truncated_blkno; /* count parity */ 146 147 … … 845 846 hr_update_ext_status(vol, bad, HR_EXT_ONLINE); 846 847 847 rc = hr_metadata_save(vol, WITH_STATE_CALLBACK);848 rc = vol->meta_ops->save(vol, WITH_STATE_CALLBACK); 848 849 849 850 end: -
uspace/srv/bd/hr/superblock.c
r6f41c21f r50603405 45 45 #include <stdio.h> 46 46 #include <str.h> 47 #include <types/uuid.h>48 47 48 #include "metadata/native.h" 49 49 #include "superblock.h" 50 50 #include "util.h" 51 51 #include "var.h" 52 52 53 errno_t hr_metadata_init(hr_volume_t *vol, hr_metadata_t *md) 53 extern hr_superblock_ops_t metadata_native_ops; 54 55 static hr_superblock_ops_t *hr_superblock_ops_all[] = { 56 [HR_METADATA_NATIVE] = &metadata_native_ops 57 }; 58 59 hr_superblock_ops_t *get_type_ops(metadata_type_t type) 54 60 { 55 HR_DEBUG("%s()", __func__);61 assert(type >= HR_METADATA_NATIVE && type < HR_METADATA_LAST_DUMMY); 56 62 57 str_cpy(md->magic, HR_MAGIC_SIZE, HR_MAGIC_STR); 58 59 md->version = HR_METADATA_VERSION; 60 vol->metadata_version = md->version; 61 62 md->counter = 0; 63 64 uuid_t uuid; 65 /* rndgen */ 66 fibril_usleep(1000); 67 errno_t rc = uuid_generate(&uuid); 68 if (rc != EOK) 69 return rc; 70 71 /* XXX: for now we just copy byte by byte as "encoding" */ 72 memcpy(md->uuid, &uuid, HR_UUID_LEN); 73 /* uuid_encode(&uuid, metadata->uuid); */ 74 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; 63 return hr_superblock_ops_all[type]; 87 64 } 88 65 89 /* 90 * XXX: finish this fcn documentation 91 * 92 * Returns ENOMEM else EOK 93 */ 94 errno_t hr_metadata_save(hr_volume_t *vol, bool with_state_callback) 95 { 96 HR_DEBUG("%s()", __func__); 97 98 errno_t rc = EOK; 99 100 void *md_block = calloc(1, vol->bsize); 101 if (md_block == NULL) 102 return ENOMEM; 103 104 fibril_rwlock_read_lock(&vol->extents_lock); 105 106 fibril_mutex_lock(&vol->md_lock); 107 108 for (size_t i = 0; i < vol->extent_no; i++) { 109 hr_extent_t *ext = &vol->extents[i]; 110 111 fibril_rwlock_read_lock(&vol->states_lock); 112 113 /* TODO: special case for REBUILD */ 114 if (ext->status != HR_EXT_ONLINE) 115 continue; 116 117 fibril_rwlock_read_unlock(&vol->states_lock); 118 119 vol->in_mem_md->index = i; 120 hr_encode_metadata_to_block(vol->in_mem_md, md_block); 121 rc = hr_write_metadata_block(ext->svc_id, md_block); 122 if (with_state_callback && rc != EOK) 123 vol->state_callback(vol, i, rc); 124 } 125 126 fibril_mutex_unlock(&vol->md_lock); 127 128 fibril_rwlock_read_unlock(&vol->extents_lock); 129 130 if (with_state_callback) 131 vol->hr_ops.status_event(vol); 132 133 free(md_block); 134 return EOK; 135 } 136 137 bool hr_valid_md_magic(const hr_metadata_t *md) 138 { 139 HR_DEBUG("%s()", __func__); 140 141 if (str_lcmp(md->magic, HR_MAGIC_STR, HR_MAGIC_SIZE) != 0) 142 return false; 143 144 return true; 145 } 146 147 errno_t hr_write_metadata_block(service_id_t dev, const void *block) 66 errno_t find_metadata(service_id_t svc_id, void **rmetadata, 67 metadata_type_t *rtype) 148 68 { 149 69 HR_DEBUG("%s()", __func__); 150 70 151 71 errno_t rc; 152 uint64_t blkno; 153 size_t bsize; 72 hr_superblock_ops_t *meta_ops; 73 void *meta_block; 74 void *metadata_struct; 154 75 155 rc = block_get_bsize(dev, &bsize); 156 if (rc != EOK) 157 return rc; 158 159 if (bsize < sizeof(hr_metadata_t)) 76 if (rmetadata == NULL) 77 return EINVAL; 78 if (rtype == NULL) 160 79 return EINVAL; 161 80 162 rc = block_get_nblocks(dev, &blkno);163 if (rc != EOK)164 return rc;81 volatile metadata_type_t type = HR_METADATA_NATIVE; 82 for (; type < HR_METADATA_LAST_DUMMY; type++) { 83 meta_ops = hr_superblock_ops_all[type]; 165 84 166 if (blkno < HR_META_SIZE) 167 return EINVAL; 85 metadata_struct = meta_ops->alloc_struct(); 86 if (metadata_struct == NULL) 87 return ENOMEM; 168 88 169 rc = block_write_direct(dev, blkno - 1, HR_META_SIZE, block); 89 rc = meta_ops->get_block(svc_id, &meta_block); 90 if (rc == ENOMEM) 91 return ENOMEM; 92 if (rc != EOK) 93 continue; 170 94 171 return rc; 172 } 95 meta_ops->decode(meta_block, metadata_struct); 173 96 174 errno_t hr_get_metadata_block(service_id_t dev, void **rblock) 175 { 176 HR_DEBUG("%s()", __func__); 97 free(meta_block); 177 98 178 errno_t rc;179 uint64_t blkno;180 size_t bsize;181 void *block;99 if (!meta_ops->has_valid_magic(metadata_struct)) { 100 free(metadata_struct); 101 continue; 102 } 182 103 183 rc = block_get_bsize(dev, &bsize); 184 if (rc != EOK) 185 return rc; 186 187 if (bsize < sizeof(hr_metadata_t)) 188 return EINVAL; 189 190 rc = block_get_nblocks(dev, &blkno); 191 if (rc != EOK) 192 return rc; 193 194 if (blkno < HR_META_SIZE) 195 return EINVAL; 196 197 block = malloc(bsize); 198 if (block == NULL) 199 return ENOMEM; 200 201 rc = block_read_direct(dev, blkno - 1, HR_META_SIZE, block); 202 /* 203 * XXX: here maybe call vol status event or the state callback... 204 * 205 * but need to pass vol pointer 206 */ 207 if (rc != EOK) { 208 free(block); 209 return rc; 104 *rmetadata = metadata_struct; 105 *rtype = type; 106 return EOK; 210 107 } 211 108 212 if (rblock == NULL) { 213 free(block); 214 return EINVAL; 215 } 216 217 *rblock = block; 218 return EOK; 219 } 220 221 void hr_encode_metadata_to_block(const hr_metadata_t *metadata, void *block) 222 { 223 HR_DEBUG("%s()", __func__); 224 225 /* 226 * Use scratch metadata for easier encoding without the need 227 * for manualy specifying offsets. 228 */ 229 hr_metadata_t scratch_md; 230 231 memcpy(scratch_md.magic, metadata->magic, HR_MAGIC_SIZE); 232 memcpy(scratch_md.uuid, metadata->uuid, HR_UUID_LEN); 233 /* uuid_decode((uint8_t *)scratch_md.uuid, (uuid_t *)metadata->uuid); */ 234 235 scratch_md.nblocks = host2uint64_t_le(metadata->nblocks); 236 scratch_md.data_blkno = host2uint64_t_le(metadata->data_blkno); 237 scratch_md.truncated_blkno = host2uint64_t_le( 238 metadata->truncated_blkno); 239 scratch_md.data_offset = host2uint64_t_le(metadata->data_offset); 240 scratch_md.counter = host2uint64_t_le(metadata->counter); 241 scratch_md.version = host2uint32_t_le(metadata->version); 242 scratch_md.extent_no = host2uint32_t_le(metadata->extent_no); 243 scratch_md.index = host2uint32_t_le(metadata->index); 244 scratch_md.level = host2uint32_t_le(metadata->level); 245 scratch_md.layout = host2uint32_t_le(metadata->layout); 246 scratch_md.strip_size = host2uint32_t_le(metadata->strip_size); 247 scratch_md.bsize = host2uint32_t_le(metadata->bsize); 248 memcpy(scratch_md.devname, metadata->devname, HR_DEVNAME_LEN); 249 250 memcpy(block, &scratch_md, sizeof(hr_metadata_t)); 251 } 252 253 void hr_decode_metadata_from_block(const void *block, hr_metadata_t *metadata) 254 { 255 HR_DEBUG("%s()", __func__); 256 257 /* 258 * Use scratch metadata for easier decoding without the need 259 * for manualy specifying offsets. 260 */ 261 hr_metadata_t scratch_md; 262 memcpy(&scratch_md, block, sizeof(hr_metadata_t)); 263 264 memcpy(metadata->magic, scratch_md.magic, HR_MAGIC_SIZE); 265 memcpy(metadata->uuid, scratch_md.uuid, HR_UUID_LEN); 266 /* uuid_decode((uint8_t *)scratch_md.uuid, (uuid_t *)metadata->uuid); */ 267 268 metadata->nblocks = uint64_t_le2host(scratch_md.nblocks); 269 metadata->data_blkno = uint64_t_le2host(scratch_md.data_blkno); 270 metadata->truncated_blkno = uint64_t_le2host( 271 scratch_md.truncated_blkno); 272 metadata->data_offset = uint64_t_le2host(scratch_md.data_offset); 273 metadata->counter = uint64_t_le2host(scratch_md.counter); 274 metadata->version = uint32_t_le2host(scratch_md.version); 275 metadata->extent_no = uint32_t_le2host(scratch_md.extent_no); 276 metadata->index = uint32_t_le2host(scratch_md.index); 277 metadata->level = uint32_t_le2host(scratch_md.level); 278 metadata->layout = uint32_t_le2host(scratch_md.layout); 279 metadata->strip_size = uint32_t_le2host(scratch_md.strip_size); 280 metadata->bsize = uint32_t_le2host(scratch_md.bsize); 281 memcpy(metadata->devname, scratch_md.devname, HR_DEVNAME_LEN); 282 } 283 284 void hr_metadata_dump(const hr_metadata_t *metadata) 285 { 286 HR_DEBUG("%s()", __func__); 287 288 printf("\tmagic: %s\n", metadata->magic); 289 printf("\tUUID: "); 290 for (size_t i = 0; i < HR_UUID_LEN; ++i) { 291 printf("%.2X", metadata->uuid[i]); 292 if (i + 1 < HR_UUID_LEN) 293 printf(" "); 294 } 295 printf("\n"); 296 printf("\tnblocks: %" PRIu64 "\n", metadata->nblocks); 297 printf("\tdata_blkno: %" PRIu64 "\n", metadata->data_blkno); 298 printf("\ttruncated_blkno: %" PRIu64 "\n", metadata->truncated_blkno); 299 printf("\tdata_offset: %" PRIu64 "\n", metadata->data_offset); 300 printf("\tcounter: %" PRIu64 "\n", metadata->counter); 301 printf("\tversion: %" PRIu32 "\n", metadata->version); 302 printf("\textent_no: %" PRIu32 "\n", metadata->extent_no); 303 printf("\tindex: %" PRIu32 "\n", metadata->index); 304 printf("\tlevel: %" PRIu32 "\n", metadata->level); 305 printf("\tlayout: %" PRIu32 "\n", metadata->layout); 306 printf("\tstrip_size: %" PRIu32 "\n", metadata->strip_size); 307 printf("\tbsize: %" PRIu32 "\n", metadata->bsize); 308 printf("\tdevname: %s\n", metadata->devname); 109 return ENOFS; 309 110 } 310 111 -
uspace/srv/bd/hr/superblock.h
r6f41c21f r50603405 39 39 #include "var.h" 40 40 41 /*42 * Metadata is stored on the last block of an extent.43 */44 #define HR_META_SIZE 1 /* in blocks */45 #define HR_DATA_OFF 046 47 #define HR_MAGIC_STR "HelenRAID"48 #define HR_MAGIC_SIZE 1649 #define HR_UUID_LEN 1650 #define HR_METADATA_VERSION 151 52 typedef struct hr_metadata hr_metadata_t;53 41 typedef struct hr_volume hr_volume_t; 54 42 55 struct hr_metadata { 56 char magic[HR_MAGIC_SIZE]; 43 typedef enum { 44 HR_METADATA_NATIVE = 0, 45 HR_METADATA_LAST_DUMMY = 1 46 } metadata_type_t; 57 47 58 uint8_t uuid[HR_UUID_LEN]; 48 #define HR_METADATA_HOTSPARE_SUPPORT 0x01 59 49 60 /* TODO: change to blkno */ 61 uint64_t nblocks; /* all blocks */ 62 uint64_t data_blkno; /* usable blocks */ 50 typedef struct hr_superblock_ops { 51 void *(*alloc_struct)(void); 52 errno_t (*init_vol2meta)(const hr_volume_t *, void *); 53 errno_t (*init_meta2vol)(const list_t *, hr_volume_t *); 54 void (*encode)(const void *, void *); 55 void (*decode)(const void *, void *); 56 errno_t (*get_block)(service_id_t, void **); 57 errno_t (*write_block)(service_id_t, const void *); 58 bool (*has_valid_magic)(const void *); 59 bool (*compare_uuids)(const void *, const void *); 60 void (*inc_counter)(void *); 61 errno_t (*save)(hr_volume_t *, bool); 62 const char *(*get_devname)(const void *); 63 hr_level_t (*get_level)(const void *); 64 uint64_t (*get_data_offset)(void); 65 size_t (*get_size)(void); 66 uint8_t (*get_flags)(void); 67 metadata_type_t (*get_type)(void); 68 void (*dump)(const void *); 69 } hr_superblock_ops_t; 63 70 64 uint64_t truncated_blkno; /* usable blocks */ 65 uint64_t data_offset; 66 67 uint64_t counter; /* XXX: yet unused */ 68 uint32_t version; /* XXX: yet unused */ 69 uint32_t extent_no; 70 71 uint32_t index; /* index of extent in volume */ 72 uint32_t level; 73 uint32_t layout; 74 uint32_t strip_size; 75 76 uint32_t bsize; 77 78 char devname[HR_DEVNAME_LEN]; 79 } __attribute__((packed)); 80 81 extern errno_t hr_metadata_init(hr_volume_t *, hr_metadata_t *); 82 extern errno_t hr_metadata_save(hr_volume_t *, bool); 83 extern errno_t hr_write_metadata_block(service_id_t, const void *); 84 extern errno_t hr_get_metadata_block(service_id_t, void **); 85 extern void hr_encode_metadata_to_block(const hr_metadata_t *, void *); 86 extern void hr_decode_metadata_from_block(const void *, hr_metadata_t *); 87 extern void hr_metadata_dump(const hr_metadata_t *); 88 extern bool hr_valid_md_magic(const hr_metadata_t *); 71 hr_superblock_ops_t *get_type_ops(metadata_type_t); 72 extern errno_t find_metadata(service_id_t, void **, metadata_type_t *); 89 73 90 74 #endif -
uspace/srv/bd/hr/util.c
r6f41c21f r50603405 55 55 #include "var.h" 56 56 57 struct svc_id_linked;58 59 57 static bool hr_range_lock_overlap(hr_range_lock_t *, hr_range_lock_t *); 60 58 static errno_t hr_add_svc_linked_to_list(list_t *, service_id_t, bool, 61 hr_metadata_t*);62 static void free_ svc_id_linked(struct svc_id_linked*);59 void *); 60 static void free_dev_list_member(struct dev_list_member *); 63 61 static void free_svc_id_list(list_t *); 64 62 static errno_t hr_fill_disk_part_svcs_list(list_t *); … … 66 64 static void block_fini_dev_list(list_t *); 67 65 static errno_t hr_util_get_matching_md_svcs_list(list_t *, list_t *, 68 service_id_t, hr_metadata_t*);69 static errno_t hr_util_assemble_from_matching_list(list_t * );66 service_id_t, metadata_type_t, void *); 67 static errno_t hr_util_assemble_from_matching_list(list_t *, metadata_type_t); 70 68 static errno_t hr_fill_svcs_list_from_cfg(hr_config_t *, list_t *); 71 69 72 #define HR_RL_LIST_LOCK(vol) (fibril_mutex_lock(& vol->range_lock_list_lock))70 #define HR_RL_LIST_LOCK(vol) (fibril_mutex_lock(&(vol)->range_lock_list_lock)) 73 71 #define HR_RL_LIST_UNLOCK(vol) \ 74 (fibril_mutex_unlock(&vol->range_lock_list_lock)) 75 76 struct svc_id_linked { 77 link_t link; 78 service_id_t svc_id; 79 hr_metadata_t *md; 80 bool inited; 81 bool md_present; 82 }; 72 (fibril_mutex_unlock(&(vol)->range_lock_list_lock)) 83 73 84 74 extern loc_srv_t *hr_srv; … … 87 77 88 78 errno_t hr_create_vol_struct(hr_volume_t **rvol, hr_level_t level, 89 const char *devname )79 const char *devname, metadata_type_t metadata_type) 90 80 { 91 81 errno_t rc; … … 98 88 vol->level = level; 99 89 90 vol->meta_ops = get_type_ops(metadata_type); 91 100 92 switch (level) { 101 case HR_LVL_1:102 vol->hr_ops.create = hr_raid1_create;103 vol->hr_ops.init = hr_raid1_init;104 vol->hr_ops.status_event = hr_raid1_status_event;105 vol->hr_ops.add_hotspare = hr_raid1_add_hotspare;106 break;107 93 case HR_LVL_0: 108 94 vol->hr_ops.create = hr_raid0_create; … … 110 96 vol->hr_ops.status_event = hr_raid0_status_event; 111 97 break; 98 case HR_LVL_1: 99 vol->hr_ops.create = hr_raid1_create; 100 vol->hr_ops.init = hr_raid1_init; 101 vol->hr_ops.status_event = hr_raid1_status_event; 102 if (vol->meta_ops->get_flags() & HR_METADATA_HOTSPARE_SUPPORT) 103 vol->hr_ops.add_hotspare = hr_raid1_add_hotspare; 104 break; 112 105 case HR_LVL_4: 113 106 vol->hr_ops.create = hr_raid5_create; 114 107 vol->hr_ops.init = hr_raid5_init; 115 108 vol->hr_ops.status_event = hr_raid5_status_event; 116 vol->hr_ops.add_hotspare = hr_raid5_add_hotspare; 109 if (vol->meta_ops->get_flags() & HR_METADATA_HOTSPARE_SUPPORT) 110 vol->hr_ops.add_hotspare = hr_raid5_add_hotspare; 117 111 break; 118 112 case HR_LVL_5: … … 120 114 vol->hr_ops.init = hr_raid5_init; 121 115 vol->hr_ops.status_event = hr_raid5_status_event; 122 vol->hr_ops.add_hotspare = hr_raid5_add_hotspare; 116 if (vol->meta_ops->get_flags() & HR_METADATA_HOTSPARE_SUPPORT) 117 vol->hr_ops.add_hotspare = hr_raid5_add_hotspare; 123 118 break; 124 119 default: … … 134 129 } 135 130 136 vol->in_mem_md = calloc(1, sizeof(hr_metadata_t));131 vol->in_mem_md = vol->meta_ops->alloc_struct(); 137 132 if (vol->in_mem_md == NULL) { 138 133 free(vol->fge); … … 221 216 fibril_rwlock_write_unlock(&hr_volumes_lock); 222 217 223 hr_metadata_save(vol, NO_STATE_CALLBACK);218 vol->meta_ops->save(vol, NO_STATE_CALLBACK); 224 219 225 220 hr_destroy_vol_struct(vol); … … 584 579 585 580 static errno_t hr_add_svc_linked_to_list(list_t *list, service_id_t svc_id, 586 bool inited, hr_metadata_t *md) 587 { 581 bool inited, void *md) 582 { 583 HR_DEBUG("%s()", __func__); 584 588 585 errno_t rc = EOK; 589 struct svc_id_linked *to_add; 590 591 to_add = malloc(sizeof(struct svc_id_linked)); 586 struct dev_list_member *to_add; 587 588 if (list == NULL) 589 return EINVAL; 590 591 to_add = malloc(sizeof(struct dev_list_member)); 592 592 if (to_add == NULL) { 593 593 rc = ENOMEM; 594 594 goto error; 595 595 } 596 596 597 to_add->svc_id = svc_id; 597 598 to_add->inited = inited; 598 599 599 600 if (md != NULL) { 600 to_add->md = malloc(sizeof(hr_metadata_t)); 601 if (to_add->md == NULL) { 602 rc = ENOMEM; 603 goto error; 604 } 601 to_add->md = md; 605 602 to_add->md_present = true; 606 memcpy(to_add->md, md, sizeof(*md));607 603 } else { 608 604 to_add->md_present = false; … … 615 611 } 616 612 617 static void free_svc_id_linked(struct svc_id_linked *p) 618 { 613 static void free_dev_list_member(struct dev_list_member *p) 614 { 615 HR_DEBUG("%s()", __func__); 616 619 617 if (p->md_present) 620 618 free(p->md); … … 624 622 static void free_svc_id_list(list_t *list) 625 623 { 626 struct svc_id_linked *dev_id; 624 HR_DEBUG("%s()", __func__); 625 626 struct dev_list_member *dev_id; 627 627 while (!list_empty(list)) { 628 dev_id = list_pop(list, struct svc_id_linked, link);629 free_ svc_id_linked(dev_id);628 dev_id = list_pop(list, struct dev_list_member, link); 629 free_dev_list_member(dev_id); 630 630 } 631 631 } … … 633 633 static errno_t hr_fill_disk_part_svcs_list(list_t *list) 634 634 { 635 HR_DEBUG("%s()", __func__); 636 635 637 errno_t rc; 636 638 size_t disk_count; … … 653 655 654 656 if (disk_info.ltype == lt_none) { 655 rc = hr_add_svc_linked_to_list(list, disk_svcs[i], false, NULL); 657 rc = hr_add_svc_linked_to_list(list, disk_svcs[i], 658 false, NULL); 656 659 if (rc != EOK) 657 660 goto error; … … 659 662 size_t part_count; 660 663 service_id_t *part_ids = NULL; 661 rc = vbd_label_get_parts(vbd, disk_svcs[i], &part_ids, &part_count); 664 rc = vbd_label_get_parts(vbd, disk_svcs[i], &part_ids, 665 &part_count); 662 666 if (rc != EOK) 663 667 goto error; … … 665 669 for (size_t j = 0; j < part_count; j++) { 666 670 vbd_part_info_t part_info; 667 rc = vbd_part_get_info(vbd, part_ids[j], &part_info); 671 rc = vbd_part_get_info(vbd, part_ids[j], 672 &part_info); 668 673 if (rc != EOK) { 669 674 free(part_ids); … … 697 702 static errno_t block_init_dev_list(list_t *list) 698 703 { 704 HR_DEBUG("%s()", __func__); 705 699 706 list_foreach_safe(*list, cur_link, next_link) { 700 struct svc_id_linked *iter; 701 iter = list_get_instance(cur_link, struct svc_id_linked, link); 707 struct dev_list_member *iter; 708 iter = list_get_instance(cur_link, struct dev_list_member, 709 link); 702 710 703 711 if (iter->inited) … … 710 718 if (rc == EEXIST) { 711 719 list_remove(cur_link); 712 free_ svc_id_linked(iter);720 free_dev_list_member(iter); 713 721 continue; 714 722 } … … 725 733 static void block_fini_dev_list(list_t *list) 726 734 { 727 list_foreach(*list, link, struct svc_id_linked, iter) { 735 HR_DEBUG("%s()", __func__); 736 737 list_foreach(*list, link, struct dev_list_member, iter) { 728 738 if (iter->inited) { 729 739 block_fini(iter->svc_id); … … 733 743 } 734 744 735 static errno_t hr_util_get_matching_md_svcs_list(list_t *rlist, list_t *devlist, 736 service_id_t svc_id, hr_metadata_t *md_main) 737 { 745 static errno_t hr_util_get_matching_md_svcs_list(list_t *rlist, list_t *list, 746 service_id_t svc_id, metadata_type_t type, void *metadata_struct_main) 747 { 748 HR_DEBUG("%s()", __func__); 749 738 750 errno_t rc = EOK; 739 751 740 list_foreach(* devlist, link, struct svc_id_linked, iter) {752 list_foreach(*list, link, struct dev_list_member, iter) { 741 753 if (iter->svc_id == svc_id) 742 754 continue; 743 void *md_block; 744 hr_metadata_t md; 745 rc = hr_get_metadata_block(iter->svc_id, &md_block); 755 756 void *metadata_struct; 757 metadata_type_t type; 758 759 rc = find_metadata(iter->svc_id, &metadata_struct, &type); 760 if (rc == ENOFS) 761 continue; 746 762 if (rc != EOK) 747 763 goto error; 748 hr_decode_metadata_from_block(md_block, &md); 749 750 free(md_block); 751 752 if (!hr_valid_md_magic(&md)) 764 765 hr_superblock_ops_t *meta_ops = get_type_ops(type); 766 767 if (!meta_ops->compare_uuids(metadata_struct_main, 768 metadata_struct)) { 769 free(metadata_struct); 753 770 continue; 754 755 if (memcmp(md_main->uuid, md.uuid, HR_UUID_LEN) != 0) 756 continue; 757 758 /* 759 * XXX: can I assume bsize and everything is fine when 760 * UUID matches? 761 */ 762 763 rc = hr_add_svc_linked_to_list(rlist, iter->svc_id, true, &md); 771 } 772 773 rc = hr_add_svc_linked_to_list(rlist, iter->svc_id, true, 774 metadata_struct); 764 775 if (rc != EOK) 765 776 goto error; … … 772 783 } 773 784 774 static errno_t hr_util_assemble_from_matching_list(list_t *list) 785 static errno_t hr_util_assemble_from_matching_list(list_t *list, 786 metadata_type_t type) 775 787 { 776 788 HR_DEBUG("%s()", __func__); … … 778 790 errno_t rc = EOK; 779 791 780 hr_metadata_t *main_md = NULL; 781 size_t max_counter_val = 0; 782 783 list_foreach(*list, link, struct svc_id_linked, iter) { 784 /* hr_metadata_dump(iter->md); */ 785 if (iter->md->counter >= max_counter_val) { 786 max_counter_val = iter->md->counter; 787 main_md = iter->md; 788 } 789 } 790 791 assert(main_md != NULL); 792 hr_superblock_ops_t *meta_ops = get_type_ops(type); 793 794 link_t *memb_l = list_first(list); 795 struct dev_list_member *memb = list_get_instance(memb_l, 796 struct dev_list_member, link); 797 798 hr_level_t level = meta_ops->get_level(memb->md); 799 const char *devname = meta_ops->get_devname(memb->md); 792 800 793 801 hr_volume_t *vol; 794 rc = hr_create_vol_struct(&vol, (hr_level_t)main_md->level, 795 main_md->devname); 802 rc = hr_create_vol_struct(&vol, level, devname, type); 796 803 if (rc != EOK) 797 804 goto error; 798 805 799 vol->nblocks = main_md->nblocks; 800 vol->data_blkno = main_md->data_blkno; 801 vol->truncated_blkno = main_md->truncated_blkno; 802 vol->data_offset = main_md->data_offset; 803 vol->metadata_version = main_md->version; 804 vol->extent_no = main_md->extent_no; 805 /* vol->level = main_md->level; */ 806 vol->layout = main_md->layout; 807 vol->strip_size = main_md->strip_size; 808 vol->bsize = main_md->bsize; 809 /* memcpy(vol->devname, main_md->devname, HR_DEVNAME_LEN); */ 810 811 memcpy(vol->in_mem_md, main_md, sizeof(hr_metadata_t)); 812 813 list_foreach(*list, link, struct svc_id_linked, iter) { 814 vol->extents[iter->md->index].svc_id = iter->svc_id; 815 816 uint64_t blkno; 817 rc = block_get_nblocks(iter->svc_id, &blkno); 818 if (rc != EOK) 819 goto error; 820 vol->extents[iter->md->index].blkno = blkno; 821 822 if (iter->md->counter == max_counter_val) 823 vol->extents[iter->md->index].status = HR_EXT_ONLINE; 824 else 825 vol->extents[iter->md->index].status = HR_EXT_INVALID; 826 } 827 828 for (size_t i = 0; i < vol->extent_no; i++) { 829 if (vol->extents[i].status == HR_EXT_NONE) 830 vol->extents[i].status = HR_EXT_MISSING; 831 } 806 meta_ops->init_meta2vol(list, vol); 832 807 833 808 /* … … 845 820 * write... but for now leave it here 846 821 */ 847 vol->in_mem_md->counter++;822 (void)vol->meta_ops->inc_counter(vol->in_mem_md); 848 823 849 824 rc = vol->hr_ops.create(vol); … … 851 826 goto error; 852 827 853 hr_metadata_save(vol, WITH_STATE_CALLBACK);854 855 828 fibril_rwlock_write_lock(&hr_volumes_lock); 856 857 list_foreach(hr_volumes, lvolumes, hr_volume_t, other) {858 uint8_t *our_uuid = vol->in_mem_md->uuid;859 uint8_t *other_uuid = other->in_mem_md->uuid;860 if (memcmp(our_uuid, other_uuid, HR_UUID_LEN) == 0) {861 rc = EEXIST;862 fibril_rwlock_write_unlock(&hr_volumes_lock);863 goto error;864 }865 }866 829 867 830 /* … … 884 847 } 885 848 849 (void)vol->meta_ops->save(vol, WITH_STATE_CALLBACK); 850 886 851 list_append(&vol->lvolumes, &hr_volumes); 887 852 … … 896 861 static errno_t hr_fill_svcs_list_from_cfg(hr_config_t *cfg, list_t *list) 897 862 { 863 HR_DEBUG("%s()", __func__); 864 898 865 errno_t rc = EOK; 899 866 for (size_t i = 0; i < cfg->dev_no; ++i) { 900 rc = hr_add_svc_linked_to_list(list, cfg->devs[i], false, NULL); 867 rc = hr_add_svc_linked_to_list(list, cfg->devs[i], false, 868 NULL); 901 869 if (rc != EOK) 902 870 goto error; … … 944 912 goto error; 945 913 946 struct svc_id_linked*iter;914 struct dev_list_member *iter; 947 915 while (!list_empty(&dev_id_list)) { 948 iter = list_pop(&dev_id_list, struct svc_id_linked, link); 949 950 void *metadata_block; 951 hr_metadata_t metadata; 952 953 rc = hr_get_metadata_block(iter->svc_id, &metadata_block); 916 iter = list_pop(&dev_id_list, struct dev_list_member, link); 917 918 void *metadata_struct_main; 919 metadata_type_t type; 920 921 rc = find_metadata(iter->svc_id, &metadata_struct_main, &type); 922 if (rc == ENOFS) { 923 block_fini(iter->svc_id); 924 free_dev_list_member(iter); 925 rc = EOK; 926 continue; 927 } 928 954 929 if (rc != EOK) 955 930 goto error; 956 957 hr_decode_metadata_from_block(metadata_block, &metadata);958 959 free(metadata_block);960 961 if (!hr_valid_md_magic(&metadata)) {962 block_fini(iter->svc_id);963 free_svc_id_linked(iter);964 continue;965 }966 967 /* hr_metadata_dump(&metadata); */968 931 969 932 char *svc_name = NULL; … … 981 944 982 945 rc = hr_util_get_matching_md_svcs_list(&matching_svcs_list, 983 &dev_id_list, iter->svc_id, &metadata);946 &dev_id_list, iter->svc_id, type, metadata_struct_main); 984 947 if (rc != EOK) 985 948 goto error; … … 987 950 /* add current iter to list as well */ 988 951 rc = hr_add_svc_linked_to_list(&matching_svcs_list, 989 iter->svc_id, true, &metadata);952 iter->svc_id, true, metadata_struct_main); 990 953 if (rc != EOK) { 991 954 free_svc_id_list(&matching_svcs_list); … … 994 957 995 958 /* remove matching list members from dev_id_list */ 996 list_foreach(matching_svcs_list, link, struct svc_id_linked,959 list_foreach(matching_svcs_list, link, struct dev_list_member, 997 960 iter2) { 998 struct svc_id_linked*to_remove;961 struct dev_list_member *to_remove; 999 962 list_foreach_safe(dev_id_list, cur_link, next_link) { 1000 963 to_remove = list_get_instance(cur_link, 1001 struct svc_id_linked, link);964 struct dev_list_member, link); 1002 965 if (to_remove->svc_id == iter2->svc_id) { 1003 966 list_remove(cur_link); 1004 free_ svc_id_linked(to_remove);967 free_dev_list_member(to_remove); 1005 968 } 1006 969 } 1007 970 } 1008 971 1009 rc = hr_util_assemble_from_matching_list(&matching_svcs_list); 972 rc = hr_util_assemble_from_matching_list(&matching_svcs_list, 973 type); 1010 974 switch (rc) { 1011 975 case EOK: … … 1065 1029 } 1066 1030 1067 /* 1068 * TODO: make more flexible, when will have foreign md, the calculation 1069 * will differ, maybe something new like vol->md_hs_blkno will be enough 1070 */ 1071 if (hs_blkno < vol->truncated_blkno - HR_META_SIZE) { 1031 if (hs_blkno < vol->truncated_blkno - vol->meta_ops->get_size()) { 1072 1032 rc = EINVAL; 1073 1033 block_fini(hotspare); -
uspace/srv/bd/hr/util.h
r6f41c21f r50603405 37 37 #define _HR_UTIL_H 38 38 39 #include <adt/list.h> 39 40 #include <errno.h> 40 41 #include <hr.h> 41 42 #include <io/log.h> 42 43 44 #include "superblock.h" 43 45 #include "var.h" 46 47 struct dev_list_member { 48 link_t link; 49 service_id_t svc_id; 50 void *md; 51 bool inited; 52 bool md_present; 53 }; 44 54 45 55 #define HR_DEBUG(format, ...) \ … … 54 64 55 65 extern errno_t hr_create_vol_struct(hr_volume_t **, hr_level_t, 56 const char * );66 const char *, metadata_type_t); 57 67 extern void hr_destroy_vol_struct(hr_volume_t *); 58 68 extern hr_volume_t *hr_get_volume(service_id_t); -
uspace/srv/bd/hr/var.h
r6f41c21f r50603405 53 53 typedef struct hr_volume hr_volume_t; 54 54 typedef struct hr_metadata hr_metadata_t; 55 typedef struct hr_superblock_ops hr_superblock_ops_t; 55 56 56 57 typedef struct hr_ops { … … 72 73 hr_fpool_t *fge; /* fibril pool */ 73 74 74 /* 75 * TODO: also print in info, doesn't have 76 * to be part of hr_volume_t but just the info 77 * that is passed to be printed 78 * 79 * Probably just defer this decition until foreign md 80 * will be handled. 81 */ 82 uint32_t metadata_version; 75 void *in_mem_md; 76 fibril_mutex_t md_lock; /* lock protecting in_mem_md */ 83 77 84 hr_metadata_t *in_mem_md; 85 fibril_mutex_t md_lock; /* lock protecting in_mem_md */ 78 hr_superblock_ops_t *meta_ops; 86 79 87 80 /* invariants */
Note:
See TracChangeset
for help on using the changeset viewer.