\input texinfo  @c -*-texinfo-*-
@setfilename hurd-ja.info

@c Get the Hurd version we are documenting.
@include hurd-v.texi

@c Unify all our little indices for now.
@defcodeindex sc
@syncodeindex sc cp
@syncodeindex fn cp
@syncodeindex vr cp
@syncodeindex tp cp
@syncodeindex pg cp

@dircategory Kernel
@direntry
* Hurd: (hurd).                 Using and programming the Hurd kernel servers.
@end direntry

@ifinfo
Copyright @copyright{} 1994-1998 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries a copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ifinfo

@setchapternewpage none
@settitle Hurd Reference Manual
@titlepage
@finalout
@title The GNU Hurd Reference Manual
@author Thomas Bushnell
@author Gordon Matzigkeit
@page

@vskip 0pt plus 1filll
Copyright @copyright{} 1994--1998 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end titlepage

@ifnottex

@node Top
@top The GNU Hurd

This file documents the GNU Hurd kernel component.  This edition of the
documentation was last updated for version @value{VERSION} of the Hurd.

@menu
* Introduction::                このマニュアルの使い方。
* Installing::                  Setting up Hurd software on your computer.
* Bootstrap::                   Turning a computer into a Hurd machine.
* Foundations::                 Hurdを通して使われている基本的な特徴。
* Input and Output::            I/Oチャネルの読み書き。
* Files::                       Regular file and directory nodes.
* Special Files::               Files with unusual Unix-compatible semantics.
* Stores::                      Generalized units of storage.
* Stored Filesystems::          物理的なメディアのためのファイルシステム。
* Twisted Filesystems::         既存データに対する新しい階層の提供。
* Distributed Filesystems::     異なるマシン間でのファイル共有。
* Networking::                  Interconnecting with other machines.
* Terminal Handling::           Helping people interact with the Hurd.
* Running Programs::            Program execution and process management.
* Authentication::              Verifying user and server privileges.
* Index::                       Guide to concepts, functions, and files.

@detailmenu
 --- The Detailed Node Listing ---

Introduction

* Audience::                    このマニュアルが書かれる対象の人々。
* Features::                    Hurdをインストールし使用する理由。
* Overview::                    Hurdの基本的なアーキテクチャ。
* History::                     Hurdがいかにして生まれたか。
* Copying::                     Hurdはフリー・ソフトウェアである。

Installing

* Binary Distributions::        Obtaining ready-to-run GNU distributions.
* Cross-Compiling::             Building GNU from its source code.

Bootstrap

* Bootloader::                  Starting the microkernel, or other OSes.
* Server Bootstrap::            Waking up the Hurd.
* Shutdown::                    Letting the Hurd get some rest.

Server Bootstrap

* Invoking serverboot::         Starting a set of interdependent servers.
* Boot Scripts::                Describing server bootstrap relationships.
* Invoking boot::               Running a Hurd under another Hurd.

Foundations

* Threads Library::             あらゆるHurdサーバとライブラリは
                                マルチスレッド化されている。
* Microkernel Object Library::  マイクロカーネル・オブジェクト・モデル(MOM)。
* Ports Library::               サーバのport受信権の管理。
* Integer Hash Library::        整数を鍵としたハッシュ表。
* Misc Library::                GNU Cライブラリにすぐに入るもの。
* Bug Address Library::         Hurdのバグを報告する場所。

Ports Library

* Buckets and Classes::         port編成の基本単位。
* Port Rights::                 port権の@code{libports}との間での移動。
* Port Metadata::               port関連の情報の管理。
* Port References::             漏曳や欠失に対する保護。
* RPC Management::              RPC操作のロックと割り込み。

Input and Output

* Iohelp Library::              I/Oの認証とロックの管理。
* Pager Library::               マルチスレッド化された外部ページャの実装。
* I/O Interface::               RPCに基く入出力チャネル。

Iohelp Library

* I/O Users::                   ユーザ認証の管理。
* Conch Management::            非難された共有I/Oの実装。

Pager Library

* Pager Management::            外部ページャへの高水準なインターフェース。
* Pager Callbacks::             ユーザが定義しなければならない関数。

I/O Interface

* I/O Object Ports::            I/Oオブジェクトへのポートの働き方。
* Simple Operations::           read、writeやseek。
* Open Modes::                  操作の一部に影響する状態ビット。
* Asynchronous I/O::            I/Oが可能な時の通知のされ方。
* Information Queries::         @code{io_stat}と@code{io_server_version}
                                  の実装法。
* Mapped Data::                 I/Oオブジェクトのデータを参照するメモリ・
                                  オブジェクトの入手。

Files

* Translators::                 Extending the Hurd filesystem hierarchy.
* Trivfs Library::              Implementing single-file translators.
* Fshelp Library::              Miscellaneous generic filesystem routines.
* File Interface::              File ports implement the file interface.
* Filesystem Interface::        Translator control interface.

Translators

* Invoking settrans::           Declaring how a node should be translated.
* Invoking showtrans::          Displaying how nodes are translated.
* Invoking mount::              Unix-compatible active filesystem translators.
* Invoking fsysopts::           Modifying translation parameters at runtime.

Trivfs Library

* Trivfs Startup::              Writing a simple trivfs-based translator.
* Trivfs Callbacks::            Mandatory user-defined trivfs functions.
* Trivfs Options::              Optional user-defined trivfs functions.
* Trivfs Ports::                Managing control and protid ports.

Fshelp Library

* Passive Translator Linkage::  Invoking passive translators.
* Active Translator Linkage::   Managing active translators.
* Fshelp Locking::              Implementing file locking.
* Fshelp Permissions::          Standard file access permission policies.
* Fshelp Misc::                 Useful standalone routines.

File Interface

* File Overview::               Basic concepts for the file interface.
* Changing Status::             Changing the owner (etc.) of a file.
* Program Execution::           Executing files.
* File Locking::                Implementing the @code{flock} call.
* File Frobbing::               Other active calls on files.
* Opening Files::               Looking up files in directories.
* Modifying Directories::       Creating and deleting nodes.
* Notifications::               File and directory change callbacks.
* File Translators::            How to set and get translators.

Stores

* Store Library::               An abstract interface to storage systems.

Store Library

* Store Arguments::             Parsing store command-line arguments.
* Store Management::            Creating and manipulating stores.
* Store I/O::                   Reading and writing data to stores.
* Store Classes::               Ready-to-use storage backends.
* Store RPC Encoding::          Transferring store descriptors via RPC.

Stored Filesystems

* Repairing Filesystems::       軽いファイルシステム・クラッシュからの回復。
* Linux Extended 2 FS::         ポピュラーなLinuxファイルシステム・フォーマット。
* BSD Unix FS::                 BSD Unix 4.xのFast File System。
* ISO-9660 CD-ROM FS::          標準的なCD-ROMフォーマット。
* Diskfs Library::              新しいファイルシステム・サーバの実装。

Diskfs Library

* Diskfs Startup::              stored（FIXME-J:ストアード？）ファイルシステムの初期化。
* Diskfs Arguments::            コマンドライン引数の解析。
* Diskfs Globals::              グローバルな振る舞いの変更。
* Diskfs Node Management::      割り当て、リファレンス・カウンティング、I/O、
                                  キャッシング、その他のディスク・ノード・ルーチン。
* Diskfs Callbacks::            必須のユーザ定義diskfs関数。
* Diskfs Options::              任意選択のユーザ定義diskfs関数。
* Diskfs Internals::            diskfsの細部の再実装。

Distributed Filesystems

* File Transfer Protocol::      FTPベースの分散ファイルシステム。
* Network File System::         SunのNFS: 出来は悪いが、よく使われているファイルシステム。

File Transfer Protocol

* FTP Connection Library::      Managing remote FTP server connections.

Networking

* Socket Interface::            Network communication I/O protocol.

Authentication

* Auth Interface::              Auth ports implement the auth interface.

Auth Interface

* Auth Protocol::               Bidirectional authentication.

@end detailmenu
@end menu

@end ifnottex


@node Introduction
@chapter 導入

GNU Hurd@footnote{@dfn{Hurd}という名前は、``Hird of Unix-Replacing
Daemons''を表す。@dfn{Hird}という名前は、``Hurd of Interfaces
Representing Depth''を表す。}はGNUプロジェクトがUnixカーネルを置き換える
ものである。HurdはMachマイクロカーネルの上で動作するサーバの集まりであり、
通常Unixカーネルや(Linuxのような)似たようなカーネルによって実装されてい
る、ファイル・システム、ネットワーク・プロトコル、ファイル・アクセス制御
やその他の機能を実装している。
@c The GNU Hurd@footnote{The name @dfn{Hurd} stands for ``Hird of
@c Unix-Replacing Daemons.''  The name @dfn{Hird} stands for ``Hurd of
@c Interfaces Representing Depth.''} is the GNU Project's replacement for
@c the Unix kernel. The Hurd is a collection of servers that run on the
@c Mach microkernel to implement file systems, network protocols, file
@c access control, and other features that are normally implemented by the
@c Unix kernel or similar kernels (such as Linux).

@menu
* Audience::                    このマニュアルが書かれる対象の人々。
* Features::                    Hurdをインストールし使用する理由。
* Overview::                    Hurdの基本的なアーキテクチャ。
* History::                     Hurdがいかにして生まれたか。
* Copying::                     Hurdはフリー・ソフトウェアである。
@end menu


@node Audience
@section 読者

このマニュアルはHurdを使ったり、管理したり、プログラミングしたりすること
に興味を持っているすべての人に役立つようにもくろまれている。
@c This manual is designed to be useful to everybody who is interested in
@c using, administering, or programming the Hurd.

もしあなたがエンド・ユーザで、Hurdを走らせるための助けを探しているなら、
このマニュアルの最初の数章でHurdワークステーションをインストールし、開始
し、そしてシャットダウンするための基本的な部分を記述している。もし特定の
プログラムの助けが必要なら、このマニュアルを使う最善の方法は、索引からそ
れを見付けて直接その適切な節に向かうことである。また、@kbd{@var{program}
--help}を走らせてみると良い。それは@var{program}に対する簡潔な使用法のメッ
セージを表示するだろう (@pxref{Foundations})。
@c If you are an end-user and you are looking for help on running the Hurd,
@c the first few chapters of this manual describes the essential parts of
@c installing, starting up, and shutting down a Hurd workstation.  If you
@c need help with a specific program, the best way to use this manual is to
@c find it in the index and go directly to the appropriate section.  You
@c may also wish to try running @kbd{@var{program} --help}, which will
@c display a brief usage message for @var{program} (@pxref{Foundations}).

このマニュアルの残りはHurdサーバとそれらの実装に関する技術的な議論であり、
Hurdの変更方法を学びたいと思うまで役には立たないだろう。
@c The rest of this manual is a technical discussion of the Hurd servers
@c and their implementation, and would not be helpful until you want to
@c learn how to modify the Hurd.

このマニュアルはサブシステムに従って構成されており、それぞれの章はそのサ
ブシステムに関連するユーティリティやサーバの説明から始まっている。もしあ
なたがシステム管理者で、例えば、Hurdネットワーキング・サブシステムについ
てもっと学びたいなら、ネットワーキングの章 (@pxref{Networking})まで飛ば
して、関連したユーティリティやサーバを拾い読みして良い。
@c This manual is organized according to subsystem, and each chapter begins
@c with descriptions of utilities and servers that are related to that
@c subsystem.  If you are a system administrator, and you want to learn
@c more about, say, the Hurd networking subsystem, you can skip to the
@c networking chapter (@pxref{Networking}), and browse the related
@c utilities and servers.

Hurdサーバの変更の仕方や新しいサーバの書き方に興味があるプログラマはHurd
が移植されているマイクロカーネル(現在はGNU Machだけ)について学び、
@ref{Foundations}を読むことから始めるべきだ。そして、すでに存在するサー
バやそれらが使用するライブラリについて読むことで、あなたが関心のあるサブ
システムに習熟するべきだ。この時点で、存在するHurdサーバのソース・コード
を勉強し、それらがHurdライブラリをいかにして使用しているかを理解できるは
ずだ。
@c Programmers who are interested in learning how to modify Hurd servers or
@c write new ones should begin by learning about a microkernel to which the
@c Hurd has been ported (currently only GNU Mach) and reading
@c @ref{Foundations}.  You should then familiarize yourself with a
@c subsystem that interests you by reading about existing servers and the
@c libraries they use.  At that point, you should be able to study the
@c source code of existing Hurd servers and understand how they use the
@c Hurd libraries.

熟練の最終段階はHurdライブラリが実装するRPC@footnote{Remote Procedure
Call。もし訊く必要があるなら、あなたはHurdプログラミングを出来るようにな
る前に作業を予定してしまっている。}インターフェースを学ぶことだ。それぞ
れの章の最後の節では、そのサブシステムで使われているどのHurdインターフェー
スについても記述している。与えられたサブシステムを理解してしまったなら、
Hurdライブラリを改善し、あなた自身のインターフェースを設計し、新しいサブ
システムを実装するのに、あなたは適任の立場にいるだろう。
@c The final level of mastery is learning the RPC@footnote{Remote Procedure
@c Call.  If you needed to ask, then you've got your work cut out for you
@c before you'll be ready for Hurd programming.} interfaces which the Hurd
@c libraries implement.  The last section of each chapter describes any
@c Hurd interfaces used in that subsystem.  Those sections assume that you
@c are perusing the referenced interface definitions as you read.  After
@c you have understood a given interface, you will be in a good position to
@c improve the Hurd libraries, design your own interfaces, and implement
@c new subsystems.


@node Features
@section 特徴

Hurdは地球に知られている最も進歩したオペレーティング・システムでは(まだ)
ないが、たくさんの誘惑的な特徴を持っている。
@c The Hurd is not the most advanced operating system known to the planet
@c (yet), but it does have a number of enticing features:

@table @asis
@item それはフリー・ソフトウェアである
誰もがそれをGNU General Public License (@pxref{Copying})の下で使用し、変
更し、再配布することができる。HurdはGNUシステムの一部であり、それはGPLで
認可された完全なオペレーティング・システムである。
@c Anybody can use, modify, and redistribute it under the terms of the GNU
@c General Public License (@pxref{Copying}).  The Hurd is part of the GNU
@c system, which is a complete operating system licensed under the GPL.

@item それは互換性がある
Hurdは慣れ親しんだプログラミングやユーザ環境を提供する。どの点に対しても、
Hurdは現代的なUnixライクのカーネルである。HurdはGNU Cライブラリを使用し、
その開発はANSI/ISO、BSD、POSIX、Single Unix、SVID、そしてX/Openのような
標準を厳密に追いかけている。
@c The Hurd provides a familiar programming and user environment.  For all
@c intents and purposes, the Hurd is a modern Unix-like kernel.  The Hurd
@c uses the GNU C Library, whose development closely tracks standards such
@c as ANSI/ISO, BSD, POSIX, Single Unix, SVID, and X/Open.

@item それは生き残るように構築されている
他の有名なカーネル・ソフトウェアと違い、Hurdはその設計を汚さずに進化でき
るような、オブジェクト指向の構造を持っている。この構造はHurdを全体的に書
き直さなくても重大な再設計や変更に耐えられるようにするのに役立つだろう。
@c Unlike other popular kernel software, the Hurd has an object-oriented
@c structure that allows it to evolve without compromising its design.
@c This structure will help the Hurd undergo major redesign and
@c modifications without having to be entirely rewritten.

@item それはscalableである
単一プロセッサと対称マルチプロセッサの両方で効率的に動作するように、Hurd
の実装は積極的にマルチスレッド化されている。Hurdのインターフェースは透過
的なネットワーク・クラスタ(@dfn{collectives})が可能なように設計されてい
る。この機能はまだ実装されていないが。
@c The Hurd implementation is aggressively multithreaded so that it runs
@c efficiently on both single processors and symmetric multiprocessors.
@c The Hurd interfaces are designed to allow transparent network clusters
@c (@dfn{collectives}), although this feature has not yet been implemented.

@item それは拡張性がある
Hurdはカーネル・ハッカーになる方法を学んだり、カーネルの技術の新しい発想
を実装するのに魅力的なプラットホームである。そのシステムのあらゆる部分が
変更され、拡張されるように設計されている。
@c The Hurd is an attractive platform for learning how to become a kernel
@c hacker or for implementing new ideas in kernel technology.  Every part
@c of the system is designed to be modified and extended.

@item それは安定である
新しいHurdカーネルの構成要素を開発し試験するために、(偶発的でもなく)マシ
ンを再起動せずに行うことが可能である。あなた自身のカーネル構成要素を動作
させることは他のユーザには干渉しないので、特別なシステム特権は必要とされ
ない。カーネル拡張の仕組みは設計により安全である。あなたの変更に権限を与
えたり、あなたがシステム管理者だったりしない限り、その変更を他のユーザに
押しつけることは不可能である。
@c It is possible to develop and test new Hurd kernel components without
@c rebooting the machine (not even accidentally).  Running your own kernel
@c components doesn't interfere with other users, and so no special system
@c privileges are required.  The mechanism for kernel extensions is secure
@c by design: it is impossible to impose your changes upon other users
@c unless they authorize them or you are the system administrator.

@item それは存在する
Hurdは直ちに動作する現実のソフトウェアである。それは研究プロジェクトや提
案ではない。それを使ったり開発したりできるようになるまで全く待たなくて良
いのだ。
@c The Hurd is real software that works Right Now.  It is not a research
@c project or a proposal.  You don't have to wait at all before you can
@c start using and developing it.
@end table


@node Overview
@section 概観

FIXME: overview of basic Hurd architecture, FAQish in nature


@node History
@section 歴史

Richard Stallman (RMS)は完全でフリーなオペレーティング・システムを作成す
るためのプロジェクトとして、1983年にGNUを発足した。GNU宣言の文章では、原
始的なカーネルがあると彼は言っていた。1986年2月の最初のGNUsletterで、GNU
のカーネルはTRIXであると彼は言っているが、それはマサチューセッツ工科大学
で開発された。
@c Richard Stallman (RMS) started GNU in 1983, as a project to create a
@c complete free operating system.  In the text of the GNU Manifesto, he
@c mentioned that there is a primitive kernel.  In the first GNUsletter,
@c Feb. 1986, he says that GNU's kernel is TRIX, which was developed at the
@c Massachusetts Institute of Technology.

1986年の12月までは、Free Software Foundation (FSF)は ``TRIXに必要な変更
の作業を始めた'' [Gnusletter, Jan, 1987]。その後ちょっとして、FSFは ``カー
ネギーメロン大学のRashid教授とMachカーネルの開発を彼らと共に作業すること
について取り決めること'' を始めた [Gnusletter, June, 1987]。その文章は、
FSFがTRIXを直さなければならないよりも、誰か他の人の作品を使いたがってい
たことを暗示している。
@c By December of 1986, the Free Software Foundation (FSF) had ``started
@c working on the changes needed to TRIX'' [Gnusletter, Jan. 1987].
@c Shortly thereafter, the FSF began ``negotiating with Professor Rashid of
@c Carnegie-Mellon University about working with them on the development of
@c the Mach kernel'' [Gnusletter, June, 1987].  The text implies that the
@c FSF wanted to use someone else's work, rather than have to fix TRIX.

[Gnusletter, Feb. 1988]において、``バークレーUnixの部分が置き換えられた
後に@dots{}''、Machを受け取り、バークレーSpriteファイルシステムをその上
に乗せることをRMSが話していた。
@c In [Gnusletter, Feb. 1988], RMS was talking about taking Mach and
@c putting the Berkeley Sprite filesystem on top of it, ``after the parts
@c of Berkeley Unix@dots{} have been replaced.''

六ヶ月後、FSFは ``もし我々がMachを手に入れられないなら、TRIXかバークレー
のSpriteを使うだろう''と言っている。ここで、彼らはSpriteを単なるファイル
システムではなく、完全なカーネルの選択として提出する。
@c Six months later, the FSF is saying that ``if we can't get Mach, we'll
@c use TRIX or Berkeley's Sprite.''  Here, they present Sprite as a
@c full-kernel option, rather than just a filesystem.

1990年の1月に、彼らは ``我々はどんなカーネルの仕事も行っていない。まだ
Machを使用することを望むときに、今カーネル・プロジェクトを発足することは
我々には意味がない''と言っている [Gnusletter, Jan. 1990]。1991年まで何も
重要なことは起きない。そのときもっと詳細な計画が公表される。
@c In January, 1990, they say ``we aren't doing any kernel work.  It does
@c not make sense for us to start a kernel project now, when we still hope
@c to use Mach'' [Gnusletter, Jan. 1990].  Nothing significant occurs until
@c 1991, when a more detailed plan is announced:

@display
``我々はなおMachの上で走る多重プロセス・カーネルに興味がある。CMUの弁護
士は現在、我々が配布できる配布条件でMachをリリースできるかどうか決定して
いる。もし彼らがそうすると決めれば、我々はおそらく作業を開始するだろう。
CMUはMachと同じtermで利用できる、Poeと名付けられた単一サーバの部分的な
Unixエミュレータを持っている。それはいくぶん遅くて最小限の機能を提供して
いる。我々は多分完全な機能を提供するようにPoeを拡張することから始めるだ
ろう。後で多重プロセスに分割されたモジュール方式のエミュレータを持つこと
を望んでいる。'' [Gnusletter, Jan. 1991]。
@c ``We are still interested in a multi-process kernel running on top of
@c Mach. The CMU lawyers are currently deciding if they can release Mach
@c with distribution conditions that will enable us to distribute it. If
@c they decide to do so, then we will probably start work. CMU has
@c available under the same terms as Mach a single-server partial Unix
@c emulator named Poe; it is rather slow and provides minimal
@c functionality. We would probably begin by extending Poe to provide full
@c functionality. Later we hope to have a modular emulator divided into
@c multiple processes.'' [Gnusletter, Jan. 1991].
@end display

RMSはHurdとLinuxの関係を
@uref{http://www.gnu.org/software/hurd/hurd-and-linux.html}で説明してお
り、そこではFSFは1990年にHurdを開発し始めたと彼は言及している。
[Gnusletter, Nov. 1991]により、(Machの上で走る)HurdはGNUの公式カーネルで
ある。
@c RMS explains the relationship between the Hurd and Linux in
@c @uref{http://www.gnu.org/software/hurd/hurd-and-linux.html}, where he
@c mentions that the FSF started developing the Hurd in 1990.  As of
@c [Gnusletter, Nov. 1991], the Hurd (running on Mach) is GNU's official
@c kernel.


@node Copying
@section GNU General Public License

@include gpl.texinfo


@node Installing
@chapter Installing

Before you can use the Hurd on your favorite machine, you'll need to
install all of its software components.  Currently, the Hurd only runs
on Intel i386-compatible architectures (such as the Pentium), using the
GNU Mach microkernel.

If you have unsupported hardware or a different microkernel, you will
not be able to run the Hurd until all the required software has been
@dfn{ported} to your architecture.  Porting is an involved process which
requires considerable programming skills, and is not recommended for the
faint-of-heart.  If you have the talent and desire to do a port, contact
@email{bug-hurd@@gnu.org} in order to coordinate the effort.

@menu
* Binary Distributions::        Obtaining ready-to-run GNU distributions.
* Cross-Compiling::             Building GNU from its source code.
@end menu


@node Binary Distributions
@section Binary Distributions

By far the easiest and best way to install the Hurd is to obtain a GNU
binary distribution.  Even if you plan on recompiling the Hurd itself,
it is best to start off with an already-working GNU system so that you
can avoid having to reboot every time you want to test a program.

@ignore @c FIXME: update when binary CD-ROMS are available
You can order GNU on a CD-ROM from the Free Software Foundation.  Orders
such as these help fund GNU software development.
@end ignore

You can get GNU from a friend under the conditions allowed by the GNU
GPL (@pxref{Copying}).  Please consider sending a donation to the Free
Software Foundation so that we can continue to improve GNU software.

You can also FTP the complete GNU system from your closest GNU mirror,
or @uref{ftp://ftp.gnu.org/pub/gnu/}.  The GNU binary distribution is
available in a subdirectory called @file{gnu-@var{n.m}}, where @var{n.m}
is the version of the Hurd that this GNU release corresponds to
(@value{VERSION} at the time of this writing).  Again, please consider
donating to the Free Software Foundation.

The format of the binary distribution is prone to change, so this manual
does not describe the details of how to install GNU.  The @file{README}
file distributed with the binary distribution gives you complete
instructions.

After you follow all the appropriate instructions, you will have a
working GNU/Hurd system.  If you have used Linux-based GNU systems or
other Unix-like systems before, the Hurd will look quite familiar.  You
should play with it for a while, referring to this manual only when you
want to learn more about the Hurd.  Have fun!

If the Hurd is your first introduction to the GNU operating system, then
you will need to learn more about GNU in order to be able to use it.
You should talk to friends who are familiar with GNU, in order to find
out about classes, online tutorials, or books which can help you learn
more about GNU.

If you have no friends who are already using GNU, you can find some
useful starting points at the GNU web site, @uref{http://www.gnu.org/}.
You can also send e-mail to @email{help-hurd@@gnu.org}, to contact
fellow Hurd users.  You can join this mailing list by sending a request
to @email{help-hurd-request@@gnu.org}.


@node Cross-Compiling
@section Cross-Compiling

Another way to install the Hurd is to use an existing operating system
in order to compile all the required Hurd components from source code.
This is called @dfn{cross-compiling}, because it is done between two
different platforms.

@emph{This process is not recommended unless you are porting the Hurd to
a new platform.}  Cross-compiling the Hurd to a platform which already
has a binary distribution is a tremendous waste of time@dots{} it is
frequently necessary to repeat steps over and over again, and you are
not even guaranteed to get a working system.  Please, obtain a GNU
binary distribution (@pxref{Binary Distributions}), and use your time to
do more useful things.  If you are capable of cross-compiling, then you
are definitely skilled enough to make more useful (and creative)
modifications to the GNU system.

If you are interested in porting the Hurd to a new platform, you should
send e-mail to the @email{bug-hurd@@gnu.org} mailing list in order to
coordinate your efforts.  People on that list will give you advice on
what to look out for, as well as helping you find other people who are
interested in working on the same port.


@node Bootstrap
@chapter Bootstrap

Bootstrapping is the procedure by which your machine loads the
microkernel and transfers control to the Hurd servers.@footnote{The term
@dfn{bootstrapping} refers to a Dutch legend about a boy who was able to
fly by pulling himself up by his bootstraps.  In computers, this term
refers to any process where a simple system activates a more complicated
system.}


@menu
* Bootloader::                  Starting the microkernel, or other OSes.
* Server Bootstrap::            Waking up the Hurd.
* Shutdown::                    Letting the Hurd get some rest.
@end menu

@node Bootloader
@section Bootloader

The @dfn{bootloader} is the first software that runs on your machine.
Many hardware architectures have a very simple startup routine which
reads a very simple bootloader from the beginning of the internal hard
disk, then transfers control to it.  Other architectures have startup
routines which are able to understand more of the contents of the hard
disk, and directly start a more advanced bootloader.

@cindex GRUB
@cindex GRand Unified Bootloader
Currently, @dfn{GRUB}@footnote{The GRand Unified Bootloader, available
from @uref{http://www.uruk.org/grub/}.} is the preferred GNU bootloader.
GRUB provides advanced functionality, and is capable of loading several
different kernels (such as Linux, DOS, and the *BSD family).

From the standpoint of the Hurd, the bootloader is just a mechanism to
get the microkernel running and transfer control to @code{serverboot}.
You will need to refer to your bootloader and microkernel documentation
for more information about the details of this process.


@node Server Bootstrap
@section Server Bootstrap
@pindex serverboot

The @code{serverboot} program is responsible for loading and executing
the rest of the Hurd servers.  Rather than containing specific
instructions for starting the Hurd, it follows general steps given in a
user-supplied boot script.

To bootstrap the Hurd, the microkernel must start this program as its
first task, and to pass it appropriate arguments.  @code{serverboot} may
also be invoked while the Hurd is already running, which allows users to
start their own complete sub-Hurds (@pxref{Invoking boot}).

@menu
* Invoking serverboot::         Starting a set of interdependent servers.
* Boot Scripts::                Describing server bootstrap relationships.
* Invoking boot::               Running a Hurd under another Hurd.
@end menu


@node Invoking serverboot
@subsection Invoking @code{serverboot}

The @code{serverboot} program has the following synopsis:

@example
serverboot -@var{switch}... [[@var{host-port} @var{device-port}] @var{root-name}]
@end example

@c FIXME: serverboot should accept --help and --version, for consistency
Each @var{switch} is a single character, out of the following set:

@table @samp
@item a
Prompt the user for the @var{root-name}, even if it was already supplied
on the command line.

@item d
Prompt the user to strike a key after the boot script has been read.

@item q
Prompt the user for the name of the boot script.  By default, use
@file{@var{root-name}:/boot/servers.boot}.
@end table

All the @var{switches} are put into the @code{$@{boot-args@}} script
variable.

@var{host-port} and @var{device-port} are integers which represent the
microkernel host and device ports, respectively (and are used to
initialize the @code{$@{host-port@}} and @code{$@{device-port@}} boot
script variables).  If these ports are not specified, then
@code{serverboot} assumes that the Hurd is already running, and fetches
the current ports from the procserver (FIXME xref).

@var{root-name} is the name of the microkernel device that should be
used as the Hurd bootstrap filesystem.  @code{serverboot} uses this name
to locate the boot script (described above), and to initialize the
@code{$@{root-device@}} script variable.


@node Boot Scripts
@subsection Boot Scripts
@pindex /boot/servers.boot
@pindex servers.boot

FIXME: finish


@node Invoking boot
@subsection Invoking @code{boot}

The @code{boot} program is used to start a set of core Hurd servers
while another Hurd is already running.  You will rarely need to do this,
and it currently requires superuser privileges (to access the host
privileged port), but it is interesting to note that it can be done.

Usually, you would make changes to only one server, and simply tell your
programs to use it in order to test out your changes.  This process can
be applied even to the core servers.  However, some changes have
far-reaching effects, and so it is nice to be able to test those effects
without having to reboot the machine.

The @code{boot} program has the following synopsis:

@example
boot [@var{option}]@dots{} @var{boot-script} @var{root-store}
@end example

@var{boot-script} is the name of the boot script (@pxref{Boot
Scripts}).  @var{root-store} is the store that is used as the root
partition (@pxref{Store Library}).

Here are the steps you can follow to test out a new set of servers:

@enumerate 1
@item
Create a new root partition and initialize it with your favorite
filesystem format.  The @code{boot} program uses libstore, so you can
use any valid store as your root, with any options that libstore
recognizes:

@example
$ dd if=/dev/zero of=my-partition bs=1024 count=80
$ mke2fs ./my-partition
@end example

It is better to use a raw partition, if possible.  With a raw partition,
the sub-Hurd doesn't depend on its parent for anything except the
default pager.

@item
Copy the core servers, C library, and any of your modified programs onto
the new partition:

@example
$ settrans -c ./my-root /hurd/ext2fs `pwd`/my-partition
$ (cd my-root && tar -zxf ../my-files.tar.gz)
@end example

@item
Use some clever shadowfs hacks (FIXME xref) to mirror the rest of your
programs under the modified partition.  Copying them will work, too, if
you don't like shadowfs.

@item
Create a boot script on the new partition, in @file{/boot/servers.boot}.

@item
Make your root filesystem read-only for the parent Hurd, to prevent any
conflicts:

@example
$ settrans -g ./my-root
$ settrans -c ./my-root /hurd/ext2fs -r `pwd`/my-partition
@end example

@item
Run @code{boot} on your new partition:

@example
$ boot -D ./my-root ./my-root/boot/servers.boot ./my-partition
@end example
@end enumerate

Note that sharing microkernel devices between the two running Hurds may
cause conflicts, so don't get any funny ideas.  When you're finished
testing your new Hurd, then you can run the @code{halt} or @code{reboot}
programs to return control to the parent Hurd.

If you're satisfied with your new Hurd, you can arrange for your
bootloader to start it, and reboot your machine.  Then, you'll be in a
safe place to overwrite your old Hurd with the new one, and reboot back
to your old configuration (with the new Hurd servers).


@node Shutdown
@section Shutdown
@scindex halt
@scindex reboot

FIXME: finish


@node Foundations
@chapter 基礎

あらゆるHurdプログラムは以下の付加的な引数を受け取る。
@c Every Hurd program accepts the following optional arguments:

@table @samp
@item --help
簡潔な使い方のメッセージを表示し、終了する。このメッセージはプログラムの
解説書を読むことの代わりではなく、プログラムが理解する特定のコマンドライ
ンのオプションについて思い出すのに役に立つのである。
@c Display a brief usage message, then exit.  This message is not a
@c substitute for reading program documentation, rather it provides useful
@c reminders about specific command-line options that a program
@c understands.

@item --version
プログラムのバージョン情報を出力し、終了する。
@c Output program version information and exit.
@end table

この章の残りで、Hurdをプログラマに対して紹介する。もしあなたがプログラマ
でないなら、この章はあなたには大して意味がない@dots{} 特定のHurdプログラ
ムの記述まで飛ばすことを考えるべきだ (@pxref{Audience})。
@c The rest of this chapter provides a programmer's introduction to the
@c Hurd.  If you are not a programmer, then this chapter will not make much
@c sense to you@dots{} you should consider skipping to descriptions of
@c specific Hurd programs (@pxref{Audience}).

Hurdのユーティリティやサーバを書くための有用なツールの組を提供するために、
Hurdの配布にはたくさんのライブラリが含まれている。これらのライブラリのい
くつかはHurdにだけではなく、一般的にマイクロカーネルに基くプログラムを書
くのに役立つ。これらの基本的なライブラリは理解するのに難しくはなく、それ
らは良い開始点である。なぜなら、Hurdの残りの部分は非常に激しくそれらに頼っ
ているからだ。
@c The Hurd distribution includes many libraries in order to provide a
@c useful set of tools for writing Hurd utilities and servers.  Several of
@c these libraries are useful not only for the Hurd, but also for writing
@c microkernel-based programs in general.  These fundamental libraries are
@c not difficult to understand, and they are a good starting point, because
@c the rest of the Hurd relies upon them quite heavily.

@menu
* Threads Library::             あらゆるHurdサーバとライブラリは
                                マルチスレッド化されている。
* Microkernel Object Library::  マイクロカーネル・オブジェクト・モデル(MOM)。
* Ports Library::               サーバのport受信権の管理。
* Integer Hash Library::        整数を鍵としたハッシュ表。
* Misc Library::                GNU Cライブラリにすぐに入るもの。
* Bug Address Library::         Hurdのバグを報告する場所。
@end menu

@node Threads Library
@section スレッド・ライブラリ
@scindex libthreads
@scindex cthreads.h

マイクロカーネルや土台となるハードウェアのよって提供される多重処理の能力
を十分に利用するために、Hurdサーバやライブラリは全て積極的にマルチスレッ
ド化されている。Hurdのスレッド・ライブラリ、@code{libthreads}はデフォル
トのHurdスレッドの実装を含み、それは@code{<cthreads.h>}で宣言されている。
@c All Hurd servers and libraries are aggressively multithreaded in order
@c to take full advantage of any multiprocessing capabilities provided by
@c the microkernel and the underlying hardware.  The Hurd threads library,
@c @code{libthreads} contains the default Hurd thread implementation, which
@c is declared in @code{<cthreads.h>}.

現在(1998年4月)、Hurdはcthreadsを使っているが、それはすでにCMUによって完
全に解説されている。最後には、それはPOSIX pthreadsを使うように移行される
だろう。それはたくさんのところで解説されている。
@c Currently (April 1998), the Hurd uses cthreads, which have already been
@c documented thoroughly by CMU.  Eventually, it will be migrated to use
@c POSIX pthreads, which are documented in a lot of places.
@c Thomas, 26-03-1998

(GNU Cライブラリを含む)Hurd配布物の中の個々のライブラリは完全にスレッド・
セーフで、Hurdサーバ自身は積極的にマルチスレッド化されている。
@c Every single library in the Hurd distribution (including the GNU C
@c library) is completely thread-safe, and the Hurd servers themselves are
@c aggressively multithreaded.


@node Microkernel Object Library
@section マイクロカーネル・オブジェクト・ライブラリ
@scindex libmom
@scindex mom.h

一般に尋ねられる質問はHurdはMachマイクロカーネルのOpen Groupのバージョン
に移植されているかどうかだ。その答えは``いいえ''だ。
@c A commonly asked question is whether the Hurd has been ported to the
@c Open Group's version of the Mach microkernel.  The answer is ``no''.

現在(1998年4月)、Hurdは非常にGNU Machマイクロカーネルに依存しており、そ
れはユタ大学のMach 4から派生している。しかしながら、Hurdの開発者はMachの
限界をあまりにも気にし過ぎている。
@c Currently (April 1998), the Hurd is quite dependent on the GNU Mach
@c microkernel, which is a derivative of the University of Utah's Mach 4.
@c However, the Hurd developers are all-too-aware of the limitations of
@c Mach.

@cindex MOM
@cindex Microkernel Object Model
@code{libmom}はHurdを他のメッセージ通信式マイクロカーネルに移植できるよ
うにするために必要とされるいくつかの段階のうち最初のものである。
@dfn{MOM}は@dfn{Microkernel Object Model}を表し、一般的なメッセージ通信
式マイクロカーネルによって提供される基本的なサービスの抽象概念である。そ
れはHurdサーバとCライブラリがマイクロカーネルに依存したカーネル呼び出し
を行わないでいいように、必要な隔離を行うだろう。
@c @code{libmom} is the first of several steps that need to be taken in
@c order to make the Hurd portable to other message-passing microkernels.
@c @dfn{MOM} stands for @dfn{Microkernel Object Model}, and is an
@c abstraction of the basic services provided by common message-passing
@c microkernels.  It will provide the necessary insulation so that Hurd
@c servers and the C library can avoid making microkernel-dependent kernel
@c calls.

でも、現在では、@code{libmom}はまだ発展中であり、完全にHurdに組み込まれ
るにはいくらか時間がかかるだろう。
@c At the present, though, @code{libmom} is still evolving, and will take
@c some time to be fully incorporated into the Hurd.


@node Ports Library
@section portのライブラリ
@scindex libports
@scindex ports.h

portはカーネルによって所有される通信路である。
@c Ports are communication channels that are held by the kernel.

portは別々の送信権と受信権を持ち、それらはカーネルを通してタスクからタ
スクへ譲られても良い。port権はUnixのファイル記述子と似ている。それらは
カーネル呼び出しを行うときにportを識別するのに使われるタスク毎の整数で
ある。送信権はRPCリクエストをportに遅るために必要で、受信権はRPCリクエ
ストに応対するために必要である。受信権は単一の@dfn{portset}に集めら
れても良く、それは有用な構成単位として役に立つ。
@c A port has separate send rights and receive rights, which may be
@c transferred from task to task via the kernel.  Port rights are similar
@c to Unix file descriptors: they are per-task integers which are used to
@c identify ports when making kernel calls.  Send rights are required in
@c order to send an RPC request down a port, and receive rights are
@c required to serve the RPC request.  Receive rights may be aggregated
@c into a single @dfn{portset}, which serve as useful organizational units.

単一スレッドのRPCクライアントでは、portを管理し類別することは難しい処
理ではない。しかしながら、複雑なマルチスレッドのサーバでは、portset
を管理するのにより抽象的なインターフェースを持つことは、サーバの抽象的な
データを管理することと同様、役に立つのである。
@c In a single-threaded RPC client, managing and categorizing ports is not
@c a difficult process.  However, in a complex multithreaded server, it is
@c useful to have a more abstract interface to managing portsets, as well
@c as maintaining server metadata.

Hurdのportのライブラリ、@code{libports}はその必要性を満たす。
@code{libports}関数は@code{<hurd/ports.h>}で宣言されている。
@c The Hurd ports library, @code{libports}, fills that need.  The
@c @code{libports} functions are declared in @code{<hurd/ports.h>}.

@menu
* Buckets and Classes::         port編成の基本単位。
* Port Rights::                 port権の@code{libports}との間での移動。
* Port Metadata::               port関連の情報の管理。
* Port References::             漏曳や欠失に対する保護。
* RPC Management::              RPC操作のロックと割り込み。
@end menu

@node Buckets and Classes
@subsection BucketとClass

@code{libports}の@dfn{bucket}はただのportの組と、いくらかの抽象データ
とロックだけである。@code{libports}関数の全てはbucketに対して操作する。
@c The @code{libports} @dfn{bucket} is simply a port set, with some
@c metadata and a lock.  All of the @code{libports} functions operate on
@c buckets.

@deftypefun {struct port_bucket *} ports_create_bucket (void)
新しい、空のbucketを作って返す。
@c Create and return a new, empty bucket.
@end deftypefun

portの@dfn{class}は個々のportの集まりで、それは簡便に扱うことができ、
解放ルーチンを強制している。bucketとclassはまったくorthogonalである。
classのportが全て同じbucketに入っている必要性はなく、bucketのportが
全て同じclassに入っている必要性もない。
@c A port @dfn{class} is a collection of individual ports, which can be
@c manipulated conveniently, and have enforced deallocation routines.
@c Buckets and classes are entirely orthogonal: there is no requirement
@c that all the ports in a class be in the same bucket, nor is there a
@c requirement that all the ports in a bucket be in the same class.

@deftypefun {struct port_class} ports_create_class (@w{void (*@var{clean_routine}) (void *@var{port})}, @w{void (*@var{dropweak_routine}) (void *@var{port})})
新しいport classを作って返す。もし非ゼロなら、@var{clean_routine}はこの
classの割り当てられたportオブジェクトが破壊されるときにそれぞれに対して
呼び出されるだろう。もし非ゼロなら、@var{dropweak_routine}は弱い参照が減
少するようにリクエストするときに呼び出されるだろう。(もし
@var{dropweak_routine}がnullなら、弱い参照と強い参照はこのclassのportに
対して等価だろう。)
@c Create and return a new port class.  If nonzero, @var{clean_routine}
@c will be called for each allocated port object in this class when it is
@c being destroyed.  If nonzero, @var{dropweak_routine} will be called to
@c request weak references to be dropped.  (If @var{dropweak_routine} is
@c null, then weak references and hard references will be identical for
@c ports of this class.)
@end deftypefun

少なくとも一つのbucketとclassを作ってしまったら、新しいportを作り、これ
らのbucketに収めて良い。あなたのアプリケーションの必要性に依存して、port
の生成に対して少数の異なる関数がある。
@c Once you have created at least one bucket and class, you may create new
@c ports, and store them in those buckets.  There are a few different
@c functions for port creation, depending on your application's
@c requirements:

@deftypefun error_t ports_create_port (@w{struct port_class *@var{class}}, @w{struct port_bucket *@var{bucket}}, @w{size_t @var{size}}, @w{void *@var{result}})
@var{class}と@var{bucket}の新しいportを作り、@var{result}に入れて返す。
@var{size}バイトがport構造体とユーザが定義するプライベートなデータを保持
するために割り当てられるだろう。
@c Create and return in @var{result} a new port in @var{class} and
@c @var{bucket}; @var{size} bytes will be allocated to hold the port
@c structure and whatever private data the user desires.
@end deftypefun

@deftypefun error_t ports_create_port_noinstall (@w{struct port_class *@var{class}}, @w{struct port_bucket *@var{bucket}}, @w{size_t @var{size}}, @w{void *@var{result}})
実際にはportを@var{bucket}の根底にあるportsetに入れられないことを除いて、
@code{ports_create_port}とちょうど同じである。これはportが完全に初期化さ
れる前にport権が配られなければならない場合に使われることを意図されている。
この呼び出しを使うと、portを初期化し終わりportsetにあなた自身がそれを入
れるまで、そのportにRPCサービスが起こらないことが保証される。
@c Just like @code{ports_create_port}, except don't actually put the port
@c into the portset underlying @var{bucket}.  This is intended to be used
@c for cases where the port right must be given out before the port is
@c fully initialized; with this call you are guaranteed that no RPC service
@c will occur on the port until you have finished initializing it and
@c installed it into the portset yourself.
@end deftypefun

@deftypefun error_t ports_import_port (@w{struct port_class *@var{class}}, @w{struct port_bucket *@var{bucket}}, @w{mach_port_t @var{port}}, @w{size_t @var{size}}, @w{void *@var{result}})
存在する@emph{受信}権に対し、新しいport構造体を作って@var{result}に返す。
@var{bucket}、@var{size}、そして@var{class}引数は
@code{ports_create_port}と同様である。
@c For an existing @emph{receive} right, create and return in @var{result}
@c a new port structure; @var{bucket}, @var{size}, and @var{class} args are
@c as for @code{ports_create_port}.
@end deftypefun


@node Port Rights
@subsection port権

以下の関数はport受信権をport構造体との間で移動する。
@c The following functions move port receive rights to and from the port
@c structure:

@deftypefun void ports_reallocate_port (@w{void *@var{port}})
現在@var{port}と結び付いている受信権を破棄し、新しい受信権を割り当てる。
@c Destroy the receive right currently associated with @var{port} and
@c allocate a new one.
@end deftypefun

@deftypefun void ports_reallocate_from_external (@w{void *@var{port}}, @w{mach_port_t @var{receive}})
現在@var{port}と結び付いている受信権を破棄し、@var{receive}を新しい受信
権として指定する。
@c Destroy the receive right currently associated with @var{port} and
@c designate @var{receive} as the new one.
@end deftypefun

@deftypefun void ports_destroy_right (@w{void *@var{port}})
現在@var{port}と結び付いている受信権を破棄する。この呼び出しの後に、
@code{ports_reallocate_port}と@code{ports_reallocate_from_external}は使
えない。
@c Destroy the receive right currently associated with @var{port}.  After
@c this call, @code{ports_reallocate_port} and
@c @code{ports_reallocate_from_external} may not be used.
@end deftypefun

@deftypefun mach_port_t ports_claim_right (@w{void *@var{port}})
現在@var{port}と結び付いている受信権を返す。@var{port}に対する効果は
受信権自体には影響しないことを除いて@code{ports_destroy_right}と同じであ
る。マルチスレッド化されているサーバでは、このportがportsetから除かれる
前にメッセージがすでにキューから除かれているかもしれないことに注意せよ。
そのようなメッセージからは@code{EOPNOTSUPP}エラーを得るであろう。
@c Return the receive right currently associated with @var{port}.  The
@c effects on @var{port} are the same as in @code{ports_destroy_right},
@c except that the receive right itself is not affected.  Note that in
@c multi-threaded servers, messages might already have been dequeued for
@c this port before it gets removed from the portset; such messages will
@c get @code{EOPNOTSUPP} errors.
@end deftypefun

@deftypefun error_t ports_transfer_right (@w{void *@var{topt}}, @w{void *@var{frompt}})
@var{frompt}から@var{topt}へ受信権を移す。(あたかも
@code{ports_destory_right}が呼ばれたように)@var{frompt}は破棄された権利
を持つようになり、(あたかも@code{ports_reallocate_from_external}が呼ばれ
たよう)@var{topt}の古い権利は破棄される。
@c Transfer the receive right from @var{frompt} to @var{topt}.
@c @var{frompt} ends up with a destroyed right (as if
@c @code{ports_destroy_right} were called) and @var{topt}'s old right is
@c destroyed (as if @code{ports_reallocate_from_external} were called.
@end deftypefun

@deftypefun mach_port_t ports_get_right (@w{void *@var{port}})
@var{port}と結び付いている受信権の名前を返す。ユーザは責任を持って、この
名前から普通の送信権を作らねばならない。
@c Return the name of the receive right associated with @var{port}.  The
@c user is responsible for creating an ordinary send right from this name.
@end deftypefun


@node Port Metadata
@subsection portの抽象データ

@code{libports}関数のそれぞれへの@var{port}引数が@code{void *}であって
@code{struct port_info *}ではないことを指摘するのは重要だ。これは任意の
抽象的な情報をあなたの@code{libports}に管理されるportへ追加できるために
行われている。単に最初の要素が@code{struct port_info}であるような、あな
た自身の構造体を定義すれば、どんな@code{libports}関数へも@var{port}引数
としてこれらの構造体へのポインタを使うことができる。
@c It is important to point out that the @var{port} argument to each of
@c the @code{libports} functions is a @code{void *} and not a @code{struct
@c port_info *}.  This is done so that you may add arbitrary
@c meta-information to your @code{libports}-managed ports.  Simply define
@c your own structure whose first element is a @code{struct port_info}, and
@c then you can use pointers to these structures as the @var{port} argument
@c to any @code{libports} function.

以下の関数はあなた自身があつらえたport構造体に収められる抽象データを管理
するのに役立つ。
@c The following functions are useful for maintaining metadata that is
@c stored in your own custom ports structure:

@deftypefun {void *} ports_lookup_port (@w{struct port_bucket *@var{bucket}}, @w{mach_port_t @var{port}}, @w{struct port_class *@var{class}})
@var{port}を探し、参照を割り当てて、結び付いているport構造体を返す。この
呼び出しが失敗すると、ゼロを返す。もし@var{bucket}が非ゼロなら、それは検
索するためのbucketを指定する。そうでなければ全てのbucketが検索されるだろ
う。もし@var{class}が非ゼロなら、@var{port}が@var{class}にないなら検索が
失敗するだろう。
@c Look up @var{port} and return the associated port structure, allocating
@c a reference.  If the call fails, return zero.  If @var{bucket} is nonzero,
@c then it specifies a bucket to search; otherwise all buckets will be
@c searched.  If @var{class} is nonzero, then the lookup will fail if
@c @var{port} is not in @var{class}.
@end deftypefun

@deftypefun error_t ports_bucket_iterate (@w{struct port_bucket *@var{bucket}}, @w{error_t (*@var{fun}) (void *@var{port})})
@var{bucket}の各portに対し一度だけ@var{fun}を呼び出す。
@c Call @var{fun} once for each port in @var{bucket}.
@end deftypefun


@node Port References
@subsection portの参照

これらの関数はport情報構造体がもはや必要とされていないときに限り解放され
るように、portへの参照を管理する。@code{libports}にいつportへの参照が変
化するかを教えるのは、あなたの責任である。
@c These functions maintain references to ports so that the port
@c information structures may be freed if and only if they are no longer
@c needed.  It is your responsibility to tell @code{libports} when
@c references to ports change.

@deftypefun void ports_port_ref (@w{void *@var{port}})
@var{port}への強い参照を割り当てる。
@c Allocate a hard reference to @var{port}.
@end deftypefun

@deftypefun void ports_port_deref (@w{void *@var{port}})
@var{port}への強い参照を減少させる。
@c Drop a hard reference to @var{port}.
@end deftypefun

@deftypefun void ports_no_senders (@w{void *@var{port}}, @w{mach_port_mscount_t @var{mscount}})
ユーザは送信元不在通知を受け取ろうとすることに責任がある。やって来たとき
には、そのメッセージが送られた@var{port}に対して、その通知からの
@var{mscount}を与えてこのルーチンを呼び出しなさい。
@c The user is responsible for listening for no senders notifications; when
@c one arrives, call this routine for the @var{port} the message was sent
@c to, providing the @var{mscount} from the notification.
@end deftypefun

@deftypefun int ports_count_class (@w{struct port_class *@var{class}})
@var{class}に新しいportを生成するのを妨げる。現在@var{class}にあるportの
数を返す。
@c Block creation of new ports in @var{class}.  Return the number of ports
@c currently in @var{class}.
@end deftypefun

@deftypefun int ports_count_bucket (@w{struct port_bucket *@var{bucket}})
@var{bucket}に新しいportを生成するのを妨げる。現在@var{bucket}にあるport
の数を返す。
@c Block creation of new ports in @var{bucket}.  Return the number of ports
@c currently in @var{bucket}.
@end deftypefun

@deftypefun void ports_enable_class (@w{struct port_class *@var{class}})
(@code{ports_count_class}によって妨げられた)中断されたport生成を続けるこ
とを許可する。
@c Permit suspended port creation (blocked by @code{ports_count_class}) to
@c continue.
@end deftypefun

@deftypefun void ports_enable_bucket (@w{struct port_bucket *@var{bucket}})
(@code{ports_count_bucket}によって妨げられた)中断されたport生成を続けるこ
とを許可する。
@c Permit suspended port creation (blocked by @code{ports_count_bucket}) to
@c continue.
@end deftypefun

弱い参照は@var{dropweak_routine}がnullであるport classでは強い参照を同じ
なので、それほど使用されない。@xref{Buckets and Classes}。
@c Weak references are not often used, as they are the same as hard
@c references for port classes where @var{dropweak_routine} is null.
@c @xref{Buckets and Classes}.

@deftypefun void ports_port_ref_weak (@w{void *@var{port}})
@var{port}への弱い参照を割り当てる。
@c Allocate a weak reference to @var{port}.
@end deftypefun

@deftypefun void ports_port_deref_weak (@w{void *@var{port}})
@var{port}への弱い参照を減少させる。
@c Drop a weak reference to @var{port}.
@end deftypefun


@node RPC Management
@subsection RPCの操作

@code{libports}関数の残りはRPC操作を制御することにささげられる。これらの
関数は頑健なサーバを構築するために必要とされるlockingやthread
cancellationを全て行うのに役立つ。
@c The rest of the @code{libports} functions are dedicated to controlling
@c RPC operations.  These functions help you do all the locking and thread
@c cancellations that are required in order to build robust servers.

@deftypefn {Typedef} {typedef int (*} ports_demuxer_type ) (@w{mach_msg_header_t *@var{inp}}, @w{mach_msg_header_t *@var{outp}})
MiGのdemuxerルーチンの型。
@c Type of MiG demuxer routines.
@end deftypefn

@deftypefun error_t ports_begin_rpc (@w{void *@var{port}}, @w{mach_msg_id_t @var{msg_id}}, @w{struct rpc_info *@var{info}})
RPCが@var{port}上で開始しているときにこれを呼び出す。@var{info}は呼び出
し元で割り当てられるべきで、動的な状態を保持するのに使われるだろう。この
RPCが放棄されれば、@code{EDIED}を返す。そうでなければゼロを返す。
@c Call this when an RPC is beginning on @var{port}.  @var{info} should be
@c allocated by the caller and will be used to hold dynamic state.  If this
@c RPC should be abandoned, return @code{EDIED}; otherwise we return zero.
@end deftypefun

@deftypefun void ports_end_rpc (@w{void *@var{port}}, @w{struct rpc_info *@var{info}})
RPCが終えられているときにこれを呼び出す。引数は対になる
@code{ports_begin_rpc}の呼び出しに渡されたものと一致しなければならない。
@c Call this when an RPC is concluding.  The arguments must match the ones
@c passed to the paired call to @code{ports_begin_rpc}.
@end deftypefun

@deftypefun void ports_manage_port_operations_one_thread (@w{struct port_bucket *@var{bucket}}, @w{ports_demuxer_type @var{demuxer}}, @w{int @var{timeout}})
@var{bucket}のportへの操作を処理し始め、それぞれのやって来るメッセージに
対し@var{demuxer}を呼び出す。@var{timeout}が非ゼロで@var{timeout}ミリ秒
の間メッセージが受け取られないと返る。たった一つのスレッドだけ(呼び出し
スレッド)を使う。
@c Begin handling operations for the ports in @var{bucket}, calling
@c @var{demuxer} for each incoming message.  Return if @var{timeout} is
@c nonzero and no messages have been received for @var{timeout}
@c milliseconds.  Use only one thread (the calling thread).
@end deftypefun

@deftypefun void ports_manage_port_operations_multithread (@w{struct port_bucket *@var{bucket}}, @w{ports_demuxer_type @var{demuxer}}, @w{int @var{thread_timeout}}, @w{int @var{global_timeout}}, @w{void (*@var{hook}) (void)})
@var{bucket}のportへの操作を処理し始め、それぞれのやって来るメッセージに
対し@var{demuxer}を呼び出す。@var{global_timeout}が非ゼロで
@var{global_timeout}ミリ秒の間メッセージを受け取られないと返る。他のport
での緩慢さが原因でどのportも飢餓状態にならないように、やって来るメッセー
ジを処理するのに必要なだけスレッドを生成する。もし@var{thread_timeout}が
非ゼロなら、個々のスレッドは@var{thread_timeout}@footnote{訳注: 原文では
@var{local_timeout}となっているが間違いだと思われる。要確認。}ミリ秒の間
やって来るメッセージを処理しなかったら死んでいくだろう。もしnullでないな
ら、@var{hook}は、新しいスレッドが作られる後にすぐ、それぞれに対して呼び
出されるだろう。
@c Begin handling operations for the ports in @var{bucket}, calling
@c @var{demuxer} for each incoming message.  Return if @var{global_timeout}
@c is nonzero and no messages have been receieved for @var{global_timeout}
@c milliseconds.  Create threads as necessary to handle incoming messages
@c so that no port is starved because of sluggishness on another port.  If
@c @var{thread_timeout} is nonzero, then individual threads will die off
@c if they handle no incoming messages for @var{local_timeout}
@c milliseconds.  If non-null, @var{hook} will be called in each new thread
@c immediately after it is created.
@end deftypefun

@deftypefun error_t ports_inhibit_port_rpcs (@w{void *@var{port}})
@var{port}へのどの未処理のRPCにも割り込む。全ての未処理のRPCが終わるのを
待ち、そしてこのportで始まるどの新しいRPCでも妨げる。
@c Interrupt any pending RPC on @var{port}.  Wait for all pending RPCs to
@c finish, and then block any new RPCs starting on that port.
@end deftypefun

@deftypefun error_t ports_inhibit_class_rpcs (@w{struct port_class *@var{class}})
@code{ports_inhibit_port_rpcs}に似ているが、@var{class}の全てのportに影
響する。
@c Similar to @code{ports_inhibit_port_rpcs}, but affects all ports in
@c @var{class}.
@end deftypefun

@deftypefun error_t ports_inhibit_bucket_rpcs (@w{struct port_bucket *@var{bucket}})
@code{ports_inhibit_port_rpcs}に似ているが、@var{bucket}の全てのportに影
響する。
@c Similar to @code{ports_inhibit_port_rpcs}, but affects all ports in
@c @var{bucket}.
@end deftypefun

@deftypefun error_t ports_inhibit_all_rpcs (void)
@code{ports_inhibit_port_rpcs}に似しているが、ありとあらゆるportに影響する。
@c Similar to @code{ports_inhibit_port_rpcs}, but affects all ports
@c whatsoever.
@end deftypefun

@deftypefun void ports_resume_port_rpcs (@w{void *@var{port}})
この@var{port}に対する以前の@code{ports_inhibit_port_rpcs}の効果を元に戻
し、妨げられたRPCを続けることを許可する。
@c Reverse the effect of a previous @code{ports_inhibit_port_rpcs} for this
@c @var{port}, allowing blocked RPCs to continue.
@end deftypefun

@deftypefun void ports_resume_class_rpcs (@w{struct port_class *@var{class}})
この@var{class}に対する以前の@code{ports_inhibit_class_rpcs}の効果を元に
戻す。
@c Reverse the effect of a previous @code{ports_inhibit_class_rpcs} for
@c @var{class}.
@end deftypefun

@deftypefun void ports_resume_bucket_rpcs (@w{struct port_bucket *@var{bucket}})
この@var{bucket}に対する以前の@code{ports_inhibit_bucket_rpcs}の効果を元
に戻す。
@c Reverse the effect of a previous @code{ports_inhibit_bucket_rpcs} for
@c @var{bucket}.
@end deftypefun

@deftypefun void ports_resume_all_rpcs (void)
以前の@code{ports_inhibit_all_rpcs}の効果を元に戻す。
@c Reverse the effect of a previous @code{ports_inhibit_all_rpcs}.
@end deftypefun

@deftypefun void ports_interrupt_rpcs (@w{void *@var{port}})
@var{port}で進行中のどのRPCも(@code{thread_cancel}を使って)中止する。
@c Cancel (with @code{thread_cancel}) any RPCs in progress on @var{port}.
@end deftypefun

@deftypefun int ports_self_interrupted (void)
もし現在のスレッドのRPCが@code{ports_interrupt_rpcs}で割り込まれたなら、
非ゼロを返し、割り込みフラグを取り除く。
@c If the current thread's RPC has been interrupted with
@c @code{ports_interrupt_rpcs}, return nonzero and clear the interrupted
@c flag.
@end deftypefun

@deftypefun error_t ports_interrupt_rpc_on_notification (@w{void *@var{object}}, @w{struct rpc_info *@var{rpc}}, @w{mach_port_t @var{port}}, @w{mach_msg_id_t @var{what}})
@var{what}にあるもののいづれかが@var{port}に対して起きたなら、
@code{hurd_cancel}が@var{rpc}のスレッド上で呼ばれるように手配する。
@var{rpc}は@var{object}上のRPCであるべきだ。
@c Arrange for @code{hurd_cancel} to be called on @var{rpc}'s thread if
@c @var{object} gets notified that any of the things in @var{what} have
@c happened to @var{port}.  @var{rpc} should be an RPC on @var{object}.
@end deftypefun

@deftypefun error_t ports_interrupt_self_on_notification (@w{void *@var{object}}, @w{mach_port_t @var{port}}, @w{mach_msg_id_t @var{what}})
もし@var{port}が@var{what}という条件で通知を受けたら、@code{hurd_cancel}
が、それは@var{object}上のRPCであるべきだが、現在のスレッド上で呼ばれる
ように手配する。
@c Arrange for @code{hurd_cancel} to be called on the current thread, which
@c should be an RPC on @var{object}, if @var{port} gets notified with the
@c condition @var{what}.
@end deftypefun

@deftypefun error_t ports_interrupt_self_on_port_death (@w{void *@var{object}}, @w{mach_port_t @var{port}})
@var{what}が@code{MACH_NOTIFY_DEAD_NAME}に設定されて
@code{ports_interrupt_self_on_notification}を呼ぶのと同じである。
@c Same as calling @code{ports_interrupt_self_on_notification} with
@c @var{what} set to @code{MACH_NOTIFY_DEAD_NAME}.
@end deftypefun

@deftypefun void ports_interrupt_notified_rpcs (@w{void *@var{object}}, @w{mach_port_t @var{port}}, @w{mach_msg_id_t @var{what}})
そのようにリクエストしている@var{object}上のどのRPCにも割り込む。
@c Interrupt any RPCs on @var{object} that have requested such.
@end deftypefun

@deftypefun void ports_dead_name (@w{void *@var{object}}, @w{mach_port_t @var{port}})
@var{what}が@code{MACH_NOTIFY_DEAD_NAME}に設定されて
@code{ports_interrupt_notified_rpcs}を呼ぶのと同じである。
@c Same as calling @code{ports_interrupt_notified_rpcs} with @var{what} set
@c to @code{MACH_NOTIFY_DEAD_NAME}.
@end deftypefun


@node Integer Hash Library
@section 整数ハッシュ・ライブラリ
@scindex libihash
@scindex ihash.h

@code{libihash}は任意の要素データ型に対して、整数を鍵としたハッシュ表を
提供する。この種のハッシュ表は疎らな配列やバッファ・キャッシュを実装する
ときに頻繁に使われる。
@c @code{libihash} provides integer-keyed hash tables, for arbitrary
@c element data types.  This kind of hash tables are frequently used when
@c implementing sparse arrays or buffer caches.

以下の関数は@code{<hurd/ihash.h>}で宣言されている。
@c The following functions are declared in @code{<hurd/ihash.h>}:

@deftypefun error_t ihash_create (@w{ihash_t *@var{ht}})
整数ハッシュ表を生成し、それを@var{ht}に返す。もしメモリ割り当てエラーが
起きれば、@code{ENOMEM}が返され、そうでなければゼロである。
@c Create an integer hash table and return it in @var{ht}.  If a memory
@c allocation error occurs, @code{ENOMEM} is returned, otherwise zero.
@end deftypefun

@deftypefun void ihash_free (@w{ihash_t @var{ht}})
@var{ht}とそれが消費している全ての資源を解放する。
@c Free @var{ht} and all resources it consumes.
@end deftypefun

@deftypefun void ihash_set_cleanup (@w{ihash_t @var{ht}}, @w{void (*@var{cleanup}) (void *@var{value}, void *@var{arg})}, @w{void *@var{arg}})
@var{ht}の要素を後始末する関数を@var{cleanup}に設定し、その二つ目の引数
を@var{arg}に設定する。その後上書きされたり削除される、あらゆる要素
@var{value}に対して、@var{arg}を二番目の引数として@var{cleanup}が呼び出
されるだろう。
@c Sets @var{ht}'s element cleanup function to @var{cleanup}, and its
@c second argument to @var{arg}.  @var{cleanup} will be called on every
@c element @var{value} to be subsequently overwritten or deleted, with
@c @var{arg} as the second argument.
@end deftypefun

@deftypefun error_t ihash_add (@w{ihash_t @var{ht}}, @w{int @var{id}}, @w{void *@var{item}}, @w{void ***@var{locp}})
整数鍵@var{id}の下に@var{item}をハッシュ表@var{ht}に加える。@var{locp}は
@var{item}に位置するポインタのアドレスである。もしnullでなければ、
@var{locp}は@code{void **}型の変数を指しているべきで、
@code{ihash_locp_remove}の引数として使われて良いポインタで埋められるだろ
う。@var{locp}によって指された変数はこの呼び出しとその要素が削除されると
きの間のいつかに上書きされるかもしれない。だからその値を他の場所に隠して
おき、その隠しておいた値を@code{ihash_locp_remove}で使おうと考えることは
できない。もしメモリ割り当てエラーが起きると、@code{ENOMEM}が返され、そ
うでなければゼロが返る。
@c Add @var{item} to the hash table @var{ht} under the integer key
@c @var{id}.  @var{locp} is the address of a pointer located in @var{item};
@c If non-null, @var{locp} should point to a variable of type @code{void
@c **}, and will be filled with a pointer that may be used as an argument
@c to @code{ihash_locp_remove}.  The variable pointed to by @var{locp} may
@c be overwritten sometime between this call and when the element is
@c deleted, so you cannot stash its value elsewhere and hope to use the
@c stashed value with @code{ihash_locp_remove}.  If a memory allocation
@c error occurs, @code{ENOMEM} is returned, otherwise zero.
@end deftypefun

@deftypefun {void *} ihash_find (@w{ihash_t @var{ht}}, @w{int @var{id}})
ハッシュ表@var{ht}で鍵@var{id}で項目を探して返す。指定された項目が存在し
なければnullを返す。
@c Find and return the item in hash table @var{ht} with key @var{id}.
@c Returns null the specified item doesn't exist.
@end deftypefun

@deftypefun error_t ihash_iterate (@w{ihash_t @var{ht}}, @w{error_t (*@var{fun}) (void *@var{value})})
@var{ht}のあらゆる要素に関数@var{fun}を呼び出す。@var{fun}の唯一の引数、
@var{value}はそのハッシュ表に収められている値へのポインタである。もし
@var{fun}が非ゼロをいつか返せば、繰り返すのを止め、@code{ihash_iterate}
はその値を返し、そうでなければそれは(最後には)0を返す。
@c Call function @var{fun} on every element of @var{ht}.  @var{fun}'s only
@c arg, @var{value}, is a pointer to the value stored in the hash table.  If
@c @var{fun} ever returns nonzero, then iteration stops and
@c @code{ihash_iterate} returns that value, otherwise it (eventually)
@c returns 0.
@end deftypefun

@deftypefun int ihash_remove (@w{ihash_t @var{ht}}, @w{int @var{id}})
@var{ht}から@var{id}の鍵に伴う項目を削除する。もしそのような要素がなかっ
たら、ゼロを返し、そうでなければ非ゼロを返す。
@c Remove the entry with a key of @var{id} from @var{ht}.  If there was no
@c such element, then return zero, otherwise nonzero.
@end deftypefun

@deftypefun void ihash_locp_remove (@w{ihash_t @var{ht}}, @w{void **@var{ht_locp}})
ハッシュ表@var{ht}から@var{locp}にある項目を削除する。@var{locp}は
@code{ihash_add}への以前の呼び出しから返されたのと同じものである。この呼
び出しは@code{ihash_remove}より速いはずだ。その呼び出しが成功するのに、
後始末が行われていない場合には、@var{ht}がnullで良い。
@c Remove the entry at @var{locp} from the hashtable @var{ht}.  @var{locp}
@c is as returned from an earlier call to @code{ihash_add}.  This call
@c should be faster than @code{ihash_remove}.  @var{ht} can be null, in
@c which case the call still succeeds, but no cleanup is done.
@end deftypefun


@node Misc Library
@section 雑多なライブラリ
@scindex libshouldbeinlibc

GNU CライブラリはHurdの必要性を満たすように絶えず発展している。しかしな
がら、Cライブラリは非常に安定している必要があるので、新しい関数のインター
フェースを注意深く指定し、完全にそれらを試験することなく、それらを加える
のは無責任である。
@c The GNU C library is constantly developing to meet the needs of the
@c Hurd.  However, because the C library needs to be very stable, it is
@c irresponsible to add new functions to it without carefully specifying
@c their interface, and testing them thoroughly.

Hurdの配布には@code{libshouldbeinlibc}と呼ばれるライブラリが含まれ、それ
はGNU Cライブラリへ追加するための試験をする基盤として役に立つ。関数の一
部はHurd開発者によってそれに加えられ、それ以外は公式のCライブラリに移動するというように、このライブラリは流動的である。
@c The Hurd distribution includes a library called
@c @code{libshouldbeinlibc}, which serves as a proving ground for additions
@c to the GNU C library.  This library is in flux, as some functions are
@c added to it by the Hurd developers and others are moved to the official
@c C library.

これらの関数は(それらのヘッダ・ファイル以外は)現在解説されていないが、こ
れらの関数がGNU Cライブラリの一部となるときに、完全な解説が
@c These functions aren't currently documented (other than in their header
@c files), but complete documentation will be added to
@iftex
@emph{The GNU C Library Reference Manual}
@end iftex
@ifinfo
@ref{Top, The GNU C Library Reference Manual,, libc},
@end ifinfo
に加えられるだろう。
@c when these functions become part of the GNU C library.


@node Bug Address Library
@section バグの宛先ライブラリ
@scindex libhurdbugaddr

@code{libhurdbugaddr}は単一の変数を定義するためだけに存在する。
@c @code{libhurdbugaddr} exists only to define a single variable:

@deftypevar {char *} argp_program_bug_address
@code{argp_program_bug_address}はデフォルトのHurdバグ報告用e-mailアドレ
スで、@email{bug-hurd@@gnu.org}である。この宛先は標準的なHurdサーバやユー
ティリティのいづれかが@samp{--help}オプションを使って起動されたときにユー
ザに示される。
@c @code{argp_program_bug_address} is the default Hurd bug-reporting e-mail
@c address, @email{bug-hurd@@gnu.org}.  This address is displayed to the
@c user when any of the standard Hurd servers and utilities are invoked
@c using the @samp{--help} option.
@end deftypevar


@node Input and Output
@chapter 入力と出力

GNU Hurdのほとんど全てのサーバで相互に作用するために使われているので、
I/Oサブシステムに伴う特定のプログラムやサーバはない。それはI/Oチャネルを
読んだり書いたりするための能力を提供しており、I/OチャネルはGNU Cライブラ
リにおけるファイルやソケットの記述子の土台となる実装である。
@c There are no specific programs or servers associated with the I/O
@c subsystem, since it is used to interact with almost all servers in the
@c GNU Hurd.  It provides facilities for reading and writing I/O channels,
@c which are the underlying implementation of file and socket descriptors
@c in the GNU C library.

@menu
* Iohelp Library::              I/Oの認証とロックの管理。
* Pager Library::               マルチスレッド化された外部ページャの実装。
* I/O Interface::               RPCに基く入出力チャネル。
@end menu

@node Iohelp Library
@section iohelpライブラリ
@scindex libiohelp
@scindex iohelp.h

@code{<hurd/iohelp.h>}ファイルは低水準のI/Oの実装に役立つ、いくつかの関
数を宣言している。ほとんどのHurdサーバはこれらの関数を直接呼び出さないが、
それらはHurdのファイルシステムやネットワーキング支援ライブラリのいくらか
で使われている。@code{libiohelp}は@code{libthreads}を必要とする。
@c The @code{<hurd/iohelp.h>} file declares several functions which are
@c useful for low-level I/O implementations.  Most Hurd servers do not call
@c these functions directly, but they are used by several of the Hurd
@c filesystem and networking helper libraries.  @code{libiohelp} requires
@c @code{libthreads}.

@menu
* I/O Users::                   ユーザ認証の管理。
* Conch Management::            非難された共有I/Oの実装。
@end menu

@node I/O Users
@subsection I/Oのユーザ

ほとんどのI/Oサーバはある種のユーザ認証確認を実装する必要がある。その過
程を容易にするために、単一の@code{struct iouser}にidvecの組(FIXME: xref
to C library)を要約するいくつかの関数を持つ。
@c Most I/O servers need to implement some kind of user authentication
@c checking.  In order to facilitate that process, @code{libiohelp} has
@c some functions which encapsulate a set of idvecs (FIXME: xref to C
@c library) in a single @code{struct iouser}.

@deftypefun {struct iouser *} iohelp_create_iouser (@w{struct idvec *@var{uids}}, @w{struct idvec *@var{gids}})
指定された@var{uids}と@var{gids}に対し新しい@var{iouser}を生成する。
@c Create a new @var{iouser} for the specified @var{uids} and @var{gids}.
@end deftypefun

@deftypefun {struct iouser *} iohelp_dup_iouser (@w{struct iouser *@var{iouser}})
@var{iouser}の複製を返す。
@c Return a copy of @var{iouser}.
@end deftypefun

@deftypefun void iohelp_free_iouser (@w{struct iouser *@var{iouser}})
@var{iouser}への参照を解放する。
@c Release a reference to @var{iouser}.
@end deftypefun

I/O再認証は信頼される第三者として認証サーバを伴ういくぶん複雑なプロト
コルである (@pxref{Auth Protocol})。駄目な実装の危険性を減らすために、
I/O再認証は@code{iohelp_reauth}関数に要約されている。
@c I/O reauthentication is a rather complex protocol involving the
@c authserver as a trusted third party (@pxref{Auth Protocol}).  In order
@c to reduce the risk of flawed implementations, I/O reauthentication is
@c encapsulated in the @code{iohelp_reauth} function:

@deftypefun {struct iouser *} iohelp_reauth (@w{auth_t @var{authserver}}, @w{mach_port_t @var{rend_port}}, @w{mach_port_t @var{newright}}, @w{int @var{permit_failure}})
再認証の処理を管理し、新しい@var{iouser}を返す。@var{authserver}はI/Oサー
バの認証portである。ユーザによって提供される待ち合わせのportは
@var{rend_port}である。
@c Conduct a reauthentication transaction, and return a new @var{iouser}.
@c @var{authserver} is the I/O server's auth port.  The rendezvous port
@c provided by the user is @var{rend_port}.

もし処理が完了できなければ、@var{permit_failure}が非ゼロでなければゼロを
返す。もし@var{permit_failure}が非ゼロで、処理が失敗したなら、識別子を持
たない@var{iouser}を返す。ユーザに送られる新しいportは@var{newright}であ
る。
@c If the transaction cannot be completed, return zero, unless
@c @var{permit_failure} is nonzero.  If @var{permit_failure} is nonzero,
@c then should the transaction fail, return an @var{iouser} that has no
@c ids.  The new port to be sent to the user is @var{newright}.
@end deftypefun


@node Conch Management
@subsection conchの管理

@cindex conch
@findex iohelp_initialize_conch
@findex iohelp_handle_io_get_conch
@findex iohelp_get_conch
@findex iohelp_handle_io_release_conch
@findex iohelp_verify_user_conch
@findex iohelp_fetch_shared_data
@findex iohelp_put_shared_data
@dfn{conch}は共有メモリI/Oサブシステムの心臓部にある。いくつかのHurdライ
ブラリは共有I/Oを実装し、だから@code{libiohelp}はconch管理を容易にする関
数を含む。
@c The @dfn{conch} is at the heart of the shared memory I/O system.
@c Several Hurd libraries implement shared I/O, and so @code{libiohelp}
@c contains functions to facilitate conch management.

共有I/Oに関するものはどれでも解説されていない。なぜなら、それは十分な性
能には必要なく、RPCインターフェースはもっと単純だからだ (@pxref{I/O
Interface})。新しいライブラリやサーバが共有I/Oを実装するのは役に立たない。
@c Everything about shared I/O is undocumented because it is not needed for
@c adequate performance, and the RPC interface is simpler (@pxref{I/O
@c Interface}).  It is not useful for new libraries or servers to implement
@c shared I/O.


@node Pager Library
@section ページャ・ライブラリ
@scindex libpager
@scindex pager.h

@cindex XP (external pager)
@cindex external pager (XP)
@dfn{外部ページャ} (@dfn{XP})マイクロカーネル・インターフェースはハード
ウェアのページ・フォールトをRPCリクエストに変換することによって、アプリ
ケーションがメモリ・オブジェクトにbacking storeを提供できるようにする。
外部ページャはmemory-mapped I/O(@pxref{Mapped Data})とstored filesystem
(@pxref{Stored Filesystems})に必要とされる。
@c The @dfn{external pager} (@dfn{XP}) microkernel interface allows
@c applications to provide the backing store for a memory object, by
@c converting hardware page faults into RPC requests.  External pagers are
@c required for memory-mapped I/O (@pxref{Mapped Data}) and stored
@c filesystems (@pxref{Stored Filesystems}).

外部ページャのインターフェースは非常に複雑なので、Hurdページャ・ライブラ
リはマルチスレッド化された外部ページャを作ることを目的とする関数を含む。
@code{libpager}は@code{<hurd/pager.h>}で宣言され、スレッドとportライブラ
リだけを必要とする。
@c The external pager interface is quite complex, so the Hurd pager library
@c contains functions which aid in creating multithreaded external pagers.
@c @code{libpager} is declared in @code{<hurd/pager.h>}, and requires only
@c the threads and ports libraries.

@menu
* Pager Management::            外部ページャへの高水準なインターフェース。
* Pager Callbacks::             ユーザが定義しなければならない関数。
@end menu


@node Pager Management
@subsection ページャの管理

ページャ・ライブラリはマルチスレッド化されたページャを実現するために
@code{struct pager}データ型を定義する。ページャを生成するための一般的な
手続きは、@ref{Pager Callbacks}で列挙される関数を定義し、ページャがアク
セスするportのための@code{libports} bucketを確保し、少なくとも一つの新し
い@code{struct pager}を@code{pager_create}で生成することである。
@c The pager library defines the @code{struct pager} data type in order to
@c represent a multi-threaded pager.  The general procedure for creating a
@c pager is to define the functions listed in @ref{Pager Callbacks},
@c allocate a @code{libports} bucket for the ports which will access the
@c pager, and create at least one new @code{struct pager} with
@c @code{pager_create}.

@deftypefun {struct pager *} pager_create (@w{struct user_pager_info *@var{u_pager}}, @w{struct port_bucket *@var{bucket}}, @w{boolean_t @var{may_cache}}, @w{memory_object_copy_strategy_t @var{copy_strategy}})
新しいページャを生成する。ページャは(@code{libports}を使って、
@var{bucket}に)それのために生成されたportを持つようになり、直ちにリクエ
ストを受け付ける準備が整うだろう。@var{u_pager}はその後の
@code{pager_find_address}への呼び出しに提供されるだろう。ページャは一つ
のユーザ参照を生成させるだろう。@var{may_cache}と@var{copy_strategy}は
@var{memory_object_ready}に対するものと同じ、これらの属性の元の値である。
ユーザは関連したportのライブラリ関数を使用してページャへの参照を生成して
よい。エラーでnullを返し、@code{errno}を設定する。
@c Create a new pager.  The pager will have a port created for it (using
@c @code{libports}, in @var{bucket}) and will be immediately ready to
@c receive requests.  @var{u_pager} will be provided to later calls to
@c @code{pager_find_address}.  The pager will have one user reference
@c created.  @var{may_cache} and @var{copy_strategy} are the original
@c values of those attributes as for @code{memory_object_ready}.  Users may
@c create references to pagers by use of the relevant ports library
@c functions.  On errors, return null and set @code{errno}.
@end deftypefun

制御をページャ・ライブラリに引き渡す準備が整うと、@code{pager_demuxer}を
portの@var{demuxer}として使って@var{bucket}上で
@code{ports_manage_port_operations_multithread}を呼び出すべきだ。これは
全ての外部ページャRPCを処理し、必要なとき、あなたのページャコールバック
を起動するだろう。
@c Once you are ready to turn over control to the pager library, you should
@c call @code{ports_manage_port_operations_multithread} on the
@c @var{bucket}, using @code{pager_demuxer} as the ports @var{demuxer}.
@c This will handle all external pager RPCs, invoking your pager callbacks
@c when necessary.

@deftypefun int pager_demuxer (@w{mach_msg_header_t *@var{inp}}, @w{mach_msg_header_t *@var{outp}})
ページャのportにやって来る@code{libports}メッセージをdemultiplexする。
@c Demultiplex incoming @code{libports} messages on pager ports.
@end deftypefun

以下の関数はページャ・ライブラリの本体であり、ページャの機能へのすっきり
したインターフェースを提供する。
@c The following functions are the body of the pager library, and provide a
@c clean interface to pager functionality:

@deftypefun void pager_sync (@w{struct pager *@var{pager}}, @w{int @var{wait}})
@deftypefunx void pager_sync_some (@w{struct pager *@var{pager}}, @w{vm_address_t @var{start}}, @w{vm_size_t @var{len}}, @w{int @var{wait}})
ページャ@var{pager}からそのbacking storeへデータを書き込む。@var{wait}が
設定されている場合に限り、その全ての書き込みが完了するまで待つ。
@c Write data from pager @var{pager} to its backing store.  Wait for all
@c the writes to complete if and only if @var{wait} is set.

@code{pager_sync}は全てのデータを書き込む。@code{pager_sync_some}は
@var{start}で始まるデータを@var{len}バイトだけ書き込む。
@c @code{pager_sync} writes all data; @code{pager_sync_some} only writes
@c data starting at @var{start}, for @var{len} bytes.
@end deftypefun

@deftypefun void pager_flush (@w{struct pager *@var{pager}}, @w{int @var{wait}})
@deftypefunx void pager_flush_some (@w{struct pager *@var{pager}}, @w{vm_address_t @var{start}}, @w{vm_size_t @var{len}}, @w{int @var{wait}})
カーネルからページャ@var{pager}のデータをフラッシュし、未処理の遅らされ
たコピーを強制する。@var{wait}が設定されている場合に限り、全てのページが
フラッシュされるまで待つ。
@c Flush data from the kernel for pager @var{pager} and force any pending
@c delayed copies.  Wait for all pages to be flushed if and only if
@c @var{wait} is set.

@code{pager_flush}は全てのデータをフラッシュする。
@code{pager_flush_some}は@var{start}で始まるデータを@var{len}バイトだけ
フラッシュする。
@c @code{pager_flush} flushes all data; @code{pager_flush_some} only
@c flushes data starting at @var{start}, for @var{len} bytes.
@end deftypefun

@deftypefun void pager_return (@w{struct pager *@var{pager}}, @w{int @var{wait}})
@deftypefunx void pager_return_some (@w{struct pager *@var{pager}}, @w{vm_address_t @var{start}}, @w{vm_size_t @var{len}}, @w{int @var{wait}})
カーネルからページャ@var{pager}のデータをフラッシュし、未処理の遅らされ
たコピーを強制する。@var{wait}が設定されている場合に限り、全てのページが
フラッシュされるまで待つ。カーネルに修正をwrite backさせる。
@c Flush data from the kernel for pager @var{pager} and force any pending
@c delayed copies.  Wait for all pages to be flushed if and only if
@c @var{wait} is set.  Have the kernel write back modifications.

@code{pager_return}は全てのデータをフラッシュして復元する。
@code{pager_return_some}は@var{start}で始まるデータを@var{len}バイトだけ
フラッシュして復元する。
@c @code{pager_return} flushes and restores all data;
@c @code{pager_return_some} only flushes and restores data starting at
@c @var{start}, for @var{len} bytes.
@end deftypefun

@deftypefun void pager_offer_page (@w{struct pager *@var{pager}}, @w{int @var{precious}}, @w{int @var{writelock}}, @w{vm_offset_t @var{page}}, @w{vm_address_t @var{buf}})
データのページをカーネルに提供する。@var{precious}が設定されていると、こ
のページはいつか将来にページ・アウトされ、そうでなければカーネルによって
外されるかもしれない。もしそのページが現在コアにあると、カーネルはこの呼
び出しを無視するかもしれない。
@c Offer a page of data to the kernel.  If @var{precious} is set, then this
@c page will be paged out at some future point, otherwise it might be
@c dropped by the kernel.  If the page is currently in core, the kernel
@c might ignore this call.
@end deftypefun

@deftypefun void pager_change_attributes (@w{struct pager *@var{pager}}, @w{boolean_t @var{may_cache}}, @w{memory_object_copy_strategy_t @var{copy_strategy}}, @w{int @var{wait}})
ページャ@var{pager}の土台となるメモリ・オブジェクトの属性を変更する。
@var{may_cache}と@var{copy_strategy}引数は
@code{memory_object_change_attributes}に対するものと同様である。
@var{wait}が設定されている場合に限り、カーネルが完了を報告するまで待つ。
@c Change the attributes of the memory object underlying pager @var{pager}.
@c The @var{may_cache} and @var{copy_strategy} arguments are as for
@c @code{memory_object_change_atributes}.  Wait for the kernel to report
@c completion if and only if @var{wait} is set.
@end deftypefun

@deftypefun void pager_shutdown (@w{struct pager *@var{pager}})
ページャの終了を強制する。これが返った後、ページャへのページング・リクエ
ストはもはや受理されず、ページャは解放されるだろう。最初に完了する現在未
処理のページング・リクエストがあるなら、本当の解放は非同期的に起きるだろ
う@footnote{訳注: XXX}。
@c Force termination of a pager.  After this returns, no more paging
@c requests on the pager will be honoured, and the pager will be
@c deallocated.  The actual deallocation might occur asynchronously if
@c there are currently outstanding paging requests that will complete
@c first.
@end deftypefun

@deftypefun error_t pager_get_error (@w{struct pager *@var{p}}, @w{vm_address_t @var{addr}})
Return the error code of the last page error for pager @var{p} at
address @var{addr}.@footnote{Note that this function will be deleted
when the Mach pager interface is fixed to provide this information.}
@end deftypefun

@deftypefun error_t pager_memcpy (@w{struct pager *@var{pager}}, @w{memory_object_t @var{memobj}}, @w{vm_offset_t @var{offset}}, @w{void *@var{other}}, @w{size_t *@var{size}}, @w{vm_prot_t @var{prot}})
Try to copy @code{*@var{size}} bytes between the region @var{other}
points to and the region at @var{offset} in the pager indicated by
@var{pager} and @var{memobj}.  If @var{prot} is @code{VM_PROT_READ},
copying is from the pager to @var{other}; if @var{prot} contains
@code{VM_PROT_WRITE}, copying is from @var{other} into the pager.
@code{*@var{size}} is always filled in the actual number of bytes
successfully copied.  Returns an error code if the pager-backed memory
faults; if there is no fault, returns zero and @code{*@var{size}} will
be unchanged.
@end deftypefun

These functions allow you to recover the internal @code{struct pager}
state, in case the @code{libpager} interface doesn't provide an
operation you need:

@deftypefun {struct user_pager_info *} pager_get_upi (@w{struct pager *@var{p}})
Return the @code{struct user_pager_info} associated with a pager.
@end deftypefun

@deftypefun mach_port_t pager_get_port (@w{struct pager *@var{pager}})
Return the port (receive right) for requests to the pager.  It is
absolutely necessary that a new send right be created from this receive
right.
@end deftypefun


@node Pager Callbacks
@subsection Pager Callbacks

Like several other Hurd libraries, @code{libpager} depends on you to
implement application-specific callback functions.  You @emph{must}
define the following functions:

@deftypefun error_t pager_read_page (@w{struct user_pager_info *@var{pager}}, @w{vm_offset_t @var{page}}, @w{vm_address_t *@var{buf}}, @w{int *@var{write_lock}})
For pager @var{pager}, read one page from offset @var{page}.  Set
@code{*@var{buf}} to be the address of the page, and set
@code{*@var{write_lock}} if the page must be provided read-only.  The
only permissable error returns are @code{EIO}, @code{EDQUOT}, and
@code{ENOSPC}.
@end deftypefun

@deftypefun error_t pager_write_page (@w{struct user_pager_info *@var{pager}}, @w{vm_offset_t @var{page}}, @w{vm_address_t @var{buf}})
For pager @var{pager}, synchronously write one page from @var{buf} to
offset @var{page}.  In addition, @code{vm_deallocate} (or equivalent)
@var{buf}.  The only permissable error returns are @code{EIO},
@code{EDQUOT}, and @code{ENOSPC}.
@end deftypefun

@deftypefun error_t pager_unlock_page (@w{struct user_pager_info *@var{pager}}, @w{vm_offset_t @var{address}})
A page should be made writable.
@end deftypefun

@deftypefun error_t pager_report_extent (@w{struct user_pager_info *@var{pager}}, @w{vm_address_t *@var{offset}}, @w{vm_size_t *@var{size}})
This function should report in @code{*@var{offset}} and
@code{*@var{size}} the minimum valid address the pager will accept and
the size of the object.
@end deftypefun

@deftypefun void pager_clear_user_data (@w{struct user_pager_info *@var{pager}})
This is called when a pager is being deallocated after all extant send
rights have been destroyed.
@end deftypefun

@deftypefun void pager_dropweak (@w{struct user_pager_info *@var{p}})
This will be called when the ports library wants to drop weak
references.  The pager library creates no weak references itself, so if
the user doesn't either, then it is alright for this function to do
nothing.
@end deftypefun


@node I/O Interface
@section I/O Interface
@scindex io.defs

The I/O interface facilities are described in @code{<hurd/io.defs>}.
This section discusses only RPC-based I/O operations.@footnote{The
latter portion of @code{<hurd/io.defs>} and all of
@code{<hurd/shared.h>} describe how to implement shared-memory I/O
operations.  However, shared I/O has been deprecated.  @xref{Conch
Management}, for more details.}

@menu
* I/O Object Ports::            How ports to I/O objects work.
* Simple Operations::           Read, write, and seek.
* Open Modes::                  State bits that affect pieces of operation.
* Asynchronous I/O::            How to be notified when I/O is possible.
* Information Queries::         How to implement @code{io_stat} and
                                  @code{io_server_version}.
* Mapped Data::                 Getting memory objects referring to the
                                  data of an I/O object.
@end menu

@node I/O Object Ports
@subsection I/O Object Ports

The I/O server must associate each I/O port with a particular set of
uids and gids, identifying the user who is responsible for operations on
the port.  Every port to an I/O server should also support either the
file protocol (@pxref{File Interface}) or the socket protocol
(@pxref{Socket Interface}); naked I/O ports are not allowed.

In addition, the server associates with each port a default file
pointer, a set of open mode bits, a pid (called the ``owner''), and some
underlying object which can absorb data (for write) or provide data (for
read).

The uid and gid sets associated with a port may not be visibly shared
with other ports, nor may they ever change.  The server must fix the
identification of a set of uids and gids with a particular port at the
moment of the port's creation.  The other characteristics of an I/O port
may be shared with other users.  The I/O server interface does not
generally specify in what way servers may share these other
characteristics are shared (with the exception of the deprecated
@code{O_ASYNC} interface); however, the file and socket interfaces make
further requirements about what sharing is expected and prohibited from
occurring.

In general, users get send rights to I/O ports by some mechanism that is
external to the I/O protocol.  (For example fileservers give out I/O
ports in response to the @code{dir_lookup} and @code{fsys_getroot}
calls.  Socket servers give out ports in response to the
@code{socket_create} and @code{socket_accept} calls.)  However, the I/O
protocol provides methods of obtaining new ports that refer to the same
underlying object as another port.  In response to all of these calls,
all underlying state (including, but not limited to, the default file
pointer, open mode bits, and underlying object) must be shared between
the old and new ports.  In the following descriptions of these calls,
the term ``identical'' means this kind of sharing.  All these calls must
return send rights to a newly-constructed Mach port.

@findex io_duplicate
The @code{io_duplicate} call simply returns another port which is
identical to an existing port and has the same uid and gid set.

@findex io_restrict_auth
The @code{io_restrict_auth} call returns another port, identical to the
provided port, but which has a smaller associated uid and gid set.  The
uid and gid sets of the new port are the intersection of the set on the
existing port and the lists of uids and gids provided in the call.

@findex io_reauthenticate
Users use the @code{io_reauthenticate} call when they wish to have an
entirely new set of uids or gids associated with a port.  In response to
the @code{io_reauthenticate} call, the server must create a new port,
and then make the call @code{auth_server_authenticate} to the auth
server.  The rendezvous port for the @code{auth_server_authenticate}
call is the I/O port to which was made the @code{io_reauthenticate}
call.  The server provides the @var{rend_int} parameter to the auth
server as a copy from the corresponding parameter in the
@code{io_reauthenticate} call.  The I/O server also gives the auth
server a new port; this must be a newly created port identical to the
old port.  The authserver will return the set of uids and gids
associated with the user, and guarantees that the new port will go
directly to the user that possessed the associated authentication port.
The server then identifies the new port given out with the specified
ID's.

@node Simple Operations
@subsection Simple Operations

@findex io_write
Users write to I/O ports by calling the @code{io_write} RPC.  They
specify an @var{offset} parameter; if the object supports writing at
arbitrary offsets, the server should honour this parameter.  If @math{-1}
is passed as the offset, then the server should use the default file
pointer.  The server should return the amount of data which was
successfully written.  If the operation was interrupted after some but
not all of the data was written, then it is considered to have succeeded
and the server should return the amount written.  If the port is not an
I/O port at all, the server should reply with the error
@code{EOPNOTSUPP}.  If the port is an I/O port, but does not happen to
support writing, then the correct error is @code{EBADF}.

@findex io_read
Users read from I/O ports by calling the @code{io_read} RPC.  They
specify the amount of data they wish to read and the offset.  The offset
has the same meaning as for @code{io_write} above.  The server should
return the data that was read.  If the call is interrupted after some
data has been read (and the operation is not idempotent) then the server
should return the amount read, even if less than the amount requested.
The server should return as much data as possible, but never more than
requested by the user.  If there is no data, but there might be later,
the call should block until data becomes available.  Indicate
end-of-file conditions by returning zero bytes.  If the call is
interrupted after some data has been read, but the call is idempotent,
then the server may return @code{EINTR} rather than actually filling the
buffer (taking care that any modifications of the default file pointer
have been reversed).  Preferably, however, servers should return data.

There are two categories of objects: seekable and non-seekable.
Seekable objects must accept arbitrary offset parameters in the
@code{io_read} and @code{io_write} calls, and to implement the
@code{io_seek} call.  Nonseekable objects must ignore the offset
parameters to @code{io_read} and @code{io_write}, and should return
@code{ESPIPE} to the @code{io_seek} call.

@findex io_seek
On seekable objects, @code{io_seek} changes the default file pointer for
reads and writes.  (@xref{File Positioning, , , libc, The GNU C Library
Reference Manual},
for the interpretation of the @var{whence} and @var{offset} arguments.)
It returns the new offset as modified by @code{io_seek}.

@findex io_readable
The @code{io_readable} interface returns the amount of data which can be
immediately read.  For the special technical meaning of ``immediately'',
see @ref{Asynchronous I/O}.

@node Open Modes
@subsection Open Modes

@findex io_set_all_openmodes
@findex io_get_openmodes
@findex io_set_some_openmodes
@findex io_clear_some_openmodes
The server associates each port with a set of bits that affect its
operation.  The @code{io_set_all_openmodes} call modifies these bits and
the @code{io_get_openmodes} call returns them.  In addition, the
@code{io_set_some_openmodes} and @code{io_clear_some_openmodes} do an
atomic read/modify/write of the openmodes.

The @code{O_APPEND} bit, when set, changes the behaviour of
@code{io_write} when it uses the default file pointer on seekable
objects.  When @code{io_write} is done on a port with the
@code{O_APPEND} bit set, is must set the file pointer to the current
file size before doing the write (which would then increment the file
pointer as usual).  The @dfn{current file size} is the smallest offset
which returns end-of-file when provided to @code{io_read}.  The server
must atomically bind this update to the actual data write with respect
to other users of @code{io_read}, @code{io_write}, and @code{io_seek}.

The @code{O_FSYNC} bit, when set, guarantees that @code{io_write} will
not return until data is fully written to the underlying medium.

The @code{O_NONBLOCK} bit, when set, prevents read and write from
blocking.  They should copy such data as is immediately available.  If
no data is immediately available they should return @code{EWOULDBLOCK}.

The definition of ``immediately'' is more-or-less server-dependent.
Some servers, notably stored filesystem servers (@pxref{Stored
Filesystems}), regard all data as immediately available.  The one
criterion is that something which must happen @dfn{immediately} may not
wait for any user-synchronizable event.

The @code{O_ASYNC} bit is deprecated; its use is documented in the
following section.  This bit must be shared between all users of the
same underlying object.


@node Asynchronous I/O
@subsection Asynchronous I/O

@findex io_async
Users may wish to be notified when I/O can be done without blocking;
they use the @code{io_async} call to indicate this to the server.  In
the @code{io_async} call the user provides a port on which will the
server should send @code{sig_post} messages as I/O becomes possible.
The server must return a port which will be the reference port in the
@code{sig_post} messages.  Each @code{io_async} call should generate a
new reference port.  (FIXME: xref the C library manual for information
on how to send sig_post messages.)

The server then sends one @code{SIGIO} signal to each registered async
user everytime I/O becomes possible.  I/O is possible if at least one
byte can be read or written immediately.  The definition of
``immediately'' must be the same as for the implementation of the
@code{O_NONBLOCK} flag (@pxref{Open Modes}).  In addition, every time a
user calls io_read or io_write on a non-seekable object, or at the
default file pointer on a seekable object, another signal should be sent
to each user if I/O is still possible.

Some objects may also define ``urgent'' conditions.  Such servers should
send the @code{SIGURG} signal to each registered async user anytime an
urgent condition appears.  After any RPC that has the possibility of
clearing the urgent condition, the server should again send the signal
to all registered users if the urgent condition is still present.

@findex io_select
A more fine-grained mechanism for doing async I/O is the
@code{io_select} call.  The user specifies the kind of access desired,
and a send-once right.  If I/O of the kind the user desires is
immediately possible, then the server should return so indicating, and
destroy the send-once right.  If I/O is not immediately possible, the
server should save the send-once right, and send a @code{select_done}
message as soon as I/O becomes immediately possible.  Again, the
definition of ``immediately'' must be the same for @code{io_select},
@code{io_async}, and @code{O_NONBLOCK} (@pxref{Open Modes}).

@findex io_mod_owner
@findex io_get_owner
@findex io_get_icky_async_id
For compatibility with 4.2 and 4.3 BSD, the I/O interface provides a
deprecated feature (known as @dfn{icky async I/O}).  The calls
@code{io_mod_owner} and @code{io_get_owner} to set the ``owner'' of the
object, providing either a pid or a pgrp (if the value is negative).
This implies that only one process at a time can do icky I/O on a given
object.  Whenever the I/O server is sending @code{sig_post} messages to
all the @code{io_async} users, if the @code{O_ASYNC} bit is set, the
server should also send a signal to the owning pid/pgrp.  The ID port
for this call should be different from all the @code{io_async} ID ports
given to users.  Users may find out what ID port the server uses for
this by calling @code{io_get_icky_async_id}.

@node Information Queries
@subsection Information Queries

@findex io_stat
Users may call @code{io_stat} to find out information about the I/O
object.  Most of the fields of a @code{struct stat} are meaningful only
for files.  All objects, however, must support the fields
@code{st_fstype}, @var{st_fsid}, @var{st_ino}, @var{st_atime},
@var{st_atime_usec}, @var{st_mtime_user}, @var{st_ctime},
@var{st_ctime_usec}, and @var{st_blksize}.

@var{st_fstype}, @var{st_fsid}, and @var{st_ino} must be unique for
the underlying object across the entire system.

@var{st_atime} and @var{st_atime_usec} hold the seconds and
microseconds, respectively, of the system clock at the last time the
object was read with @code{io_read}.

@var{st_mtime} and @var{st_mtime_usec} hold the second and microseconds,
respectively, of the system clock at the last time the object was
written with @code{io_write}.

Other appropriate operations may update the @var{atime} and the
@var{mtime} as well; both the file and socket interfaces specify such
operations.

@var{st_ctime} and @var{st_ctime_usec} hold the seconds and
microseconds, respectively, of the system clock at the last time
permanent meta-data associated with the object was changed.  The exact
operations which couse such an update are server-dependent, but must
include the creation of the object.

The server is permitted to delay the actual update of these times until
stat is called; before the server stores the times on permanent media
(if it ever does so) it should update them if necessary.

@var{st_blksize} gives the optimal I/O size in bytes for @code{io_read}
and @code{io_write}; users should endeavor to read and write amounts
which are multiples of the optimal size, and to use offsets which are
multiples of the optimal size

In addition, objects which are seekable should set @var{st_size} to the
current file size as in the description of the @code{O_APPEND} flag
(@pxref{Open Modes}).

The @var{st_uid} and @var{st_gid} fields are unrelated to the ``owner''
as described above for icky async I/O.

@findex io_server_version
Users may find out the version of the server they are talking to by
calling @code{io_server_version}; this should return strings and
integers describing the version number of the server, as well as its
name.

@node Mapped Data
@subsection Mapped Data

@findex io_map
Servers may optionally implement the @code{io_map} call.  The ports
returned by @code{io_map} must implement the external pager kernel
interface (@pxref{Pager Library}) and be suitable as arguments to
@code{vm_map}.

Seekable objects must allow access from zero up to (but not including)
the current file size as described for @code{O_APPEND} (@pxref{Open
Modes}).  Whether they provide access beyond such a point is
server-dependent; in addition, the meaning of accessing a non-seekable
object is server-dependent.


@node Files
@chapter Files

A file is traditionally thought of as a quantity of disk storage.  In
the Hurd, files are an extension of the I/O interface, but they do not
necessarily correspond to disk storage.

Every file in the Hurd is represented by a port, which is connected to
the server that manages the file.  When a client wants to operate on a
file, it makes RPC requests via a file port to its server process, which
is commonly called a @dfn{translator}.

@menu
* Translators::                 Extending the Hurd filesystem hierarchy.
* Trivfs Library::              Implementing single-file translators.
* Fshelp Library::              Miscellaneous generic filesystem routines.
* File Interface::              File ports implement the file interface.
* Filesystem Interface::        Translator control interface.
@end menu


@node Translators
@section Translators

The Hurd filesystem allows you to set translators on any file or
directory that you own.  A @dfn{translator} is any Hurd server which
provides the basic filesystem interface.  Translated nodes are somewhat
like a cross between Unix symbolic links and mount points.

Whenever a program tries to access the contents of a translated node,
the filesystem server redirects the request to the appropriate
translator (starting it if necessary).  Then, the new translator
services the client's request.  The GNU C library makes this behaviour
seamless from the client's perspective, so that standard Unix programs
behave correctly under the Hurd.

Translators run with the priviledges of the translated node's
@emph{owner}, so they cannot be used to compromise the security of the
system.  This also means that @emph{any} user can write their own
translators, and provide other users with arbitrary
filesystem-structured data, regardless of the data's actual source.
Other chapters in this manual describe existing translators, and how you
can modify them or write your own.

The standard Hurd filesystem servers are constantly evolving to provide
innovative features that users want.  Here are a few examples of
existing translators:

@itemize @bullet
@item
Disk-based filesystem formats, such as @code{ext2fs}, @code{ufs}, and
@code{isofs} (@pxref{Stored Filesystems}).

@item
Network filesystems, such as @code{nfs} and @code{ftpfs}
(@pxref{Distributed Filesystems}).

@item
Single files with dynamic content, such as a @file{~/.plan} which is
automatically updated every time somebody fingers your account.

@item
Filesystem nodes can serve as naming points for standard Hurd servers,
even if they are unrelated to the filesystem.  For example,
@code{pflocal} implements the filesystem interfaces, but it also
provides a special Unix-domain socket RPC interface (FIXME xref).
Programs can fetch a port to this translator simply by calling
@code{file_name_lookup} (FIXME xref) on
@file{/servers/socket/1}@footnote{The number 1 corresponds to the
@code{PF_LOCAL} C library socket domain constant.} then use Unix
socket-specific RPC's on that port.
@end itemize

This section focuses on the generic programs that need to be understood
in order to use existing translators.  Many other parts of this manual
describe how you can write your own translators.

@menu
* Invoking settrans::           Declaring how a node should be translated.
* Invoking showtrans::          Displaying how nodes are translated.
* Invoking mount::              Unix-compatible active filesystem translators.
* Invoking fsysopts::           Modifying translation parameters at runtime.
@end menu


@node Invoking settrans
@subsection Invoking @code{settrans}
@pindex settrans

The @code{settrans} program allows you to set a translator on a file or
directory.  By default, the passive translator is set (see the
@samp{--passive} option).

The @code{settrans} program has the following synopsis:

@example
settrans [@var{option}]@dots{} @var{node} [@var{translator} @var{arg}@dots{}]
@end example

@noindent
where @var{translator} is the absolute filename of the new translator
program.  Each @var{arg} is passed to @var{translator} when it starts.
If @var{translator} is not specified, then @code{settrans} clears the
existing translator rather than setting a new one.

@code{settrans} accepts the following options:

@table @samp
@item -a
@itemx --active
Set @var{node}'s active translator.  @dfn{Active translators} are
started immediately and are not persistent: if the system is rebooted
then they are lost.

@item -c
@itemx --create
Create @var{node} as a zero-length file if it doesn't already exist.

@item -L
@itemx --dereference
If @var{node} is already translated, stack the new translator on top of
it (rather than replacing the existing translator).

@item --help
Display a brief usage message, then exit.

@item -p
@itemx --passive
Set @var{node}'s passive translator.  @dfn{Passive translators} are only
activated by the underlying filesystem when clients try to use the
@var{node}, and they shut down automatically after they are no longer
active in order to conserve system resources.

Passive translators are stored on the underlying filesystem media, and
so they persist between system reboots.  Not all filesystems support
passive translators, due to limitations in their underlying media@dots{}
consult the filesystem-specific documentation to see if they are
supported.

If you are setting the passive translator, and @var{node} already has an
active translator, then the following options apply:

@table @samp
@item -g
@itemx --goaway
Tell the active translator to go away.  In this case, the following
additional options apply:

@table @samp
@item -f
@itemx --force
If the active translator doesn't go away, then force it.

@item -S
@itemx --nosync
Don't flush its contents to disk before terminating.

@item -R
@itemx --recursive
Shut down all of the active translator's children, too.
@end table


@item -k
@itemx --keep-active
Leave the existing active translator running.  The new translator will
not be started unless the active translator has stopped.
@end table

@item -P
@itemx --pause
When starting an active translator, prompt and wait for a newline on
standard input before completing the startup handshake.  This is useful
when debugging a translator, as it gives you time to start the debugger.

@item -t @var{sec}
@itemx --timeout=@var{sec}
If the translator does not start up in @var{sec} seconds (the default is
60), then return an error; if @var{sec} is 0, then never timeout.

@item --version
Output program version information and exit.

@item -x
@itemx --exclusive
Only set the translator if there is none already.
@end table


FIXME: finish
@node Invoking showtrans
@subsection Invoking @code{showtrans}
@node Invoking mount
@subsection Invoking @code{mount}
@node Invoking fsysopts
@subsection Invoking @code{fsysopts}


@node Trivfs Library
@section Trivfs Library
@scindex libtrivfs
@scindex trivfs.h

Certain translators do not need to be very complex, because they
represent a single file rather than an entire directory hierarchy.  The
trivfs library, which is declared in @code{<hurd/trivfs.h>}, does most of
the work of implementing this kind of translator.  This library requires
the iohelp and ports libraries.

@menu
* Trivfs Startup::              Writing a simple trivfs-based translator.
* Trivfs Callbacks::            Mandatory user-defined trivfs functions.
* Trivfs Options::              Optional user-defined trivfs functions.
* Trivfs Ports::                Managing control and protid ports.
@end menu

@node Trivfs Startup
@subsection Trivfs Startup

In order to use the trivfs library, you will need to define the
appropriate callbacks (@pxref{Trivfs Callbacks}).  As with all Hurd
servers, your trivfs-based translator should first parse any
command-line options, in case the user is just asking for help.  Trivfs
uses argp (@pxref{Argp, , , libc, The GNU C Library Reference Manual})
for parsing command-line arguments.

Your translator should redefine the following functions and variables as
necessary, and then call @code{argp_parse} with the relevant arguments:

@deftypevar {extern struct argp *} trivfs_runtime_argp
If this is defined or set to an argp structure, it will be used by the
default @code{trivfs_set_options} to handle runtime options parsing.
Redefining this is the normal way to add option parsing to a trivfs
program.
@end deftypevar

@deftypefun error_t trivfs_set_options (@w{struct trivfs_control *@var{fsys}}, @w{char *@var{argz}}, @w{size_t @var{argz_len}})
Set runtime options for @var{fsys} to @var{argz} and @var{argz_len}.
The default definition for this routine simply uses
@var{trivfs_runtime_argp} (supplying @var{fsys} as the argp input
field).
@end deftypefun

@deftypefun error_t trivfs_append_args (@w{struct trivfs_control *@var{fsys}}, @w{char **@var{argz}}, @w{size_t *@var{argz_len}})
Append to the malloced string @code{*@var{argz}} of length
@code{*@var{argz_len}} a NUL-separated list of the arguments to this
translator.
@end deftypefun

After your translator parses its command-line arguments, it should fetch
its bootstrap port by using @code{task_get_bootstrap_port}.  If this
port is @code{MACH_PORT_NULL}, then your program wasn't started as a
translator.  Otherwise, you can use the bootstrap port to create a new
control structure (and advertise its port) with @code{trivfs_startup}:

@deftypefun error_t trivfs_startup (@w{mach_port_t @var{bootstrap}}, @w{int @var{flags}}, @w{struct port_class *@var{control_class}}, @w{struct port_bucket *@var{control_bucket}}, @w{struct port_class *@var{protid_class}}, @w{struct port_bucket *@var{protid_bucket}}, @w{struct trivfs_control **@var{control}})
@deftypefunx error_t trivfs_create_control (@w{mach_port_t @var{bootstrap}}, @w{struct port_class *@var{control_class}}, @w{struct port_bucket *@var{control_bucket}}, @w{struct port_class *@var{protid_class}}, @w{struct port_bucket *@var{protid_bucket}}, @w{struct trivfs_control **@var{control}})
@code{trivfs_startup} creates a new trivfs control port, advertises it
to the underlying node @var{bootstrap} with @code{fsys_startup},
returning the results of this call, and places its control structure in
@code{*@var{control}}.  @code{trivfs_create_control} does the same
thing, except it doesn't advertise the control port to the underlying
node.  @var{control_class} and @var{control_bucket} are passed to
@code{libports} to create the control port, and @var{protid_class} and
@var{protid_bucket} are used when creating ports representing opens of
this node; any of these may be zero, in which case an appropriate port
class/bucket is created.  If @var{control} is non-null, the trivfs
control port is returned in it.  @var{flags} (a bitmask of the
appropriate @code{O_*} constants) specifies how to open the underlying
node.
@end deftypefun

If you did not supply zeros as the class and bucket arguments to
@code{trivfs_startup}, you will probably need to use the trivfs port
management functions (@pxref{Trivfs Ports}).

Once you have successfully called @code{trivfs_startup}, and have a
pointer to the control structure stored in, say, the @var{fsys}
variable, you are ready to call one of the
@code{ports_manage_port_operations_*} functions using
@code{@var{fsys}->pi.bucket} and @code{trivfs_demuxer}.  This will
handle any incoming filesystem requests, invoking your callbacks when
necessary.

@deftypefun int trivfs_demuxer (@w{mach_msg_header_t *@var{inp}}, @w{mach_msg_header_t *@var{outp}})
Demultiplex incoming @code{libports} messages on trivfs ports.
@end deftypefun

The following functions are not usually necessary, but they allow you to
use the trivfs library even when it is not possible to turn
message-handling over to @code{trivfs_demuxer} and @code{libports}:

@deftypefun {struct trivfs_control *} trivfs_begin_using_control (@w{mach_port_t @var{port}})
@deftypefunx {struct trivfs_protid *} trivfs_begin_using_protid (@w{mach_port_t @var{port}})
These functions can be used as @code{intran} functions for a MiG port
type to have the stubs called with either the control or protid pointer.
@end deftypefun

@deftypefun void trivfs_end_using_control (@w{struct trivfs_control *@var{port}})
@deftypefunx void trivfs_end_using_protid (@w{struct trivfs_protid *@var{port}})
These can be used as `destructor' functions for a MiG port type, to have
the stubs called with the control or protid pointer.
@end deftypefun

@deftypefun error_t trivfs_open (@w{struct trivfs_control *@var{fsys}}, @w{struct iouser *@var{user}}, @w{unsigned @var{flags}}, @w{mach_port_t @var{realnode}}, @w{struct trivfs_protid **@var{cred}})
Return a new protid (that is, a port representing an open of this node)
pointing to a new peropen in @var{cred}, with @var{realnode} as the
underlying node reference, with the given identity, and open flags in
@var{flags}.  @var{cntl} is the trivfs control object.
@end deftypefun

@deftypefun error_t trivfs_protid_dup (@w{struct trivfs_protid *@var{cred}}, @w{struct trivfs_protid **@var{dup}})
Return a duplicate of @var{cred} in @var{dup}, sharing the same peropen
and hook.  A non-null protid @var{hook} indicates that
@var{trivfs_peropen_create_hook} created this protid (@pxref{Trivfs
Options}).
@end deftypefun

@deftypefun error_t trivfs_set_atime (@w{struct trivfs_control *@var{cntl}})
@deftypefunx error_t trivfs_set_mtime (@w{struct trivfs_control *@var{cntl}})
Call these to set atime or mtime for the node to the current time.
@end deftypefun


@node Trivfs Callbacks
@subsection Trivfs Callbacks

Like several other Hurd libraries, @code{libtrivfs} requires that you
define a number of application-specific callback functions and
configuration variables.  You @emph{must} define the following variables
and functions:

@deftypevar {extern int} trivfs_fstype
@deftypevarx {extern int} trivfs_fsid
These variables are returned in the @var{st_fstype} and @var{st_fsid}
fields of @code{struct stat}.  @var{trivfs_fstype} should be chosen
from the @code{FSTYPE_*} constants found in @code{<hurd/hurd_types.h>}.
@end deftypevar

@deftypevar {extern int} trivfs_allow_open
Set this to some bitwise OR combination of @code{O_READ},
@code{O_WRITE}, and @code{O_EXEC}; trivfs will only allow opens of the
specified modes.
@end deftypevar

@deftypevar {extern int} trivfs_support_read
@deftypevarx {extern int} trivfs_support_write
@deftypevarx {extern int} trivfs_support_exec
Set these to nonzero if trivfs should allow read, write, or execute of
the file.  These variables are necessary because @var{trivfs_allow_open}
is used only to validate opens, not actual operations.
@end deftypevar

@deftypefun void trivfs_modify_stat (@w{struct trivfs_protid *@var{cred}}, @w{struct stat *@var{stbuf}})
This should modify a @code{struct stat} (as returned from the underlying
node) for presentation to callers of @code{io_stat}.  It is permissable
for this function to do nothing, but it must still be defined.
@end deftypefun

@deftypefun error_t trivfs_goaway (@w{struct trivfs_control *@var{cntl}}, @w{int @var{flags}})
This function is called when someone wants the filesystem @var{cntl} to
go away.  @var{flags} are from the set @code{FSYS_GOAWAY_*} found in
@code{<hurd/hurd_types.h>}.
@end deftypefun


@node Trivfs Options
@subsection Trivfs Options

The functions and variables described in this subsection already have
default definitions in @code{libtrivfs}, so you are not forced to define
them; rather, they may be redefined on a case-by-case basis.

@deftypevar {extern struct port_class *} trivfs_protid_portclasses[]
@deftypevarx {extern int} trivfs_protid_nportclasses
@deftypevarx {extern struct port_class *} trivfs_cntl_portclasses[]
@deftypevarx {extern int} trivfs_cntl_nportclasses
If you define these, they should be vectors (and the associated sizes)
of port classes that will be translated into control and protid pointers
for passing to RPCs, in addition to those passed to or created by
@code{trivfs_create_control} (or @code{trivfs_startup}) will
automatically be recognized.
@end deftypevar

@deftypefn {Variable} {error_t (*} trivfs_check_open_hook ) (@w{struct trivfs_control *@var{cntl}}, @w{struct iouser *@var{user}}, @w{int @var{flags}})
If this variable is set, it is called every time an open happens.
@var{user} and @var{flags} are from the open; @var{cntl} identifies the
node being opened.  This call need not check permissions on the
underlying node.  This call can block as necessary, unless
@code{O_NONBLOCK} is set in @var{flags}.  Any desired error can be
returned, which will be reflected to the user and prevent the open from
succeeding.
@end deftypefn

@deftypefn {Variable} {error_t (*} trivfs_protid_create_hook ) (@w{struct trivfs_protid *@var{prot}})
@deftypefnx {Variable} {error_t (*} trivfs_peropen_create_hook ) (@w{struct trivfs_peropen *@var{perop}})
If these variables are set, they is called every time a new protid or
peropen structure is created and initialized.
@end deftypefn

@deftypefn {Variable} {void (*} trivfs_protid_destroy_hook ) (@w{struct trivfs_protid *@var{prot}})
@deftypefnx {Variable} {void (*} trivfs_peropen_destroy_hook ) (@w{struct trivfs_peropen *@var{perop}})
If these variables is set, they are called every time a protid or
peropen structure is about to be destroyed.
@end deftypefn

@deftypefn {Variable} {error_t (*} trivfs_getroot_hook ) (@w{struct trivfs_control *@var{cntl}}, @w{mach_port_t @var{reply_port}}, @w{mach_msg_type_name_t @var{reply_port_type}}, @w{mach_port_t @var{dotdot}}, @w{uid_t *@var{uids}}, @w{u_int @var{nuids}}, @w{uid_t *@var{gids}}, @w{u_int @var{ngids}}, @w{int @var{flags}}, @w{retry_type *@var{do_retry}}, @w{char *@var{retry_name}}, @w{mach_port_t *@var{node}}, @w{mach_msg_type_name_t *@var{node_type}})
If this variable is set, it is called by @code{trivfs_S_fsys_getroot}
before any other processing takes place; if the return value is
@code{EAGAIN}, normal trivfs getroot processing continues, otherwise the
RPC returns with that return value.
@end deftypefn


@node Trivfs Ports
@subsection Trivfs Ports

If you choose to allocate your own trivfs port classes and buckets, the
following functions may come in handy:

@deftypefun error_t trivfs_add_port_bucket (@w{struct port_bucket **@var{bucket}})
Add the port bucket @code{*@var{bucket}} to the list of dynamically
allocated port buckets; if @code{*@var{bucket}} is zero, an attempt is
made to allocate a new port bucket, which is then stored in
@code{*@var{bucket}}.
@end deftypefun

@deftypefun void trivfs_remove_port_bucket (@w{struct port_bucket *@var{bucket}})
Remove the previously added dynamic port bucket @var{bucket}, freeing it
if it was allocated by @code{trivfs_add_port_bucket}.
@end deftypefun

@deftypefun error_t trivfs_add_control_port_class (@w{struct port_class **@var{class}})
@deftypefunx error_t trivfs_add_protid_port_class (@w{struct port_class **@var{class}})
Add the port class @code{*@var{class}} to the list of control or protid port
classes recognized by trivfs; if @code{*@var{class}} is zero, an attempt is
made to allocate a new port class, which is stored in @code{*@var{class}}.
@end deftypefun

@deftypefun void trivfs_remove_control_port_class (@w{struct port_class *@var{class}})
@deftypefunx void trivfs_remove_protid_port_class (@w{struct port_class *@var{class}})
Remove the previously added dynamic control or protid port class
@var{class}, freeing it if it was allocated by
@code{trivfs_add_control_port_class} or
@code{trivfs_add_protid_port_class}.
@end deftypefun

Even if you do not use the above allocation functions, you may still be
able to use the default trivfs cleanroutines:

@deftypefun void trivfs_clean_cntl (@w{void *@var{port}})
@deftypefunx void trivfs_clean_protid (@w{void *@var{port}})
These functions should be installed as @code{libports} cleanroutines for
control port classes and protid port classes, respectively.
@end deftypefun


@node Fshelp Library
@section Fshelp Library
@scindex libfshelp
@scindex fshelp.h

The fshelp library implements various things that are generic to most
implementors of the file protocol.  It presumes that you are using the
iohelp library as well.  @code{libfshelp} is divided into separate
facilities which may be used independently.  These functions are
declared in @code{<hurd/fshelp.h>}.


@menu
* Passive Translator Linkage::  Invoking passive translators.
* Active Translator Linkage::   Managing active translators.
* Fshelp Locking::              Implementing file locking.
* Fshelp Permissions::          Standard file access permission policies.
* Fshelp Misc::                 Useful standalone routines.
@end menu

@node Passive Translator Linkage
@subsection Passive Translator Linkage

These routines are self-contained and start passive translators,
returning the control port.  They do not require multithreading or the
ports library.

@deftypefn {Typedef} {typedef error_t (*} fshelp_open_fn_t ) (@w{int @var{flags}}, @w{file_t *@var{node}}, @w{mach_msg_type_name_t *@var{node_type}})
A callback used by the translator starting functions, which should be a
function that given some open flags, opens the appropiate file, and
returns the node port.
@end deftypefn

@deftypefun error_t fshelp_start_translator_long (@w{fshelp_open_fn_t @var{underlying_open_fn}}, @w{char *@var{name}}, @w{char *@var{argz}}, @w{int @var{argz_len}}, @w{mach_port_t *@var{fds}}, @w{mach_msg_type_name_t @var{fds_type}}, @w{int @var{fds_len}}, @w{mach_port_t *@var{ports}}, @w{mach_msg_type_name_t @var{ports_type}}, @w{int @var{ports_len}}, @w{int *@var{ints}}, @w{int @var{ints_len}}, @w{int @var{timeout}}, @w{fsys_t *@var{control}})
Start a passive translator @var{name} with arguments @var{argz} (length
@var{argz_len}).  Initialize the initports to @var{ports} (length
@var{ports_len}), the initints to @var{ints} (length @var{ints_len}),
and the file descriptor table to @var{fds} (length @var{fds_len}).
Return the control port in @code{*@var{control}}.  If the translator doesn't
respond or die in @var{timeout} milliseconds (if @var{timeout} is
greater than zero), return an appropriate error.  If the translator dies
before responding, return @code{EDIED}.
@end deftypefun

@deftypefun error_t fshelp_start_translator (@w{fshelp_open_fn_t @var{underlying_open_fn}}, @w{char *@var{name}}, @w{char *@var{argz}}, @w{int @var{argz_len}}, @w{int @var{timeout}}, @w{fsys_t *@var{control}})
Same as @code{fshelp_start_translator_long}, except the initports and
ints are copied from our own state, @var{fd[2]} is copied from our own
stderr, and the other fds are cleared.
@end deftypefun

@node Active Translator Linkage
@subsection Active Translator Linkage

These routines implement the linkage to active translators needed
by any filesystem which supports them.  They require the threads
library and use the passive translator routines above, but they don't
require the ports library at all.

This interface is complex, because creating the ports and state
necessary for @code{start_translator_long} is expensive.  The caller to
@code{fshelp_fetch_root} should not need to create them on every call,
since usually there will be an existing active translator.

@deftypefun void fshelp_transbox_init (@w{struct transbox *@var{transbox}}, @w{struct mutex *@var{lock}}, @w{void *@var{cookie}})
Initialize a transbox, which contains state information for active
translators.
@end deftypefun

@deftypefn {Typedef} {typedef error_t (*} fshelp_fetch_root_callback1_t ) (@w{void *@var{cookie1}}, @w{void *@var{cookie2}}, @w{uid_t *@var{uid}}, @w{gid_t *@var{gid}}, @w{char **@var{argz}}, @w{size_t *@var{argz_len}})
This routine is called by @code{fshelp_fetch_root} to fetch more
information.  Return the owner and group of the underlying translated
file in @code{*@var{uid}} and @code{*@var{gid}}; point
@code{*@var{argz}} at the entire passive translator specification for
the file (setting @code{*@var{argz_len}} to the length).  If there is no
passive translator, then return @code{ENOENT}.  @var{cookie1} is the
cookie passed in @code{fshelp_transbox_init}.  @var{cookie2} is the
cookie passed in the call to @code{fshelp_fetch_root}.
@end deftypefn

@deftypefn {Typedef} {typedef error_t (*} fshelp_fetch_root_callback2_t ) (@w{void *@var{cookie1}}, @w{void *@var{cookie2}}, @w{int @var{flags}}, @w{mach_port_t *@var{underlying}}, @w{mach_msg_type_name_t *@var{underlying_type}})
This routine is called by @code{fshelp_fetch_root} to fetch more
information.  Return an unauthenticated node for the file itself in
@code{*@var{underlying}} and @code{*@var{underlying_type}} (opened with
@var{flags}).  @var{cookie1} is the cookie passed in
@code{fshelp_transbox_init}.  @var{cookie2} is the cookie passed in the
call to @code{fshelp_fetch_root}.
@end deftypefn

@deftypefun error_t fshelp_fetch_root (@w{struct transbox *@var{transbox}}, @w{void *@var{cookie}}, @w{file_t @var{dotdot}}, @w{struct iouser *@var{user}}, @w{int @var{flags}}, @w{fshelp_fetch_root_callback1_t @var{callback1}}, @w{fshelp_fetch_root_callback2_t @var{callback2}}, @w{retry_type *@var{retry}}, @w{char *@var{retryname}}, @w{mach_port_t *@var{root}})
Fetch the root from @var{transbox}.  @var{dotdot} is an unauthenticated
port for the directory in which we are looking; @var{user} specifies the
ids of the user responsible for the call.  @var{flags} are as for
@code{dir_pathtrans} (but @code{O_CREAT} and @code{O_EXCL} are not
meaningful and are ignored).  The transbox lock (as set by
@code{fshelp_transbox_init}) must be held before the call, and will be
held upon return, but may be released during the operation of the call.
@end deftypefun

@deftypefun int fshelp_translated (@w{struct transbox *@var{box}})
Return true if and only if there is an active translator on this box.
@end deftypefun

@deftypefun error_t fshelp_set_active (@w{struct transbox *@var{box}}, @w{fsys_t @var{newactive}}, @w{int @var{excl}})
Atomically replace the existing active translator port for this box with
@var{newactive}.  If @var{excl} is non-zero then don't modify an
existing active transbox; return @code{EBUSY} instead.
@end deftypefun

@deftypefun error_t fshelp_fetch_control (@w{struct transbox *@var{box}}, @w{mach_port_t *@var{control}})
Fetch the control port to make a request on it.  It's a bad idea to use
@code{fsys_getroot} with the result; use @code{fshelp_fetch_root}
instead.
@end deftypefun

@deftypefun void fshelp_drop_transbox (@w{struct transbox *@var{box}})
Clean transbox state so that deallocation or reuse is possible.
@end deftypefun


@node Fshelp Locking
@subsection Fshelp Locking

The @code{flock} call is in flux, as the current Hurd interface (as of
version @value{VERSION}) is not suitable for implementing the POSIX
record-locking semantics.


@node Fshelp Permissions
@subsection Fshelp Permissions

These functions are designed to aid with user permission checking.  It
is a good idea to use these routines rather than to roll your own, so
that Hurd users see consistent handling of file and directory permission
bits.

@deftypefun error_t fshelp_isowner (@w{struct stat *@var{st}}, @w{struct iouser *@var{user}})
Check to see whether @var{user} should be considered the owner of the
file identified by @var{st}.  If so, return zero; otherwise return an
appropriate error code.
@end deftypefun

@deftypefun error_t fshelp_access (@w{struct stat *@var{st}}, @w{int @var{op}}, @w{struct iouser *@var{user}})
Check to see whether the user @var{user} can operate on the file
identified by @var{st}.  @var{op} is one of @code{S_IREAD},
@code{S_IWRITE}, and @code{S_IEXEC}.  If the access is permitted, return
zero; otherwise return an appropriate error code.
@end deftypefun

@deftypefun error_t fshelp_checkdirmod (@w{struct stat *@var{dir}}, @w{struct stat *@var{st}}, @w{struct iouser *@var{user}})
Check to see whether @var{user} is allowed to modify @var{dir} with respect to
existing file @var{st}.  If there is no existing file, then @var{st}
should be set to zero.  If the access is permissable return zero;
otherwise return an appropriate error code.
@end deftypefun


@node Fshelp Misc
@subsection Fshelp Misc

The following functions are completely standalone:

@deftypefun error_t fshelp_delegate_translation (@w{char *@var{server_name}}, @w{mach_port_t @var{requestor}}, @w{char **@var{argv}})
Try to hand off responsibility from a translator to the server located
on the node @var{server_name}.  @var{requestor} is the translator's
bootstrap port, and @var{argv} is the command line.  If
@var{server_name} is null, then a name is concocted by appending
@code{argv[0]} to @code{_servers}.
@end deftypefun

@deftypefun error_t fshelp_exec_reauth (@w{int @var{suid}}, @w{uid_t @var{uid}}, @w{int @var{sgid}}, @w{gid_t @var{gid}}, @w{auth_t @var{auth}}, error_t (*@var{get_file_ids}) (@w{struct idvec *@var{uids}}, @w{struct idvec *@var{gids}}), @w{mach_port_t *@var{ports}}, @w{mach_msg_type_number_t @var{num_ports}}, @w{mach_port_t *@var{fds}}, @w{mach_msg_type_number_t @var{num_fds}}, @w{int *@var{secure}})
If @var{suid} or @var{sgid} is true, adds @var{uid} and/or @var{gid}
respectively to the authentication in
@code{@var{ports}[INIT_PORT_AUTH]}, and replaces it with the result.
All the other ports in @var{ports} and @var{fds} are then
reauthenticated, using any privileges available through @var{auth}.  If
the auth port in @code{@var{ports}[INIT_PORT_AUTH]} is bogus, and
@var{get_file_ids} is non-null, it is called to get a list
of uids and gids from the file to use as a replacement.  If @var{secure}
is non-null and any added ids are new, then the variable it points to is
set to nonzero, otherwise zero.  If either the uid or gid case fails,
then the other may still apply.
@end deftypefun

@deftypefun error_t fshelp_get_identity (@w{struct port_bucket *@var{bucket}}, @w{ino_t @var{fileno}}, @w{mach_port_t *@var{pt}})
Return an identity port in @code{*@var{pt}} for the node numbered
@var{fileno}, suitable for returning from @code{io_identity}; exactly
one send right must be created from the returned value.  @var{fileno}
should be the same value returned as the @var{fileno} out-parameter in
@code{io_identity}, and in the enclosing directory (except for mount
points), and in the @code{st_ino} stat field.  @var{bucket} should be a
@code{libports} port bucket; fshelp requires the caller to make sure
port operations (for no-senders notifications) are used.
@end deftypefun

@deftypefun error_t fshelp_return_malloced_buffer (@w{char *@var{buf}}, @w{size_t @var{len}}, @w{char **@var{rbuf}}, @w{mach_msg_type_number_t *@var{rlen}})
Put data from the malloced buffer @var{buf}, @var{len} bytes long, into
@var{rbuf} (which is @var{rlen} bytes long), suitable for returning from
an RPC.  If @var{len} is greater than zero, @var{buf} is freed,
regardless of whether an error is returned or not.
@end deftypefun

@deftypefun error_t fshelp_set_options (@w{struct argp *@var{argp}}, @w{int @var{flags}}, @w{char *@var{argz}}, @w{size_t @var{argz_len}}, @w{void *@var{input}})
Invoke @code{argp_parse} in the standard way, with data from @var{argz}
and @var{argz_len}.
@end deftypefun

@deftypefun void fshelp_touch (@w{struct stat *@var{st}}, @w{unsigned @var{what}}, @w{volatile struct mapped_time_value *@var{maptime}})
Change the stat times of @var{node} as indicated by @var{what} to
the current time.  @var{what} is a bitmask of one or more of
the @code{TOUCH_ATIME}, @code{TOUCH_MTIME}, and @code{TOUCH_CTIME}
constants.
@end deftypefun


@node File Interface
@section File Interface
@scindex fs.defs

This section documents the interface for operating on files.

@menu
* File Overview::               Basic concepts for the file interface.
* Changing Status::             Changing the owner (etc.) of a file.
* Program Execution::           Executing files.
* File Locking::                Implementing the @code{flock} call.
* File Frobbing::               Other active calls on files.
* Opening Files::               Looking up files in directories.
* Modifying Directories::       Creating and deleting nodes.
* Notifications::               File and directory change callbacks.
* File Translators::            How to set and get translators.
@end menu

@node File Overview
@subsection File Overview

The file interface is a superset of the I/O interface (@pxref{I/O
Interface}).  Servers which provide the file interface are required to
support the I/O interface as well.  All objects reachable in the
filesystem are expected to provide the file interface, even if they do
not contain data.  (The @code{trivfs} library makes it easy to do so for
ordinary sorts of cases.  @xref{Trivfs Library}.)

The interface definitions for the file interface are found in
@code{<hurd/fs.defs>}.

Files have various pieces of status information which are returned by
@code{io_stat} (@pxref{Information Queries}).  Most of this status
information can be directly changed by various calls in the file
interface; some of it should vary implicitly as the contents of the file
change.

Many of these calls have general rules associated with them describing
how security and privilege should operate.  The @code{diskfs} library
(@pxref{Diskfs Library}) implements these rules for stored filesystems.
These rules have also been implemented in the fshelp library
(@pxref{Fshelp Library}).  Trivfs-based servers generally have no need
to implement these rules at all.

In special cases, there may be a reason to implement a different
security check from that specified here, or to implement a call to do
something slightly different.  But such cases must be carefully
considered; make sure that you will not confuse innocent user programs
through excessive cleverness.

If some operation cannot be implemented (for example, @code{chauthor}
over FTP), then the call should return @code{EOPNOTSUPP}.  If it is
merely difficult to implement a call, it is much better to figure out a
way to implement it as a series of operations rather than returning
errors to the user.

@node Changing Status
@subsection Changing Status

There are several RPCs available for users to change much of the status
information associated with a file.  (The information is returned by the
@code{io_stat} RPC; see @ref{Information Queries}.)

All these operations are restricted to root and the owner of the file.
When attempted by another user, they should return @code{EPERM}.

@findex file_chown
The @code{file_chown} RPC changes the owner and group of the file.  Only
root should be able to change the owner, and changing the group to a
group the caller is not in should also be prohibited.  Violating either
of these conditions should return @code{EPERM}.

@findex file_chauthor
The @code{file_chauthor} RPC changes the author of the file.  It should
be legitimate to change the author to any value without restriction.

@findex file_chmod
The @code{file_chmod} RPC changes the file permission mode bits.

@findex file_chflags
The @code{file_chflags} RPC changes the flags of the file.  It should be
legitimate to change the flags to any value without restriction.  No
standard meanings have been assigned to the flags yet, but we intend to
do so.  Do not assume that the flags format we choose will map
identically to that of some existing filesystem format.

@findex file_utimes
The @code{file_utimes} RPC changes the @var{atime} and @var{mtime} of
the file.  Making this call must cause the @var{ctime} to be updated as
well, even if no actual change to either the @var{mtime} or the
@var{atime} occurs.

@findex file_set_size
The @code{file_set_size} RPC is special; not only does it change the
status word specifing the size of the file, but it also changes the
actual contents of the file.  If the file size is being reduced it
should release secondary storage associated with the previous contents
of the file.  If the file is being extended, the new region added to the
file must be zero-filled.  Unlike the other RPCs in this section,
@code{file_set_size} should be permitted to any user who is allowed to
write the file.


@node Program Execution
@subsection Program Execution

@findex file_exec
Execution of programs on the Hurd is done through fileservers with the
@code{file_exec} RPC.  The fileserver is expected to verify that the
user is allowed to execute the file, make whatever modifications to the
ports are necessary for setuid execution, and then invoke the standard
execserver found on @file{/servers/exec}.

This section specifically addresses what fileservers are expected to do,
with minimal attention to the other parts of the process.  @xref{Running
Programs}, for more general information.

The file must be opened for execution; if it is not, @code{EBADF} should
be returned In addition, at least one of the execute bits must be on.  A
failure of this check should result in @code{EACCES}---not
@code{ENOEXEC}.  It is not proper for the fileserver ever to respond to
the @code{file_exec} RPC with @code{ENOEXEC}.

If either the setuid or setgid bits are set, the server needs to
construct a new authentication handle with the additional new ID's.
Then all the ports passed to @code{file_exec} need to be reauthenticated
with the new handle.  If the fileserver is unable to make the new
authentication handle (for example, because it is not running as root)
it is not acceptable to return an error; in such a case the server
should simply silently fail to implement the setuid/setgid semantics.

If the setuid/setgid transformation adds a new uid or gid to the user's
authentication handle that was not previously present (as opposed to
merely reordering them) then the @code{EXEC_SECURE} and
@code{EXEC_NEWTASK} flags should both be added in the call to
@code{exec_exec}.

The server then needs to open a new port onto the executed file which
will not share any file pointers with the port the user passed in,
opened with @code{O_READ}.  Finally, all the information (mutated
appropriately for setuid/setgid) should be sent to the execserver with
@code{exec_exec}.  Whatever error code @code{exec_exec} returns should
returned to the caller of @code{file_exec}.

@node File Locking
@subsection File Locking

The @code{flock} call is in flux, as the current Hurd interface (as of
version @value{VERSION}) is not suitable for implementing the POSIX
record-locking semantics.

@findex file_lock
@findex file_lock_stat
You should ignore the @code{file_lock} and @code{file_lock_stat} calls
until the new record-locking interface is implemented.


@node File Frobbing
@subsection File Frobbing

FIXME: Other active calls on files

@code{file_sync}

@code{file_getfh}

@code{file_getlinknode}

@code{file_check_access}

These manipulate meta-information:

@code{file_reparent}

@code{file_statfs}

@code{file_syncfs}

@code{file_getcontrol}

@code{file_get_storage_info}

@code{file_get_fs_options}


@node Opening Files
@subsection Opening Files

FIXME: Looking up files in directories

@code{dir_lookup}

@code{dir_readdir}

@node Modifying Directories
@subsection Modifying Directories

FIXME: Creating and deleting nodes

@code{dir_mkfile}

@code{dir_mkdir}

@code{dir_rmdir}

@code{dir_unlink}

@code{dir_link}

@code{dir_rename}

@node Notifications
@subsection Notifications

FIXME: File and directory change callbacks

File change notifications are not yet implemented, but directory
notifications are.

@code{file_notice_changes}

@code{dir_notice_changes}

@node File Translators
@subsection File Translators

FIXME: How to set and get translators

@code{file_set_translator}

@code{file_get_translator}

@code{file_get_translator_cntl}


@node Filesystem Interface
@section Filesystem Interface
@scindex fsys.defs

The filesystem interface (described in @code{<hurd/fsys.defs>}) is
supported by translator control ports.

FIXME: finish


@node Special Files
@chapter Special Files

In Unix, any file that does not act as a general-purpose unit of storage
is called a @dfn{special file}.  These are FIFOs, Unix-domain sockets,
and device nodes.  In the Hurd, there is no need for the ``special
file'' distinction, since they are implemented by translators, just as
regular files are.

Nevertheless, the Hurd maintains this distinction, in order to provide
backward-compatibility for Unix programs (which do not know about
translators).  Studying the implementation of Hurd special files is a
good way to introduce the idea of translators to people who are familiar
with Unix.

This chapter does not discuss @file{/dev/zero} or any of the
microkernel-based devices, since these are translated by the generalized
storeio server (FIXME xref).

FIXME: finish

@section fifo
@section ifsock
@section magic
@section null


FIXME: a chapter on libtreefs and libdirmgt will probably go here


@node Stores
@chapter Stores

A @dfn{store} is a fixed-size block of storage, which can be read and
perhaps written to.  A store is more general than a file: it refers to
any type of storage such as devices, files, memory, tasks, etc.  Stores
can also be representations of other stores, which may be combined and
filtered in various ways.

@menu
* Store Library::               An abstract interface to storage systems.
@end menu

@section storeinfo, storecat, storeread
@section storeio

FIXME: finish

@node Store Library
@section Store Library
@scindex libstore
@scindex store.h

The store library (which is declared in @code{<hurd/store.h>})
implements many different backends which support the store abstraction.
Hurd programs use @code{libstore} so that new storage types can be
implemented with minimum impact.

@menu
* Store Arguments::             Parsing store command-line arguments.
* Store Management::            Creating and manipulating stores.
* Store I/O::                   Reading and writing data to stores.
* Store Classes::               Ready-to-use storage backends.
* Store RPC Encoding::          Transferring store descriptors via RPC.
@end menu


@node Store Arguments
@subsection Store Arguments

FIXME: describe startup sequence

@deftypevr {Structure} struct store_parsed
The result of parsing a store, which should be enough information to
open it, or return the arguments.
@end deftypevr

@deftypefn {Structure} struct store_argp_params @{ @w{struct store_parsed *@var{result}}; @w{const char *@var{default_type}}; @w{const struct store_class *const *@var{classes}}; @}
This is the structure used to pass args back and forth from
@var{store_argp}.  @var{result} is the resulting parsed result.  If
@samp{--store-type} isn't specified, then @var{default_type} should be
used as the store type; zero is equivalent to @code{"query"}.
@var{classes} is set of classes used to validate store types and
argument syntax.
@end deftypefn

@deftypevar {extern struct argp} store_argp
This is an argument parser that may be used for parsing a simple command
line specification for stores.  The accompanying input parameter must be
a pointer to a @code{struct store_argp_params}.
@end deftypevar

@deftypefun void store_parsed_free (@w{struct store_parsed *@var{parsed}})
Free all resources used by @var{parsed}.
@end deftypefun

@deftypefun error_t store_parsed_open (@w{const struct store_parsed *@var{parsed}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Open the store specified by @var{parsed}, and return it in @var{store}.
@end deftypefun

@deftypefun error_t store_parsed_append_args (@w{const struct store_parsed *@var{parsed}}, @w{char **@var{argz}}, @w{size_t *@var{argz_len}})
Add the arguments used to create @var{parsed} to @var{argz} and
@var{argz_len}.
@end deftypefun

@deftypefun error_t store_parsed_name (@w{const struct store_parsed *@var{parsed}}, @w{char **@var{name}})
Make an option string describing @var{parsed}, and return it in malloced
storage in @var{name}.
@end deftypefun


@node Store Management
@subsection Store Management

The following functions provide basic management of stores:

@deftypefun error_t store_create (@w{file_t @var{source}}, @w{int @var{flags}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{store}})
Return a new store in @var{store}, which refers to the storage
underlying @var{source}.  @var{classes} is used to select classes
specified by the provider; if zero, @var{store_std_classes} is used.
@var{flags} is set with @code{store_set_flags}, with the exception of
@code{STORE_INACTIVE}, which merely indicates that no attempt should be
made to activate an inactive store; if @code{STORE_INACTIVE} is not
specified, and the store returned for SOURCE is inactive, an attempt is
made to activate it (failure of which causes an error to be returned).
A reference to @var{source} is created (but may be destroyed with
@code{store_close_source}).

It is usually better to use a specific store open or create function
such as @code{store_open} (@pxref{Store Classes}), since they are
tailored to the needs of a specific store.  Generally, you should only
use @code{store_create} if you are defining your own store class, or you
need options that are not provided by a more specific store creation
function.
@end deftypefun

@deftypefun void store_close_source (@w{struct store *@var{store}})
If @var{store} was created using @code{store_create}, remove the
reference to the source from which it was created.
@end deftypefun

@deftypefun void store_free (@w{struct store *@var{store}})
Clean up and deallocate @var{store}'s underlying stores.
@end deftypefun

@deftypefn {Structure} struct store_run @{ @w{off_t @var{start}}, @var{length}; @}
A @code{struct store_run} represents a contiguous region in a store's
address range.  These are used to designate active portions of a store.
If @var{start} is -1, then the region is a @dfn{hole} (it is zero-filled
and doesn't correspond to any real addresses).
@end deftypefn

@deftypefun error_t store_set_runs (@w{struct store *@var{store}}, @w{const struct store_run *@var{runs}}, @w{size_t @var{num_runs}})
Set @var{store}'s current runs list to (a copy of) @var{runs} and
@var{num_runs}.
@end deftypefun

@deftypefun error_t store_set_children (@w{struct store *@var{store}}, @w{struct store *const *@var{children}}, @w{size_t @var{num_children}})
Set @var{store}'s current children to (a copy of) @var{children} and
@var{num_children} (note that just the vector @var{children} is copied,
not the actual children).
@end deftypefun

@deftypefun error_t store_children_name (@w{const struct store *@var{store}}, @w{char **@var{name}})
Try to come up with a name for the children in @var{store}, combining
the names of each child in a way that could be used to parse them with
@code{store_open_children}.  This is done heuristically, and so may not
succeed.  If a child doesn't have a name, @code{EINVAL} is returned.
@end deftypefun

@deftypefun error_t store_set_name (@w{struct store *@var{store}}, @w{const char *@var{name}})
Sets the name associated with @var{store} to a copy of @var{name}.
@end deftypefun

@deftypefun error_t store_set_flags (@w{struct store *@var{store}}, @w{int @var{flags}})
Add @var{flags} to @var{store}'s currently set flags.
@end deftypefun

@deftypefun error_t store_clear_flags (@w{struct store *@var{store}}, @w{int @var{flags}})
Remove @var{flags} from @var{store}'s currently set flags.
@end deftypefun

@deftypefun error_t store_set_child_flags (@w{struct store *@var{store}}, @w{int @var{flags}})
Set @var{flags} in all children of @var{store}, and if successful, add
@var{flags} to @var{store}'s flags.
@end deftypefun

@deftypefun error_t store_clear_child_flags (@w{struct store *@var{store}}, @w{int @var{flags}})
Clear @var{flags} in all children of @var{store}, and if successful,
remove @var{flags} from @var{store}'s flags.
@end deftypefun

@deftypefun int store_is_securely_returnable (@w{struct store *@var{store}}, @w{int @var{open_flags}})
Returns true if @var{store} can safely be returned to a user who has
accessed it via a node using @var{open_flags}, without compromising
security.
@end deftypefun

@deftypefun error_t store_clone (@w{struct store *@var{from}}, @w{struct store **@var{to}})
Return a copy of @var{from} in @var{to}.
@end deftypefun

@deftypefun error_t store_remap (@w{struct store *@var{source}}, @w{const struct store_run *@var{runs}}, @w{size_t @var{num_runs}}, @w{struct store **@var{store}})
Return a store in @var{store} that reflects the blocks in @var{runs} and
@var{runs_len} from source; @var{source} is consumed, but not
@var{runs}.  Unlike the @code{store_remap_create} function, this may
simply modify @var{source} and return it.
@end deftypefun


@node Store I/O
@subsection Store I/O

The following functions allow you to read and modify the contents of a
store:

@deftypefun error_t store_map (@w{const struct store *@var{store}}, @w{vm_prot_t @var{prot}}, @w{mach_port_t *@var{memobj}})
Return a memory object paging on @var{store}.
@ignore @c FIXME: update if/when there are more pager-related functions
If this call fails with @code{EOPNOTSUPP}, you can try calling some of
the routines below to get a pager.
@end ignore
@end deftypefun

@deftypefun error_t store_read (@w{struct store *@var{store}}, @w{off_t @var{addr}}, @w{size_t @var{amount}}, @w{void **@var{buf}}, @w{size_t *@var{len}})
Read @var{amount} bytes from @var{store} at @var{addr} into @var{buf}
and @var{len} (which follows the usual Mach buffer-return semantics) to
@var{store} at @var{addr}.  @var{addr} is in @var{blocks} (as defined by
@code{@var{store}->block_size}).  Note that @var{len} is in bytes.
@end deftypefun

@deftypefun error_t store_write (@w{struct store *@var{store}}, @w{off_t @var{addr}}, @w{void *@var{buf}}, @w{size_t @var{len}}, @w{size_t *@var{amount}})
Write @var{len} bytes from @var{buf} to @var{store} at @var{addr}.
Returns the amount written in @var{amount} (in bytes).  @var{addr} is in
@var{blocks} (as defined by @code{@var{store}->block_size}).
@end deftypefun


@node Store Classes
@subsection Store Classes

The store library comes with a number of standard store class
implementations:

@deftypevar {extern const struct store_class *const} store_std_classes[]
This is a null-terminated vector of the standard store classes
implemented by @code{libstore}.
@end deftypevar

If you are building your own class vectors, the following function may
be useful:

@deftypevar error_t store_concat_class_vectors (@w{struct store_class **@var{cv1}}, @w{struct store_class **@var{cv2}}, @w{struct store_class ***@var{concat}})
Concatenate the store class vectors in @var{cv1} and @var{cv2}, and
return a new (malloced) vector in @var{concat}.
@end deftypevar

@subsubsection @code{query} store
@cindex @code{query} store

@deftypevar {extern const struct store_class} store_query_class
This store is a virtual store which queries a filesystem node, and
delegates control to an appropriate store class.
@end deftypevar

@deftypefun error_t store_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{store}})
Open the file @var{name}, and return a new store in @var{store}, which
refers to the storage underlying it.  @var{classes} is used to select
classes specified by the provider; if it is zero, then
@var{store_std_classes} is used.  @var{flags} is set with
@code{store_set_flags}.  A reference to the open file is created (but
may be destroyed with @code{store_close_source}).
@end deftypefun

@subsubsection @code{typed_open} store
@cindex @code{typed_open} store

@deftypevar {extern const struct store_class} store_typed_open_class
This store is special in that it doesn't correspond to any specific
store functions, rather it provides a way to interpret character strings
as specifications for other stores.
@end deftypevar

@deftypefun error_t store_typed_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{store}})
Open the store indicated by @var{name}, which should consist of a store
type name followed by a @samp{:} and any type-specific name, returning the
new store in @var{store}.  @var{classes} is used to select classes
specified by the type name; if it is zero, @var{store_std_classes} is
used.
@end deftypefun

@deftypefun error_t store_open_children (@w{const char *@var{name}}, @w{int @var{flags}}, @w{const struct store_class *const *@var{classes}}, @w{struct store ***@var{stores}}, @w{size_t *@var{num_stores}})
Parse multiple store names in @var{name}, and open each individually,
returning all in the vector @var{stores}, and the number in
@var{num_stores}.  The syntax of @var{name} is a single non-alphanumeric
separator character, followed by each child store name separated by the
same separator; each child name is @samp{@var{type}:@var{name}} notation
as parsed by @code{store_typed_open}.  If every child uses the same
@samp{@var{type}:} prefix, then it may be factored out and put before
the child list instead (the two notations are differentiated by whether
or not the first character of @var{name} is alphanumeric).
@end deftypefun

@subsubsection @code{device} store
@cindex @code{device} store

@cindex @code{device drivers}
@deftypevar {extern const struct store_class} store_device_class
This store is a simple wrapper for a microkernel device
driver.@footnote{It is important to note that device drivers are not
provided by the Hurd, but by the underlying microkernel.  Hurd `devices'
are just storeio-translated nodes which make the microkernel device
drivers obey Hurd semantics.  If you wish to implement a new device
driver, you will need to consult the appropriate microkernel
documentation.}
@end deftypevar

@deftypefun error_t store_device_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Open the device named @var{name}, and return the corresponding store in
@var{store}.
@end deftypefun

@deftypefun error_t store_device_create (@w{device_t @var{device}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} referring to the microkernel device
@var{device}.  Consumes the @var{device} send right.
@end deftypefun

@subsubsection @code{file} store
@cindex @code{file} store

@deftypevar {extern const struct store_class} store_file_class
This store reads and writes the contents of a Hurd file.
@end deftypevar

@deftypefun error_t store_file_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Open the file @var{name}, and return the corresponding store in @var{store}.
@end deftypefun

@deftypefun error_t store_file_create (@w{file_t @var{file}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} referring to the file @var{file}.
Unlike @code{store_create}, this will always use file I/O, even it would
be possible to be more direct.  This may work in more cases, for instance
if the file has holes.  Consumes the @var{file} send right.
@end deftypefun

@subsubsection @code{task} store
@cindex @code{task} store

@deftypevar {extern const struct store_class} store_task_class
This store provides access to the contents of a microkernel task.
@end deftypevar

@deftypevar error_t store_task_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Open the task @var{name} (@var{name} should be the task's pid), and
return the corresponding store in @var{store}.
@end deftypevar

@deftypevar {error_t} store_task_create (@w{task_t @var{task}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} referring to the task @var{task},
consuming the @var{task} send right.
@end deftypevar

@subsubsection @code{zero} store
@cindex @code{zero} store

@deftypevar {extern const struct store_class} store_zero_class
Reads to this store always return zero-filled buffers, no matter what
has been written into it.  This store corresponds to the Unix
@file{/dev/zero} device node.
@end deftypevar

@deftypefun error_t store_zero_create (@w{off_t @var{size}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new zero store @var{size} bytes long in @var{store}.
@end deftypefun

@subsubsection @code{copy} store
@cindex @code{copy} store

@deftypevar {extern const struct store_class} store_copy_class
This store provides a temporary copy of another store.  This is useful
if you want to provide writable data, but do not wish to modify the
underlying store.  All changes to a copy store are lost when it is
closed.
@end deftypevar

@deftypefun error_t store_copy_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{store}})
Open the copy store @var{name} (which consists of another store class
name, a @samp{:}, and a name for the store class to open) and return the
corresponding store in @var{store}.  @var{classes} is used to select
classes specified by the type name; if it is zero,
@var{store_std_classes} is used.
@end deftypefun

@deftypefun error_t store_copy_create (@w{struct store *@var{from}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} which contains a snapshot of the
contents of the store @var{from}; @var{from} is consumed.
@end deftypefun

@deftypefun error_t store_buffer_create (@w{void *@var{buf}}, @w{size_t @var{buf_len}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} which contains the memory buffer
@var{buf}, of length @var{buf_len}.  @var{buf} must be allocated with
@code{vm_allocate}, and will be consumed.
@end deftypefun

@subsubsection @code{gunzip} store
@cindex @code{gunzip} store

@deftypevar {extern const struct store_class} store_gunzip_class
This store provides transparent GNU zip decompression of a substore.
Unfortunately, this store is currently read-only.
@end deftypevar

@deftypevar error_t store_gunzip_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{store}})
Open the gunzip store @var{name} (which consists of another store class
name, a @samp{:}, and a name for that store class to open), and return
the corresponding store in @var{store}.  @var{classes} is used to select
classes specified by the type name; if it is zero,
@var{store_std_classes} is used.
@end deftypevar

@deftypevar error_t store_gunzip_create (@w{struct store *@var{from}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} which contains a snapshot of the
uncompressed contents of the store @var{from}; @var{from} is consumed.
@var{block_size} is the desired block size of the result.
@end deftypevar

@subsubsection @code{concat} store
@cindex @code{concat} store

@cindex linear concatenation
@cindex appending disks
@cindex disks, appending
@cindex disk concatenation
@cindex concatenation, disk
@deftypevar {extern const struct store_class} store_concat_class
This class provides a linear concatenation storage mode.  It creates a
new virtual store which consists of several different substores appended
to one another.

This mode is designed to increase storage capacity, so that when one
substore is filled, new data is transparently written to the next
substore.  Concatenation requires robust hardware, since a failure in
any single substore will wipe out a large section of the data.
@end deftypevar

@deftypefun error_t store_concat_open (@w{const char *@var{name}}, @w{int @var{flags}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{store}})
Return a new store that concatenates the stores created by opening all
the individual stores described in @var{name}; for the syntax of
@var{name}, see @code{store_open_children}.
@end deftypefun

@deftypefun error_t store_concat_create (@w{struct store * const *@var{stores}}, @w{size_t @var{num_stores}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} that concatenates all the stores in
@var{stores} (@var{num_stores} of them).  The stores in @var{stores} are
consumed; that is, they will be freed when this store is freed.  The
@var{stores} @emph{array}, however, is copied, and so should be freed by
the caller.
@end deftypefun

@subsubsection @code{ileave} store
@cindex @code{ileave} store

@cindex RAID-0
@cindex striping, disk
@cindex disk striping
@cindex interleaving disks
@cindex disks, interleaving
@deftypevar {extern const struct store_class} store_ileave_class
This class provides a RAID-0@footnote{RAID is a @dfn{Redundant Array of
Independent Disks}, which refers to the idea of using several disks in
parallel in order to achieve increased capacity, redundancy and/or
performance.} storage mode (also called @dfn{disk striping}).  It
creates a new virtual store by interleaving the contents of several
different substores.

This RAID mode is designed to increase storage performance, since I/O
will probably occur in parallel if the substores reside on different
physical devices.  Interleaving works best with evenly-yoked
substores@dots{} if the stores are different sizes, some space will be
not be used at the end of the larger stores; if the stores are different
speeds, then I/O will have to wait for the slowest store; if some stores
are not as reliable as others, failures will wipe out every @var{n}th
storage block, where @var{n} is the number of substores.
@end deftypevar

@deftypefun error_t store_ileave_create (@w{struct store * const *@var{stripes}}, @w{size_t @w{num_stripes}}, @w{off_t @var{interleave}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} that interleaves all the stores in
@var{stripes} (@var{num_stripes} of them) every @var{interleave} bytes;
@var{interleave} must be an integer multiple of each stripe's block
size.  The stores in @var{stripes} are consumed; that is, they will be
freed when this store is freed.  The @var{stripes} @emph{array},
however, is copied, and so should be freed by the caller.
@end deftypefun

@subsubsection @code{mvol} store
@cindex @code{mvol} store

@deftypevar {extern const struct store_class} store_mvol_class
This store provides access to multiple volumes using a single-volume
device.  One use of this store would be to provide a store which
consists of multiple floppy disks when there is only a single disk
drive.  It works by remapping a single linear address range to multiple
address ranges, and keeping track of the currently active range.
Whenever a request maps to a range that is not active, a callback is
made in order to switch to the new range.

This class is not included in @var{store_std_classes}, because it
requires an application-specific callback.
@end deftypevar

@deftypefun error_t store_mvol_create (@w{struct store *@var{phys}}, error_t (*@var{swap_vols}) (@w{struct store *@var{store}}, @w{size_t @var{new_vol}}, @w{ssize_t @var{old_vol}}), @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} that multiplexes multiple physical
volumes from @var{phys} as one larger virtual volume.  @var{swap_vols}
is a function that will be called whenever reads or writes refer to a
block which is not on addressable on the currently active volume.
@var{phys} is consumed.
@end deftypefun

@subsubsection @code{remap} store
@pindex @code{remap} store

@deftypevar {extern const struct store_class} store_remap_class
This store translates I/O requests into different addresses on a
different store.
@end deftypevar

@deftypefun error_t store_remap_create (@w{struct store *@var{source}}, @w{const struct store_run *@var{runs}}, @w{size_t @var{num_runs}}, @w{int @var{flags}}, @w{struct store **@var{store}})
Return a new store in @var{store} that reflects the blocks in @var{runs}
and @var{runs_len} from @var{source}; @var{source} is consumed, but
@var{runs} is not.  Unlike the @code{store_remap} function, this
function always operates by creating a new store of type @samp{remap}
which has @var{source} as a child, and so may be less efficient than
@w{store_remap} for some types of stores.
@end deftypefun


@node Store RPC Encoding
@subsection Store RPC Encoding

The store library also provides some functions which help transfer
stores between tasks via RPC:

@deftypevr {Structure} struct store_enc
This structure is used to hold the various bits that make up the
representation of a store for transmission via RPC.  See
@code{<hurd/hurd_types.h>} for an explanation of the encodings for the
various storage types.
@end deftypevr

@deftypefun void store_enc_init (@w{struct store_enc *@var{enc}}, @w{mach_port_t *@var{ports}}, @w{mach_msg_type_number_t @var{num_ports}}, @w{int *@var{ints}}, @w{mach_msg_type_number_t @var{num_ints}}, @w{off_t *@var{offsets}}, @w{mach_msg_type_number_t @var{num_offsets}}, @w{char *@var{data}}, @w{mach_msg_type_number_t @var{data_len}})
Initialize @var{enc}.  The given vector and sizes will be used for the
encoding if they are big enough (otherwise new ones will be
automatically allocated).
@end deftypefun

@deftypefun void store_enc_dealloc (@w{struct store_enc *@var{enc}})
Deallocate storage used by the fields in @var{enc} (but nothing is done
with @var{enc} itself).
@end deftypefun

@deftypefun void store_enc_return (@w{struct store_enc *@var{enc}}, @w{mach_port_t **@var{ports}}, @w{mach_msg_type_number_t *@var{num_ports}}, @w{int **@var{ints}}, @w{mach_msg_type_number_t *@var{num_ints}}, @w{off_t **@var{offsets}}, @w{mach_msg_type_number_t *@var{num_offsets}}, @w{char **@var{data}}, @w{mach_msg_type_number_t *@var{data_len}})
Copy out the parameters from @var{enc} into the given variables suitably
for returning from a @code{file_get_storage_info} RPC, and deallocate
@var{enc}.
@end deftypefun

@deftypefun error_t store_return (@w{const struct store *@var{store}}, @w{mach_port_t **@var{ports}}, @w{mach_msg_type_number_t *@var{num_ports}}, @w{int **@var{ints}}, @w{mach_msg_type_number_t *@var{num_ints}}, @w{off_t **@var{offsets}}, @w{mach_msg_type_number_t *@var{num_offsets}}, @w{char **@var{data}}, @w{mach_msg_type_number_t *@var{data_len}})
Encode @var{store} into the given return variables, suitably for
returning from a @code{file_get_storage_info} RPC.
@end deftypefun

@deftypefun error_t store_encode (@w{const struct store *@var{store}}, @w{struct store_enc *@var{enc}})
Encode @var{store} into @var{enc}, which should have been prepared with
@code{store_enc_init}, or return an error.  The contents of @var{enc}
may then be returned as the value of @code{file_get_storage_info}; if
for some reason this can't be done, @code{store_enc_dealloc} may be used
to deallocate the mmemory used by the unsent vectors.
@end deftypefun

@deftypefun error_t store_decode (@w{struct store_enc *@var{enc}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{store}})
Decode @var{enc}, either returning a new store in @var{store}, or an
error.  @var{classes} the mapping from Hurd storage class ids to store
classes; if it is zero, @var{store_std_classes} is used.  If nothing
else is to be done with @var{enc}, its contents may then be freed using
@code{store_enc_dealloc}.
@end deftypefun

@deftypefun error_t store_allocate_child_encodings (@w{const struct store *@var{store}}, @w{struct store_enc *@var{enc}})
Calls the @code{allocate_encoding} method in each child store of
@var{store}, propagating any errors.  If any child does not have such a
method, @code{EOPNOTSUPP} is returned.
@end deftypefun

@deftypefun error_t store_encode_children (@w{const struct store *@var{store}}, @w{struct store_enc *@var{enc}})
Calls the encode method in each child store of @var{store}, propagating
any errors.  If any child does not hae such a method, @code{EOPNOTSUPP}
is returned.
@end deftypefun

@deftypefun error_t store_decode_children (@w{struct store_enc *@var{enc}}, @w{int @var{num_children}}, @w{const struct store_class *const *@var{classes}}, @w{struct store **@var{children}})
Decodes @var{num_children} from @var{enc}, storing the results into
successive positions in @var{children}.
@end deftypefun

@deftypefun error_t store_with_decoded_runs (@w{struct store_enc *@var{enc}}, @w{size_t @var{num_runs}}, error_t (*@var{fun}) (@w{const struct store_run *@var{runs}}, @w{size_t @var{num_runs}}))
Call @var{fun} with the vector @var{runs} of length @var{num_runs}
extracted from @var{enc}.
@end deftypefun

@deftypefun error_t store_std_leaf_allocate_encoding (@w{const struct store *@var{store}}, @w{struct store_enc *@var{enc}})
@deftypefunx error_t store_std_leaf_encode (@w{const struct store *@var{store}}, @w{struct store_enc *@var{enc}})
Standard encoding used for most data-providing (as opposed to filtering)
store classes.
@end deftypefun

@deftypefn {Typedef} {typedef error_t (*} store_std_leaf_create_t )(@w{mach_port_t @var{port}}, @w{int @var{flags}}, @w{size_t @var{block_size}}, @w{const struct store_run *@var{runs}}, @w{size_t @var{num_runs}}, @w{struct store **@var{store}})
Creation function used by @code{store_std_leaf_decode}.
@end deftypefn

@deftypefun error_t store_std_leaf_decode (@w{struct store_enc *@var{enc}}, @w{store_std_leaf_create_t @var{create}}, @w{struct store **@var{store}})
Decodes the standard leaf encoding which is common to various builtin
formats, and calls @var{create} to actually create the store.
@end deftypefun


@node Stored Filesystems
@chapter Stored（FIXME-J:ストアード？）ファイルシステム
@c @chapter Stored Filesystems
@cindex disk-based filesystems
@cindex filesystems, disk-based

Stored（FIXME-J:ストアード？）ファイルシステムにより、
ユーザはハード・ディスク、
フロッピ・ディスク、
CD-ROMのようなランダム・アクセス可能なメディアをターゲットにして、
パーシステント(永続的)なデータをセーブしたりロードしたりすることができる。
Stored（FIXME-J:ストアード？）ファイルシステムは、
スタンドアロンなワークステーションをbootstrap（FIXME-J:ブートストラップ？）する場合にも必要になる。
@c Stored filesystems allow users to save and load persistent data from any
@c random-access storage media, such as hard disks, floppy diskettes, and
@c CD-ROMs.  Stored filesystems are required for bootstrapping standalone
@c workstations, as well.

@menu
* Repairing Filesystems::       軽いファイルシステム・クラッシュからの回復。
* Linux Extended 2 FS::         ポピュラーなLinuxファイルシステム・フォーマット。
* BSD Unix FS::                 BSD Unix 4.xのFast File System。
* ISO-9660 CD-ROM FS::          標準的なCD-ROMフォーマット。
* Diskfs Library::              新しいファイルシステム・サーバの実装。
@end menu


@node Repairing Filesystems
@section ファイルシステムの修復
@c @section Repairing Filesystems
@pindex fsck

FIXME: finish


@node Linux Extended 2 FS
@section Linux Extended 2 FS
@pindex ext2fs

FIXME: finish


@node BSD Unix FS
@section BSD Unix FS
@scindex ufs

FIXME: finish


@node ISO-9660 CD-ROM FS
@section ISO-9660 CD-ROM FS
@pindex isofs

FIXME: finish


@node Diskfs Library
@section Diskfsライブラリ
@c @section Diskfs Library
@scindex libdiskfs
@scindex diskfs.h

diskfsライブラリは@code{<hurd/diskfs.h>}に宣言されており、
stored（FIXME-J:ストアード？）ファイルシステムの実装に係わる多くの仕事を行っている。
@code{libdiskfs}は、
threads、ports、iohelp、fshelp、storeの各ライブラリを必要とする。
diskfsを使おうと試みる前に、
これらすべてのライブラリのことを理解するべきである。
また、
pagerライブラリについても熟知しているべきである(@pxref{Pager Library})。
@c The diskfs library is declared in @code{<hurd/diskfs.h>}, and does a lot
@c of the work of implementing stored filesystems.  @code{libdiskfs}
@c requires the threads, ports, iohelp, fshelp, and store libraries.  You
@c should understand all these libraries before you attempt to use diskfs,
@c and you should also be familiar with the pager library (@pxref{Pager
@c Library}).

@scindex libstorefs
昔からのしがらみで、
stored（FIXME-J:ストアード？）ファイルシステムを実装するライブラリは@code{libstorefs}ではなく@code{libdiskfs}と呼ばれている。
@c {{block-addressedは「ブロック単位にアドレス付けされる」で良いか？}}
しかしながら、
diskfsはI/Oを行うのにstoreライブラリを使っているので、
ブロック単位にアドレス付けされるものでさえあれば、
どのような記憶デバイス上に実装されているファイルシステムにとっても有用なものであるということを覚えておいていただきたい。
@c For historical reasons, the library for implementing stored filesystems
@c is called @code{libdiskfs} instead of @code{libstorefs}.  Keep in mind,
@c however, that diskfs is useful for filesystems which are implemented on
@c any block-addressed storage device, since it uses the store library to
@c do I/O.

diskfsのコールバック・インターフェイスは単純ではないので、
stored（FIXME-J:ストアード？）ファイルシステムを実装するのは手の込んだ作業となる可能性がある。
本当のところは、
ゼロから書き始めようとするよりも、
既存のファイルシステム・サーバのうち類似のもののソース・コードを調べて、
それを例として模倣するのが最も良いのである。
@c Note that stored filesystems can be tricky to implement, since the
@c diskfs callback interfaces are not trivial.  It really is best if you
@c examine the source code of a similar existing filesystem server, and
@c follow its example rather than trying to write your own from scratch.

@menu
* Diskfs Startup::              stored（FIXME-J:ストアード？）ファイルシステムの初期化。
* Diskfs Arguments::            コマンドライン引数の解析。
* Diskfs Globals::              グローバルな振る舞いの変更。
* Diskfs Node Management::      割り当て、リファレンス・カウンティング、
                                  キャッシング、その他のディスク・ノード・ルーチン。
* Diskfs Callbacks::            必須のユーザ定義diskfs関数。
* Diskfs Options::              任意選択のユーザ定義diskfs関数。
* Diskfs Internals::            diskfsの細部の再実装。
@end menu


@node Diskfs Startup
@subsection Diskfsスタートアップ
@c @subsection Diskfs Startup

このサブセクションでは、
ファイルシステム・サーバを実装する際の一般的なステップの概要を示す。
これはチュートリアルというよりはむしろ、
読者が記憶を新たにするのを助けたり、
解説を提供したりしようとするものである。
@c This subsection gives an outline of the general steps involved in
@c implementing a filesystem server, to help refresh your memory and to
@c offer explanations rather than to serve as a tutorial.

ファイルシステム・サーバが最初にしなければならないのは、
コマンドライン引数を解析することである
(@pxref{Diskfs Arguments})。
その後に、
それがブートストラップ・ファイルシステムであれば、
標準出力ストリームと標準エラー・ストリームをコンソールにリダイレクトして、
エラー・メッセージが失われることがないようにしなければならない。
@c {{これらのストリームをコンソールにリダイレクトするのは、ブートストラップ・ファイルシステムの場合だけ、という解釈で良いか？}}
@c The first thing a filesystem server should do is parse its command-line
@c arguments (@pxref{Diskfs Arguments}).  Then, the standard output and
@c error streams should be redirected to the console, so that error
@c messages are not lost if this is the bootstrap filesystem:

@deftypefun void diskfs_console_stdio (void)
エラー・メッセージがユーザに見えるようにコンソールへリダイレクトする。
@c Redirect error messages to the console, so that they can be seen by
@c users.
@end deftypefun

以下に、
サーバの初期化処理の残りの部分で呼出されるであろう関連する関数のリストを示す。
繰り返しになるが、
これらの関数がどのように使われるべきであるかという点に関してなにか疑問があるなら、
既に動いているファイルシステムの実装を参照するべきである。
@c The following is a list of the relevant functions which would be called
@c during the rest of the server initialization.  Again, you should refer
@c to the implementation of an already-working filesystem if you have any
@c questions about how these functions should be used:

@deftypefun error_t diskfs_init_diskfs (void)
引数の解析後に、ライブラリを初期化するためにこの関数を呼出す。
diskfsオプションの解析が終了したら、
他の任意のdiskfs関数を呼出す前に、
この関数を呼出さなければならない。
@c Call this function after arguments have been parsed to initialize the
@c library.  You must call this before calling any other diskfs functions,
@c and after parsing diskfs options.
@end deftypefun

@deftypefun void diskfs_spawn_first_thread (void)
(@code{diskfs_root_node}の設定を除く)
フォーマット固有のすべての初期化処理の完了後にこの関数を呼出す。
この時点で、
ページャを起動する準備ができているはずである。
@c Call this after all format-specific initialization is done (except for
@c setting @code{diskfs_root_node}); at this point the pagers should be
@c ready to go.
@end deftypefun

@deftypefun mach_port_t diskfs_startup_diskfs (@w{mach_port_t @var{bootstrap}}, @w{int @var{flags}})
ファイルシステムの初期化が完全に終了した後にこの関数を呼出す。
これは、
新しいファイルシステムcontrol port（FIXME-J:コントロール・ポート、制御ポート？）のことを親ファイルシステムに通知するためである。
もし@var{bootstrap}がセットされていれば、
diskfsはそのポートに対して適宜@code{fsys_startup}を呼出し、
その呼出しによって返された@var{realnode}を返す。
@var{bootstrap}がセットされていなければ、
この関数は@code{diskfs_start_bootstrap}を呼出し、
@code{MACH_PORT_NULL}を返す。
(O_*の集合の要素を値として取る)@var{flags}は、
@var{realnode}をどのようにオープンするかを指定する。
@c Call this once the filesystem is fully initialized, to advertise the new
@c filesystem control port to our parent filesystem.  If @var{bootstrap} is set,
@c diskfs will call @code{fsys_startup} on that port as appropriate and return
@c the @var{realnode} from that call; otherwise we call
@c @code{diskfs_start_bootstrap} and return @code{MACH_PORT_NULL}.
@c @var{flags} specifies how to open @var{realnode} (from the O_* set).
@end deftypefun

以下の関数を直接呼出す必要はないはずである。
なぜなら、
@code{diskfs_startup_diskfs}が必要に応じてこの関数を呼出してくれるからである。
@c You should not need to call the following function directly, since
@c @code{diskfs_startup_diskfs} will do it for you, when appropriate:

@deftypefun void diskfs_start_bootstrap (void)
このファイルシステムがあたかもブートストラップ・ファイルシステムであるかのように、
Hurdのbootstrap sequence（FIXME-J:ブートストラップ・シーケンス？）を開始する。
この関数を呼出す前に、
ファイルシステムの初期化処理はすべて完了していなければならない。
@c Start the Hurd bootstrap sequence as if we are the bootstrap filesystem
@c (that is, @code{diskfs_boot_flags} is nonzero).  All filesystem
@c initialization must be complete before you call this function.
@end deftypefun


@node Diskfs Arguments
@subsection Diskfs引数
@c @subsection Diskfs Arguments

以下の関数は、
argp (@pxref{Argp, , , libc, The GNU C Library Reference Manual})
を使って、
標準的なdiskfsコマンドライン引数と実行時引数の解析処理を実装している。
@c The following functions implement standard diskfs command-line and
@c runtime argument parsing, using argp (@pxref{Argp, , , libc, The GNU C
@c Library Reference Manual}):

@deftypefun error_t diskfs_set_options (@w{char *@var{argz}}, @w{size_t @var{argz_len}})
@var{argz}と@var{argz_len}により指定される実行時オプションを解析して実行する。
認識できないオプションがあれば@code{EINVAL}が返される。
このルーチンのデフォルトの定義では、
@code{diskfs_runtime_argp}を使用して実行時オプションが解析される。
@c Parse and execute the runtime options specified by @var{argz} and
@c @var{argz_len}.  @code{EINVAL} is returned if some option is
@c unrecognized.  The default definition of this routine will parse them
@c using @code{diskfs_runtime_argp}.
@end deftypefun

@deftypefun error_t diskfs_append_args (@w{char **@var{argz}}, @w{unsigned *@var{argz_len}})
mallocされた領域にある、
長さ@code{*@var{argz_len}}の文字列@code{*@var{argz}}の末尾に、
このトランスレータに渡された引数をNULで区切られたリストにしたものを追加する。
このルーチンのデフォルトの定義では、
単に@code{diskfs_append_std_options}が呼出される。
@c Append to the malloced string @code{*@var{argz}} of length
@c @code{*@var{argz_len}} a NUL-separated list of the arguments to this
@c translator.  The default definition of this routine simply calls
@c @code{diskfs_append_std_options}.
@end deftypefun

@deftypefun error_t diskfs_append_std_options (@w{char **@var{argz}}, @w{unsigned *@var{argz_len}})
標準的なdiskfsオプション状態を説明する情報とともに、
NULで区切られたオプションを@var{argz}の@emph{末尾に追加}し、
@var{argz_len}の値を適宜増加させる。
@code{diskfs_get_options}とは異なり、
@var{argz}と@var{argz_len}には既にまともな値が入っていなければならない点に注意すること。
@c @emph{Appends} NUL-separated options describing the standard diskfs
@c option state to @var{argz} and increments @var{argz_len} appropriately.
@c Note that unlike @code{diskfs_get_options}, @var{argz} and
@c @var{argz_len} must already have sane values.
@end deftypefun

@deftypevar {struct argp *} diskfs_runtime_argp
これが定義されているか、
もしくは、
argp構造体を指すようセットされていると、
デフォルトの@code{diskfs_set_options}が実行時オプションの解析処理にこれを使うことになる。
デフォルトの定義では、
@code{diskfs_std_runtime_argp}へのポインタとして初期化されている。
@c If this is defined or set to an argp structure, it will be used by the
@c default @code{diskfs_set_options} to handle runtime option parsing.  The
@c default definition is initialized to a pointer to
@c @code{diskfs_std_runtime_argp}.
@end deftypevar

@deftypevar {const struct argp} diskfs_std_runtime_argp
標準的なdiskfs実行時オプション用のargp。
@code{diskfs_runtime_argp}のデフォルトの定義はこれを指す。
ただし、
ユーザがこれを独自のargpにつなぐよう再定義することは可能である。
@c An argp for the standard diskfs runtime options.  The default definition
@c of @code{diskfs_runtime_argp} points to this, although the user can
@c redefine that to chain this onto his own argp.
@end deftypevar

@deftypevar {const struct argp} diskfs_startup_argp
標準的なdiskfsコマンドライン引数用のargp構造体。
ユーザは、
コマンドラインを解析するためにこれを使用して@code{argp_parse}を呼出すこともできるし、
これを独自のargp構造体の末尾につなぐこともできる。
また、
これを完全に無視することもできる。
@c An argp structure for the standard diskfs command line arguments.  The
@c user may call @code{argp_parse} on this to parse the command line, chain
@c it onto the end of his own argp structure, or ignore it completely.
@end deftypevar

@deftypevar {const struct argp} diskfs_store_startup_argp
標準的なdiskfsコマンドライン引数用、
および、
store specification（FIXME-J:指定、仕様？）用のargp構造体。
結果として作成される@code{struct store_parsed}構造体を返すべき場所のアドレスが、
@code{argp_parse}への入力引数として渡されなければならない。
FIXME xref the declaration for STORE_ARGP.
@c An argp structure for the standard diskfs command line arguments plus a
@c store specification.  The address of a location in which to return the
@c resulting @code{struct store_parsed} structure should be passed as the
@c input argument to @code{argp_parse}; FIXME xref the declaration for
@c STORE_ARGP.
@end deftypevar


@node Diskfs Globals
@subsection Diskfsグローバル関数、グローバル変数
@c @subsection Diskfs Globals

以下の関数や変数は、
このライブラリの全般的な振舞いを制御する。
あなたの書くコールバック関数はこれらを参照する必要があるかもしれないが、
これらを変更したり再定義したりする必要はないはずである。
@c The following functions and variables control the overall behaviour of
@c the library.  Your callback functions may need to refer to these, but
@c you should not need to modify or redefine them.

@deftypevar mach_port_t diskfs_default_pager
@deftypevarx mach_port_t diskfs_exec_ctl
@deftypevarx mach_port_t diskfs_exec
@deftypevarx auth_t diskfs_auth_server_port
これらはそれぞれ、
デフォルト・ページャ、
execserverのcontrol port（FIXME-J:コントロール・ポート、制御ポート？）、
execserverそれ自身、
authserverへのsend rights（FIXME-J:センド・ライト？）である。
@c These are the respective send rights to the default pager, execserver
@c control port, execserver itself, and authserver.
@end deftypevar

@deftypevar mach_port_t diskfs_fsys_identity
ファイルシステムの@code{io_identity} identity port（FIXME-J:アイデンティティ・ポート？）。
@c The @code{io_identity} identity port for the filesystem.
@end deftypevar

@deftypevar {char **} diskfs_argv
デフォルトの引数パーサによりセットされた、
diskfsの起動コマンドライン。
あなたが引数パーサを使わないのであれば、
これを自分でセットすること。
@c {{itは引数パーサで良いか？}}
これはprocserverに与えるために、
ブートストラップ・ファイルシステムによってのみ使用される。
@c The command line diskfs was started, set by the default argument parser.
@c If you don't use it, set this yourself.  This is only used for bootstrap
@c file systems, to give the procserver.
@end deftypevar

@deftypevar {char *} diskfs_boot_flags
ブートストラップ・ファイルシステムの場合、
カーネルから渡されたコマンドライン・オプション。
ブートストラップ・ファイルシステムでない場合は、
この２つのケースを区別するのに使えるようゼロが入る。
@c When this is a bootstrap filesystem, the command line options passed from
@c the kernel.  If not a bootstrap filesystem, it is zero, so it can be used to
@c distinguish between the two cases.
@end deftypevar

@deftypevar {struct rwlock} diskfs_fsys_lock
ファイルシステム・レベルの操作を行っている間はこのロックを保有すること。
特に害のない操作を行うユーザは単にreader lock（FIXME-J）を保有するだけで良いが、
他のスレッドに悪影響を及ぼす可能性のある操作ではwriter lock（FIXME-J）を保有するべきである。
@c Hold this lock while doing filesystem-level operations.  Innocuous users
@c can just hold a reader lock, but operations that might corrupt other
@c threads should hold a writer lock.
@end deftypevar

@deftypevar {volatile struct mapped_time_value *} diskfs_mtime
diskfsルーチンによって使用されている現在のシステム時刻。
これは、
Cのライブラリ関数@code{maptime_read}によって@code{struct timeval}に変換される(FIXME xref)。
@c The current system time, as used by the diskfs routines.  This is
@c converted into a @code{struct timeval} by the @code{maptime_read}
@c C library function (FIXME xref).
@end deftypevar

@deftypevar int diskfs_synchronous
すべての操作が同期的に行われなければならない場合のみ真となる。
これがセットされている場合、
アロケーション（FIXME-J:割当て？）情報が永遠に同期されるようにするのはフォーマット固有のコードの責任である。
これ以外のことはフォーマット非依存のコードにより実行される。
@c True if and only if we should do every operation synchronously.  It
@c is the format-specific code's responsibility to keep allocation
@c information permanently in sync if this is set; the rest will
@c be done by format-independent code.
@end deftypevar

@deftypefun error_t diskfs_set_sync_interval (@w{int @var{interval}})
@var{interval}秒ごとにファイルシステムに対してsync（FIXME-J）を実行するため、
スレッドを生成する。
@var{interval}がゼロの場合は、
スレッドの生成を行わない。
スレッドの生成時にエラーが発生した場合は、
エラー値が返される。
エラーが発生しなかった場合はゼロが返される。
２回目以降の呼出し時にも新しいスレッドが生成され、
古いスレッドは(最終的には)取り除かれる。
いずれにしろ古いスレッドはこれ以上sync（FIXME-J）を実行することはない。
@c Establish a thread to sync the filesystem every @var{interval} seconds,
@c or never, if @var{interval} is zero.  If an error occurs creating the
@c thread, it is returned, otherwise zero.  Subsequent calls will create a
@c new thread and (eventually) get rid of the old one; the old thread won't
@c do any more syncs, regardless.
@end deftypefun

@deftypevar spin_lock_t diskfs_node_refcnt_lock
ページャのリファレンス・カウント・ロック。
@c Pager reference count lock.
@end deftypevar

@deftypevar int diskfs_readonly
ファイルシステムが現在書込み可能であればゼロがセットされる。
@c Set to zero if the filesystem is currently writable.
@end deftypevar

@deftypefun error_t diskfs_set_readonly (@w{int @var{readonly}})
アクティブなファイルシステムのモードを、
読込みのみ可能なモード、
もしくは、
書込み可能なモードに変更する。
同時に現在のモードを反映するようグローバル変数@var{diskfs_readonly}をセットする。
エラーが返された場合は、
何も変更されていない。
このルーチンを呼出している間は、
@var{diskfs_fsys_lock}を保有していなければならない。
@c Change an active filesystem between read-only and writable modes,
@c setting the global variable @var{diskfs_readonly} to reflect the current
@c mode.  If an error is returned, nothing will have changed.
@c @var{diskfs_fsys_lock} should be held while calling this routine.
@end deftypefun

@deftypefun int diskfs_check_readonly (void)
ファイルシステムに書込みを行う操作の前に、
そのファイルシステムが読込みのみ可能かどうかをチェックする。
読込みのみ可能であればゼロ以外の値を返し、
そうでなければゼロを返す。
@c Check if the filesystem is readonly before an operation that writes it.
@c Return nonzero if readonly, otherwise zero.
@end deftypefun

@deftypefun error_t diskfs_remount (void)
すべてのin-core（FIXME-J）データ構造をディスクから再度読込む。
この関数の呼出しは、
@var{diskfs_readonly}が真である場合しか成功することはありえない。
このルーチンを呼出している間は、
@var{diskfs_fsys_lock}を保有していなければならない。
@c Reread all in-core data structures from disk.  This function can only be
@c successful if @var{diskfs_readonly} is true.  @var{diskfs_fsys_lock}
@c should be held while calling this routine.
@end deftypefun

@deftypefun error_t diskfs_shutdown (@w{int @var{flags}})
ファイルシステムをシャットダウンする。
@var{flags}の意味は、
@code{fsys_shutdown}の場合と同様である。
@c Shutdown the filesystem; @var{flags} are as for @code{fsys_shutdown}.
@end deftypefun


@node Diskfs Node Management
@subsection Diskfsノード管理
@c @subsection Diskfs Node Management

すべてのファイルやディレクトリはdiskfs@dfn{ノード}である。
以下の関数は、
あなたの書いたdiskfsコールバックがノードやノードへのreference（FIXME-J:リファレンス、参照？）を管理するのを支援してくれるものである。
@c Every file or directory is a diskfs @dfn{node}.  The following functions
@c help your diskfs callbacks manage nodes and their references:

@deftypefun void diskfs_drop_node (@w{struct node *@var{np}})
ノード@var{np}はもはやreference（FIXME-J:リファレンス、参照？）を持たないので、
すべてをクリーンな（FIXME-J）状態にする。
@var{diskfs_node_refcnt_lock}は保有されていなければならず、
この関数から復帰する際に解放される。
@var{np}はロックされていなければならない。
@c Node @var{np} now has no more references; clean all state.  The
@c @var{diskfs_node_refcnt_lock} must be held, and will be released upon
@c return.  @var{np} must be locked.
@end deftypefun

@deftypefun void diskfs_node_update (@w{struct node *@var{np}}, @w{int @var{wait}})
@code{@var{np}->dn_stat}の情報を使用して、
disk fields（FIXME-J:ディスク・フィールド？）をセットする。
必要であればctime、atime、mtimeを更新する。
@var{wait}が真であれば、
物理的なメディアの更新が完全に終了するまで復帰しない。
@c Set disk fields from @code{@var{np}->dn_stat}; update ctime, atime, and mtime
@c if necessary.  If @var{wait} is true, then return only after the
@c physical media has been completely updated.
@end deftypefun

@deftypefun void diskfs_nref (@w{struct node *@var{np}})
ノード@var{np}に対してhard reference（FIXME-J）を追加する。
ノードにhard reference（FIXME-J）があらかじめ存在しない場合、
そのノードをロックすることはできない
(なぜなら、
ロックを保有するためにはhard reference（FIXME-J）を保有していなければならないのであるから)。
@c Add a hard reference to node @var{np}.  If there were no hard references
@c previously, then the node cannot be locked (because you must hold a hard
@c reference to hold the lock).
@end deftypefun

@deftypefun void diskfs_nput (@w{struct node *@var{np}})
ノード@var{np}のロックを解除し、
hard reference（FIXME-J）を解放する。
これが最後のhard reference（FIXME-J）であり、
かつ、
そのファイルに対するリンクが存在しなければ、
light reference（FIXME-J）を除去するよう要求する。 
@c Unlock node @var{np} and release a hard reference; if this is the last
@c hard reference and there are no links to the file then request light
@c references to be dropped.
@end deftypefun

@deftypefun void diskfs_nrele (@w{struct node *@var{np}})
@var{np}のhard reference（FIXME-J）を解放する。
@var{np}が何者かによってロックされていれば、
これが最後のhard reference（FIXME-J）であることはありえない
(なぜなら、
ロックを保有するためにはhard reference（FIXME-J）を保有していなければならないのであるから)。
これが最後のhard reference（FIXME-J）であり、
かつ、
リンクが存在しなければ、
light reference（FIXME-J）を除去するよう要求する。 
@c Release a hard reference on @var{np}.  If @var{np} is locked by anyone,
@c then this cannot be the last hard reference (because you must hold a
@c hard reference in order to hold the lock).  If this is the last hard
@c reference and there are no links, then request light references to be
@c dropped.
@end deftypefun

@deftypefun void diskfs_nref_light (@w{struct node *@var{np}})
ノードに対してlight reference（FIXME-J）を追加する。
@c Add a light reference to a node.
@end deftypefun

@deftypefun void diskfs_nput_light (@w{struct node *@var{np}})
ノード@var{np}のロックを解除し、
light reference（FIXME-J）を解放する。
@c Unlock node @var{np} and release a light reference.
@end deftypefun

@deftypefun void diskfs_nrele_light (@w{struct node *@var{np}})
@var{np}に対するlight reference（FIXME-J）を解放する。
@var{np}が何者かによってロックされていれば、
これが最後のreference（FIXME-J:リファレンス、参照？）であることはありえない
(なぜなら、
ロックを保有するためにはhard reference（FIXME-J）を保有していなければならないのであるから)。
@c Release a light reference on @var{np}.  If @var{np} is locked by anyone,
@c then this cannot be the last reference (because you must hold a hard
@c reference in order to hold the lock).
@end deftypefun

@deftypefun error_t diskfs_node_rdwr (@w{struct node *@var{np}}, @w{char *@var{data}}, @w{off_t @var{off}}, @w{size_t @var{amt}}, @w{int @var{direction}}, @w{struct protid *@var{cred}}, @w{size_t *@var{amtread}})
これは、
ファイルの読み書きを行う場合や自動的なファイル・サイズの拡張が必要である場合に、
他のファイルシステム・ルーチンから呼出されるものである。
@var{np}は読み書きされるノードであり、
ロックされていなければならない。
@var{data}の指すデータがファイルに書込まれたり、
あるいは、
ファイルから読込まれたデータが@var{data}の指す領域に書込まれたりする。
@var{off}は、
I/Oが実際に行われるべきファイル中の場所を示す
(負の値は許されない)。
@var{amt}は@var{data}のサイズであり、
どれだけのデータをコピーするべきかを示す。
@var{dir}は、
読込みの場合はゼロであり、
書込みの場合はゼロ以外の値である。
@var{cred}は、
アクセスを行っているユーザを示す
(ファイルを拡張しようとする試みの正当性を判断するためだけに使われる)。
読込みの場合、
実際に読込まれたデータのサイズが@code{*@var{amtread}}に入れられる。
@c This is called by other filesystem routines to read or write files, and
@c extends them automatically, if necessary.  @var{np} is the node to be
@c read or written, and must be locked.  @var{data} will be written or
@c filled.  @var{off} identifies where in the file the I/O is to take place
@c (negative values are not allowed).  @var{amt} is the size of @var{data}
@c and tells how much to copy.  @var{dir} is zero for reading or nonzero
@c for writing.  @var{cred} is the user doing the access (only used to
@c validate attempted file extension).  For reads, @code{*@var{amtread}} is
@c filled with the amount actually read.
@end deftypefun

@deftypefun void diskfs_notice_dirchange (@w{struct node *@var{dp}}, @w{enum dir_changed_type @var{type}}, @w{char *@var{name}})
@code{dir_notice_changes}によってディレクトリ@var{dp}に関するnotification（FIXME-J）を要求したユーザに対して、
notification（FIXME-J）を送信する。
変更の種類と変更により影響を受けた名前が、
それぞれ@var{type}と@var{name}である。
これは、
@code{diskfs_direnter}、@code{diskfs_dirremove}、@code{diskfs_dirrewrite}、
および、
そのディレクトリを変更する任意の関数から、
その変更が完全に終了した後に呼出されるべきものである。
@c Send notifications to users who have requested them for directory
@c @var{dp} with @code{dir_notice_changes}.  The type of modification and
@c affected name are @var{type} and @var{name} respectively.  This should
@c be called by @code{diskfs_direnter}, @code{diskfs_dirremove},
@c @code{diskfs_dirrewrite}, and anything else that changes the directory,
@c after the change is fully completed.
@end deftypefun

@deftypefun {struct node *} diskfs_make_node (@w{struct disknode *@var{dn}})
@var{dn}を物理的なdisknode（FIXME-J）とする新しいnode構造体を作成する。
@c @var{ds}は@var{dn}の誤り（のはず）。
新しく作成されたノード（node）は、
hard reference（FIXME-J）を１個持ち、
light reference（FIXME-J）は持たない。
@c Create a new node structure with @var{ds} as its physical disknode.  The
@c new node will have one hard reference and no light references.
@end deftypefun

以下のノード操作関数群は一般的には有用ではないが、
diskfs関数を再定義する必要がある場合には便利であるかもしれない。
@c These next node manipulation functions are not generally useful, but may
@c come in handy if you need to redefine any diskfs functions.

@deftypefun error_t diskfs_create_node (@w{struct node *@var{dir}}, @w{char *@var{name}}, @w{mode_t @var{mode}}, @w{struct node **@var{newnode}}, @w{struct protid *@var{cred}}, @w{struct dirstat *@var{ds}})
新しいノードを作成し、
そのモードを@var{mode}とする。
@var{mode}に@code{IFDIR}が含まれていれば、
新しいディレクトリ中の@file{.}と@file{..}も初期化する。
作成されたノードは@var{npp}に入れて返す。
@var{cred}は、
この関数の呼出しに責任を負うユーザを識別する。
@var{name}がゼロ以外の値であれば、
新しく作成されたノードを@var{name}という名前で@var{dir}にリンクする。
@var{ds}は、
ノード作成のために事前に呼出された@code{diskfs_lookup}の結果である
(@var{dir}は、
@code{diskfs_lookup}の呼出し以降ロックされたままである)。
@var{dir}は、
少なくともディスク・アロケーション（FIXME-J:割当て？）方針のヒントとして、
常にこの関数に渡されなければならない。
@c Create a new node.  Give it @var{mode}: if @var{mode} includes
@c @code{IFDIR}, also initialize @file{.} and @file{..} in the new
@c directory.  Return the node in @var{npp}.  @var{cred} identifies the
@c user responsible for the call.  If @var{name} is nonzero, then link the
@c new node into @var{dir} with name @var{name}; @var{ds} is the result of
@c a prior @code{diskfs_lookup} for creation (and @var{dir} has been held
@c locked since).  @var{dir} must always be provided as at least a hint for
@c disk allocation strategies.
@end deftypefun

@deftypefun void diskfs_set_node_times (@w{struct node *@var{np}})
@code{@var{np}->dn_set_ctime}がセットされていれば、
しかるべく@code{@var{np}->dn_stat.st_ctime}を変更する。
atimeとmtimeについても同じような操作を行う。
@c If @code{@var{np}->dn_set_ctime} is set, then modify
@c @code{@var{np}->dn_stat.st_ctime} appropriately; do the analogous
@c operations for atime and mtime as well.
@end deftypefun

@deftypefun {struct node *} diskfs_check_lookup_cache (@w{struct node *@var{dir}}, @w{char *@var{name}})
キャッシュの中から@var{dir}の中の@var{name}を探す。
既知の範囲でそのようなエントリが存在しなければゼロを返す。
@c {{ゼロを返すのは条件を満足しないものも含めて、エントリというものが１つも存在しない場合、という解釈の方が正しいか？}}
そのようなエントリが存在しないことが確実であれば-1を返す。
これ以外の場合は、
新しく割当てられたreference（FIXME-J:リファレンス、参照？）とともに、
エントリに対応する@var{np}を返す。
@c Scan the cache looking for @var{name} inside @var{dir}.  If we don't
@c know any entries at all, then return zero.  If the entry is confirmed to
@c not exist, then return -1.  Otherwise, return @var{np} for the entry,
@c with a newly-allocated reference.
@end deftypefun

@deftypefun error_t diskfs_cached_lookup (@w{int @var{cache_id}}, @w{struct node **@var{npp}})
@code{*@var{npp}}の中の@var{cache_id}に対応するノードを返す。
@c Return the node corresponding to @var{cache_id} in @code{*@var{npp}}.
@end deftypefun

@deftypefun void diskfs_enter_lookup_cache (@w{struct node *@var{dir}}, @w{struct node *@var{np}}, @w{char *@var{name}})
ノード@var{np}は、
@var{dir}の中で@var{name}という名前で見つけられたものである。
@var{np}がNULLであれば、
この名前のエントリがディレクトリの中に存在しないことが確認されたということを意味する。
@c Node @var{np} has just been found in @var{dir} with @var{name}.  If
@c @var{np} is null, that means that this name has been confirmed as absent
@c in the directory.
@end deftypefun

@deftypefun void diskfs_purge_lookup_cache (@w{struct node *@var{dp}}, @w{struct node *@var{np}})
ディレクトリ@var{dp}の中のノードとして@var{np}を参照する、
キャッシュ内のすべてのreference（FIXME-J:リファレンス、参照？）を除去する。
@c Purge all references in the cache to @var{np} as a node inside directory
@c @var{dp}.
@end deftypefun


@node Diskfs Callbacks
@subsection Diskfsコールバック
@c @subsection Diskfs Callbacks

ほかのいくつかのHurdライブラリと同様、
@code{libdiskfs}もあなたがアプリケーション固有のコールバック関数を実装することをあてにしている。
あなたは以下の関数と変数を定義@emph{しなければならない}。
また、
いくつかのdiskfsオプションのデフォルト値は、
良いファイルシステム・サポートを提供するためには変更するべきであるので、
@ref{Diskfs Options}も参照するべきである。
@c Like several other Hurd libraries, @code{libdiskfs} depends on you to
@c implement application-specific callback functions.  You @emph{must}
@c define the following functions and variables, but you should also look
@c at @ref{Diskfs Options}, as there are several defaults which should be
@c modified to provide good filesystem support:

@deftypevr {Structure} struct dirstat
この型はあなたが定義しなければならない。
この型が、
@code{diskfs_lookup}の呼出しから@code{diskfs_direnter}、@code{diskfs_dirremove}、@code{diskfs_dirrewrite}のいずれか１つの呼出しまでの間、
情報を保有することになる。
これらの呼出しが以下に説明するように機能するために十分な情報が、
この型の中に保持されなければならない。
@c You must define this type, which will hold information between a call to
@c @code{diskfs_lookup} and a call to one of @code{diskfs_direnter},
@c @code{diskfs_dirremove}, or @code{diskfs_dirrewrite}.  It must contain
@c enough information so that those calls work as described below.
@end deftypevr

@deftypevar size_t diskfs_dirstat_size
これは@code{struct dirstat}のバイト単位のサイズでなければならない。
@c This must be the size in bytes of a @code{struct dirstat}.
@end deftypevar

@deftypevar int diskfs_link_max
これは、
１個のファイルに対して存在することのできるリンクの最大個数であり、
正の整数でなければならない。
@code{dir_rename}の実装は、
許されるリンク数がただの１個である場合に処理を成功させる方法を知らない。
そのようなフォーマットの場合、
あなたは自分で@code{dir_rename}を再実装する必要がある。
@c This is the maximum number of links to any one file, which must be a
@c positive integer.  The implementation of @code{dir_rename} does not know
@c how to succeed if this is only one allowed link; on such formats you
@c need to reimplement @code{dir_rename} yourself.
@end deftypevar

@deftypevar int diskfs_maxsymlinks
これは、
１回の@code{dir_pathtrans}の呼出しでたどることのできるシンボリック・リンクの最大数を示す正の整数である。
この値を超過すると、
@code{dir_pathtrans}は@code{ELOOP}を返すことになる。
@c This variable is a positive integer which is the maximum number of
@c symbolic links which can be traversed within a single call to
@c @code{dir_pathtrans}.  If this is exceeded, @code{dir_pathtrans} will
@c return @code{ELOOP}.
@end deftypevar

@deftypevar {struct node *} diskfs_root_node
ここにはファイルシステムのルート・ノードをセットする。
@c Set this to be the node of the root of the filesystem.
@end deftypevar

@deftypevar {char *} diskfs_server_name
ここにはファイルシステム・サーバの名前をセットする。
@c Set this to the name of the filesystem server.
@end deftypevar

@deftypevar {char *} diskfs_server_version
ここにはサーバのバージョンを示す文字列をセットする。
@c Set this to be the server version string.
@end deftypevar

@deftypevar {char *} diskfs_disk_name
これは、
このファイルシステムが解釈している特定のディスクを何らかの形で識別する文字列でなければならない。
通常これは、
メッセージを表示したり、
同一のファイルシステム・タイプの複数のインスタンスを区別するためにのみ使用される。
このファイルシステムが外部メディアに一切アクセスしないのであれば、
これをゼロとして定義する。
@c This should be a string that somehow identifies the particular disk this
@c filesystem is interpreting.  It is generally only used to print messages
@c or to distinguish instances of the same filesystem type from one
@c another.  If this filesystem accesses no external media, then define
@c this to be zero.
@end deftypevar

@deftypefun error_t diskfs_set_statfs (@w{fsys_statfsbuf_t *@var{statfsbuf}})
ファイルシステムの現在の状態を反映するよう適切な値を@code{*@var{statfsbuf}}にセットする。
@c Set @code{*@var{statfsbuf}} with appropriate values to reflect the
@c current state of the filesystem.
@end deftypefun

@deftypefun error_t diskfs_lookup (@w{struct node *@var{dp}}, @w{char *@var{name}}, @w{enum lookup_type @var{type}}, @w{struct node **@var{np}}, @w{struct dirstat *@var{ds}}, @w{struct protid *@var{cred}})
@deftypefunx error_t diskfs_lookup_hard (@w{struct node *@var{dp}}, @w{char *@var{name}}, @w{enum lookup_type @var{type}}, @w{struct node **@var{np}}, @w{struct dirstat *@var{ds}}, @w{struct protid *@var{cred}})
あなたは@code{diskfs_lookup}を定義するべきではない。
なぜなら、
これは単に@code{diskfs_lookup_hard}に対するラッパーに過ぎず、
既に@code{libdiskfs}の中で定義されているからである。
@c You should not define @code{diskfs_lookup}, because it is simply a
@c wrapper for @code{diskfs_lookup_hard}, and is already defined in
@c @code{libdiskfs}.

(ロックされている)ディレクトリ@var{dp}の中で名前@var{name}を捜し出す(ルックアップする)。
@c {{後に「ルックアップ処理」、「ルックアップ関数」という言葉を使いたいので、ここで「ルックアップ」＝「捜し出すこと」という関係を示しておきたい。}}
@var{type}は、
@code{LOOKUP}、@code{CREATE}、@code{RENAME}、@code{REMOVE}のいずれかである。
@var{cred}は、
呼出しを行ったユーザを識別する。
@c Lookup in directory @var{dp} (which is locked) the name @var{name}.
@c @var{type} will either be @code{LOOKUP}, @code{CREATE}, @code{RENAME},
@c or @code{REMOVE}.  @var{cred} identifies the user making the call.

名前@var{name}が見つかればゼロを返し、
(@var{np}の値がゼロ以外であれば)
それに対応するノードを指すように@code{*@var{np}}をセットする
このノードはロックされなければならない。
その名前が見つからない場合は@code{ENOENT}を返し、
(@var{np}の値がゼロ以外であれば)
@code{*@var{np}}にゼロをセットする。
@var{np}がゼロであれば、
見つかったノードは一時的にであれロックされてはならない。
(見つかったノードに対するパーミションのチェックがしばしば実行されなければならない)
@code{REMOVE}と@code{RENAME}のためのルックアップの場合、
@var{np}は常にセットされる。
@c If the name is found, return zero, and (if @var{np} is nonzero) set
@c @code{*@var{np}} to point to the node for it, which should be locked.
@c If the name is not found, return @code{ENOENT}, and (if @var{np} is
@c nonzero) set @code{*@var{np}} to zero.  If @var{np} is zero, then the
@c node found must not be locked, not even transitorily.  Lookups for
@c @code{REMOVE} and @code{RENAME} (which must often check permissions on
@c the node being found) will always set @var{np}.

@var{ds}の値がゼロ以外であれば、
要求されたルックアップ種別@var{type}によって振舞いが変わることになる。
@c If @var{ds} is nonzero then the behaviour varies depending on the
@c requested lookup @var{type}:

@table @code
@item LOOKUP
@code{diskfs_drop_dirstat}によって無視されるよう@code{*@var{ds}}をセットする。
@c Set @code{*@var{ds}} to be ignored by @code{diskfs_drop_dirstat}

@item CREATE
成功した場合は、
@code{diskfs_drop_dirstat}によって無視されるよう@code{*@var{ds}}をセットする。@*
失敗した場合は、
将来の@code{diskfs_direnter}の呼出し用に@code{*@var{ds}}をセットする。
@c On success, set @code{*@var{ds}} to be ignored by
@c @code{diskfs_drop_dirstat}. @*
@c On failure, set @code{*@var{ds}} for a future call to
@c @code{diskfs_direnter}.

@item RENAME
成功した場合は、
将来の@code{diskfs_dirrewrite}の呼出し用に@code{*@var{ds}}をセットする。@*
失敗した場合は、
将来の@code{diskfs_direnter}の呼出し用に@code{*@var{ds}}をセットする。
@c On success, set @code{*@var{ds}} for a future call to
@c @code{diskfs_dirrewrite}. @*
@c On failure, set @code{*@var{ds}} for a future call to
@c @code{diskfs_direnter}.

@item REMOVE
成功した場合は、
将来の@code{diskfs_dirremove}の呼出し用に@code{*@var{ds}}をセットする。@*
失敗した場合は、
@code{diskfs_drop_dirstat}によって無視されるよう@code{*@var{ds}}をセットする。
@c On success, set @code{*@var{ds}} for a future call to
@c @code{diskfs_dirremove}. @*
@c On failure, set @code{*@var{ds}} to be ignored by
@c @code{diskfs_drop_dirstat}.
@end table

この関数の呼出し側は、
次の２つのことを保証する。
まず第１に、
@var{ds}がゼロ以外であれば、
ディレクトリ@var{dp}のロックが解除される前に、
上にリストされた適切な呼出しが行われること、
もしくは、
@code{diskfs_drop_dirstat}が@var{ds}を引数として呼出されることを保証する。
第２に、
今回ルックアップ関数を呼出してから*DSを使用する
(もしくは、破棄する)
までの間に、
このディレクトリに対してルックアップ関数は一切呼出されないことを保証する。
@c The caller of this function guarantees that if @var{ds} is nonzero, then
@c either the appropriate call listed above or @code{diskfs_drop_dirstat}
@c will be called with @var{ds} before the directory @var{dp} is unlocked,
@c and guarantees that no lookup calls will be made on this directory
@c between this lookup and the use (or destruction) of *DS.

あなたが@code{diskfs_rename_dir}、@code{diskfs_clear_directory}、@code{diskfs_init_dir}のライブラリ・バージョンを使うのであれば、
@file{..}に対するルックアップでは、
フラグ@code{SPEC_DOTDOT}がORされているかもしれない。
要求されたルックアップ種別@var{type}によっては、
これが特別な意味を持つ。
@c If you use the library's versions of @code{diskfs_rename_dir},
@c @code{diskfs_clear_directory}, and @code{diskfs_init_dir}, then lookups
@c for @file{..} might have the flag @code{SPEC_DOTDOT} ORed in.  This has a
@c special meaning depending on the requested lookup @var{type}:

@table @code
@item LOOKUP
復帰する前に、
@var{dp}のロックは解除されなければならず、
また、
そのreference（FIXME-J:リファレンス、参照？）は除去されなければならない。
@c @var{dp} should be unlocked and its reference dropped before returning.

@item CREATE
@code{SPEC_DOTDOT}が与えられないことは保証されているので、
このケースは無視してよい。
@c Ignore this case, because @code{SPEC_DOTDOT} is guaranteed not to be
@c given.

@item RENAME
@itemx REMOVE
どちらの場合も、
見つかったノード(@code{*@var{np}})は既にロックされている。
したがって、
それをさらにロックしたり、
reference（FIXME-J:リファレンス、参照？）を追加したりしないこと。
@c In both of these cases, the node being found (@code{*@var{np}}) is
@c already held locked, so don't lock it or add a reference to it.
@end table

名前@var{name}がディレクトリの中に存在しない場合は@code{ENOENT}を返す。
@var{name}が、
このファイルシステムのルートの@file{..}を指している場合は、
@code{EAGAIN}を返す。
@code{EIO}を返すことが適切な場合には、
@code{EIO}を返す。
@c Return @code{ENOENT} if @var{name} isn't in the directory.  Return
@c @code{EAGAIN} if @var{name} refers to the @file{..} of this filesystem's
@c root.  Return @code{EIO} if appropriate.
@end deftypefun

@deftypefun error_t diskfs_direnter (@w{struct node *@var{dp}}, @w{char *@var{name}}, @w{struct node *@var{np}}, @w{struct dirstat *@var{ds}}, @w{struct protid *@var{cred}})
@deftypefunx error_t diskfs_direnter_hard (@w{struct node *@var{dp}}, @w{char *@var{name}}, @w{struct node *@var{np}}, @w{struct dirstat *@var{ds}}, @w{struct protid *@var{cred}})
あなたは@code{diskfs_direnter}を定義するべきではない。
なぜなら、
これは単に@code{diskfs_direnter_hard}に対するラッパーに過ぎず、
既に@code{libdiskfs}の中で定義されているからである。
@c You should not define @code{diskfs_direnter}, because it is simply a
@c wrapper for @code{diskfs_direnter_hard}, and is already defined in
@c @code{libdiskfs}.

ディレクトリ@var{dp}に@var{name}という名前で@var{np}を追加する。
これは、
@code{CREATE}、
もしくは、
@code{RENAME}の@code{diskfs_lookup}呼出しが失敗した後にのみ呼出されることになる。
@var{dp}は、
この@code{diskfs_lookup}の呼出し以降ロックされたままであり、
@var{ds}の内容は、
@code{diskfs_lookup}の呼出しによってセットされたままの状態である。
また、
@var{np}はロックされている。
@var{cred}は、
この関数の呼出しに責任を負うユーザを識別する
(ディレクトリ拡張の正当性を判断するためだけに使われる)。
@c Add @var{np} to directory @var{dp} under the name @var{name}.  This will
@c only be called after an unsuccessful call to @code{diskfs_lookup} of type
@c @code{CREATE} or @code{RENAME}; @var{dp} has been locked continuously
@c since that call and @var{ds} is as that call set it, @var{np} is locked.
@c @var{cred} identifies the user responsible for the call (to be used only
@c to validate directory growth).
@end deftypefun

@deftypefun error_t diskfs_dirrewrite (@w{struct node *@var{dp}}, @w{struct node *@var{oldnp}}, @w{struct node *@var{np}}, @w{char *@var{name}}, @w{struct dirstat *@var{ds}})
@deftypefunx error_t diskfs_dirrewrite_hard (@w{struct node *@var{dp}}, @w{struct node *@var{np}}, @w{struct dirstat *@var{ds}})
あなたは@code{diskfs_dirrewrite}を定義するべきではない。
なぜなら、
これは単に@code{diskfs_dirrewrite_hard}に対するラッパーに過ぎず、
既に@code{libdiskfs}の中で定義されているからである。
@c You should not define @code{diskfs_dirrewrite}, because it is simply a
@c wrapper for @code{diskfs_dirrewrite_hard}, and is already defined in
@c @code{libdiskfs}.

これは、
@code{RENAME}の@code{diskfs_lookup}呼出しが成功した後にのみ呼出されることになる。
この呼出しにより、
ディレクトリ@var{dp}に見つかった名前は、
それが以前に参照していたノードに換わって、
ノード@var{np}を指すように変更されているはずである。
@var{dp}は、
この@code{diskfs_lookup}の呼出し以降ロックされたままであり、
@var{ds}の内容は、
@code{diskfs_lookup}の呼出しによってセットされたままの状態である。
また、
@var{np}はロックされている。
@c This will only be called after a successful call to @code{diskfs_lookup}
@c of type @code{RENAME}; this call should change the name found in
@c directory @var{dp} to point to node @var{np} instead of its previous
@c referent.  @var{dp} has been locked continuously since the call to
@c @code{diskfs_lookup} and @var{ds} is as that call set it; @var{np} is
@c locked.

@code{diskfs_dirrewrite}については、
さらに追加仕様がある。
@var{name}は、
@var{dp}の中で以前参照されていたノード@var{oldnp}に対応していた名前である。
更新されるのはこのreference（FIXME-J:リファレンス、参照？）である。
@code{@var{dp}->dirmod_reqs}がゼロ以外であれば、
@code{diskfs_dirrewrite}は@code{diskfs_notice_dirchange}も呼出す。
@c @code{diskfs_dirrewrite} has some additional specifications: @var{name}
@c is the name within @var{dp} which used to correspond to the previous
@c referent, @var{oldnp}; it is this reference which is being rewritten.
@c @code{diskfs_dirrewrite} also calls @code{diskfs_notice_dirchange} if
@c @code{@var{dp}->dirmod_reqs} is nonzero.
@end deftypefun

@deftypefun error_t diskfs_dirremove (@w{struct node *@var{dp}}, @w{struct node *@var{np}}, @w{char *@var{name}}, @w{struct dirstat *@var{ds}})
@deftypefunx error_t diskfs_dirremove_hard (@w{struct node *@var{dp}}, @w{struct dirstat *@var{ds}})
あなたは@code{diskfs_dirremove}を定義するべきではない。
なぜなら、
これは単に@code{diskfs_dirremove_hard}に対するラッパーに過ぎず、
既に@code{libdiskfs}の中で定義されているからである。
@c You should not define @code{diskfs_dirremove}, because it is simply a
@c wrapper for @code{diskfs_dirremove_hard}, and is already defined in
@c @code{libdiskfs}.

これは、
@code{REMOVE}の@code{diskfs_lookup}呼出しが成功した後にのみ呼出されることになる。
この呼出しにより、
ディレクトリ@var{ds}に見つかった名前は削除されているはずである。
@var{dp}は、
この@code{diskfs_lookup}の呼出し以降ロックされたままであり、
@var{ds}の内容は、
@code{diskfs_lookup}の呼出しによってセットされたままの状態である。
@c This will only be called after a successful call to @code{diskfs_lookup}
@c of type @code{REMOVE}; this call should remove the name found from the
@c directory @var{ds}.  @var{dp} has been locked continuously since the
@c call to @code{diskfs_lookup} and @var{ds} is as that call set it.

@code{diskfs_dirremove}については、
さらに追加仕様がある。
@code{@var{dp}->dirmod_reqs}がゼロ以外であれば、
このルーチンは@code{diskfs_notice_dirchange}も呼出さなければならない。
削除されるエントリは、
@var{name}という名前を持ち、
@var{np}を参照している。
@c @code{diskfs_dirremove} has some additional specifications: this routine
@c should call @code{diskfs_notice_dirchange} if
@c @code{@var{dp}->dirmod_reqs} is nonzero.  The entry being removed has
@c name @var{name} and refers to @var{np}.
@end deftypefun

@deftypefun error_t diskfs_drop_dirstat (@w{struct node *@var{dp}}, @w{struct dirstat *@var{ds}})
@var{ds}は、
ディレクトリ@var{dp}に対する@code{diskfs_lookup}の前回の呼出しによってセットされたものである。
@code{diskfs_direnter}、@code{diskfs_dirrewrite}、@code{diskfs_dirremove}が以前に呼出されていなければ、
この関数が呼出されることは保証されている。
この関数は、
@code{struct dirstat}により保持されているどのような状態も解放するべきである。
@var{dp}は、
@code{diskfs_lookup}の呼出し以降ロックされたままの状態である。
@c @var{ds} has been set by a previous call to @code{diskfs_lookup} on
@c directory @var{dp}; this function is guaranteed to be called if
@c @code{diskfs_direnter}, @code{diskfs_dirrewrite}, and
@c @code{diskfs_dirremove} have not been called, and should free any state
@c retained by a @code{struct dirstat}.  @var{dp} has been locked
@c continuously since the call to @code{diskfs_lookup}.
@end deftypefun

@deftypefun void diskfs_null_dirstat (@w{struct dirstat *@var{ds}})
@code{diskfs_drop_dirstat}が無視するように@var{ds}を初期化する。
@c Initialize @var{ds} such that @code{diskfs_drop_dirstat} will ignore it.
@end deftypefun

@deftypefun error_t diskfs_get_directs (@w{struct node *@var{dp}}, @w{int @var{entry}}, @w{int @var{n}}, @w{char **@var{data}}, @w{u_int *@var{datacnt}}, @w{vm_size_t @var{bufsiz}}, @w{int *@var{amt}})
ロックされたディレクトリ・ノード@var{dp}の@var{entry}から始まる@var{n}個のディレクトリ・エントリを返す。
これらのエントリは、
現在@code{*@var{datacnt}}バイトの領域を指す@code{*@var{data}}に入れられる。
このサイズが十分でない場合には、
@code{*@var{data}}に対して@code{vm_allocate}を呼出す。
@c {{「...に対して...を呼出す」で良いか？}}
@code{*@var{datacnt}}には、
実際に使用された総サイズをセットする。
@var{amt}にはコピーされたエントリの数を入れる。
ただし、
@var{bufsiz}バイトを超えてコピーしないこと。
@var{bufsiz}がゼロであれば、
@code{*@var{datacnt}}の上限はない。
@var{n}が-1であれば、
@var{amt}の上限はない。
@c Return @var{n} directory entries starting at @var{entry} from locked
@c directory node @var{dp}.  Fill @code{*@var{data}} with the entries;
@c which currently points to @code{*@var{datacnt}} bytes.  If it isn't big
@c enough, @code{vm_allocate} into @code{*@var{data}}.  Set
@c @code{*@var{datacnt}} with the total size used.  Fill @var{amt} with the
@c number of entries copied.  Regardless, never copy more than @var{bufsiz}
@c bytes.  If @var{bufsiz} is zero, then there is no limit on
@c @code{*@var{datacnt}}; if @var{n} is -1, then there is no limit on
@c @var{amt}.
@end deftypefun

@deftypefun int diskfs_dirempty (@w{struct node *@var{dp}}, @w{struct protid *@var{cred}})
ロックされたディレクトリ@var{dp}が空であれば、
ゼロ以外の値を返す。
ユーザが、
@code{diskfs_clear_directory}と@code{diskfs_init_directory}を再定義していなければ、
「空」とは「@file{.}というラベルのエントリと@file{..}というラベルのエントリだけを持つ」という意味である。
@var{cred}は、
この呼出しを行ったユーザを識別する@dots{}
そのディレクトリを探索することがこのユーザにはできない場合、
このルーチンの呼出しは失敗しなければならない。
@c Return nonzero if locked directory @var{dp} is empty.  If the user has
@c not redefined @code{diskfs_clear_directory} and
@c @code{diskfs_init_directory}, then `empty' means `only possesses entries
@c labelled @file{.} and @file{..}.  @var{cred} identifies the user making
@c the call@dots{} if this user cannot search the directory, then this
@c routine should fail.
@end deftypefun

@deftypefun error_t diskfs_get_translator (@w{struct node *@var{np}}, @w{char **@var{namep}}, @w{u_int *@var{namelen}})
(@code{diskfs_node_translated}が真であるような)
ロックされたノード@var{np}について、
そのトランスレータの名前を捜し出す。
新たにmallocにより獲得された領域にその名前を格納し、
その名前全体の長さを@code{*@var{namelen}}にセットする。
@c For locked node @var{np} (for which @code{diskfs_node_translated} is
@c true) look up the name of its translator.  Store the name into newly
@c malloced storage and set @code{*@var{namelen}} to the total length.
@end deftypefun

@deftypefun error_t diskfs_set_translator (@w{struct node *@var{np}}, @w{char *@var{name}}, @w{u_int @var{namelen}}, @w{struct protid *@var{cred}})
ロックされたノード@var{np}について、
そのトランスレータの名前として@var{name}の値を、
また、
その名前のバイト長として@var{namelen}の値を、
それぞれセットする。
@var{cred}は、
この関数の呼出しに責任を負うユーザを識別する。
@c For locked node @var{np}, set the name of the translating program to be
@c @var{name}, which is @var{namelen} bytes long.  @var{cred} identifies
@c the user responsible for the call.
@end deftypefun

@deftypefun error_t diskfs_truncate (@w{struct node *@var{np}}, @w{off_t @var{size}})
ロックされたノード@var{np}の長さを@var{size}バイトに切り詰める。
@var{np}の長さが既に@var{size}バイト以下であれば、
何もしない。
これがsymlink（FIXME-J:シンボリック・リンク？）である
(かつ、
@code{diskfs_shortcut_symlink}がセットされている)
場合は、
@code{diskfs_create_symlink_hook}がリンクのターゲットをどこか別の場所にセットしている場合でも、
そのsymlink（FIXME-J:シンボリック・リンク？）は除去されなければならない。
@c Truncate locked node @var{np} to be @var{size} bytes long.  If @var{np}
@c is already less than or equal to @var{size} bytes long, do nothing.  If
@c this is a symlink (and @code{diskfs_shortcut_symlink} is set) then this
@c should clear the symlink, even if @code{diskfs_create_symlink_hook}
@c stores the link target elsewhere.
@end deftypefun

@deftypefun error_t diskfs_grow (@w{struct node *@var{np}}, @w{off_t @var{size}}, @w{struct protid *@var{cred}})
ロックされたノード@var{np}に対して割当てられたディスクを、
少なくとも@var{size}バイト以上になるようサイズを拡張し、
実際に割当てられたサイズを@code{@var{np}->allocsize}にセットする。
割当てられているサイズが既に@var{size}バイトである場合には、
何もしない。
@var{cred}は、
この関数の呼出しに責任を負うユーザを識別する。
@c Grow the disk allocated to locked node @var{np} to be at least
@c @var{size} bytes, and set @code{@var{np}->allocsize} to the actual
@c allocated size.  If the allocated size is already @var{size} bytes, do
@c nothing.  @var{cred} identifies the user responsible for the call.
@end deftypefun

@deftypefun error_t diskfs_node_reload (@w{struct node *@var{node}})
この関数は、
ディスクに対して一切書込みを行うことなく、
ディスクからノード@var{node}に固有なデータをすべて再読込みしなければならない。
これは常に、
@var{diskfs_readonly}が真にセットされた状態で呼出される。
@c This function must reread all data specific to @var{node} from disk,
@c without writing anything.  It is always called with
@c @var{diskfs_readonly} set to true.
@end deftypefun

@deftypefun error_t diskfs_reload_global_state (void)
この関数は、
キャッシュされているすべてのグローバルな状態を無効にしなければならない。
また、
ディスクに対して一切書込みを行うことなく、
必要に応じてディスクからそれを再読込みしなければならない。
これは常に、
@var{diskfs_readonly}を真にセットした状態で呼出される。
常に、
この関数の呼出しに続いて、
すべてのアクティブなノードに対して@code{diskfs_node_reload}が呼出されるので、
この関数ではノード固有のデータを再読込みする必要はない。
@c This function must invalidate all cached global state, and reread it as
@c necessary from disk, without writing anything.  It is always called with
@c @var{diskfs_readonly} set to true.  @code{diskfs_node_reload} is
@c subsequently called on all active nodes, so this call doesn't need to
@c reread any node-specific data.
@end deftypefun

@deftypefun error_t diskfs_node_iterate (error_t (*@var{fun}) (@w{struct node *@var{np}}))
アクティブなノード@var{np}の１つ１つについて、
@var{fun}を呼出す。
ノードは、
@var{fun}の呼出しの間はロックされる。
@var{fun}が任意のノードについてゼロ以外の値を返した場合は、
即座に処理を停止し、
その値を返す。
@c For each active node @var{np}, call @var{fun}.  The node is to be locked
@c around the call to @var{fun}.  If @var{fun} returns nonzero for any
@c node, then stop immediately, and return that value.
@end deftypefun

@deftypefun error_t diskfs_alloc_node (@w{struct node *@var{dp}}, @w{mode_t @var{mode}}, @w{struct node **@var{np}})
ロックされたディレクトリ@var{dp}の中でモード@var{mode}を持つノードとするために新しいノードを割当てる。
ただし、
実際にそのモードをセットしたり、
ディレクトリを変更したりすることはしない。
これらは、
呼出し側によって行われるからである。
このリクエストに責任を負うユーザは、
@var{cred}により識別することができる。
新しく割当てられたノードを@code{*@var{np}}にセットする。
@c Allocate a new node to be of mode @var{mode} in locked directory
@c @var{dp}, but don't actually set the mode or modify the directory, since
@c that will be done by the caller.  The user responsible for the request
@c can be identified with @var{cred}.  Set @code{*@var{np}} to be the newly
@c allocated node.
@end deftypefun

@deftypefun void diskfs_free_node (@w{struct node *@var{np}}, @w{mode_t @var{mode}})
ノード@var{np}を解放する。
(@code{@var{np}->dn_stat.st_mode}がゼロであったものについては)
ディスク上のコピーは既に@code{diskfs_node_update}によって同期が取られている。
@var{np}のかつてのモードが@var{mode}である。
@c Free node @var{np}; the on-disk copy has already been synchronized with
@c @code{diskfs_node_update} (where @code{@var{np}->dn_stat.st_mode} was
@c zero).  @var{np}'s mode used to be @var{mode}.
@end deftypefun

@deftypefun void diskfs_lost_hardrefs (@w{struct node *@var{np}})
ロックされたノード@var{np}は、
まだいくつかlight reference（FIXME-J）は持つものの、
ちょうど最後のhard reference（FIXME-J）を失ったところである。
@c Locked node @var{np} has some light references but has just lost its
@c last hard reference.
@end deftypefun

@deftypefun void diskfs_new_hardrefs (@w{struct node *@var{np}})
ロックされたノード@var{np}はこれまでhard reference（FIXME-J）を持たなかったが、
ちょうど１つ獲得したところである。
したがって、
実際にユーザがいなくてもlight reference（FIXME-J）を持つことができるようになった。
@c Locked node @var{np} has just acquired a hard reference where it had
@c none previously.  Therefore, it is okay again to have light references
@c without real users.
@end deftypefun

@deftypefun void diskfs_try_dropping_softrefs (@w{struct node *@var{np}})
ノード@var{np}は、
まだいくつかlight reference（FIXME-J）は持つものの、
ちょうど最後のhard reference（FIXME-J）を失ったところである。
light reference（FIXME-J）に解放可能なものがあれば、
それを解放するような手段を講じる。
@var{diskfs_node_refcnt_lock}と@var{np}はどちらもロックされている。
この関数は、
@code{diskfs_lost_hardrefs}の後に呼出される。
@c Node @var{np} has some light references, but has just lost its last hard
@c references.  Take steps so that if any light references can be freed,
@c they are.  Both @var{diskfs_node_refcnt_lock} and @var{np} are locked.
@c This function will be called after @code{diskfs_lost_hardrefs}.
@end deftypefun

@deftypefun void diskfs_node_norefs (@w{struct node *@var{np}})
ノード@var{np}はもはやreference（FIXME-J:リファレンス、参照？）を持たない。
@code{*@var{np}}が保持されるべきでなければ、
それも含めてローカルな状態を解放する。
@var{diskfs_node_refcnt_lock}は保有されている。
@c Node @var{np} has no more references; free local state, including
@c @code{*@var{np}} if it shouldn't be retained.
@c @var{diskfs_node_refcnt_lock} is held.
@end deftypefun

@deftypefun error_t diskfs_set_hypermetadata (@w{int @var{wait}}, @w{int @var{clean}})
フォーマット固有のバッファにある、
ページングされていないメタデータをディスクに書込む。
@c {{non-pagedは「ページングされていない」で良いか？}}
この書込みは、
@var{wait}の値がゼロであれば、
非同期に行われる。
@var{clean}の値がゼロ以外であれば、
この書込みが行われた後にファイルシステムは完全にクリーンな状態になり、
ページングされていないメタデータがその事実を示すことができなければならない。
@c Write any non-paged metadata from format-specific buffers to disk,
@c asynchronously unless @var{wait} is nonzero.  If @var{clean} is nonzero,
@c then after this is written the filesystem will be absolutely clean, and
@c it must be possible for the non-paged metadata to indicate that fact.
@end deftypefun

@deftypefun void diskfs_write_disknode (@w{struct node *@var{np}}, @w{int @var{wait}})
@code{@var{np}->dn_stat}の中の情報とそれに関連するフォーマット固有の情報をディスクに書込む。
@var{wait}が真であれば、
物理的なメディアが完全に更新された後にはじめて復帰する。
@c Write the information in @code{@var{np}->dn_stat} and any associated
@c format-specific information to the disk.  If @var{wait} is true, then
@c return only after the physicial media has been completely updated.
@end deftypefun

@deftypefun void diskfs_file_update (@w{struct node *@var{np}}, @w{int @var{wait}})
ファイルNPの内容とそれに関連するすべてのメタデータをディスクに書込む。
一般にこれは、
メタデータのほとんどの部分に関して@code{diskfs_node_update}を呼出すことになる。
@var{wait}が真であれば、
物理的なメディアが完全に更新された後にはじめて復帰する。
@c Write the contents and all associated metadata of file NP to disk.
@c Generally, this will involve calling @code{diskfs_node_update} for much
@c of the metadata.  If @var{wait} is true, then return only after the
@c physical media has been completely updated.
@end deftypefun

@deftypefun mach_port_t diskfs_get_filemap (@w{struct node *@var{np}}, @w{vm_prot_t @var{prot}})
@var{np}のファイル内容に対応するメモリ・オブジェクトのポート(send right（FIXME-J:センド・ライト？）)を返す。
@var{prot}は、
許容される最大限のアクセスを示す。
エラーが発生した場合には、
@code{MACH_PORT_NULL}を返し、
@code{errno}をセットする。
@c Return a memory object port (send right) for the file contents of
@c @var{np}.  @var{prot} is the maximum allowable access.  On errors,
@c return @code{MACH_PORT_NULL} and set @code{errno}.
@end deftypefun

@deftypefun {struct pager *} diskfs_get_filemap_pager_struct (@w{struct node *@var{np}})
ロックされたノードNPに対してdiskfs_get_filemapが返したページャを参照する@code{struct pager *}を返す。
この戻り値は、
@code{pager_memcpy}の引数として使うのに適している。
@c Return a @code{struct pager *} that refers to the pager returned by
@c diskfs_get_filemap for locked node NP, suitable for use as an argument
@c to @code{pager_memcpy}.
@end deftypefun

@deftypefun vm_prot_t diskfs_max_user_pager_prot (void)
すべてのアクティブなユーザ・ページャに設定された最大限の@code{prot}パラメータ
(@code{diskfs_get_filemap}の第２引数)
のビットごとのORを返す。
@c Return the bitwise OR of the maximum @code{prot} parameter (the second
@c argument to @code{diskfs_get_filemap}) for all active user pagers.
@end deftypefun

@deftypefun int diskfs_pager_users (void)
ユーザによって使用されているかもしれないエクスポートされたページャ・ポートが存在すればゼロ以外の値を返す。
この関数がゼロを返すまでは、
それ以上のページャの生成はブロックされるべきである。
@c Return nonzero if there are pager ports exported that might be in use by
@c users.  Further pager creation should be blocked before this function
@c returns zero.
@end deftypefun

@deftypefun void diskfs_sync_everything (@w{int @var{wait}})
すべてのページャをsync（FIXME-J）して、
hypermetadata（FIXME-J:ハイパメタデータ？）を除き、
ディスク上に存在するべきデータをすべて書込む。
@var{wait}が真であれば、
物理的なメディアが完全に更新された後にはじめて復帰する。
@c Sync all the pagers and write any data belonging on disk except for the
@c hypermetadata.  If @var{wait} is true, then return only after the
@c physicial media has been completely updated.
@end deftypefun

@deftypefun void diskfs_shutdown_pager (void)
すべてのページャをシャットダウンする。
これは一度始めると元に戻すことはできず、
ファイルシステムが終了する時に実行される。
@c Shut down all pagers.  This is irreversable, and is done when the
@c filesystem is exiting.
@end deftypefun


@node Diskfs Options
@subsection Diskfsオプション
@c @subsection Diskfs Options

このサブセクションで説明する関数や変数には既に@code{libdiskfs}の中にデフォルトの実装があるため、
それらを再定義するよう強制されることはない。
ケース・バイ・ケースで、
それらを再定義しても構わない。
@c The functions and variables described in this subsection already have
@c default definitions in @code{libdiskfs}, so you are not forced to define
@c them; rather, they may be redefined on a case-by-case basis.

オプション(任意選択)の変数はいずれも、
プログラムが起動したらすぐに
(例えば引数解析のようなdiskfs関数の呼出しを行うよりも前に)
値をセットしなければならない。
@c You should set the value of any option variables as soon as your program
@c starts (before you make any calls to diskfs, such as argument parsing).

@deftypevar int diskfs_hard_readonly
ファイルシステムのメディアを決して書込み可能にすることができないのであれば、
この変数にゼロ以外の値をセットするべきである。
@c You should set this variable to nonzero if the filesystem media can
@c never be made writable.
@end deftypevar

@deftypevar {char *} diskfs_extra_version
--versionオプションが使われた際に表示されるべき追加的なバージョン情報をここにセットする。
@c Set this to be any additional version specification that should be
@c printed for --version.
@end deftypevar

@deftypevar int diskfs_shortcut_symlink
これは、
ファイルシステム・フォーマットがショートカットのためのシンボリック・リンクtranslation(FIXME-J:翻訳、トランスレーション？)をサポートしている場合に限り、
ゼロ以外の値を取るべきである。
ライブラリは、
ユーザがこのノードの内容を直接読み書きできないことを保証する。
ライブラリがこのような保証を行うのは、
symlink hook(FIXME-J:シンボリック・リンクをフックする、シンボリック・リンクのフック？)関数
(@code{diskfs_create_symlink_hook}と@code{diskfs_read_symlink_hook})
が@code{EINVAL}を返す場合か、
それらの関数が定義されていない場合だけである。
@c {{FIXME-J: do soはguaranteeを指す？}}
たとえhook function(FIXME-J:フック関数？)が使われている場合でも、
ライブラリは、
@code{dn_stat.st_size}フィールドがsymlink(FIXME-J:シンボリック・リンク？)の長さであることを知っている。
@c This should be nonzero if and only if the filesystem format supports
@c shortcutting symbolic link translation.  The library guarantees that
@c users will not be able to read or write the contents of the node
@c directly, and the library will only do so if the symlink hook functions
@c (@code{diskfs_create_symlink_hook} and @code{diskfs_read_symlink_hook})
@c return @code{EINVAL} or are not defined.  The library knows that the
@c @code{dn_stat.st_size} field is the length of the symlink, even if the
@c hook functions are used.
@end deftypevar

@deftypevar int diskfs_shortcut_chrdev
@deftypevarx int diskfs_shortcut_blkdev
@deftypevarx int diskfs_shortcut_fifo
@deftypevarx int diskfs_shortcut_ifsock
これらの変数は、
ファイルシステム・フォーマットが、
ショートカットのためのキャラクタ・デバイス・ノード、
ブロック・デバイス・ノード、
FIFO、
UNIXドメイン・ソケットのtranslation(FIXME-J:翻訳、ランスレーション？)をそれぞれサポートしている場合にのみ、
ゼロ以外の値を取るべきである。
@c These variables should be nonzero if and only if the filesystem format
@c supports shortcutting character device node, block device node, FIFO, or
@c Unix-domain socket translation, respectively.
@end deftypevar

@deftypevar int diskfs_default_sync_interval
最初のdiskfsスレッドが（@code{diskfs_spawn_first_thread}の中で）起動された時に、
この値を引数として@code{diskfs_set_sync_interval}が呼出される。
この変数のデフォルトの値は30であり、
このデフォルトでは、
ディスク・バッファは少なくとも30秒ごとにフラッシュされることになる。
@c @code{diskfs_set_sync_interval} is called with this value when the first
@c diskfs thread is started up (in @code{diskfs_spawn_first_thread}).  This
@c variable has a default default value of 30, which causes disk buffers to
@c be flushed at least every 30 seconds.
@end deftypevar

@deftypefun error_t diskfs_validate_mode_change (@w{struct node *@var{np}}, @w{mode_t @var{mode}})
@deftypefunx error_t diskfs_validate_owner_change (@w{struct node *@var{np}}, @w{uid_t @var{uid}})
@deftypefunx error_t diskfs_validate_group_change (@w{struct node *@var{np}}, @w{gid_t @var{gid}})
@deftypefunx error_t diskfs_validate_author_change (@w{struct node *@var{np}}, @w{uid_t @var{author}})
@deftypefunx error_t diskfs_validate_flags_change (@w{struct node *@var{np}}, @w{int @var{flags}})
@deftypefunx error_t diskfs_validate_rdev_change (@w{struct node *@var{np}}, @w{dev_t @var{rdev}})
ノード@var{np}が要求されたとおりに変更可能であればゼロを返す。
これはすなわち、
@var{np}のモードを@var{mode}に、
オーナを@var{uid}に、
グループを@var{gid}に、
author（FIXME-J：作成者？）を@var{author}に、
フラグを@var{flags}に、
ロー・デバイス番号を@var{rdev}に、
それぞれ変更可能である場合を指す。
変更可能でない場合はエラー・コードを返す。
@c Return zero if for the node @var{np} can be changed as requested.  That
@c is, if @var{np}'s mode can be changed to @var{mode}, owner to @var{uid},
@c group to @var{gid}, author to @var{author}, flags to @var{flags}, or raw
@c device number to @var{rdev}, respectively.  Otherwise, return an error
@c code.

モードやフラグをクリアすることは常に可能でなければならない。
diskfsは、
これらをクリアする前に許可を求めることはしない。
@c It must always be possible to clear the mode or the flags; diskfs will
@c not ask for permission before doing so.
@end deftypefun

@deftypefun void diskfs_readonly_changed (@w{int @var{readonly}})
これは、
ディスクが読込みのみ可能なモードから読み書き可能なモードに変更された時、
あるいは、
その逆の変更が行われた時に呼出される。
@var{readonly}は新しい状態を表す
（これは@var{diskfs_readonly}にも反映される）。
ファイルシステムが書込み可能なものとなる場合、
この関数は初期起動時にも呼出される。
@c This is called when the disk has been changed from read-only to
@c read-write mode or vice-versa.  @var{readonly} is the new state (which
@c is also reflected in @var{diskfs_readonly}).  This function is also
@c called during initial startup if the filesystem is to be writable.
@end deftypefun

@deftypefn {Variable} {error_t (*} diskfs_create_symlink_hook ) (@w{struct node *@var{np}}, @w{char *@var{target}})
この関数ポインタがゼロ以外の値である場合
（かつ、@code{diskfs_shortcut_symlink}がセットされている場合）、
symlink(FIXME-J:シンボリック・リンク？)をセットするためにその関数が呼出される。
その関数が@code{EINVAL}を返した場合、
あるいは、
そもそも関数がセットされていない場合、
通常の方式
（すなわち、ファイル・データへの書込み）
が使われる。
これ以外のエラーが返された場合は、
そのエラーはユーザに返される。
@c If this function pointer is nonzero (and @code{diskfs_shortcut_symlink}
@c is set) it is called to set a symlink.  If it returns @code{EINVAL} or
@c isn't set, then the normal method (writing the contents into the file
@c data) is used.  If it returns any other error, it is returned to the
@c user.
@end deftypefn

@deftypefn {Variable} {error_t (*} diskfs_read_symlink_hook ) (@w{struct node *@var{np}}, @w{char *@var{target}})
この関数ポインタがゼロ以外の値である場合
（かつ、@code{diskfs_shortcut_symlink}がセットされている場合）、
symlink(FIXME-J:シンボリック・リンク？)の内容を読込むためにその関数が呼出される。
その関数が@code{EINVAL}を返した場合、
あるいは、
そもそも関数がセットされていない場合、
通常の方式
（すなわち、ファイル・データの読込み）
が使われる。
これ以外のエラーが返された場合は、
そのエラーはユーザに返される。
@c If this function pointer is nonzero (and @code{diskfs_shortcut_symlink}
@c is set) it is called to read the contents of a symlink.  If it returns
@c @code{EINVAL} or isn't set, then the normal method (reading from the
@c file data) is used.  If it returns any other error, it is returned to
@c the user.
@end deftypefn

@deftypefun error_t diskfs_rename_dir (@w{struct node *@var{fdp}}, @w{struct node *@var{fnp}}, @w{char *@var{fromname}}, @w{struct node *@var{tdp}}, @w{char *@var{toname}}, @w{struct protid *@var{fromcred}}, @w{struct protid *@var{tocred}})
（@var{fdp}を親ディレクトリ・ノードとして持ち、
そのディレクトリの中で@var{fromname}という名前を持つ）
ディレクトリ・ノード@var{fnp}を、
ディレクトリ@var{tdp}の中で@var{toname}という名前を持つように、
名前変更する。
これらのノードはどれもロックされておらず、
関数の復帰時にどれもロックされていてはならない。
このルーチンはserialize（FIXME-J:シリアライズ？）されるので、
再入可能である必要はない。
ディレクトリがこのルーチン以外によって名前変更されることは決してない。
@var{fromcred}は@var{fdp}と@var{fnp}に対して責任を負うユーザである。
また、
@var{tocred}は@var{tdp}に対して責任を負うユーザである。
このルーチンは、
@file{.}と@file{..}は普通の慣例どおり通常のリンクによって表されるものと想定している。
あなたが実装するフォーマットにおいてこの想定が正しくない場合、
あなたはこの関数を再定義しなければならない。
@c Rename directory node @var{fnp} (whose parent is @var{fdp}, and which
@c has name @var{fromname} in that directory) to have name @var{toname}
@c inside directory @var{tdp}.  None of these nodes are locked, and none
@c should be locked upon return.  This routine is serialized, so it doesn't
@c have to be reentrant.  Directories will never be renamed except by this
@c routine.  @var{fromcred} is the user responsible for @var{fdp} and
@c @var{fnp}.  @var{tocred} is the user responsible for @var{tdp}.  This
@c routine assumes the usual convention where @file{.}  and @file{..} are
@c represented by ordinary links; if that is not true for your format, you
@c have to redefine this function.
@end deftypefun

@deftypefun error_t diskfs_clear_directory (@w{struct node *@var{dp}}, @w{struct node *@var{pdp}}, @w{struct protid *@var{cred}})
ディレクトリ@var{dp}から@file{.}と@file{..}のエントリをクリア（FIXME-J:削除？）する。
@var{dp}の親ディレクトリが@var{pdp}であり、
この親ディレクトリに対して責任を負うユーザは@var{cred}により識別される。
どちらのディレクトリもロックされていなければならない。
このルーチンは、
@file{.}と@file{..}は普通の慣例どおり通常のリンクによって表されるものと想定している。
あなたが実装するフォーマットにおいてこの想定が正しくない場合、
あなたはこの関数を再定義しなければならない。
@c Clear the @file{.} and @file{..} entries from directory @var{dp}.  Its
@c parent is @var{pdp}, and the user responsible for this is identified by
@c @var{cred}.  Both directories must be locked.  This routine assumes the
@c usual convention where @file{.} and @file{..} are represented by
@c ordinary links; if that is not true for your format, you have to
@c redefine this function.
@end deftypefun

@deftypefun error_t diskfs_init_dir (@w{struct node *@var{dp}}, @w{struct node *@var{pdp}}, @w{struct protid *@var{cred}})
ロックされたノード@var{dp}は新規ディレクトリである。
これに構造体（FIXME-J:構造？）を提供するために必要なリンクをすべて追加する。
このノードの親ノードが（ロックされている）@var{pdp}である。
このルーチンは、
@var{pdp}に対して@code{diskfs_lookup}を呼出さないこともある。
この新規ディレクトリは、
@code{diskfs_dirempty}の意味する範囲においてクリア（FIXME-J:？）でなければならない。
このルーチンは、
@file{.}と@file{..}は普通の慣例どおり通常のリンクによって表されるものと想定している。
あなたが実装するフォーマットにおいてこの想定が正しくない場合、
あなたはこの関数を再定義しなければならない。
@var{cred}は、
この関数呼出しをおこなったユーザを識別する。
@c Locked node @var{dp} is a new directory; add whatever links are
@c necessary to give it structure; its parent is the (locked) node
@c @var{pdp}.  This routine may not call @code{diskfs_lookup} on @var{pdp}.
@c The new directory must be clear within the meaning of
@c @code{diskfs_dirempty}.  This routine assumes the usual convention where
@c @file{.} and @file{..} are represented by ordinary links; if that is not
@c true for your format, you have to redefine this function.  @var{cred}
@c identifies the user making the call.
@end deftypefun


@node Diskfs Internals
@subsection Diskfsの内部詳細
@c @subsection Diskfs Internals

このライブラリは以下の関数群もエクスポートしている。
ただし、
このライブラリが提供している他の関数群を再定義するのでなければ、
これらは一般的には有用ではない。
@c The library also exports the following functions, but they are not
@c generally useful unless you are redefining other functions the library
@c provides.

@deftypefun error_t diskfs_create_protid (@w{struct peropen *@var{po}}, @w{struct iouser *@var{user}}, @w{struct protid **@var{cred}})
ユーザ@var{user}を指す@var{cred}の中の既存のperopen @var{po}に対応するprotidを作成して返す。
ノード@code{@var{po}->np}はロックされていなければならない。
@c Create and return a protid for an existing peropen @var{po} in
@c @var{cred}, referring to user @var{user}.  The node @code{@var{po}->np}
@c must be locked.
@end deftypefun

@deftypefun error_t diskfs_start_protid (@w{struct peropen *@var{po}}, @w{struct protid **@var{cred}})
peropen @var{po}に対応する、
ユーザ識別情報を持たないprotidを@var{cred}の中に構築して返す。
ノード@code{@var{po}->np}はロックされていなければならない。
@c Build and return in @var{cred} a protid which has no user
@c identification, for peropen @var{po}.  The node @code{@var{po}->np} must
@c be locked.
@end deftypefun

@deftypefun void diskfs_finish_protid (@w{struct protid *@var{cred}}, @w{struct iouser *@var{user}})
@code{diskfs_start_protid}により開始されたprotid @var{cred}の構築を終了させる。
protidに組み込まれるユーザが@var{user}である。
@c Finish building protid @var{cred} started with @code{diskfs_start_protid};
@c the user to install is @var{user}.
@end deftypefun

@deftypefun void diskfs_protid_rele (@w{void *@var{arg}})
protid @var{cred}がもはやreference（FIXME-J:リファレンス、参照？）を持たなくなった時に呼出される。
protidへのreference（FIXME-J:リファレンス、参照？）はポート管理ライブラリによって保守されるため、
これはクリーンな（FIXME-J:？）ルーチンの一覧に含められる。
ポート・ライブラリがこの構造体を解放する。
@c Called when a protid @var{cred} has no more references.  Because
@c references to protids are maintained by the port management library,
@c this is installed in the clean routines list.  The ports library will
@c free the structure.
@end deftypefun

@deftypefun {struct peropen *} diskfs_make_peropen (@w{struct node *@var{np}}, @w{int @var{flags}}, @w{struct peropen *@var{context}})
ノード@var{np}上にオープン・フラグ@var{flags}を持つ新しいperopen構造体を作成して返す。
@code{root_parent}、
@code{shadow_root}、
@code{shadow_root_parent}の各フィールドの初期値は、
@var{context}がゼロ以外であればそこからコピーされる。
@var{context}がゼロであれば、
これらの値はいずれもゼロにセットされる。
@c Create and return a new peropen structure on node @var{np} with open
@c flags @var{flags}.  The initial values for the @code{root_parent},
@c @code{shadow_root}, and @code{shadow_root_parent} fields are copied from
@c @var{context} if it is nonzero, otherwise each of these values are
@c set to zero.
@end deftypefun

@deftypefun void diskfs_release_peropen (@w{struct peropen *@var{po}})
@var{po}に対するreference（FIXME-J:リファレンス、参照？）・カウントをデクリメントする。
@c Decrement the reference count on @var{po}.
@end deftypefun

@deftypefun error_t diskfs_execboot_fsys_startup (@w{mach_port_t @var{port}}, @w{int @var{flags}}, @w{mach_port_t @var{ctl}}, @w{mach_port_t *@var{real}}, @w{mach_msg_type_name_t *@var{realpoly}})
この関数は、
execserverのブートストラップのために@code{S_fsys_startup}により呼出される。
execserverは本物のノードがなくても機能することができるので、
このようなぺてんが可能である（FIXME-J:？）。
引数は@code{<hurd/fsys.defs>}の中の@code{fsys_startup}と同様である。
@c This function is called by @code{S_fsys_startup} for execserver
@c bootstrap.  The execserver is able to function without a real node,
@c hence this fraud.  Arguments are as for @code{fsys_startup} in
@c @code{<hurd/fsys.defs>}.
@end deftypefun

@deftypefun int diskfs_demuxer (@w{mach_msg_header_t *@var{inp}}, @w{mach_msg_header_t *@var{outp}})
diskfsポートに対して入ってくる@code{libports}メッセージをdemultiplex（FIXME-J:？）する。
@c Demultiplex incoming @code{libports} messages on diskfs ports.
@end deftypefun

@findex diskfs_S_*
diskfsライブラリは、
fs、io、fsys、interrupt、notifyの各インターフェイスをdemultiplex（FIXME-J:？）するための関数群も提供している。
すべてのサーバ・ルーチンは、
@code{diskfs_S_}という接頭辞を持つ。
これらのルーチンについては、
@code{file_t}型、もしくは、@code{io_t}型の@code{in}（入力）引数は、
スタブからは@code{struct protid *}として見える。
@c The diskfs library also provides functions to demultiplex the fs, io,
@c fsys, interrupt, and notify interfaces.  All the server routines have
@c the prefix @code{diskfs_S_}.  For those routines, @code{in} arguments of
@c type @code{file_t} or @code{io_t} appear as @code{struct protid *} to
@c the stub.


@node Twisted Filesystems
@chapter Twisted（FIXME-J:？）ファイルシステム
@c @chapter Twisted Filesystems

Hurdでは、
ファイルシステムに対するリクエストをトランスレータが別のトランスレータへ転送することが可能であり、
これにより、
背後にあるデータが同一であっても、
それが複数の異なる見え方をするというような実装を実現することが可能になる。
この章で説明するトランスレータは、
データに対する直接的なアクセスを提供するものではない。
むしろ、
既存の物理的なファイルシステム・レイアウトを単純化するのに役立つ構成ツールである。
@c In the Hurd, translators are capable of redirecting filesystem requests
@c to other translators, which makes it possible to implement alternative
@c views of the same underlying data.  The translators described in this
@c chapter do not provide direct access to any data; rather, they are
@c organizational tools to help you simplify an existing physical
@c filesystem layout.

これらのトランスレータは細心の注意を払って使うべきである。
さもないと、
ファイルシステムは厳密なツリー構造であってほしいと考えている人々に、
誤って害を与えることがあるかもしれない。@footnote{ねじれ曲がったファイルシステムの迷路の中で迷子になってしまう、等々@dots{}}
@c Be prudent with these translators: you may accidentally injure people
@c who want their filesystems to be rigidly tree-structured.@footnote{You
@c are lost in a maze of twisty little filesystems, all alike@dots{}.}

FIXME: finish

@section symlink, firmlink
@section hostmux, usermux
@section shadowfs


@node Distributed Filesystems
@chapter 分散ファイルシステム
@c @chapter Distributed Filesystems

分散ファイルシステムは、
何らかのネットワーク接続を使って別々のマシン間でファイルを共有するために設計されている。
そのデザインは、
stored（FIXME-J）ファイルシステムのデザインとは大きく異なっている(@pxref{Stored Filesystems})。
ネットワークの遅延や障害といった問題に対処する必要があり、
また、
複数のファイル・サーバ間でやりとりされる複雑なauthentication（FIXME-J:認証？）プロトコルやreplication（FIXME-J）プロトコルを必要とする可能性もある。
@c Distributed filesystems are designed to share files between separate
@c machines via a network connection of some sort.  Their design is
@c significantly different than stored filesystems (@pxref{Stored
@c Filesystems}): they need to deal with the problems of network delays and
@c failures, and may require complex authentication and replication
@c protocols involving multiple file servers.

@menu
* File Transfer Protocol::      FTPベースの分散ファイルシステム。
* Network File System::         SunのNFS: 出来は悪いが、よく使われているファイルシステム。
@end menu


@node File Transfer Protocol
@section File Transfer Protocol
@cindex FTP

FIXME: finish

@menu
* FTP Connection Library::      Managing remote FTP server connections.
@end menu

@subsection ftpcp, ftpdir
@subsection ftpfs

@node FTP Connection Library
@subsection FTP Connection Library
@scindex libftpconn
@scindex ftpconn.h

FIXME: finish


@node Network File System
@section Network File System
@cindex NFS

FIXME: finish

@subsection nfsd
@subsection nfs


@node Networking
@chapter Networking

FIXME: this subsystem is in flux @c Thomas, 26-03-1998

@menu
* Socket Interface::            Network communication I/O protocol.
@end menu


@section pfinet
@section pflocal
@section libpipe

@node Socket Interface
@section Socket Interface
@scindex socket.defs

FIXME: net frobbing stuff may be added to socket.defs
@c Thomas, 26-03-1998


@node Terminal Handling
@chapter Terminal Handling

FIXME: finish

@section term
@section term.defs


@node Running Programs
@chapter Running Programs

FIXME: finish

@section ps, w
@section libps
@section exec
@section proc
@section crash


@node Authentication
@chapter Authentication

FIXME: finish

@menu
* Auth Interface::              Auth ports implement the auth interface.
@end menu

@section addauth, rmauth, setauth
@section su, sush, unsu
@section login, loginpr
@section auth

@node Auth Interface
@section Auth Interface
@scindex auth.defs

FIXME: finish

@menu
* Auth Protocol::               Bidirectional authentication.
@end menu

@node Auth Protocol
@subsection Auth Protocol

FIXME: finish


@node Index
@unnumbered Index

@printindex cp

@summarycontents
@contents
@bye
