99#include <linux/delay.h>
1010#include <linux/device-mapper.h>
1111#include <linux/err.h>
12+ #include <linux/log2.h>
1213#include <linux/module.h>
1314#include <linux/mutex.h>
1415#include <linux/spinlock.h>
@@ -377,6 +378,75 @@ static inline int __must_check parse_bool(const char *bool_str, const char *true
377378 return VDO_SUCCESS ;
378379}
379380
381+ /**
382+ * parse_memory() - Parse a string into an index memory value.
383+ * @memory_str: The string value to convert to a memory value.
384+ * @memory_ptr: A pointer to return the memory value in.
385+ *
386+ * Return: VDO_SUCCESS or an error
387+ */
388+ static int __must_check parse_memory (const char * memory_str ,
389+ uds_memory_config_size_t * memory_ptr )
390+ {
391+ uds_memory_config_size_t memory ;
392+
393+ if (strcmp (memory_str , "0.25" ) == 0 ) {
394+ memory = UDS_MEMORY_CONFIG_256MB ;
395+ } else if ((strcmp (memory_str , "0.5" ) == 0 ) || (strcmp (memory_str , "0.50" ) == 0 )) {
396+ memory = UDS_MEMORY_CONFIG_512MB ;
397+ } else if (strcmp (memory_str , "0.75" ) == 0 ) {
398+ memory = UDS_MEMORY_CONFIG_768MB ;
399+ } else {
400+ unsigned int value ;
401+ int result ;
402+
403+ result = kstrtouint (memory_str , 10 , & value );
404+ if (result ) {
405+ vdo_log_error ("optional parameter error: invalid memory size, must be a postive integer" );
406+ return - EINVAL ;
407+ }
408+
409+ if (value > UDS_MEMORY_CONFIG_MAX ) {
410+ vdo_log_error ("optional parameter error: invalid memory size, must not be greater than %d" ,
411+ UDS_MEMORY_CONFIG_MAX );
412+ return - EINVAL ;
413+ }
414+
415+ memory = value ;
416+ }
417+
418+ * memory_ptr = memory ;
419+ return VDO_SUCCESS ;
420+ }
421+
422+ /**
423+ * parse_slab_size() - Parse a string option into a slab size value.
424+ * @slab_str: The string value representing slab size.
425+ * @slab_size_ptr: A pointer to return the slab size in.
426+ *
427+ * Return: VDO_SUCCESS or an error
428+ */
429+ static int __must_check parse_slab_size (const char * slab_str , block_count_t * slab_size_ptr )
430+ {
431+ block_count_t value ;
432+ int result ;
433+
434+ result = kstrtoull (slab_str , 10 , & value );
435+ if (result ) {
436+ vdo_log_error ("optional parameter error: invalid slab size, must be a postive integer" );
437+ return - EINVAL ;
438+ }
439+
440+ if (value < MIN_VDO_SLAB_BLOCKS || value > MAX_VDO_SLAB_BLOCKS || (!is_power_of_2 (value ))) {
441+ vdo_log_error ("optional parameter error: invalid slab size, must be a power of two between %u and %u" ,
442+ MIN_VDO_SLAB_BLOCKS , MAX_VDO_SLAB_BLOCKS );
443+ return - EINVAL ;
444+ }
445+
446+ * slab_size_ptr = value ;
447+ return VDO_SUCCESS ;
448+ }
449+
380450/**
381451 * process_one_thread_config_spec() - Process one component of a thread parameter configuration
382452 * string and update the configuration data structure.
@@ -566,7 +636,7 @@ static int process_one_key_value_pair(const char *key, unsigned int value,
566636 }
567637 /* Max discard sectors in blkdev_issue_discard is UINT_MAX >> 9 */
568638 if (value > (UINT_MAX / VDO_BLOCK_SIZE )) {
569- vdo_log_error ("optional parameter error: at most %d max discard blocks are allowed" ,
639+ vdo_log_error ("optional parameter error: at most %d max discard blocks are allowed" ,
570640 UINT_MAX / VDO_BLOCK_SIZE );
571641 return - EINVAL ;
572642 }
@@ -598,7 +668,16 @@ static int parse_one_key_value_pair(const char *key, const char *value,
598668 if (strcmp (key , "compression" ) == 0 )
599669 return parse_bool (value , "on" , "off" , & config -> compression );
600670
601- /* The remaining arguments must have integral values. */
671+ if (strcmp (key , "indexSparse" ) == 0 )
672+ return parse_bool (value , "on" , "off" , & config -> index_sparse );
673+
674+ if (strcmp (key , "indexMemory" ) == 0 )
675+ return parse_memory (value , & config -> index_memory );
676+
677+ if (strcmp (key , "slabSize" ) == 0 )
678+ return parse_slab_size (value , & config -> slab_blocks );
679+
680+ /* The remaining arguments must have non-negative integral values. */
602681 result = kstrtouint (value , 10 , & count );
603682 if (result ) {
604683 vdo_log_error ("optional config string error: integer value needed, found \"%s\"" ,
@@ -756,6 +835,9 @@ static int parse_device_config(int argc, char **argv, struct dm_target *ti,
756835 config -> max_discard_blocks = 1 ;
757836 config -> deduplication = true;
758837 config -> compression = false;
838+ config -> index_memory = UDS_MEMORY_CONFIG_256MB ;
839+ config -> index_sparse = false;
840+ config -> slab_blocks = DEFAULT_VDO_SLAB_BLOCKS ;
759841
760842 arg_set .argc = argc ;
761843 arg_set .argv = argv ;
@@ -781,7 +863,7 @@ static int parse_device_config(int argc, char **argv, struct dm_target *ti,
781863 /* Get the physical blocks, if known. */
782864 if (config -> version >= 1 ) {
783865 result = kstrtoull (dm_shift_arg (& arg_set ), 10 , & config -> physical_blocks );
784- if (result != VDO_SUCCESS ) {
866+ if (result ) {
785867 handle_parse_error (config , error_ptr ,
786868 "Invalid physical block count" );
787869 return VDO_BAD_CONFIGURATION ;
@@ -802,15 +884,15 @@ static int parse_device_config(int argc, char **argv, struct dm_target *ti,
802884
803885 /* Get the page cache size. */
804886 result = kstrtouint (dm_shift_arg (& arg_set ), 10 , & config -> cache_size );
805- if (result != VDO_SUCCESS ) {
887+ if (result ) {
806888 handle_parse_error (config , error_ptr ,
807889 "Invalid block map page cache size" );
808890 return VDO_BAD_CONFIGURATION ;
809891 }
810892
811893 /* Get the block map era length. */
812894 result = kstrtouint (dm_shift_arg (& arg_set ), 10 , & config -> block_map_maximum_age );
813- if (result != VDO_SUCCESS ) {
895+ if (result ) {
814896 handle_parse_error (config , error_ptr , "Invalid block map maximum age" );
815897 return VDO_BAD_CONFIGURATION ;
816898 }
@@ -1457,10 +1539,13 @@ static int vdo_initialize(struct dm_target *ti, unsigned int instance,
14571539 vdo_log_debug ("Logical blocks = %llu" , logical_blocks );
14581540 vdo_log_debug ("Physical block size = %llu" , (u64 ) block_size );
14591541 vdo_log_debug ("Physical blocks = %llu" , config -> physical_blocks );
1542+ vdo_log_debug ("Slab size = %llu" , config -> slab_blocks );
14601543 vdo_log_debug ("Block map cache blocks = %u" , config -> cache_size );
14611544 vdo_log_debug ("Block map maximum age = %u" , config -> block_map_maximum_age );
14621545 vdo_log_debug ("Deduplication = %s" , (config -> deduplication ? "on" : "off" ));
14631546 vdo_log_debug ("Compression = %s" , (config -> compression ? "on" : "off" ));
1547+ vdo_log_debug ("Index memory = %u" , config -> index_memory );
1548+ vdo_log_debug ("Index sparse = %s" , (config -> index_sparse ? "on" : "off" ));
14641549
14651550 vdo = vdo_find_matching (vdo_uses_device , config );
14661551 if (vdo != NULL ) {
@@ -2856,7 +2941,7 @@ static void vdo_resume(struct dm_target *ti)
28562941static struct target_type vdo_target_bio = {
28572942 .features = DM_TARGET_SINGLETON ,
28582943 .name = "vdo" ,
2859- .version = { 9 , 1 , 0 },
2944+ .version = { 9 , 2 , 0 },
28602945 .module = THIS_MODULE ,
28612946 .ctr = vdo_ctr ,
28622947 .dtr = vdo_dtr ,
0 commit comments