Функция idr_alloc (...) иногда завершается с ошибкой -EINVAL (-22) - PullRequest
0 голосов
/ 27 мая 2019

Я пробую API ядра для IDR (управление целочисленными идентификаторами).Это карта, где идентификатор получает связан с указателем.API изменился, так что старые примеры, которые я нашел, не сработали.Так что я сделал свой собственный пример, и он работает только частично.Иногда происходит сбой функции idr_alloc с -22 (-EINVAL).

Когда я посмотрел на исходный код реализации (https://elixir.bootlin.com/linux/latest/source),, я обнаружил, что единственной ошибкой является (-ENOMEM, нет памяти и-ENOSPC (больше нет идентификаторов). Я компилирую свой код для: Linux Ubuntu 4.15.0-33-generic.

#include <linux/module.h>
#include <linux/init.h>
#include <linux/idr.h>

struct idr map;

char *cptr1 = "Chennai";
char *cptr2 = "Lockheed Martin";
char *cptr3 = "Libary";

int deleter (int id, void *ptr, void *data ) {
    idr_remove( &map, id );
    return 0;
}

int showKeyValuePair( int id, void *ptr, void *data ) {
    printk("Key : %d | Value : %s\n", id, (char *)ptr );
    return 0;
}

static int __init mod_init(void)        
{                                                                   
    int id[3];
    char *ptr;

    printk("IDR\n");    
    idr_init( &map );       

    id[0] = idr_alloc( &map, (void *)cptr1, 0, 0, GFP_KERNEL );
    id[1] = idr_alloc( &map, (void *)cptr2, 0, 0, GFP_KERNEL );
    id[2] = idr_alloc( &map, (void *)cptr3, 0, 0, GFP_KERNEL );

    printk("Reserved ID's : {%d, %d, %d}\n", id[0], id[1], id[2] );

    ptr = idr_find( &map, id[0] );
    printk("Find for ID %d = %s\n", id[0], (ptr != NULL) ? ptr : "not found" );


    idr_for_each( &map, showKeyValuePair, NULL );

    return 0;
}

static void __exit mod_exit(void) 
{
    idr_for_each( &map, deleter, NULL );    
    idr_destroy( &map );        // void idr_destroy (struct idr *)
}

module_init(mod_init);  
module_exit(mod_exit);
MODULE_LICENSE("GPL");

1 Ответ

1 голос
/ 27 мая 2019

Хорошо, я обнаружил, что реализация в Linux ubuntu 4.15.0-33-generic глючит. Я скомпилировал свой код для Kernel Source Tree версии 4.9.0-8-amd64, и это сработало. Код -EINVAL возвращается при запуске, третий параметр idr_alloc меньше 0, но это не так, но idr_alloc вызывает idr_alloc_cmn в старой версии, и это, вероятно, возвращает -EINVAL. Я не могу найти реализацию idr_alloc_cmn, но самое главное: она работает сейчас.

...