Skip to content

Commit 3f9e05a

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 975e81665d2f92d264b13760c9e2fdb22b0fb112)
1 parent af5b740 commit 3f9e05a

File tree

3 files changed

+144
-133
lines changed

3 files changed

+144
-133
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: 128 additions & 121 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;
@@ -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

260308
static 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
538554
static 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

Comments
 (0)