|
@@ -552,10 +552,11 @@ int store_setting ( struct settings *settings, struct setting *setting,
|
552
|
552
|
}
|
553
|
553
|
|
554
|
554
|
/**
|
555
|
|
- * Fetch value of setting
|
|
555
|
+ * Fetch value and origin of setting
|
556
|
556
|
*
|
557
|
557
|
* @v settings Settings block, or NULL to search all blocks
|
558
|
558
|
* @v setting Setting to fetch
|
|
559
|
+ * @v origin Origin of setting to fill in
|
559
|
560
|
* @v data Buffer to fill with setting data
|
560
|
561
|
* @v len Length of buffer
|
561
|
562
|
* @ret len Length of setting data, or negative error
|
|
@@ -563,13 +564,17 @@ int store_setting ( struct settings *settings, struct setting *setting,
|
563
|
564
|
* The actual length of the setting will be returned even if
|
564
|
565
|
* the buffer was too small.
|
565
|
566
|
*/
|
566
|
|
-int fetch_setting ( struct settings *settings, struct setting *setting,
|
567
|
|
- void *data, size_t len ) {
|
|
567
|
+static int fetch_setting_and_origin ( struct settings *settings,
|
|
568
|
+ struct setting *setting,
|
|
569
|
+ struct settings **origin,
|
|
570
|
+ void *data, size_t len ) {
|
568
|
571
|
struct settings *child;
|
569
|
572
|
int ret;
|
570
|
573
|
|
571
|
574
|
/* Avoid returning uninitialised data on error */
|
572
|
575
|
memset ( data, 0, len );
|
|
576
|
+ if ( origin )
|
|
577
|
+ *origin = NULL;
|
573
|
578
|
|
574
|
579
|
/* NULL settings implies starting at the global settings root */
|
575
|
580
|
if ( ! settings )
|
|
@@ -583,19 +588,56 @@ int fetch_setting ( struct settings *settings, struct setting *setting,
|
583
|
588
|
if ( setting_applies ( settings, setting ) &&
|
584
|
589
|
( ( ret = settings->op->fetch ( settings, setting,
|
585
|
590
|
data, len ) ) >= 0 ) ) {
|
|
591
|
+ if ( origin )
|
|
592
|
+ *origin = settings;
|
586
|
593
|
return ret;
|
587
|
594
|
}
|
588
|
595
|
|
589
|
596
|
/* Recurse into each child block in turn */
|
590
|
597
|
list_for_each_entry ( child, &settings->children, siblings ) {
|
591
|
|
- if ( ( ret = fetch_setting ( child, setting,
|
592
|
|
- data, len ) ) >= 0 )
|
|
598
|
+ if ( ( ret = fetch_setting_and_origin ( child, setting, origin,
|
|
599
|
+ data, len ) ) >= 0 )
|
593
|
600
|
return ret;
|
594
|
601
|
}
|
595
|
602
|
|
596
|
603
|
return -ENOENT;
|
597
|
604
|
}
|
598
|
605
|
|
|
606
|
+/**
|
|
607
|
+ * Fetch value of setting
|
|
608
|
+ *
|
|
609
|
+ * @v settings Settings block, or NULL to search all blocks
|
|
610
|
+ * @v setting Setting to fetch
|
|
611
|
+ * @v data Buffer to fill with setting data
|
|
612
|
+ * @v len Length of buffer
|
|
613
|
+ * @ret len Length of setting data, or negative error
|
|
614
|
+ *
|
|
615
|
+ * The actual length of the setting will be returned even if
|
|
616
|
+ * the buffer was too small.
|
|
617
|
+ */
|
|
618
|
+int fetch_setting ( struct settings *settings, struct setting *setting,
|
|
619
|
+ void *data, size_t len ) {
|
|
620
|
+ return fetch_setting_and_origin ( settings, setting, NULL, data, len );
|
|
621
|
+}
|
|
622
|
+
|
|
623
|
+/**
|
|
624
|
+ * Fetch origin of setting
|
|
625
|
+ *
|
|
626
|
+ * @v settings Settings block, or NULL to search all blocks
|
|
627
|
+ * @v setting Setting to fetch
|
|
628
|
+ * @ret origin Origin of setting, or NULL if not found
|
|
629
|
+ *
|
|
630
|
+ * This function can also be used as an existence check for the
|
|
631
|
+ * setting.
|
|
632
|
+ */
|
|
633
|
+struct settings * fetch_setting_origin ( struct settings *settings,
|
|
634
|
+ struct setting *setting ) {
|
|
635
|
+ struct settings *origin;
|
|
636
|
+
|
|
637
|
+ fetch_setting_and_origin ( settings, setting, &origin, NULL, 0 );
|
|
638
|
+ return origin;
|
|
639
|
+}
|
|
640
|
+
|
599
|
641
|
/**
|
600
|
642
|
* Fetch length of setting
|
601
|
643
|
*
|