@@ -150,6 +150,56 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
150150 return rc ;
151151}
152152
153+ #ifdef CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH
154+ /* Loads first the key which is defined by the name found in "subtree" root.
155+ * If the key is not found or further keys under the same subtree are needed
156+ * by the caller, returns 0.
157+ */
158+ static int settings_zms_load_subtree (struct settings_store * cs , const struct settings_load_arg * arg )
159+ {
160+ struct settings_zms * cf = CONTAINER_OF (cs , struct settings_zms , cf_store );
161+ struct settings_zms_read_fn_arg read_fn_arg ;
162+ char name [SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1 ];
163+ ssize_t rc1 ;
164+ ssize_t rc2 ;
165+ uint32_t name_hash ;
166+
167+ name_hash = sys_hash32 (arg -> subtree , strlen (arg -> subtree )) & ZMS_HASH_MASK ;
168+ for (int i = 0 ; i <= cf -> hash_collision_num ; i ++ ) {
169+ name_hash = ZMS_UPDATE_COLLISION_NUM (name_hash , i );
170+ /* Get the name entry from ZMS */
171+ rc1 = zms_read (& cf -> cf_zms , ZMS_NAME_ID_FROM_HASH (name_hash ), & name ,
172+ sizeof (name ) - 1 );
173+ /* get the length of data and verify that it exists */
174+ rc2 = zms_get_data_length (& cf -> cf_zms ,
175+ ZMS_NAME_ID_FROM_HASH (name_hash ) + ZMS_DATA_ID_OFFSET );
176+ if ((rc1 <= 0 ) || (rc2 <= 0 )) {
177+ /* Name or data doesn't exist */
178+ continue ;
179+ }
180+ /* Found a name, this might not include a trailing \0 */
181+ name [rc1 ] = '\0' ;
182+ if (strcmp (arg -> subtree , name )) {
183+ /* Names are not equal let's continue to the next collision hash
184+ * if it exists.
185+ */
186+ continue ;
187+ }
188+ /* At this steps the names are equal, let's set the handler */
189+ read_fn_arg .fs = & cf -> cf_zms ;
190+ read_fn_arg .id = ZMS_NAME_ID_FROM_HASH (name_hash ) + ZMS_DATA_ID_OFFSET ;
191+
192+ /* We should return here as there is no need to look for the next
193+ * hash collision
194+ */
195+ return settings_call_set_handler (arg -> subtree , rc2 , settings_zms_read_fn , & read_fn_arg ,
196+ (void * )arg );
197+ }
198+
199+ return 0 ;
200+ }
201+ #endif /* CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH */
202+
153203static int settings_zms_load (struct settings_store * cs , const struct settings_load_arg * arg )
154204{
155205 int ret = 0 ;
@@ -160,6 +210,15 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
160210 ssize_t rc1 ;
161211 ssize_t rc2 ;
162212 uint32_t ll_hash_id ;
213+ #ifdef CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH
214+ /* If arg->subtree is not null we must first load settings in that subtree */
215+ if (arg -> subtree != NULL ) {
216+ ret = settings_zms_load_subtree (cs , arg );
217+ if (ret ) {
218+ return ret ;
219+ }
220+ }
221+ #endif /* CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH */
163222
164223 ret = zms_read (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
165224 sizeof (struct settings_hash_linked_list ));
@@ -168,6 +227,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
168227 }
169228 ll_hash_id = settings_element .next_hash ;
170229
230+ /* If subtree is NULL then we must load all found Settings */
171231 while (ll_hash_id ) {
172232
173233 /* In the ZMS backend, each setting item is stored in two ZMS
0 commit comments