読者です 読者をやめる 読者になる 読者になる

テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

(nim-fuse) プロトコルはrust-fuseと同じく7.8を採用する

fuseは, カーネル内のプログラムとfuseバインディングの間でプロトコルのバージョン合意をinit時に行う. initは, マウントしたあとに行う.

仕組みは, 以下に書いてある. 古い方に合わせるという当たり前の処理である.

/*
 * Version negotiation:
 *
 * Both the kernel and userspace send the version they support in the
 * INIT request and reply respectively.
 *
 * If the major versions match then both shall use the smallest
 * of the two minor versions for communication.
 *
 * If the kernel supports a larger major version, then userspace shall
 * reply with the major version it supports, ignore the rest of the
 * INIT message and expect a new INIT message from the kernel with a
 * matching major version.
 *
 * If the library supports a larger major version, then it shall fall
 * back to the major protocol version sent by the kernel for
 * communication and reply with that major version (and an arbitrary
 * supported minor version).
 */

あらゆる古いバージョンのプロトコルを保つため, c-fuseは大変な努力をしている. 例えば以下, バージョン7.9より前の挙動のためにCOMPATサイズというものが定義されている. ようするにそれより前は, fuse_entry_outのサイズは120バイトでしたよと言ってる.

#define FUSE_COMPAT_ENTRY_OUT_SIZE 120

struct fuse_entry_out {
        __u64   nodeid;         /* Inode ID */
        __u64   generation;     /* Inode generation: nodeid:gen must
                                   be unique for the fs's lifetime */
        __u64   entry_valid;    /* Cache timeout for the name */
        __u64   attr_valid;     /* Cache timeout for the attributes */
        __u32   entry_valid_nsec;
        __u32   attr_valid_nsec;
        struct fuse_attr attr;
};

こういう, 負の遺産がc-fuseにはところどころにある.

rust-fuseはバージョン7.8のみをサポートすると宣言している. これはカーネルが2.6.24の時のバージョンであり, 現在のシステムであればほとんどでこれより新しいカーネルを使っている(Oh... RHEL5は2.6.18なのか)ため, たいていは7.8で合意出来る. なぜrust-fuseが7.8で決め打ちしているのか?上で, 7.9以前の互換性を保つということを書いたが, まさにそれに尽きる. 7.8と7.9以降では複雑さが全く違うのだ. 特に7.9と7.12でほぼ破壊的な変更が加えられていることがわかる.

古いプロトコルをサポートすればユーザは不満に思うかもしれないが, 新しい拡張は間違いなく, 少数意見を取り込んだものであり, 基本的な実装としては7.8で十分なのである. 世の中にあるようなfuseを使ったおもしろfsを実装するためには間違いなく十分である. カーネルとしても2.6.24というのはバージョンで見るほど古くはなく, 今のLinuxカーネルはもうほぼ出来上がってたと言ってよい. したがって, 7.8をサポートすればほとんどのユーザには不都合ない.

ためしに7.8にプロトコルを減らしてみたところ, ほとんどのフラグがなくなった. 特別な用途のためにフラグを渡すという拡張がされていったのだろう. 明らかにやばい.

プロトコルが素直なので, 実装のみならず設計もシンプルに出来る可能性がある. rust-fuseが恐ろしくシンプルなのはこのおかげだろうと思う. 私のnim-fuseプロトコルについてrust-fuseと同じにしようと思う.