preadシステムコール


Rev.2を表示中。最新版はこちら

preadシステムコールはファイルの指定位置から読み込み、ファイルの読み込み位置を更新しません。以下のサンプルでreadで読み込むと、01234/56789/NULLとなります。

manによると、 他のスレッドによるファイルオフセットの変更の影響を受けることなく、 複数のスレッドが同じファイルディスクリプタに対して入出力を行うことができる。と言うことですが、また、再読込みはキャッシュから読み込まれるため、巨大なファイルデータをわざわざバッファに読み込んで、処理するのでなく、ファイルその物をデータバッファの如く取り扱うといった利用も可能となります。
#include <stdio.h>
#include <fcntl.h>

void    main(void)
{
   int  fd, i;
   char buf[6];

   fd = open("hoge", O_RDONLY);
   for (i = 0; i < 5; i++) {
       pread(fd, buf, 5, 0);
       buf[5] = 0;
       printf("%s\n", buf);
   }
   pread(fd, buf, 5, 5);
   buf[5] = 0;
   printf("%s\n", buf);
}

[root@localhost lkm]# echo 0123456789 > hoge
[root@localhost lkm]# ./a.out
01234
01234
01234
01234
01234
56789
readは、file_pos_read()を読込み位置に、file_pos_write()で読込んだ位置をfile->f_posとしますが、preadは引数をそのまま読込み位置とし、file->f_posを更新しないだけです。pwriteについても同じです。openしたファイルはFMODE_PREADF/MODE_PWRITEが設定されており、FMODE_PREADF/MODE_PWRITEはカーネル内でリセットされるフラグです。

sql_fileはMODE_PWRITEがリセットされます。objectがリスト管理されていて、飛び越えたobjectを書き込む場合、リストする親が存在してなく、当該のobjectを登録する事ができないからです。
SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
                       size_t count, loff_t pos)
{
       struct file *file;
       ssize_t ret = -EBADF;
       int fput_needed;

       if (pos < 0)
               return -EINVAL;

       file = fget_light(fd, &fput_needed);
       if (file) {
               ret = -ESPIPE;
               if (file->f_mode & FMODE_PREAD)
                       ret = vfs_read(file, buf, count, &pos);
               fput_light(file, fput_needed);
       }

       return ret;
}

SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
       struct file *file;
       ssize_t ret = -EBADF;
       int fput_needed;

       file = fget_light(fd, &fput_needed);
       if (file) {
               loff_t pos = file_pos_read(file);
               ret = vfs_read(file, buf, count, &pos);
               file_pos_write(file, pos);
               fput_light(file, fput_needed);
       }

       return ret;
}

static inline void file_pos_write(struct file *file, loff_t pos)
{
       file->f_pos = pos;
}


最終更新 2015/01/20 00:20:24 - north
(2015/01/19 22:13:37 作成)


検索

アクセス数
3690422
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。