ダウンロード:
files.txt
現在作業中の文書です。お気づきの点がありましたら、jf@listserv.linux.or.jp、チケット、フォーラムのいずれかにお寄せください。
=========================================================
これは、
Linux-2.6.29/Documentation/filesystems/files.txt の和訳
です。
翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
更新日 : 2009/04/11
翻訳者 : Seiji Kaneko < skaneko at mbn dot or dot jp >
=========================================================
#File management in the Linux kernel
#-----------------------------------
Linux カーネルでのファイル管理
------------------------------
#This document describes how locking for files (struct file)
#and file descriptor table (struct files) works.
この文書は、ファイル (file 構造体) のロックとファイルディスクリプタテーブ
ル (ファイル構造体) がどのように動作するかを記載したものです。
#Up until 2.6.12, the file descriptor table has been protected
#with a lock (files->file_lock) and reference count (files->count).
#->file_lock protected accesses to all the file related fields
#of the table. ->count was used for sharing the file descriptor
#table between tasks cloned with CLONE_FILES flag. Typically
#this would be the case for posix threads. As with the common
#refcounting model in the kernel, the last task doing
#a put_files_struct() frees the file descriptor (fd) table.
#The files (struct file) themselves are protected using
#reference count (->f_count).
2.6.12 まではファイルディスクリプタテーブルはロック (files->file_lock) と
リファレンスカウント (files->count) で保護されていました。テーブルのファイ
ルに関するすべてのフィールドへのアクセスは ->file_lock で保護されていまし
た。また、->count は CLONE_FILES フラグつきで複製されたタスク間での、ファ
イルディスクリプタテーブルの共有に用いられていました。通常、posix スレッド
はこの場合に当たります。カーネル内のリファレンスカウント共通モデルに沿って、
put_files_struct() を最後に行ったタスクがファイルディスクリプタ (fd) テー
ブルを解放します。ファイル群 (struct file) 自体はリファレンスカウント
(->f_count) を使って保護されています。
#In the new lock-free model of file descriptor management,
#the reference counting is similar, but the locking is
#based on RCU. The file descriptor table contains multiple
#elements - the fd sets (open_fds and close_on_exec, the
#array of file pointers, the sizes of the sets and the array
#etc.). In order for the updates to appear atomic to
#a lock-free reader, all the elements of the file descriptor
#table are in a separate structure - struct fdtable.
#files_struct contains a pointer to struct fdtable through
#which the actual fd table is accessed. Initially the
#fdtable is embedded in files_struct itself. On a subsequent
#expansion of fdtable, a new fdtable structure is allocated
#and files->fdtab points to the new structure. The fdtable
#structure is freed with RCU and lock-free readers either
#see the old fdtable or the new fdtable making the update
#appear atomic. Here are the locking rules for
#the fdtable structure -
新しいファイルディスクリプタのロックフリーモデルでは、リファレンスカウント
動作は従来と同様ですが、ロック処理は RCU に基づくものになります。ファイル
ディスクリプタテーブルには複数の要素 - fd 一式 (open_fd 群や close_on_exec,
file ポインタの配列, 組や配列の数やサイズなど) - が格納されています。ロッ
クを持たない読み出し側から更新がアトミックであるように見せるためには、ファ
イルディスクリプタテーブルの各要素はすべて別々の構造体 - fdtable 構造体 -
でなければいけません。files_struct には fdtable 構造体へのポインタが格納さ
れ、そのポインタ経由で実際の fd テーブルへのアクセスが行われます。もともと
は fdtable は files_struct 自体に埋め込まれていました。それ以降の fdtable
の拡張時に、新しい fdtable 構造体が導入され、files->fdtab がこの新しい構造
体を指すようになりました。fdtable 構造体は、ロックを持たない読み出し処理か
ら古い fdtable と新しい fdtable の両方がアトミックに更新されているように見
せることができるよう、RCU により解放されます。以下が fdtable 構造体へのロッ
ク取得規則です。
#1. All references to the fdtable must be done through
# the files_fdtable() macro :
1. fdtable への参照は、必ず files_fdtable() マクロ経由で行なわなければいけ
ません。
struct fdtable *fdt;
rcu_read_lock();
fdt = files_fdtable(files);
....
if (n <= fdt->max_fds)
....
...
rcu_read_unlock();
# files_fdtable() uses rcu_dereference() macro which takes care of
# the memory barrier requirements for lock-free dereference.
# The fdtable pointer must be read within the read-side
# critical section.
files_fdtable() は rcu_dereference() マクロを使います。rcu_dereference()
マクロが、ロックなしの参照を行なうのに必要なメモリバリア要求の面倒を見ま
す。fdtable ポインタは読み出し側のクリティカルセクション中で読み出さなけ
ればいけません。
#2. Reading of the fdtable as described above must be protected
# by rcu_read_lock()/rcu_read_unlock().
2. 上記の fdtable の読み出しは、rcu_read_lock()/rcu_read_unlock() で保護し
なければいけません。
#3. For any update to the fd table, files->file_lock must
# be held.
3. fd テーブルを更新する場合には、どのような更新でも files->file_lock を持
っていなければいけません。
#4. To look up the file structure given an fd, a reader
# must use either fcheck() or fcheck_files() APIs. These
# take care of barrier requirements due to lock-free lookup.
# An example :
4. ある fd に対してファイル構造体を参照するには、読み側では fcheck() または
fcheck_files() API を使わなければいけません。これらの API はロック不要の参
照に伴うバリアの要求の面倒を見てくれます。
以下に例を示します。
struct file *file;
rcu_read_lock();
file = fcheck(fd);
if (file) {
...
}
....
rcu_read_unlock();
#5. Handling of the file structures is special. Since the look-up
# of the fd (fget()/fget_light()) are lock-free, it is possible
# that look-up may race with the last put() operation on the
# file structure. This is avoided using atomic_long_inc_not_zero()
# on ->f_count :
5. ファイル構造体の操作には特別の注意が必要です。fd の検索
(fget()/fget_light()) はロックをとりませんから、検索時にファイル構造体の
最後の put() 操作と競合を起こす可能性があります。これは ->f_count に対し
て atomic_inc_not_zero() を用いることによって回避します。
rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
if (atomic_long_inc_not_zero(&file->f_count))
*fput_needed = 1;
else
/* Didn't get the reference, someone's freed */
file = NULL;
}
rcu_read_unlock();
....
return file;
# atomic_long_inc_not_zero() detects if refcounts is already zero or
# goes to zero during increment. If it does, we fail
# fget()/fget_light().
atomic_inc_not_zero() は refcount が既に 0 となっていること、または増加
時に 0 となることを検出します。このような場合、fget()/fget_light() は失
敗します。
#6. Since both fdtable and file structures can be looked up
# lock-free, they must be installed using rcu_assign_pointer()
# API. If they are looked up lock-free, rcu_dereference()
# must be used. However it is advisable to use files_fdtable()
# and fcheck()/fcheck_files() which take care of these issues.
6. fdtable と file 構造体のいずれもがロックをとらないで参照可能ですから、こ
れらについては rcu_assign_pointer() API を用いてインストールする必要があ
ります。ロックをとらないで参照する場合、rcu_dereference() を使う必要があ
ります。ただし、files_fdtable() と fcheck()/fcheck_files() はこれらの面倒
を見てくれますので、これを使うのがおすすめです。
#7. While updating, the fdtable pointer must be looked up while
# holding files->file_lock. If ->file_lock is dropped, then
# another thread expand the files thereby creating a new
# fdtable and making the earlier fdtable pointer stale.
# For example :
7. 更新時には、fdtable ポインタは files->file_lock を持った状態で参照する必
要があります。->file_lock を持っていない場合、他のスレッドがファイルを展
開して新しい fdtable を作成し、以前の fdtable を無効状態にしてしまう可能
性があります。
例を以下に示します。
spin_lock(&files->file_lock);
fd = locate_fd(files, file, start);
if (fd >= 0) {
/* locate_fd() may have expanded fdtable, load the ptr */
fdt = files_fdtable(files);
FD_SET(fd, fdt->open_fds);
FD_CLR(fd, fdt->close_on_exec);
spin_unlock(&files->file_lock);
.....
# Since locate_fd() can drop ->file_lock (and reacquire ->file_lock),
# the fdtable pointer (fdt) must be loaded after locate_fd().
locate_fd() が ->file_lock を解放して (その後 ->file_lock を再取得する)
可能性があるため、fdtable ポインタ (fdt) は locate_fd() 実行後ロードす
る必要があります。
コメントが長くなった場合は、JF@linux.or.jp にお寄せください。
[PageInfo]
LastUpdate: 2009-04-19 23:09:01, ModifiedBy: yasikoba
[Permissions]
view:all, edit:login users, delete/config:project members