ブロックデバイスドライバファイル(/ dev/mybd)でlseek64を呼び出すと、常に失敗します。 (私は/ dev/mybd okで開いて、読み書きできます)。lseek64にはデバイス固有のアクションが発生しますか?
しかし、私がlseek64を/ dev/sdb(データディスク)と同じ引数で使うことができれば、常に成功します。
lseekにはブロックデバイスのサポートが必要ですか?それとも純粋なカーネル関数ですか?コードを見ると、デフォルトではブロック・デバイス用の
ブロックデバイスドライバファイル(/ dev/mybd)でlseek64を呼び出すと、常に失敗します。 (私は/ dev/mybd okで開いて、読み書きできます)。lseek64にはデバイス固有のアクションが発生しますか?
しかし、私がlseek64を/ dev/sdb(データディスク)と同じ引数で使うことができれば、常に成功します。
lseekにはブロックデバイスのサポートが必要ですか?それとも純粋なカーネル関数ですか?コードを見ると、デフォルトではブロック・デバイス用の
求める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の魔法の一部です。
lseekはシステムコールです。そしてそれはカーネル固有です。デバイス用にこの関数を実装する必要があり、llseek呼び出しでデバイスドライバの "file_operations"構造を追加する必要があります。
file_operation構造では、すべてのデバイス関連関数が関連するシステムコールにマップされます。読み込み、書き込み、開かれると、すべてが特定のデバイスドライバコードにリンクされます。したがって、これらの関数を呼び出すたびに、カーネルは呼び出しにリンクされたデバイスドライバのコードを実行します。デバイスドライバが決して呼び出しを実装しない場合、対応する値はNULLとして指定されます。この場合、指定されたNULL呼び出しを呼び出すと、呼び出しは常に失敗します。
しかし、 'file_operations'構造リンクがNULLの場合、カーネルはファイル位置に対する 'file'構造体ポインタを処理します。これにより、予期しない結果が生じることがあります。しかし、とにかくコールは(o'relleyの出版物からLinuxのデバイスドライバごとに)動作します。
ここで本当の問題は何か分かりません。したがって、実際にlseekコールを実装していない場合は、実装してもう一度試してみてください。
はい。何を試しましたか? –
@BasileStarynkevitchそれでは、デバイスドライバをlseekに対応させるにはどうすればよいですか? – yangsuli
私はカーネルの専門家ではありません。あなたはhttp://www.makelinux.net/ldd3/chp-16-sect-2 –