@@ -30,6 +30,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
30
30
static int settings_zms_save (struct settings_store * cs , const char * name , const char * value ,
31
31
size_t val_len );
32
32
static void * settings_zms_storage_get (struct settings_store * cs );
33
+ static int settings_zms_get_last_hash_ids (struct settings_zms * cf );
33
34
34
35
static struct settings_store_itf settings_zms_itf = {.csi_load = settings_zms_load ,
35
36
.csi_save = settings_zms_save ,
@@ -169,18 +170,19 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
169
170
* entries one for the setting's name and one with the
170
171
* setting's value.
171
172
*/
172
- rc1 = zms_read (& cf -> cf_zms , ZMS_NAME_HASH_ID (ll_hash_id ), & name , sizeof (name ) - 1 );
173
+ rc1 = zms_read (& cf -> cf_zms , ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ), & name ,
174
+ sizeof (name ) - 1 );
173
175
/* get the length of data and verify that it exists */
174
- rc2 = zms_get_data_length (& cf -> cf_zms ,
175
- ZMS_NAME_HASH_ID ( ll_hash_id ) + ZMS_DATA_ID_OFFSET );
176
+ rc2 = zms_get_data_length (& cf -> cf_zms , ZMS_NAME_ID_FROM_LL_NODE ( ll_hash_id ) +
177
+ ZMS_DATA_ID_OFFSET );
176
178
177
179
if ((rc1 <= 0 ) || (rc2 <= 0 )) {
178
180
/* Settings item is not stored correctly in the ZMS.
179
181
* ZMS entry for its name or value is either missing
180
182
* or deleted. Clean dirty entries to make space for
181
183
* future settings item.
182
184
*/
183
- ret = settings_zms_delete (cf , ZMS_NAME_HASH_ID (ll_hash_id ));
185
+ ret = settings_zms_delete (cf , ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ));
184
186
if (ret < 0 ) {
185
187
return ret ;
186
188
}
@@ -190,7 +192,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
190
192
/* Found a name, this might not include a trailing \0 */
191
193
name [rc1 ] = '\0' ;
192
194
read_fn_arg .fs = & cf -> cf_zms ;
193
- read_fn_arg .id = ZMS_NAME_HASH_ID (ll_hash_id ) + ZMS_DATA_ID_OFFSET ;
195
+ read_fn_arg .id = ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ) + ZMS_DATA_ID_OFFSET ;
194
196
195
197
ret = settings_call_set_handler (name , rc2 , settings_zms_read_fn , & read_fn_arg ,
196
198
(void * )arg );
@@ -232,8 +234,10 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
232
234
delete = ((value == NULL ) || (val_len == 0 ));
233
235
234
236
name_hash = sys_hash32 (name , strlen (name )) & ZMS_HASH_MASK ;
237
+ /* MSB is always 1 */
238
+ name_hash |= BIT (31 );
235
239
236
- /* Let's find out if there is no hash collisions in the storage */
240
+ /* Let's find out if there are hash collisions in the storage */
237
241
write_name = true;
238
242
hash_collision = true;
239
243
@@ -311,6 +315,16 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
311
315
}
312
316
/* write linked list structure element */
313
317
settings_element .next_hash = 0 ;
318
+ /* Verify first that the linked list last element is not broken.
319
+ * Settings subsystem uses ID that starts from ZMS_LL_HEAD_HASH_ID.
320
+ */
321
+ if (cf -> last_hash_id < ZMS_LL_HEAD_HASH_ID ) {
322
+ LOG_WRN ("Linked list for hashes is broken, Trying to recover" );
323
+ rc = settings_zms_get_last_hash_ids (cf );
324
+ if (rc < 0 ) {
325
+ return rc ;
326
+ }
327
+ }
314
328
settings_element .previous_hash = cf -> last_hash_id ;
315
329
rc = zms_write (& cf -> cf_zms , name_hash | 1 , & settings_element ,
316
330
sizeof (struct settings_hash_linked_list ));
@@ -342,9 +356,22 @@ static int settings_zms_get_last_hash_ids(struct settings_zms *cf)
342
356
do {
343
357
rc = zms_read (& cf -> cf_zms , ll_last_hash_id , & settings_element ,
344
358
sizeof (settings_element ));
345
- if (rc ) {
359
+ if (rc == - ENOENT ) {
360
+ /* header doesn't exist or linked list broken, reinitialize the header */
361
+ const struct settings_hash_linked_list settings_element = {
362
+ .previous_hash = 0 , .next_hash = 0 };
363
+ rc = zms_write (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
364
+ sizeof (struct settings_hash_linked_list ));
365
+ if (rc < 0 ) {
366
+ return rc ;
367
+ }
368
+ cf -> last_hash_id = ZMS_LL_HEAD_HASH_ID ;
369
+ cf -> second_to_last_hash_id = 0 ;
370
+ return 0 ;
371
+ } else if (rc < 0 ) {
346
372
return rc ;
347
373
}
374
+
348
375
/* increment hash collision number if necessary */
349
376
if (ZMS_COLLISION_NUM (ll_last_hash_id ) > cf -> hash_collision_num ) {
350
377
cf -> hash_collision_num = ZMS_COLLISION_NUM (ll_last_hash_id );
@@ -375,23 +402,9 @@ static int settings_zms_backend_init(struct settings_zms *cf)
375
402
cf -> hash_collision_num = 0 ;
376
403
377
404
rc = settings_zms_get_last_hash_ids (cf );
378
- if (rc == - ENOENT ) {
379
- /* header doesn't exist or linked list broken, reinitialize the header */
380
- const struct settings_hash_linked_list settings_element = {.previous_hash = 0 ,
381
- .next_hash = 0 };
382
- rc = zms_write (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
383
- sizeof (struct settings_hash_linked_list ));
384
- if (rc < 0 ) {
385
- return rc ;
386
- }
387
- cf -> last_hash_id = ZMS_LL_HEAD_HASH_ID ;
388
- cf -> second_to_last_hash_id = 0 ;
389
- } else if (rc < 0 ) {
390
- return rc ;
391
- }
392
405
393
406
LOG_DBG ("ZMS backend initialized" );
394
- return 0 ;
407
+ return rc ;
395
408
}
396
409
397
410
int settings_backend_init (void )
0 commit comments