2016-10-05 7 views
1

カーネル空間のバッファにファイルを読み込むための読み込み関数を作成しました。カーネルの2回目の読み込みは、最初のインスタンスをオーバーライドします。

int readfile(const char *filename, void *buf, int len, int offset) 
{ 
    struct file *filp; 
    mm_segment_t oldfs; 
    int bytes; 
    filp = NULL; 
    filp = filp_open(filename, O_RDONLY, 0); 
    if(!filp || IS_ERR(filp)) { 
     printk(" Error in reading file %s. Error = %d\n", filename, \ 
       (int) PTR_ERR(filp)); 
     return -1; 
    } 
    filp->f_pos = offset; 
    oldfs = get_fs(); 
    set_fs(get_ds()); 
    bytes = vfs_read(filp, buf, len, &filp->f_pos); 
    set_fs(oldfs); 
    filp_close(filp, NULL); 
    return bytes; 
} 

さて、この機能は本当にうまく機能し、私はその後、私のシステムコール

char *firstbuffer; 
firstbuffer = kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL); 

bytesread = readfile(firstfile, firstbuffer, len, 0); 

// Null terminate read string 
firstbuffer[bytesread] = '\0'; 
printk("first buffer = %s\n",firstbuffer); 

からこの関数を呼び出すことにより、BUFにfilenameの内容を読み取ることができています、私は読むためにもう一度この関数を呼び出しています第2のファイルの内容を第2のバッファに入れる。

char *secondbuffer; 
secondbuffer = kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL); 
bytesread2 = readfile(secondfile, secondbuffer, len, 0); 
// Null terminate read string 
secondbuffer[bytesread2] = '\0'; 
printk("second buffer %s", secondbuffer); 

問題がsecondfileの読み取り機能を呼び出した後、私のfirstbufferの内容はsecondbufferの内容で上書きなっていることです。例えば

:firstfileの内容はsecondfileの

A 
B 
C 

及びコンテンツである場合、最初のファイルの呼び出しを読んだ後

X 
Y 
Z 

次いで、firstbufferの含有量がされています

A 
B 
C 

を読み込み、2回目の読み込みファイル呼び出しの後、最初のバッファの内容は

A 
X 
Y 
Z 

ここで何がうまくいかないのかは分かりませんが、2回目のread関数呼び出しの後、firstbufferの内容がsecondbufferの内容とマージされています。これをどうやって解決するのですか?

免責事項:

私たちはカーネル空間でファイルI/Oを行うべきではありません知っています。これは、純粋にカーネル空間での読み取り関数の働きを学ぶことです。

+0

'firstbuffer'と' secondbuffer'の値を印刷できますか?例えば、 'printf(" 1%p \ n2:%p \ n "、firstbuffer、secondbuffer);' – jxh

+0

@jxh:はい私はその値を表示できます。 printk( "%s \ n、firstbuffer)とprintk("%s \ n、secondbuffer ")を使ってください。 – Piyush

+0

@JohnKugelman:完了。 mcvの例が追加されました。 – Piyush

答えて

1
kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL) 

これは、sizeof(PAGE_SIZE)バイトを割り当てます。今、PAGE_SIZEは整数なので、おそらく4バイトの長さなので、4バイトを割り当てます。あなたがPAGE_SIZEバイトを割り当てたい場合

は、使用:

kmalloc(PAGE_SIZE, GFP_KERNEL) 
+0

ああ、ありがとうございました。これは問題を解決しました。どのような愚かな間違い。さて、私は、プログラムがどのように動作していたかについてはまだ分かりません。私はいつも4バイト以上を書いていたと確信しています。とにかくもう一度@immibis – Piyush

+1

@ Piyush 4バイトを割り当てることは、4バイトがあなたのために予約されていることを意味しますが、4バイトしか存在しないことを意味します。あなたに予約されている4バイトの後に書き込むことができます。その後、他の誰かのメモリ、または未使用のメモリに書き込むことができます。 – immibis

-1
int readfile(const char *filename, void *buf, int len, int offset) 
{ 
    struct file *filp; 
    mm_segment_t oldfs; 
    int bytes; 
    filp = NULL; 

なぜ?これは直ちに上書きされます。

filp = filp_open(filename, O_RDONLY, 0); 
    if(!filp || IS_ERR(filp)) { 

filp_openはNULLを返しません。

 printk(" Error in reading file %s. Error = %d\n", filename, \ 
       (int) PTR_ERR(filp)); 

ログレベルの不足(例:KERN_WARNING)。不正なメッセージで、実際の読み取りに失敗したことが示唆されます。 PTR_ERRは既にintを返します。

 return -1; 

これはPTR_ERR(filp)ではなく-1を返すのはなぜですか?

} 
    filp->f_pos = offset; 

これは奇妙な虐待です。なぜあなたはf_posをファイルオブジェクトに設定していますか?あなたが賞賛のように消費者をチェックするならば、あなたはオフセットのための専用の変数を持っていて、フィールドだけを残すはずです。

oldfs = get_fs(); 
    set_fs(get_ds()); 
    bytes = vfs_read(filp, buf, len, &filp->f_pos); 
    set_fs(oldfs); 
    filp_close(filp, NULL); 
    return bytes; 
} 

今、他の部分:

char *firstbuffer; 
firstbuffer = kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL); 

のsizeofのバグはすでに述べました。エラーチェックがありませんが、簡潔さのためにカットされたものとしましょう。

bytesread = readfile(firstfile, firstbuffer, len, 0); 

は、なぜあなたはPAGE_SIZEを割り当てるが、LENを読んでいますか?

// Null terminate read string 

役に立たなかった点

firstbuffer[bytesread] = '\0'; 

bytesread == PAGE_SIZEの場合、これはオフラインです。

printk("first buffer = %s\n",firstbuffer); 
[snip] 
printk("second buffer %s", secondbuffer); 

不良デバッグprintfs。ものをダンプする必要がある場合は、何かを囲む必要があります。 "[%s]"空きスペースがない場合firstbuffer。メッセージには一貫性がありません。一方は「=」を持ち、もう一方はそうではありません。

関連する問題