@@ -150,6 +150,56 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
150
150
return rc ;
151
151
}
152
152
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
+
153
203
static int settings_zms_load (struct settings_store * cs , const struct settings_load_arg * arg )
154
204
{
155
205
int ret = 0 ;
@@ -160,6 +210,15 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
160
210
ssize_t rc1 ;
161
211
ssize_t rc2 ;
162
212
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 */
163
222
164
223
ret = zms_read (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
165
224
sizeof (struct settings_hash_linked_list ));
@@ -168,6 +227,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
168
227
}
169
228
ll_hash_id = settings_element .next_hash ;
170
229
230
+ /* If subtree is NULL then we must load all found Settings */
171
231
while (ll_hash_id ) {
172
232
173
233
/* In the ZMS backend, each setting item is stored in two ZMS
0 commit comments