2009-07-26 15 views
73

私は、カーネルからファイルを読み書きするべきではなく、代わりに/ procやnetlinkを使ってファイルを読み書きするべきであるという議論を知っています。私はとにかく読み書きしたい。私も Driving Me Nuts - Things You Never Should Do in the Kernelを読んだ。Linuxカーネルモジュール内でファイルを読み書きする方法は?

ただし、問題は2.6.30はsys_read()をエクスポートしません。むしろそれはSYSCALL_DEFINE3に包まれています。だから私は、私のモジュールで、私は次の警告を得ることを使用する場合:

WARNING: "sys_read" [xxx.ko] undefined! 
WARNING: "sys_open" [xxx.ko] undefined! 

リンクが正しく行われないので、明らかにinsmodモジュールをロードすることはできません。

質問:

  • 方法(sys_read()/sys_open()はエクスポートされません)2.6.22後のカーネル内の読み取り/書き込みするには?
  • 一般に、カーネル内のマクロSYSCALL_DEFINEn()にラップされたシステムコールを使用する方法はありますか?

答えて

94

可能な場合はファイルI/Oを避ける必要があることに注意してください。

が含まれています::

#include <linux/fs.h> 
#include <asm/segment.h> 
#include <asm/uaccess.h> 
#include <linux/buffer_head.h> 

(開くことが似ている)ファイルを開く:

struct file *file_open(const char *path, int flags, int rights) 
{ 
    struct file *filp = NULL; 
    mm_segment_t oldfs; 
    int err = 0; 

    oldfs = get_fs(); 
    set_fs(get_ds()); 
    filp = filp_open(path, flags, rights); 
    set_fs(oldfs); 
    if (IS_ERR(filp)) { 
     err = PTR_ERR(filp); 
     return NULL; 
    } 
    return filp; 
} 

を主なアイデアは、「1つのレベルより深い」行き、直接システムコールハンドラの代わりにVFS level functionsを呼び出すことですファイルを閉じる(閉じるに類似):

void file_close(struct file *file) 
{ 
    filp_close(file, NULL); 
} 

ファイルからデータを読み込むD):PWRITEのようなファイル()へ

int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{ 
    mm_segment_t oldfs; 
    int ret; 

    oldfs = get_fs(); 
    set_fs(get_ds()); 

    ret = vfs_read(file, data, size, &offset); 

    set_fs(oldfs); 
    return ret; 
} 

書き込みデータ:元々

int file_sync(struct file *file) 
{ 
    vfs_fsync(file, 0); 
    return 0; 
} 

[編集]:

int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{ 
    mm_segment_t oldfs; 
    int ret; 

    oldfs = get_fs(); 
    set_fs(get_ds()); 

    ret = vfs_write(file, data, size, &offset); 

    set_fs(oldfs); 
    return ret; 
} 

の同期にはfsyncに似たファイルを()を変更します私はfile_fsyncを使うことを提案しました。これは新しいカーネルバージョンではなくなりました。変更を提案した貧しい人に感謝しますが、その変更は拒否されました。私はそれを見直す前に編集が拒否されました。

+2

ありがとうございます。私はsys_read/sys_openの機能を複製することで同様のことを行うことを考えていました。しかし、これは大きな助けです。好奇心、SYSCALL_DEFINEを使って宣言されたシステムコールを使う方法はありますか? – Methos

+5

私はこのコードをカーネル2.6.30(Ubuntu 9.04)で試してみましたが、ファイルを読むとシステムがクラッシュしました。誰もが同じ問題を経験しましたか? –

+0

@Enrico Detoma?ああすごい。これはあなたが私にあなたが使ったモジュールを与えることができる何らかの方法ですか?前にそれを見たことがない? – dmeister

関連する問題