2012-03-05 2 views
1

Я заметил, что когда я вызываю lseek64 в файл драйвера блока устройства (/ dev/mybd), он всегда терпит неудачу. (Я могу открывать, читать и писать на/dev/mybd ok).Выполняет ли lseek64 какое-либо действие какого-либо устройства?

Однако, если я могу lseek64 с тем же аргументом на/dev/sdb, который является диском sata, он всегда преуспевает.

Требуется ли lseek для поддержки любого блока? Или это чистая функция ядра?

+1

Да, так оно и есть. Что вы пробовали? –

+0

@BasileStarynkevitch Итак, что мне делать, чтобы заставить драйвер устройства поддерживать lseek? – yangsuli

+0

Я не эксперт в области ядра. Вы читали http://www.makelinux.net/ldd3/chp-16-sect-2 –

ответ

3

Глядя на код, по умолчанию искать для блочных устройств в fs/block_dev.c:

static loff_t block_llseek(struct file *file, loff_t offset, int origin) 
{ 
     struct inode *bd_inode = file->f_mapping->host; 
     loff_t size; 
     loff_t retval; 

     mutex_lock(&bd_inode->i_mutex); 
     size = i_size_read(bd_inode); 

     retval = -EINVAL; 
     switch (origin) { 
       case SEEK_END: 
         offset += size; 
         break; 
       case SEEK_CUR: 
         offset += file->f_pos; 
       case SEEK_SET: 
         break; 
       default: 
         goto out; 
     } 
     if (offset >= 0 && offset <= size) { 
       if (offset != file->f_pos) { 
         file->f_pos = offset; 
       } 
       retval = offset; 
     } 
out: 
     mutex_unlock(&bd_inode->i_mutex); 
     return retval; 
} 

Нет вызова к конкретному блочному устройству. Единственный конкретный вызов - i_size_read, который просто делает магию SMP.

0

lseek - системный вызов. И это конкретное ядро. Вы должны реализовать эту функцию для своего устройства и добавить в структуру «file_operations» драйвера устройства в вызове llseek.

В структуре file_operation все связанные с устройством функции будут сопоставлены с соответствующими системными вызовами. Подобно чтению, записи, открытию все будет связано с конкретным кодом драйвера устройства. Поэтому всякий раз, когда вы вызываете эти функции, ядро ​​запускает код драйвера устройства, связанный с вызовом. Если драйвер устройства никогда не выполняет вызов, соответствующее значение будет указано как NULL. В этом случае, если вы вызываете указанный NULL вызов, вызов будет всегда терпеть неудачу.

Но в lseek, если ссылка структуры 'file_operations' равна NULL, ядро ​​будет работать с указателем структуры файла в позицию файла. Это может привести к непредсказуемым результатам. Но в любом случае вызов будет работать (согласно драйверам устройств Linux из публикации o'relley).

Так что я не уверен, что представляет собой настоящую проблему. Поэтому, если вы еще не реализовали вызов lseek, выполните его и попробуйте еще раз.