Skip to content

Commit 40d6569

Browse files
committed
[nrf fromlist] settings: zms: code style clean up
Clean some parts of the code and refactor it to avoid multiple nested conditions. Upstream PR #: 87792 Signed-off-by: Riadh Ghaddab <[email protected]> (cherry picked from commit 2c122d964b64289f925f2da2a6aa916215ae664a)
1 parent af5b740 commit 40d6569

File tree

3 files changed

+143
-129
lines changed

3 files changed

+143
-129
lines changed

subsys/settings/include/settings/settings_zms.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ extern "C" {
6868
((x & ~ZMS_COLLISIONS_MASK) | ((y << 1) & ZMS_COLLISIONS_MASK))
6969
#define ZMS_COLLISION_NUM(x) ((x & ZMS_COLLISIONS_MASK) >> 1)
7070
#define ZMS_NAME_ID_FROM_HASH(x) ((x & ZMS_HASH_TOTAL_MASK) | BIT(31))
71+
#define ZMS_DATA_ID_FROM_HASH(x) (ZMS_NAME_ID_FROM_HASH(x) + ZMS_DATA_ID_OFFSET)
72+
#define ZMS_DATA_ID_FROM_NAME(x) (x + ZMS_DATA_ID_OFFSET)
73+
#define ZMS_DATA_ID_FROM_LL_NODE(x) (ZMS_NAME_ID_FROM_LL_NODE(x) + ZMS_DATA_ID_OFFSET)
7174

7275
struct settings_hash_linked_list {
7376
uint32_t previous_hash;

subsys/settings/src/settings_zms.c

Lines changed: 127 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -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

260311
static 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
538557
static 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

Comments
 (0)