@@ -144,7 +144,7 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
144144
145145 rc = zms_delete (& cf -> cf_zms , name_hash );
146146 if (rc >= 0 ) {
147- rc = zms_delete (& cf -> cf_zms , name_hash + ZMS_DATA_ID_OFFSET );
147+ rc = zms_delete (& cf -> cf_zms , ZMS_DATA_ID_FROM_NAME ( name_hash ) );
148148 }
149149 if (rc < 0 ) {
150150 return rc ;
@@ -185,8 +185,7 @@ static int settings_zms_load_subtree(struct settings_store *cs, const struct set
185185 rc1 = zms_read (& cf -> cf_zms , ZMS_NAME_ID_FROM_HASH (name_hash ), & name ,
186186 sizeof (name ) - 1 );
187187 /* get the length of data and verify that it exists */
188- rc2 = zms_get_data_length (& cf -> cf_zms ,
189- ZMS_NAME_ID_FROM_HASH (name_hash ) + ZMS_DATA_ID_OFFSET );
188+ rc2 = zms_get_data_length (& cf -> cf_zms , ZMS_DATA_ID_FROM_HASH (name_hash ));
190189 if ((rc1 <= 0 ) || (rc2 <= 0 )) {
191190 /* Name or data doesn't exist */
192191 continue ;
@@ -201,32 +200,28 @@ static int settings_zms_load_subtree(struct settings_store *cs, const struct set
201200 }
202201 /* At this steps the names are equal, let's set the handler */
203202 read_fn_arg .fs = & cf -> cf_zms ;
204- read_fn_arg .id = ZMS_NAME_ID_FROM_HASH (name_hash ) + ZMS_DATA_ID_OFFSET ;
203+ read_fn_arg .id = ZMS_DATA_ID_FROM_HASH (name_hash );
205204
206205 /* We should return here as there is no need to look for the next
207206 * hash collision
208207 */
209- return settings_call_set_handler (arg -> subtree , rc2 , settings_zms_read_fn , & read_fn_arg ,
210- (void * )arg );
208+ return settings_call_set_handler (arg -> subtree , rc2 , settings_zms_read_fn ,
209+ & read_fn_arg , (void * )arg );
211210 }
212211
213212 return 0 ;
214213}
215214#endif /* CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH */
216215
217- static ssize_t settings_zms_load_one (struct settings_store * cs , const char * name , char * buf ,
218- size_t buf_len )
216+ /* Search for the name_hash that corresponds to name.
217+ * If no hash that corresponds to name is found in the persistent storage,
218+ * returns 0.
219+ */
220+ static uint32_t settings_zms_find_hash_from_name (struct settings_zms * cf , const char * name )
219221{
220- struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
222+ uint32_t name_hash = 0 ;
223+ int rc = 0 ;
221224 char r_name [SETTINGS_FULL_NAME_LEN ];
222- ssize_t rc = 0 ;
223- uint32_t name_hash ;
224- uint32_t value_id ;
225-
226- /* verify that name is not NULL */
227- if (!name || !buf ) {
228- return - EINVAL ;
229- }
230225
231226 name_hash = sys_hash32 (name , strnlen (name , SETTINGS_FULL_NAME_LEN )) & ZMS_HASH_MASK ;
232227 for (int i = 0 ; i <= cf -> hash_collision_num ; i ++ ) {
@@ -246,27 +241,84 @@ static ssize_t settings_zms_load_one(struct settings_store *cs, const char *name
246241 */
247242 continue ;
248243 }
244+ /* At this step names are equal, we found the corresponding hash */
245+ return name_hash ;
246+ }
249247
250- /* At this steps the names are equal, let's read the data */
251- value_id = ZMS_NAME_ID_FROM_HASH (name_hash ) + ZMS_DATA_ID_OFFSET ;
248+ return 0 ;
249+ }
250+
251+ static ssize_t settings_zms_load_one (struct settings_store * cs , const char * name , char * buf ,
252+ size_t buf_len )
253+ {
254+ struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
255+ uint32_t name_hash = 0 ;
256+ ssize_t rc = 0 ;
257+ uint32_t value_id ;
258+
259+ /* verify that name is not NULL */
260+ if (!name || !buf ) {
261+ return - EINVAL ;
262+ }
263+
264+ name_hash = settings_zms_find_hash_from_name (cf , name );
265+ if (name_hash ) {
266+ /* we found a name_hash corresponding to name */
267+ value_id = ZMS_DATA_ID_FROM_HASH (name_hash );
252268 rc = zms_read (& cf -> cf_zms , value_id , buf , buf_len );
253269
254270 return rc == buf_len ? zms_get_data_length (& cf -> cf_zms , value_id ) : rc ;
255271 }
256272
257- return rc ;
273+ return 0 ;
274+ }
275+
276+ /* Gets the next linked list node either from cache (if enabled) or from persistent
277+ * storage if cache is full or cache is not enabled.
278+ * It updates as well the next cache index and the next linked list node ID.
279+ */
280+ static int settings_zms_get_next_ll (struct settings_zms * cf , uint32_t * ll_hash_id ,
281+ [[maybe_unused ]] uint32_t * ll_cache_index )
282+ {
283+ struct settings_hash_linked_list settings_element ;
284+ int ret = 0 ;
285+
286+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
287+ if (* ll_cache_index < cf -> ll_cache_next ) {
288+ settings_element = cf -> ll_cache [* ll_cache_index ];
289+ * ll_cache_index = * ll_cache_index + 1 ;
290+ } else if (* ll_hash_id == cf -> second_to_last_hash_id ) {
291+ /* The last ll node is not stored in the cache as it is already
292+ * in the cf->last_hash_id.
293+ */
294+ settings_element .next_hash = cf -> last_hash_id ;
295+ } else {
296+ #endif
297+ ret = zms_read (& cf -> cf_zms , * ll_hash_id , & settings_element ,
298+ sizeof (struct settings_hash_linked_list ));
299+ if (ret < 0 ) {
300+ return ret ;
301+ }
302+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
303+ }
304+ #endif
305+ /* update next ll_hash_id */
306+ * ll_hash_id = settings_element .next_hash ;
307+
308+ return 0 ;
258309}
259310
260311static int settings_zms_load (struct settings_store * cs , const struct settings_load_arg * arg )
261312{
262313 int ret = 0 ;
263314 struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
264315 struct settings_zms_read_fn_arg read_fn_arg ;
265- struct settings_hash_linked_list settings_element ;
266316 char name [SETTINGS_FULL_NAME_LEN ];
267317 ssize_t rc1 ;
268318 ssize_t rc2 ;
269319 uint32_t ll_hash_id ;
320+ uint32_t ll_cache_index = 0 ;
321+
270322#ifdef CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH
271323 /* If arg->subtree is not null we must first load settings in that subtree */
272324 if (arg -> subtree != NULL ) {
@@ -278,26 +330,22 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
278330#endif /* CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH */
279331
280332#ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
281- uint32_t ll_cache_index = 0 ;
282-
283333 if (cf -> ll_has_changed ) {
284334 /* reload the linked list in cache */
285335 ret = settings_zms_get_last_hash_ids (cf );
286336 if (ret < 0 ) {
287337 return ret ;
288338 }
289339 }
290- settings_element = cf -> ll_cache [ll_cache_index ++ ];
291- #else
292- ret = zms_read (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
293- sizeof (struct settings_hash_linked_list ));
340+ #endif
341+
342+ /* If subtree is NULL then we must load all found Settings */
343+ ll_hash_id = ZMS_LL_HEAD_HASH_ID ;
344+ ret = settings_zms_get_next_ll (cf , & ll_hash_id , & ll_cache_index );
294345 if (ret < 0 ) {
295346 return ret ;
296347 }
297- #endif /* CONFIG_SETTINGS_ZMS_LL_CACHE */
298- ll_hash_id = settings_element .next_hash ;
299348
300- /* If subtree is NULL then we must load all found Settings */
301349 while (ll_hash_id ) {
302350 /* In the ZMS backend, each setting item is stored in two ZMS
303351 * entries one for the setting's name and one with the
@@ -306,8 +354,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
306354 rc1 = zms_read (& cf -> cf_zms , ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ), & name ,
307355 sizeof (name ) - 1 );
308356 /* get the length of data and verify that it exists */
309- rc2 = zms_get_data_length (& cf -> cf_zms , ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ) +
310- ZMS_DATA_ID_OFFSET );
357+ rc2 = zms_get_data_length (& cf -> cf_zms , ZMS_DATA_ID_FROM_LL_NODE (ll_hash_id ));
311358
312359 if ((rc1 <= 0 ) || (rc2 <= 0 )) {
313360 /* In case we are not updating the linked list, this is an empty mode
@@ -323,57 +370,29 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
323370 return ret ;
324371 }
325372#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
326- #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
327- if (ll_cache_index < cf -> ll_cache_next ) {
328- settings_element = cf -> ll_cache [ll_cache_index ++ ];
329- } else if (ll_hash_id == cf -> second_to_last_hash_id ) {
330- /* The last ll node is not stored in the cache as it is already
331- * in the cf->last_hash_id.
332- */
333- settings_element .next_hash = cf -> last_hash_id ;
334- } else {
335- #endif
336- ret = zms_read (& cf -> cf_zms , ll_hash_id , & settings_element ,
337- sizeof (struct settings_hash_linked_list ));
338- if (ret < 0 ) {
339- return ret ;
340- }
341- #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
373+
374+ ret = settings_zms_get_next_ll (cf , & ll_hash_id , & ll_cache_index );
375+ if (ret < 0 ) {
376+ return ret ;
342377 }
343- #endif
344- /* update next ll_hash_id */
345- ll_hash_id = settings_element .next_hash ;
378+
346379 continue ;
347380 }
348381
349382 /* Found a name, this might not include a trailing \0 */
350383 name [rc1 ] = '\0' ;
351384 read_fn_arg .fs = & cf -> cf_zms ;
352- read_fn_arg .id = ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ) + ZMS_DATA_ID_OFFSET ;
385+ read_fn_arg .id = ZMS_DATA_ID_FROM_LL_NODE (ll_hash_id );
353386
354- ret = settings_call_set_handler (name , rc2 , settings_zms_read_fn , & read_fn_arg ,
355- (void * )arg );
387+ ret = settings_call_set_handler (name , rc2 , settings_zms_read_fn , & read_fn_arg , arg );
356388 if (ret ) {
357- break ;
389+ return ret ;
358390 }
359391
360- #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
361- if (ll_cache_index < cf -> ll_cache_next ) {
362- settings_element = cf -> ll_cache [ll_cache_index ++ ];
363- } else if (ll_hash_id == cf -> second_to_last_hash_id ) {
364- settings_element .next_hash = cf -> last_hash_id ;
365- } else {
366- #endif
367- ret = zms_read (& cf -> cf_zms , ll_hash_id , & settings_element ,
368- sizeof (struct settings_hash_linked_list ));
369- if (ret < 0 ) {
370- return ret ;
371- }
372- #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
392+ ret = settings_zms_get_next_ll (cf , & ll_hash_id , & ll_cache_index );
393+ if (ret < 0 ) {
394+ return ret ;
373395 }
374- #endif
375- /* update next ll_hash_id */
376- ll_hash_id = settings_element .next_hash ;
377396 }
378397
379398 return ret ;
@@ -469,7 +488,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
469488 }
470489
471490 /* write the value */
472- rc = zms_write (& cf -> cf_zms , name_hash + ZMS_DATA_ID_OFFSET , value , val_len );
491+ rc = zms_write (& cf -> cf_zms , ZMS_DATA_ID_FROM_NAME ( name_hash ) , value , val_len );
473492 if (rc < 0 ) {
474493 return rc ;
475494 }
@@ -538,36 +557,49 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
538557static ssize_t settings_zms_get_val_len (struct settings_store * cs , const char * name )
539558{
540559 struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
541- char r_name [SETTINGS_FULL_NAME_LEN ];
542- ssize_t rc = 0 ;
543- uint32_t name_hash ;
560+ uint32_t name_hash = 0 ;
544561
545562 /* verify that name is not NULL */
546563 if (!name ) {
547564 return - EINVAL ;
548565 }
549566
550- name_hash = sys_hash32 (name , strnlen (name , SETTINGS_FULL_NAME_LEN )) & ZMS_HASH_MASK ;
551- for (int i = 0 ; i <= cf -> hash_collision_num ; i ++ ) {
552- name_hash = ZMS_UPDATE_COLLISION_NUM (name_hash , i );
553- /* Get the name entry from ZMS */
554- rc = zms_read (& cf -> cf_zms , ZMS_NAME_ID_FROM_HASH (name_hash ), r_name ,
555- sizeof (r_name ) - 1 );
556- if (rc <= 0 ) {
557- /* Name doesn't exist */
558- continue ;
567+ name_hash = settings_zms_find_hash_from_name (cf , name );
568+ if (name_hash ) {
569+ return zms_get_data_length (& cf -> cf_zms , ZMS_DATA_ID_FROM_HASH (name_hash ));
570+ }
571+
572+ return 0 ;
573+ }
574+
575+ /* This function inits the linked list head if it doesn't exist or recover it
576+ * if the ll_last_hash_id is different than the head hash ID
577+ */
578+ static int settings_zms_init_or_recover_ll (struct settings_zms * cf , uint32_t ll_last_hash_id )
579+ {
580+ struct settings_hash_linked_list settings_element ;
581+ int rc = 0 ;
582+
583+ if (ll_last_hash_id == ZMS_LL_HEAD_HASH_ID ) {
584+ /* header doesn't exist */
585+ settings_element .previous_hash = 0 ;
586+ settings_element .next_hash = 0 ;
587+ rc = zms_write (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
588+ sizeof (struct settings_hash_linked_list ));
589+ if (rc < 0 ) {
590+ return rc ;
559591 }
560- /* Found a name, this might not include a trailing \0 */
561- r_name [rc ] = '\0' ;
562- if (strcmp (name , r_name )) {
563- /* Names are not equal let's continue to the next collision hash
564- * if it exists.
565- */
566- continue ;
592+ cf -> last_hash_id = ZMS_LL_HEAD_HASH_ID ;
593+ cf -> second_to_last_hash_id = 0 ;
594+ } else {
595+ /* let's recover it by keeping all nodes until the last one */
596+ settings_element .previous_hash = cf -> second_to_last_hash_id ;
597+ settings_element .next_hash = 0 ;
598+ rc = zms_write (& cf -> cf_zms , cf -> last_hash_id , & settings_element ,
599+ sizeof (struct settings_hash_linked_list ));
600+ if (rc < 0 ) {
601+ return rc ;
567602 }
568- /* At this steps the names are equal, let's read the data size*/
569- return zms_get_data_length (& cf -> cf_zms ,
570- ZMS_NAME_ID_FROM_HASH (name_hash ) + ZMS_DATA_ID_OFFSET );
571603 }
572604
573605 return 0 ;
@@ -591,29 +623,7 @@ static int settings_zms_get_last_hash_ids(struct settings_zms *cf)
591623 /* header doesn't exist or linked list broken, reinitialize the header
592624 * if it doesn't exist and recover it if it is broken
593625 */
594- if (ll_last_hash_id == ZMS_LL_HEAD_HASH_ID ) {
595- /* header doesn't exist */
596- const struct settings_hash_linked_list settings_element = {
597- .previous_hash = 0 , .next_hash = 0 };
598- rc = zms_write (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
599- sizeof (struct settings_hash_linked_list ));
600- if (rc < 0 ) {
601- return rc ;
602- }
603- cf -> last_hash_id = ZMS_LL_HEAD_HASH_ID ;
604- cf -> second_to_last_hash_id = 0 ;
605- } else {
606- /* let's recover it by keeping all nodes until the last one */
607- const struct settings_hash_linked_list settings_element = {
608- .previous_hash = cf -> second_to_last_hash_id ,
609- .next_hash = 0 };
610- rc = zms_write (& cf -> cf_zms , cf -> last_hash_id , & settings_element ,
611- sizeof (struct settings_hash_linked_list ));
612- if (rc < 0 ) {
613- return rc ;
614- }
615- }
616- return 0 ;
626+ return settings_zms_init_or_recover_ll (cf , ll_last_hash_id );
617627 } else if (rc < 0 ) {
618628 return rc ;
619629 }
0 commit comments