The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"странное поведение copy_from_user()"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы OpenNET: Виртуальная конференция (Public)
Изначальное сообщение [Проследить за развитием треда]

"странное поведение copy_from_user()"
Сообщение от dmitri emailИскать по авторуВ закладки on 02-Авг-03, 22:36  (MSK)

Пишу свой первый драйвер (модуль ядра) под linux. И вот наткнулся
на интересную фишку. В функциях dev_read() и dev_write()
забыл поставить copy_to_user() и copy_from_user() соответственно.
Самое интересное что обнаружил это только через несколько дней.
Все это время драйвер исправно работал. Кто нибудь из kernel guru
может пояснить почему так получилось. Интересно просто..

Ядро у меня 2.4.18, компилятор 2.95.3

// reads from the internal memory of a device, automatically selects HPI or DMA
// depending on block size and memory region (some are not accessible via DMA)
static ssize_t dev_read(struct file *f, char *buf, size_t len, loff_t *off)
{
    struct dev_res *dev;
    unsigned dsp_addr = *off;
    DECLARE_WAITQUEUE(wait, current);
    ssize_t retval;
    
    dprintk("dev_read \n");
    if(!(dev = dev_ptr(f)))
return -EINVAL;
        
    if(should_use_hpi(dev, dsp_addr, len)) {
    
dprintk("hpi_read: addr 0x%x len %d \n", dsp_addr, len);
    
if(hpi_read(dev, dsp_addr, (unsigned *)buf, len/4) == -1)
    return -EAGAIN;
    
return len;
    }
    
    dprintk("dma_read: addr 0x%x len %d \n", dsp_addr, len);
        
    spin_lock_irq(&dev_lock);
    dev->is_reading = 1;
    spin_unlock_irq(&dev_lock);
    
    dma_read(dev, dsp_addr, len);
        
    add_wait_queue(&dev_waitq, &wait);
    current->state = TASK_INTERRUPTIBLE;

    while(1) {
    
int is_reading;
    
spin_lock_irq(&dev_lock);
is_reading = dev->is_reading;
spin_unlock_irq(&dev_lock);

if(!is_reading)
    break;
    
if(f->f_flags & O_NONBLOCK) {
    retval = -EAGAIN;
    goto out1;
}

if(signal_pending(current)) {
    retval = -ERESTARTSYS;
    goto out1;
}     
schedule();
    }
    
    copy_to_user(buf, (void *)dev->dma_buf, len);

    retval = len;
    
out1:
    current->state = TASK_RUNNING;
    remove_wait_queue(&dev_waitq, &wait);
    
    return retval;
}

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру