@@ -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 ;
@@ -155,11 +155,8 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
155155 cf -> ll_has_changed = true;
156156#endif
157157 rc = settings_zms_unlink_ll_node (cf , name_hash );
158- if (rc < 0 ) {
159- return rc ;
160- }
161-
162158#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
159+
163160 return rc ;
164161}
165162
@@ -185,8 +182,7 @@ static int settings_zms_load_subtree(struct settings_store *cs, const struct set
185182 rc1 = zms_read (& cf -> cf_zms , ZMS_NAME_ID_FROM_HASH (name_hash ), & name ,
186183 sizeof (name ) - 1 );
187184 /* 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 );
185+ rc2 = zms_get_data_length (& cf -> cf_zms , ZMS_DATA_ID_FROM_HASH (name_hash ));
190186 if ((rc1 <= 0 ) || (rc2 <= 0 )) {
191187 /* Name or data doesn't exist */
192188 continue ;
@@ -201,32 +197,28 @@ static int settings_zms_load_subtree(struct settings_store *cs, const struct set
201197 }
202198 /* At this steps the names are equal, let's set the handler */
203199 read_fn_arg .fs = & cf -> cf_zms ;
204- read_fn_arg .id = ZMS_NAME_ID_FROM_HASH (name_hash ) + ZMS_DATA_ID_OFFSET ;
200+ read_fn_arg .id = ZMS_DATA_ID_FROM_HASH (name_hash );
205201
206202 /* We should return here as there is no need to look for the next
207203 * hash collision
208204 */
209- return settings_call_set_handler (arg -> subtree , rc2 , settings_zms_read_fn , & read_fn_arg ,
210- (void * )arg );
205+ return settings_call_set_handler (arg -> subtree , rc2 , settings_zms_read_fn ,
206+ & read_fn_arg , (void * )arg );
211207 }
212208
213209 return 0 ;
214210}
215211#endif /* CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH */
216212
217- static ssize_t settings_zms_load_one (struct settings_store * cs , const char * name , char * buf ,
218- size_t buf_len )
213+ /* Search for the name_hash that corresponds to name.
214+ * If no hash that corresponds to name is found in the persistent storage,
215+ * returns 0.
216+ */
217+ static uint32_t settings_zms_find_hash_from_name (struct settings_zms * cf , const char * name )
219218{
220- struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
219+ uint32_t name_hash = 0 ;
220+ int rc = 0 ;
221221 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- }
230222
231223 name_hash = sys_hash32 (name , strnlen (name , SETTINGS_FULL_NAME_LEN )) & ZMS_HASH_MASK ;
232224 for (int i = 0 ; i <= cf -> hash_collision_num ; i ++ ) {
@@ -246,27 +238,84 @@ static ssize_t settings_zms_load_one(struct settings_store *cs, const char *name
246238 */
247239 continue ;
248240 }
241+ /* At this step names are equal, we found the corresponding hash */
242+ return name_hash ;
243+ }
244+
245+ return 0 ;
246+ }
247+
248+ static ssize_t settings_zms_load_one (struct settings_store * cs , const char * name , char * buf ,
249+ size_t buf_len )
250+ {
251+ struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
252+ uint32_t name_hash = 0 ;
253+ ssize_t rc = 0 ;
254+ uint32_t value_id ;
255+
256+ /* verify that name is not NULL */
257+ if (!name || !buf ) {
258+ return - EINVAL ;
259+ }
249260
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 ;
261+ name_hash = settings_zms_find_hash_from_name (cf , name );
262+ if (name_hash ) {
263+ /* we found a name_hash corresponding to name */
264+ value_id = ZMS_DATA_ID_FROM_HASH (name_hash );
252265 rc = zms_read (& cf -> cf_zms , value_id , buf , buf_len );
253266
254267 return rc == buf_len ? zms_get_data_length (& cf -> cf_zms , value_id ) : rc ;
255268 }
256269
257- return rc ;
270+ return 0 ;
271+ }
272+
273+ /* Gets the next linked list node either from cache (if enabled) or from persistent
274+ * storage if cache is full or cache is not enabled.
275+ * It updates as well the next cache index and the next linked list node ID.
276+ */
277+ static int settings_zms_get_next_ll (struct settings_zms * cf , uint32_t * ll_hash_id ,
278+ [[maybe_unused ]] uint32_t * ll_cache_index )
279+ {
280+ struct settings_hash_linked_list settings_element ;
281+ int ret = 0 ;
282+
283+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
284+ if (* ll_cache_index < cf -> ll_cache_next ) {
285+ settings_element = cf -> ll_cache [* ll_cache_index ];
286+ * ll_cache_index = * ll_cache_index + 1 ;
287+ } else if (* ll_hash_id == cf -> second_to_last_hash_id ) {
288+ /* The last ll node is not stored in the cache as it is already
289+ * in the cf->last_hash_id.
290+ */
291+ settings_element .next_hash = cf -> last_hash_id ;
292+ } else {
293+ #endif
294+ ret = zms_read (& cf -> cf_zms , * ll_hash_id , & settings_element ,
295+ sizeof (struct settings_hash_linked_list ));
296+ if (ret < 0 ) {
297+ return ret ;
298+ }
299+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
300+ }
301+ #endif
302+ /* update next ll_hash_id */
303+ * ll_hash_id = settings_element .next_hash ;
304+
305+ return 0 ;
258306}
259307
260308static int settings_zms_load (struct settings_store * cs , const struct settings_load_arg * arg )
261309{
262310 int ret = 0 ;
263311 struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
264312 struct settings_zms_read_fn_arg read_fn_arg ;
265- struct settings_hash_linked_list settings_element ;
266313 char name [SETTINGS_FULL_NAME_LEN ];
267314 ssize_t rc1 ;
268315 ssize_t rc2 ;
269316 uint32_t ll_hash_id ;
317+ uint32_t ll_cache_index = 0 ;
318+
270319#ifdef CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH
271320 /* If arg->subtree is not null we must first load settings in that subtree */
272321 if (arg -> subtree != NULL ) {
@@ -278,26 +327,22 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
278327#endif /* CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH */
279328
280329#ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
281- uint32_t ll_cache_index = 0 ;
282-
283330 if (cf -> ll_has_changed ) {
284331 /* reload the linked list in cache */
285332 ret = settings_zms_get_last_hash_ids (cf );
286333 if (ret < 0 ) {
287334 return ret ;
288335 }
289336 }
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 ));
337+ #endif
338+
339+ /* If subtree is NULL then we must load all found Settings */
340+ ll_hash_id = ZMS_LL_HEAD_HASH_ID ;
341+ ret = settings_zms_get_next_ll (cf , & ll_hash_id , & ll_cache_index );
294342 if (ret < 0 ) {
295343 return ret ;
296344 }
297- #endif /* CONFIG_SETTINGS_ZMS_LL_CACHE */
298- ll_hash_id = settings_element .next_hash ;
299345
300- /* If subtree is NULL then we must load all found Settings */
301346 while (ll_hash_id ) {
302347 /* In the ZMS backend, each setting item is stored in two ZMS
303348 * entries one for the setting's name and one with the
@@ -306,8 +351,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
306351 rc1 = zms_read (& cf -> cf_zms , ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ), & name ,
307352 sizeof (name ) - 1 );
308353 /* 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 );
354+ rc2 = zms_get_data_length (& cf -> cf_zms , ZMS_DATA_ID_FROM_LL_NODE (ll_hash_id ));
311355
312356 if ((rc1 <= 0 ) || (rc2 <= 0 )) {
313357 /* In case we are not updating the linked list, this is an empty mode
@@ -323,57 +367,29 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
323367 return ret ;
324368 }
325369#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
370+
371+ ret = settings_zms_get_next_ll (cf , & ll_hash_id , & ll_cache_index );
372+ if (ret < 0 ) {
373+ return ret ;
342374 }
343- #endif
344- /* update next ll_hash_id */
345- ll_hash_id = settings_element .next_hash ;
375+
346376 continue ;
347377 }
348378
349379 /* Found a name, this might not include a trailing \0 */
350380 name [rc1 ] = '\0' ;
351381 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 ;
382+ read_fn_arg .id = ZMS_DATA_ID_FROM_LL_NODE (ll_hash_id );
353383
354- ret = settings_call_set_handler (name , rc2 , settings_zms_read_fn , & read_fn_arg ,
355- (void * )arg );
384+ ret = settings_call_set_handler (name , rc2 , settings_zms_read_fn , & read_fn_arg , arg );
356385 if (ret ) {
357- break ;
386+ return ret ;
358387 }
359388
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
389+ ret = settings_zms_get_next_ll (cf , & ll_hash_id , & ll_cache_index );
390+ if (ret < 0 ) {
391+ return ret ;
373392 }
374- #endif
375- /* update next ll_hash_id */
376- ll_hash_id = settings_element .next_hash ;
377393 }
378394
379395 return ret ;
@@ -469,7 +485,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
469485 }
470486
471487 /* write the value */
472- rc = zms_write (& cf -> cf_zms , name_hash + ZMS_DATA_ID_OFFSET , value , val_len );
488+ rc = zms_write (& cf -> cf_zms , ZMS_DATA_ID_FROM_NAME ( name_hash ) , value , val_len );
473489 if (rc < 0 ) {
474490 return rc ;
475491 }
@@ -538,36 +554,49 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
538554static ssize_t settings_zms_get_val_len (struct settings_store * cs , const char * name )
539555{
540556 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 ;
557+ uint32_t name_hash = 0 ;
544558
545559 /* verify that name is not NULL */
546560 if (!name ) {
547561 return - EINVAL ;
548562 }
549563
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 ;
564+ name_hash = settings_zms_find_hash_from_name (cf , name );
565+ if (name_hash ) {
566+ return zms_get_data_length (& cf -> cf_zms , ZMS_DATA_ID_FROM_HASH (name_hash ));
567+ }
568+
569+ return 0 ;
570+ }
571+
572+ /* This function inits the linked list head if it doesn't exist or recover it
573+ * if the ll_last_hash_id is different than the head hash ID
574+ */
575+ static int settings_zms_init_or_recover_ll (struct settings_zms * cf , uint32_t ll_last_hash_id )
576+ {
577+ struct settings_hash_linked_list settings_element ;
578+ int rc = 0 ;
579+
580+ if (ll_last_hash_id == ZMS_LL_HEAD_HASH_ID ) {
581+ /* header doesn't exist */
582+ settings_element .previous_hash = 0 ;
583+ settings_element .next_hash = 0 ;
584+ rc = zms_write (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
585+ sizeof (struct settings_hash_linked_list ));
586+ if (rc < 0 ) {
587+ return rc ;
559588 }
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 ;
589+ cf -> last_hash_id = ZMS_LL_HEAD_HASH_ID ;
590+ cf -> second_to_last_hash_id = 0 ;
591+ } else {
592+ /* let's recover it by keeping all nodes until the last one */
593+ settings_element .previous_hash = cf -> second_to_last_hash_id ;
594+ settings_element .next_hash = 0 ;
595+ rc = zms_write (& cf -> cf_zms , cf -> last_hash_id , & settings_element ,
596+ sizeof (struct settings_hash_linked_list ));
597+ if (rc < 0 ) {
598+ return rc ;
567599 }
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 );
571600 }
572601
573602 return 0 ;
@@ -591,29 +620,7 @@ static int settings_zms_get_last_hash_ids(struct settings_zms *cf)
591620 /* header doesn't exist or linked list broken, reinitialize the header
592621 * if it doesn't exist and recover it if it is broken
593622 */
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 ;
623+ return settings_zms_init_or_recover_ll (cf , ll_last_hash_id );
617624 } else if (rc < 0 ) {
618625 return rc ;
619626 }
0 commit comments