Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_all 

名前
open, creat - ファイルやデバイスのオープン、作成を行う
書式
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
説明
ファイルの pathname を与えると、 open() はファイルディスクリプタを返す。 ファイルディスクリプタは、この
後に続くシステムコール (read(2), write(2), lseek(2), fcntl(2) など) で使用される小さな非負の整数である。
このシステムコールが成功した場合に返されるファイルディスクリプタは そのプロセスがその時点でオープンしてい
ないファイルディスクリプタの うち最小の数字のものとなる。
デフォルトでは、新しいファイルディスクリプタは execve(2) を実行した後も オープンされたままとなる (つま
り、 fcntl(2) に説明がある FD_CLOEXEC ファイルディスクリプタフラグは最初は無効である; 後述の O_CLOEXEC フ
ラグ を使うとこのデフォルトを変更することができる)。 ファイルオフセット (file offset) はファイルの先頭に
設定される (lseek(2) 参照)。
open() を呼び出すと、「オープンファイル記述」 (open file description) が作成される。ファイル記述とは、シ
ステム全体の オープン中のファイルのテーブルのエントリである。 このエントリは、ファイルオフセットとファイ
ル状態フラグ (fcntl(2) F_SETFL 操作により変更可能) が保持する。 ファイルディスクリプタはこれらのエントリ
の一つへの参照である。 この後で pathname が削除されたり、他のファイルを参照するように変更されたりしても、
この参照は影響を受けない。 新しいオープンファイル記述は最初は他のどのプロセスとも 共有されていないが、
fork(2) で共有が起こる場合がある。
引き数 flags には、アクセスモード O_RDONLY, O_WRONLY, O_RDWR のどれかひとつが入っていなければならない。
これらはそれぞれ読み込み専用、書き込み専用、読み書き用に ファイルをオープンすることを要求するものである。
さらに、 flags には、ファイル作成フラグ (file creation flag) とファイル状態フラグ (file status flag) を 0
個以上「ビット単位の OR (bitwise-or)」で 指定することができる。 ファイル作成フラグ は O_CLOEXEC, O_CREAT,
O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TRUNC, O_TTY_INIT である。 ファイル状態フラグ は以下のリスト
のうち上記以外の残りのものである。 二種類のフラグの違いは、ファイル状態フラグの方は fcntl(2) を使ってその
内容を取得したり (場合によっては) 変更したりできる点にある。 ファイル作成フラグとファイル状態フラグの全リ
ストを以下に示す:
O_APPEND
ファイルを追加 (append) モードでオープンする。 毎回の write(2) の前に lseek(2) を行ったかのよう
に、ファイルポインタをファイルの最後に移動する。 NFS ファイルシステムで、 O_APPEND を使用する
と、複数のプロセスがひとつのファイルに同時にデータを追加した場合、 ファイルが壊れてしまうことがあ
る。 これは NFS が追加モードをサポートしていないため、 クライアントのカーネル (kernel) がそれをシ
ミュレートしなければならないのだが、 競合状態を避けることはできないからである。
O_ASYNC
シグナル駆動 I/O (signal-driven I/O) を有効にする: このファイルディスクリプタへの 入力または出力が
可能になった場合に、シグナルを生成する (デフォルトは SIGIO であるが、 fcntl(2) によって変更可能で
ある)。 この機能が使用可能なのは端末、疑似端末、ソケットのみであり、 (Linux 2.6 以降では) パイプと
FIFO に対しても使用できる。 さらに詳しい説明は fcntl(2) を参照すること。
O_CLOEXEC (Linux 2.6.23 以降)
新しいファイルディスクリプタに対して close-on-exec フラグを有効にする。 このフラグを指定すること
で、プログラムは FD_CLOEXEC フラグをセットするための fcntl(2) F_SETFD 操作を別途呼び出す必要がな
くなる。 また、ある種のマルチスレッドのプログラムはこのフラグの使用は 不可欠である。なぜなら、個別
に FD_CLOEXEC フラグを設定する fcntl(2) F_SETFD 操作を呼び出したとしても、あるスレッドがファイル
ディスクリプタを オープンするのと同時に別のスレッドが fork(2) と execve(2) を実行するという競合
条件を避けるのには十分ではないからである。
O_CREAT
ファイルが存在しなかった場合は作成 (create) する。 ファイルの所有者 (ユーザー ID) は、プロセスの実
効ユーザー ID に設定される。 グループ所有権 (グループ ID) は、プロセスの実効グループ ID または親
ディレクトリのグループ ID に設定される (これは、ファイルシステムタイプ、マウントオプション、 親
ディレクトリのモードに依存する。 mount(8) で説明されているマウントオプション bsdgroups と
sysvgroups を参照)。
mode は新しいファイルを作成する場合に使用するアクセス許可 (permission) を指定する。 flags に
O_CREAT が指定されている場合、 mode を指定しなければならない。 O_CREAT が指定されていない場合、
mode は無視される。 有効なアクセス許可は、普段と同じようにプロセスの umask によって修正され、作成
されたファイルの許可は (mode & ~umask) となる。 このモードは、新しく作成されたファイルに対するそれ
以降のアクセス にのみ適用される点に注意すること。 読み取り専用のファイルを作成する open() コール
であっても、 読み書き可能なファイルディスクリプタを返すことがありうる。
mode のために以下のシンボル定数が提供されている :
S_IRWXU 00700 ユーザー (ファイルの所有者) に読み込み、書き込み、 実行の許可がある。
S_IRUSR 00400 ユーザーに読み込みの許可がある。
S_IWUSR 00200 ユーザーに書き込みの許可がある。
S_IXUSR 00100 ユーザーに実行の許可がある。
S_IRWXG 00070 グループに読み込み、書き込み、実行の許可がある。
S_IRGRP 00040 グループに読み込みの許可がある。
S_IWGRP 00020 グループに書き込みの許可がある。
S_IXGRP 00010 グループに実行の許可がある。
S_IRWXO 00007 他人 (others) に読み込み、書き込み、実行の許可がある。
S_IROTH 00004 他人に読み込みの許可がある。
S_IWOTH 00002 他人に書き込みの許可がある。
S_IXOTH 00001 他人に実行の許可がある。
O_DIRECT (Linux 2.4.10 以降)
このファイルに対する I/O のキャッシュの効果を最小化しようとする。このフラグを使うと、一般的に性能
が低下する。 しかしアプリケーションが独自にキャッシングを行っているような 特別な場合には役に立つ。
ファイルの I/O はユーザー空間バッファに対して直接行われる。 O_DIRECT フラグ自身はデータを同期で転
送しようとはするが、 O_SYNC フラグのようにデータと必要なメタデータの転送が保証されるわけではな
い。同期 I/O を保証するためには、 O_DIRECT に加えて O_SYNC を使用しなければならない。下記の「注
意」の節の議論も参照。
ブロックデバイスに対する似通った意味のインターフェースが raw(8) で説明されている (但し、このイン
タフェースは非推奨である)。
O_DIRECTORY
pathname がディレクトリでなければオープンは失敗する。 このフラグは Linux 特有であり、 opendir(3)
が FIFO やテープデバイスに対してコールされた場合の サービス不能 (denial-of-service) 攻撃を避けるた
めに カーネル 2.1.126 で追加された。
O_EXCL この呼び出しでファイルが作成されることを保証する。このフラグが O_CREAT と 一緒に指定され、
pathname のファイルが既に存在した場合、 open() は失敗 する。
これら二つのフラグが指定された際、シンボリックリンクは辿られない。 pathname がシンボリックリンクの
場合、 シンボリックリンクがどこを指しているかに関わらず open() は失敗する。
一般的には、 O_CREAT を指定せずに O_EXCL を使用した場合の O_EXCL の動作は規定されていない。 これに
は一つ例外があり、Linux 2.6 以降では、 pathname がブロックデバイスを参照している場合、 O_CREAT な
しで O_EXCL を使用することができる。 システムがそのブロックデバイスを使用中の場合 (例えば、 マウン
トされているなど)、 open() はエラー EBUSY で失敗する。
NFS では、 O_EXCL は、Linux 2.6 以降で NFSv3 以降を使っている場合でのみサポートされる。 O_EXCL サ
ポートが提供されていない NFS 環境では、このフラグに頼って ロック処理を実行するプログラムは競合状態
(race condition) に出会う 可能性がある。 ロックファイルを使用して不可分 (atomic) なファイルロック
を実現し、 NFS が O_EXCL をサポートしているかに依存しないようにしたい場合、 移植性のある方法は、同
じファイルシステム上に他と名前の重ならない ファイル (例えばホスト名と PID を組み合わせた名前) を作
成し、 link(2) を使用してそのロックファイルへのリンクを作成することである。 link(2) コールの返り
値が 0 ならばロックに成功している。 あるいは、そのファイルに stat(2) を使用してリンク数 (link
count) が 2 になっているかをチェックする。 そうなっていれば、同じくロックに成功しているということ
である。
O_LARGEFILE
(LFS) off_t ではサイズを表せない (だだし off64_t ではサイズを表せる)ファ イルをオープン可能にす
る。この定義を有効にするためには、(どのヘッダファイ ルをインクルードするよりも前に)
_LARGEFILE64_SOURCE マクロを定義しなければ ならない。 32 ビットシステムにおいて大きなファイルにア
クセスしたい場合、 (O_LARGEFILE を使うよりも) _FILE_OFFSET_BITS 機能検査マクロを 64 に セットする
方が望ましい方法である (feature_test_macros(7) を参照)。
O_NOATIME (Linux 2.6.8 以降)
ファイルに対して read(2) が実行されたときに、最終アクセス時刻 (inode の st_atime) を更新しない。
このフラグはインデックス作成やバックアッププログラムで使うことを意図している。 これを使うとディス
クに対する操作を大幅に減らすことができる。 このフラグは全てのファイルシステムに対して有効であるわ
けではない。 その一例が NFS であり、サーバがアクセス時刻を管理している。
O_NOCTTY
pathname が端末 (terminal) デバイス — tty(4) 参照 — を指している 場合に、たとえそのプロセスが制御
端末を持っていなくても、オープンしたファイル は制御端末にはならない。
O_NOFOLLOW
pathname がシンボリックリンクだった場合、オープンは失敗する。 これは FreeBSD の拡張で、Linux には
バージョン 2.1.126 で追加された。 このフラグが指定された場合でも pathname の前の方の要素 (最後の
ディレクトリセパレータより前の部分) にあるシンボリックリンクについてはリンクが辿られる。 下記の
O_PATH も参照のこと。
O_NONBLOCK または O_NDELAY
可能ならば、ファイルは非停止 (nonblocking) モードでオープンされる。 open() も、返したファイルディ
スクリプタに対する以後のすべての操作も呼び出 したプロセスを待たせることはない。 FIFO (名前付きパイ
プ) を扱う場合には fifo(7) も参照すること。 強制ファイルロック (mandatory file lock) やファイ ル
リース (file lease) と組み合わせた場合の、 O_NONBLOCK の効果についての 議論は、 fcntl(2) を参照す
ること。
O_PATH (Linux 2.6.39 以降)
このフラグを指定して取得したファイルディスクリプタは、 ファイルシステムツリー内での場所を示すた
め、 純粋にファイルディスクリプタレベルでの作用する操作を実行するため、 の二つの目的で使用すること
ができる。 ファイル自身はオープンされず、 他のファイル操作 (例えば read(2), write(2), fchmod(2),
fchown(2), fgetxattr(2), mmap(2)) はエラー EBADF で失敗する。
取得したファイルディスクリプタに対して以下の操作を行うことが「できる」。
* close(2); fchdir(2) (Linux 3.5 以降); fstat(2) (Linux 3.6 以降)
* ファイルディスクリプタの複製 (dup(2), fcntl(2) F_DUPFD など)
* ファイルディスクリプタフラグの取得と設定 (fcntl(2) の F_GETFD と F_SETFD)
* fcntl(2) の F_GETFL 操作を使ったオープンされたファイルの状態フラグの取得。 返されるフラグには
O_PATH ビットが含まれる。
* openat(2) や他の "*at()" 系のシステムコールの dirfd 引数としてそのファイルディスクリプタを渡
す。
* そのファイルディスクリプタを別のプロセスに UNIX ドメインソケット経由で渡す。 (unix(7) の
SCM_RIGHTS を参照)
flags に O_PATH が指定された場合、 O_DIRECTORY と O_NOFOLLOW 以外のフラグビットは無視される。
O_NOFOLLOW フラグも合わせて指定された場合、 この呼び出しではシンボリックリンクを参照するファイル
ディスクリプタを返す。 このファイルディスクリプタは、 空のパス名を指定した fchownat(2),
fstatat(2), linkat(2), readlinkat(2) の呼び出しで dirfd 引数として使うことで、 そのシンボリックリ
ンクに対して操作を行うことができる。
O_SYNC ファイルは同期 (synchronous) I/O モードでオープンされる。 open() が返したファイルディスクリプタに
対して write(2) を行うと、必ず呼び出したプロセスをブロックし、 該当ハードウェアに物理的に書き込ま
れるまで返らない。 以下の「注意」の章も参照。
O_TRUNC
ファイルが既に存在し、通常ファイルであり、 書き込み可モードでオープンされている (つまり、 O_RDWRま
たはO_WRONLY の) 場合、長さ 0 に切り詰め (truncate) られる。 ファイルが FIFO または端末デバイス
ファイルの場合、 O_TRUNC フラグは無視される。 それ以外の場合、 O_TRUNC の効果は未定義である。
これらの選択フラグのいくつかはファイルをオープンした後でも fcntl(2) を使用して変更することができる。
creat() は flags に O_CREAT|O_WRONLY|O_TRUNC を指定して open() を行うのと等価である。
返り値
open() と creat() は新しいファイルディスクリプタを返す。 エラーが発生した場合は -1 を返す (その場合は
errno が適切に設定される)。
エラー
EACCES ファイルに対する要求されたアクセスが許されていないか、 pathname のディレクトリ部分の何れかのディレ
クトリに検索許可がなかった。 またはファイルが存在せず、親ディレクトリへの書き込み許可がなかった。
(path_resolution(7) も参照すること。)
EDQUOT O_CREAT が指定された場合で、そのファイルが存在せず、ディスクブロックか inode がそのファイルシステ
ムのユーザクォータに達していた。
EEXIST pathname は既に存在し、 O_CREAT と O_EXCL が使用された。
EFAULT pathname がアクセス可能なアドレス空間の外を指している。
EFBIG EOVERFLOW 参照。
EINTR 遅いデバイス (例えば FIFO、 fifo(7) 参照) のオープンが完了するのを待って停止している間に システム
コールがシグナルハンドラにより割り込まれた。 signal(7) 参照。
EINVAL ファイルシステムが O_DIRECT フラグをサポートしていない。 詳細は注意を参照。
EISDIR pathname はディレクトリを参照しており、書き込み要求が含まれていた (つまり O_WRONLY または O_RDWR
が設定されている)。
ELOOP pathname を解決する際に遭遇したシンボリックリンクが多過ぎる。 または O_NOFOLLOW が指定されており、
pathname がシンボリックリンクだった。
EMFILE プロセスがオープンしているファイル数がすでに最大数に達している。
ENAMETOOLONG
pathname が長過ぎる。
ENFILE オープンされているファイルの総数がシステムの制限に達している。
ENODEV pathname がデバイススペシャルファイルを参照しており、対応するデバイスが存在しない。 (これは Linux
カーネルのバグであり、この場合には ENXIO が返されるべきである)
ENOENT O_CREAT が設定されておらず、かつ指定されたファイルが存在しない。 または、 pathname のディレクトリ
部分が存在しないか壊れた (dangling) シンボリックリンクである。
ENOMEM 十分なカーネルメモリーがない。
ENOSPC pathname を作成する必要があるが、 pathname を含んでいるデバイスに新しいファイルのための空き容量が
ない。
ENOTDIR
pathname に含まれるディレクトリ部分のどれかが実際にはディレクトリでない。 または O_DIRECTORY が指
定されており、 pathname がディレクトリでない。
ENXIO O_NONBLOCK | O_WRONLY が設定されており、指定したファイルが FIFO で そのファイルを読み込みのために
オープンしているプロセスが存在しない。 または、ファイルがデバイススペシャルファイルで 対応するデバ
イスが存在しない。
EOVERFLOW
pathname が参照しているのが、大き過ぎてオープンできない通常のファイルである。 通常、このエラーが発
生するは、32 ビットプラットフォーム上で -D_FILE_OFFSET_BITS=64 を指定せずにコンパイルされたアプリ
ケーションが、ファイルサイズが (2<31)-1 ビットを超えるファイルを開こうとした場合である。 上記の
O_LARGEFILE も参照。 これは POSIX.1-2001 で規定されているエラーである。 2.6.24 より前のカーネルで
は、Linux はこの場合にエラー EFBIG を返していた。
EPERM O_NOATIME フラグが指定されたが、呼び出し元の実効ユーザー ID が ファイルの所有者と一致せず、かつ呼
び出し元に特権 (CAP_FOWNER) がない。
EROFS pathname が読み込み専用のファイルシステム上のファイルを参照しており、 書き込みアクセスが要求され
た。
ETXTBSY
pathname が現在実行中の実行イメージを参照しており、書き込みが要求された。
EWOULDBLOCK
O_NONBLOCK フラグが指定されたが、そのファイルには矛盾するリースが設定されていた (fcntl(2) 参照)。
準拠
SVr4, 4.3BSD, POSIX.1-2001. フラグ O_DIRECTORY, O_NOATIME, O_NOFOLLOW, O_PATH は Linux 特有のものであ
り、 これらのフラグの定義を得るためには、 (「どの」ヘッダファイルをインクルードするよりも前に)
_GNU_SOURCE を定義する必要があるかもしれない。
O_CLOEXEC フラグは POSIX.1-2001 では規定されていないが、 POSIX.1-2008 で規定されている。
O_DIRECT は POSIX では規定されていない。 O_DIRECT の定義を得るには (「どの」ヘッダファイルをインクルード
するよりも前に) _GNU_SOURCE を定義しなければならない。
注意
Linux では、 O_NONBLOCK フラグは、 open を実行したいが read または write を実行する意図は 必ずしもないこ
とを意味する。 これは ioctl(2) のためのファイルディスクリプタを取得するために、 デバイスをオープンすると
きによく用いられる。
「アクセスモード」の値 O_RDONLY, O_WRONLY, O_RDWR は、 flags に指定できる他の値と違い、個々のビットを指定
するものではなく、 これらの値は flags の下位 2 ビットを定義する。 O_RDONLY, O_WRONLY, O_RDWR はそれぞれ
0, 1, 2 に定義されている。 言い換えると、 O_RDONLY | O_WRONLY の組み合わせは論理的に間違いであり、確かに
O_RDWR と同じ意味ではない。 Linux では、特別な、非標準なアクセスモードとして 3 (バイナリでは 11) が 予約
されており flags に指定できる。 このアクセスモードを指定すると、ファイルの読み出し/書き込み許可をチェック
し、 読み出しにも書き込みにも使用できないディスクリプタを返す。 この非標準のアクセスモードはいくつかの
Linux ドライバで、デバイス固有の ioctl(2) 操作にのみ使用されるディスクリプタを返すために使われている。
O_RDONLY | O_TRUNC の影響は未定義であり、その動作は実装によって異なる。 多くのシステムではファイルは実際
に切り詰められる。
NFS を実現しているプロトコルには多くの不備があり、特に O_SYNC と O_NDELAY に影響する。
POSIX では、3 種類の同期 I/O が提供されており、 O_SYNC, O_DSYNC, O_RSYNC フラグがこれに対応するものであ
る。 今のところ (カーネル 2.6.31)、 Linux では O_SYNC だけが実装されているが、 glibc は O_DSYNC と
O_RSYNC に O_SYNC と同じ数値を割り当てている。 ほとんどの Linux のファイルシステムは、実際には POSIX の
O_SYNC の動作ではなく O_DSYNC の動作だけを実装している。 POSIX の O_SYNC では、 open() がユーザ空間に返
る際に、書き込みに関する全てのメタデータの 更新がディスクに書き込まれている必要がある。 一方、 O_DSYNC で
は、 open() が返るまでに、実際のファイルのデータとそのデータを取得するために 必要なメタデータだけがディス
クに書き込まれていればよい。
open() はスペシャルファイルをオープンすることができるが、 creat() でスペシャルファイルを作成できない点
に注意すること。 代わりに mknod(2) を使用する。
UID マッピングを使用している NFS ファイルシステムでは、 open() がファイルディスクリプタを返した場合でも
read(2) が EACCES で拒否される場合がある。 これはクライアントがアクセス許可のチェックを行って open() を実
行するが、読み込みや書き込みの際には サーバーで UID マッピングが行われるためである。
ファイルが新しく作成されると、 ファイルの st_atime, st_ctime, st_mtime フィールド (それぞれ最終アクセス時
刻、最終状態変更時刻、最終修正時刻である。 stat(2) 参照) が現在時刻に設定される。 さらに親ディレクトリの
st_ctime と st_mtime も現在時刻に設定される。 それ以外の場合で、O_TRUNC フラグでファイルが修正されたとき
は、 ファイルの st_ctime と st_mtime フィールドが現在時刻に設定される。
O_DIRECT
O_DIRECT フラグを使用する場合、ユーザ空間バッファの長さやアドレス、 I/O のファイルオフセットに関してアラ
インメントの制限が課されることがある。 Linux では、アラインメントの制限はファイルシステムやカーネルのバー
ジョンに よって異なり、全く制限が存在しない場合もある。 しかしながら、現在のところ、指定されたファイルや
ファイルシステムに対して こうした制限があるかを見つけるための、アプリケーション向けのインタフェースで
ファイルシステム非依存のものは存在しない。 いくつかのファイルシステムでは、制限を確認するための独自のイン
タフェースが 提供されている。例えば、 xfsctl(3) の XFS_IOC_DIOINFO 命令である。
Linux 2.4 では、転送サイズ、 ユーザーバッファのアラインメント、ファイルオフセットは、 ファイルシステムの
論理ブロックサイズの倍数でなければならない。 Linux 2.6 では、512 バイトごとの境界に配置されていれば充分で
ある。
メモリバッファがプライベートマッピング (mmap(2) の MAP_PRIVATE フラグで作成されたマッピング) の場合に
は、O_DIRECT I/O は fork(2) システムコールと同時に決して実行すべきではない (プライベートマッピングに
は、ヒープ領域に割り当てられたメモリや静的に 割り当てたバッファも含まれる)。非同期 I/O インターフェース
(AIO) 経由 やプロセス内の他のスレッドから発行された、このような I/O は、 fork(2) が呼び出される前に完了さ
れるべきである。 そうしなかった場合、データ破壊や、親プロセスや子プロセスでの予期しない 動作が起こる可能
性がある。 O_DIRECT I/O 用のメモリバッファが shmat(2) やMAP_SHARED フラグ 付きの mmap(2) で作成された場合
には、この制限はあてはまらない。 madvise(2) でメモリバッファにアドバイス MADV_DONTFORK が設定され ている
場合にも、この制限はあてはまらない(MADV_DONTFORK はそのメモリ バッファが fork(2) 後に子プロセスからは利用
できないことを保証するも のである)。
O_DIRECT フラグは SGI IRIX で導入された。SGI IRIX にも Linux 2.4 と同様の (ユーザーバッファの) アラインメ
ントの制限がある。 また、IRIX には適切な配置とサイズを取得するための fcntl(2) コールがある。 FreeBSD 4.x
も同じ名前のフラグを導入したが、アラインメントの制限はない。
O_DIRECT が Linux でサポートされたのは、カーネルバージョン 2.4.10 である。 古い Linux カーネルは、このフ
ラグを単に無視する。 O_DIRECT フラグをサポートしていないファイルシステムもあり、その場合は、 O_DIRECT を
使用すると open() は EINVAL で失敗する。
アプリケーションは、同じファイル、 特に同じファイルの重複するバイト領域に対して、 O_DIRECT と通常の I/O
を混ぜて使うのは避けるべきである。 ファイルシステムがこのような状況において一貫性の問題を正しく 扱うこと
ができる場合であっても、全体の I/O スループットは どちらか一方を使用するときと比べて低速になるであろう。
同様に、アプリケーションは、同じファイルに対して mmap(2) と直接 I/O (O_DIRECT) を混ぜて使うのも避けるべ
きである。
NFS で O_DIRECT を使った場合の動作はローカルのファイルシステムの場合と違う。 古いカーネルや、ある種の設定
でコンパイルされたカーネルは、 O_DIRECT と NFS の組み合わせをサポートしていないかもしれない。 NFS プロト
コル自体はサーバにフラグを渡す機能は持っていないので、 O_DIRECT I/O はクライアント上のページキャッシュを
バイパスするだけになり、 サーバは I/O をキャッシュしているかもしれない。 クライアントは、 O_DIRECT の同期
機構を保持するため、サーバに対して I/O を同期して行うように依頼する。 サーバによっては、こうした状況
下、特に I/O サイズが小さい場合に 性能が大きく劣化する。 また、サーバによっては、I/O が安定したストレージ
にまで行われたと、 クライアントに対して嘘をつくものもある。 これは、サーバの電源故障が起こった際にデータ
の完全性が保たれない 危険は少しあるが、性能面での不利な条件を回避するために行われている。 Linux の NFS ク
ライアントでは O_DIRECT I/O でのアラインメントの制限はない。
まとめると、 O_DIRECT は、注意して使うべきであるが、強力なツールとなる可能性を持っている。 アプリケーショ
ンは O_DIRECT をデフォルトでは無効になっている性能向上のためのオプションと 考えておくのがよいであろう。
「O_DIRECT でいつも困るのは、インタフェース全部が本当にお馬鹿な点だ。 たぶん危ないマインドコント
ロール剤で 頭がおかしくなったサルが設計したんじゃないかな」 — Linus
バグ
現在のところ、 open() の呼び出し時に O_ASYNC を指定してシグナル駆動 I/O を有効にすることはできない。 こ
のフラグを有効にするには fcntl(2) を使用すること。
関連項目
chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2),
openat(2), read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), fifo(7),
path_resolution(7), symlink(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.54 の一部 である。プロジェクトの説明とバグ報告
に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
Linux 2013-08-09 OPEN(2)