========================================================= これは、 Linux-2.6.33/Documentation/filesystems/fiemap.txt の和訳です。 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > 更新日 : 2010/02/10 翻訳者 : Seiji Kaneko < skaneko at mbn dot or dot jp > ========================================================= ============ Fiemap Ioctl ============ #The fiemap ioctl is an efficient method for userspace to get file #extent mappings. Instead of block-by-block mapping (such as bmap), fiemap #returns a list of extents. fiemap ioctl はユーザ空間からファイルエクステントマッピングを得るための効 率的なメソッドです。ブロック対ブロックのマッピング (例えば bmap) の代わり に、fiemap はエクステントのリストを返します。 #Request Basics リクエストの基本 --------------- #A fiemap request is encoded within struct fiemap: fiemap リクエストは、fiemap 構造体内にエンコードされています。 #struct fiemap { # __u64 fm_start; /* logical offset (inclusive) at # * which to start mapping (in) */ # __u64 fm_length; /* logical length of mapping which # * userspace cares about (in) */ # __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */ # __u32 fm_mapped_extents; /* number of extents that were # * mapped (out) */ # __u32 fm_extent_count; /* size of fm_extents array (in) */ # __u32 fm_reserved; # struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */ #}; struct fiemap { __u64 fm_start; /* マッピングが始まる論理オフセット地点 * (入力。開始地点を含む) */ __u64 fm_length; /* ユーザ空間で考慮すべきマッピングの論 * 理長 (入力) */ __u32 fm_flags; /* リクエストの FIEMAP_FLAG_* フラグ * (入出力) */ __u32 fm_mapped_extents; /* マップされたエクステント数 (出力) */ __u32 fm_extent_count; /* fm_extents 配列のサイズ (入力) */ __u32 fm_reserved; struct fiemap_extent fm_extents[0]; /* マップされたエクステント * の配列 (出力) */ }; #fm_start, and fm_length specify the logical range within the file #which the process would like mappings for. Extents returned mirror #those on disk - that is, the logical offset of the 1st returned extent #may start before fm_start, and the range covered by the last returned #extent may end after fm_length. All offsets and lengths are in bytes. fm_start と fm_length は、プロセスがマッピング対象にしようとしているファイ ル内の論理範囲を指定します。返されるエクステントはそれらのディスク上の状態 を反映します - つまり、最初の返すエクステントの論理オフセットは fm_start より前になっているかもしれず、返す最後のエクステントの範囲は fm_length の 後を指しているかもしれません。全てのオフセット及び長さはバイト単位です。 #Certain flags to modify the way in which mappings are looked up can be #set in fm_flags. If the kernel doesn't understand some particular #flags, it will return EBADR and the contents of fm_flags will contain #the set of flags which caused the error. If the kernel is compatible #with all flags passed, the contents of fm_flags will be unmodified. #It is up to userspace to determine whether rejection of a particular #flag is fatal to it's operation. This scheme is intended to allow the #fiemap interface to grow in the future but without losing #compatibility with old software. マッピングの検索方法を変更するためのフラグは fm_flags で設定できます。カー ネルに一部のフラグが理解できなかった場合、EBADR が返され、fm_flags にはエ ラーの原因となったフラグ群が格納されます。カーネルが渡されたフラグ全てに互 換な場合、fm_flags の内容は変更されません。特定のフラグが拒否されたことが 処理上致命的であるかどうかの判断は、ユーザ空間側に任されます。この方法は fiemap インターフェースの将来の拡張を、従来のソフトウェアへの互換性を失わ ず対処することを意図しています。 #fm_extent_count specifies the number of elements in the fm_extents[] array #that can be used to return extents. If fm_extent_count is zero, then the #fm_extents[] array is ignored (no extents will be returned), and the #fm_mapped_extents count will hold the number of extents needed in #fm_extents[] to hold the file's current mapping. Note that there is #nothing to prevent the file from changing between calls to FIEMAP. fm_extent_count は fm_extents[] 配列でエクステントを返すのに使用できる要 素数を指定します。fm_extent_count の値が 0 の場合、fm_extents[] 配列は無 視され、エクステントは返されません。また、fm_mapped_extents にはファイ ルの現在のマッピングを fm_extents[] に格納するのに必要なエクステント数が 返されます。但し、FIEMAP のコール間でファイルが変更されるのを防止するもの は何もありません。 #The following flags can be set in fm_flags: 以下のフラグが fm_flags で設定可能です: * FIEMAP_FLAG_SYNC #If this flag is set, the kernel will sync the file before mapping extents. このフラグがセットされている場合、エクステントマップの前にカーネルはファイ ルを sync します。 * FIEMAP_FLAG_XATTR #If this flag is set, the extents returned will describe the inodes #extended attribute lookup tree, instead of it's data tree. このフラグがセットされている場合、戻されるエクステントは inode のデータツ リーではなく、 拡張アトリビュートルックアップツリーに対応したものになりま す。 #Extent Mapping エクステントマッピング ---------------------- #Extent information is returned within the embedded fm_extents array #which userspace must allocate along with the fiemap structure. The #number of elements in the fiemap_extents[] array should be passed via #fm_extent_count. The number of extents mapped by kernel will be #returned via fm_mapped_extents. If the number of fiemap_extents #allocated is less than would be required to map the requested range, #the maximum number of extents that can be mapped in the fm_extent[] #array will be returned and fm_mapped_extents will be equal to #fm_extent_count. In that case, the last extent in the array will not #complete the requested range and will not have the FIEMAP_EXTENT_LAST #flag set (see the next section on extent flags). エクステントの情報は fm_extents 配列に埋め込んで返されるため、ユーザ空間 では fiemap 構造体とは別にメモリを割り当てなければいけません。 fiemap_extents[] 配列の要素数は fm_extent_count を用いて渡すべきです。カ ーネルがマップしたエクステント数は、fm_mapped_extents に格納して戻されま す。割り当てられた fiemap_extents 数が要求された範囲をマップするのに必要 な数より小さい場合、fm_extent[] 配列にマップ可能なエクステントの最大数が戻 され、fm_mapped_extents の値は fm_extent_count と同じになります。この場 合、配列の最後のエクステントは要求された範囲のマップを完了したものとはなら ず、FIEMAP_EXTENT_LAST フラグはセットされないでしょう (次節のエクステン トフラグの説明を参照ください)。 #Each extent is described by a single fiemap_extent structure as #returned in fm_extents. 各エクステントは、一つの fiemap_extent 構造体で記述され、fm_extents に格 納されて戻されます。 #struct fiemap_extent { # __u64 fe_logical; /* logical offset in bytes for the start of # * the extent */ # __u64 fe_physical; /* physical offset in bytes for the start # * of the extent */ # __u64 fe_length; /* length in bytes for the extent */ # __u64 fe_reserved64[2]; # __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */ # __u32 fe_reserved[3]; #}; struct fiemap_extent { __u64 fe_logical; /* エクステントの開始地点のバイト単位の論理 * オフセット */ __u64 fe_physical; /* エクステントの開始地点のバイト単位の物理 * オフセット */ __u64 fe_length; /* エクステントのバイト単位の長さ */ __u64 fe_reserved64[2]; __u32 fe_flags; /* このエクステントの FIEMAP_EXTENT_* フラグ */ __u32 fe_reserved[3]; }; #All offsets and lengths are in bytes and mirror those on disk. It is valid #for an extents logical offset to start before the request or it's logical #length to extend past the request. Unless FIEMAP_EXTENT_NOT_ALIGNED is #returned, fe_logical, fe_physical, and fe_length will be aligned to the #block size of the file system. With the exception of extents flagged as #FIEMAP_EXTENT_MERGED, adjacent extents will not be merged. 各オフセットと長さの値はバイト単位で、ディスク上の値を反映しています。エク ステントの開始地点の論理オフセットがリクエストでの要求地点の前から始まって いること、および拡張する論理長がリクエストの後となることが許されています。 FIEMAP_EXTENT_NOT_ALIGNED が戻されていない場合には、fe_logical, fe_physical, fe_length はファイルシステムのブロックサイズにアラインされ ています。FIEMAP_EXTENT_MERGED フラグがセットされたエクステントを除いて は、隣り合ったエクステントはマージされません。 #The fe_flags field contains flags which describe the extent returned. #A special flag, FIEMAP_EXTENT_LAST is always set on the last extent in #the file so that the process making fiemap calls can determine when no #more extents are available, without having to call the ioctl again. fe_flags フィールドには戻されたエクステントを記述したフラグが格納されます。 特別のフラグ FIEMAP_EXTENT_LAST はファイルの最後のエクステントで常にセッ トされ、fiemap 呼び出しを行ったプロセスがそれ以上のエクステントがないとい う判断を、再度 ioctl の呼び出しを行うことなく行えます。 #Some flags are intentionally vague and will always be set in the #presence of other more specific flags. This way a program looking for #a general property does not have to know all existing and future flags #which imply that property. 一部のフラグは意図的に曖昧な意味づけがされており、他のより詳細なフラグを加 えてセットされます。このようにして一般的なプロパティを見ようとするプログラ ムが、既存あるいは将来のこの方針に従うフラグの全てを理解する必要がないよう にしています。 #For example, if FIEMAP_EXTENT_DATA_INLINE or FIEMAP_EXTENT_DATA_TAIL #are set, FIEMAP_EXTENT_NOT_ALIGNED will also be set. A program looking #for inline or tail-packed data can key on the specific flag. Software #which simply cares not to try operating on non-aligned extents #however, can just key on FIEMAP_EXTENT_NOT_ALIGNED, and not have to #worry about all present and future flags which might imply unaligned #data. Note that the opposite is not true - it would be valid for #FIEMAP_EXTENT_NOT_ALIGNED to appear alone. 例えば、FIRMAP_EXTENT_DATA_INLINE または FIEMAP_EXTENT_DATA_TAIL がセッ トされている場合、FIEMAP_EXTENT_NOT_ALIGNED が同時にセットされているでし ょう。インラインまたは末尾にパックされたデータは所定のフラグを鍵として処理 できます。アラインされていないエクステントの処理を行わないようにすることだ けを考慮しているソフトウェアは、単に FIEMAP_EXTENT_NOT_ALIGNED を鍵とし て処理を行うことができ、データがアラインされていないことを暗黙で含む既存あ るいは将来のフラグのことを心配する必要はありません。但し、この逆は言えませ ん。つまり、FIEMAP_EXTENT_NOT_ALIGNED が単体で現れることには問題はありま せん。 * FIEMAP_EXTENT_LAST #This is the last extent in the file. A mapping attempt past this #extent will return nothing. これはファイルの最後のエクステントです。このエクステント以降でのマッピング の試行は、何も返しません。 * FIEMAP_EXTENT_UNKNOWN #The location of this extent is currently unknown. This may indicate #the data is stored on an inaccessible volume or that no storage has #been allocated for the file yet. このエクステントの位置は現在不明です。これは、データが (現在) アクセスでき ないボリュームに格納されているか、当該ファイルに記憶領域がまだ割り当てられ ていない、などを示唆します。 * FIEMAP_EXTENT_DELALLOC # - This will also set FIEMAP_EXTENT_UNKNOWN. #Delayed allocation - while there is data for this extent, it's #physical location has not been allocated yet. 同時に FIEMAP_EXTENT_UNKNOWN もセットされています。 遅延割り当て関連 - このエクステントにデータはありますが、物理位置はまだ割 り当てられてはいません。 * FIEMAP_EXTENT_ENCODED #This extent does not consist of plain filesystem blocks but is #encoded (e.g. encrypted or compressed). Reading the data in this #extent via I/O to the block device will have undefined results. このエクステントにはプレーンなファイルシステムブロックを含まず、何らかのエ ンコードがされています (例えば、暗号化や圧縮などが行われている)。このエク ステントからブロックデバイス入出力経由でデータを読み出した場合、結果は不定 になります。 #Note that it is *always* undefined to try to update the data #in-place by writing to the indicated location without the #assistance of the filesystem, or to access the data using the #information returned by the FIEMAP interface while the filesystem #is mounted. In other words, user applications may only read the #extent data via I/O to the block device while the filesystem is #unmounted, and then only if the FIEMAP_EXTENT_ENCODED flag is #clear; user applications must not try reading or writing to the #filesystem via the block device under any other circumstances. 注意が必要なのは、ファイルシステムの助けなしに指された位置に直接書き込むこ とでデータを更新した場合の結果、および FIEMAP インターフェースで返された情 報を使ってマウントされているファイルシステムのデータをアクセスした結果は *常に*予測できないということです。言い換えれば、ユーザアプリケーションが ブロックデバイスに対する入出力処理を用いてエクステントデータを読み取り可能 なのは、ファイルシステムがマウントされていないときだけであり、さらに FIEMAP_EXTENT_ENCODED フラグがセットされていないときのみだということです。 それ以外の状況では、ユーザアプリケーションはブロックデバイス経由でファイル システムに対する読み書き処理を行ってはいけません。 * FIEMAP_EXTENT_DATA_ENCRYPTED # - This will also set FIEMAP_EXTENT_ENCODED #The data in this extent has been encrypted by the file system. 同時に FIEMAP_EXTENT_ENCODED がセットされています。 このエクステントのデータはファイルシステムにより暗号化されています。 * FIEMAP_EXTENT_NOT_ALIGNED #Extent offsets and length are not guaranteed to be block aligned. エクステントのオフセットとサイズは、ブロック境界にアラインされているという 保証がありません。 * FIEMAP_EXTENT_DATA_INLINE # This will also set FIEMAP_EXTENT_NOT_ALIGNED #Data is located within a meta data block. 同時に FIEMAP_EXTENT_NOT_ALIGNED がセットされています。 データはメタデータブロック内に配置されています。 * FIEMAP_EXTENT_DATA_TAIL # This will also set FIEMAP_EXTENT_NOT_ALIGNED #Data is packed into a block with data from other files. 同時に FIEMAP_EXTENT_NOT_ALIGNED がセットされています。 データは他のファイルのデータと一緒にブロックに圧縮格納されています。 * FIEMAP_EXTENT_UNWRITTEN #Unwritten extent - the extent is allocated but it's data has not been #initialized. This indicates the extent's data will be all zero if read #through the filesystem but the contents are undefined if read directly from #the device. 未書き込みエクステント - エクステントは割り当てられていますが、データ内容 は初期化されていません。これは、ファイルシステム経由でデータを読み出した場 合には全て 0 に、デバイスを直接読み出した場合には内容は不定であることを示 します。 * FIEMAP_EXTENT_MERGED #This will be set when a file does not support extents, i.e., it uses a block #based addressing scheme. Since returning an extent for each block back to #userspace would be highly inefficient, the kernel will try to merge most #adjacent blocks into 'extents'. このフラグは、ファイルがエクステントをサポートしていない場合にセットされま す。即ち、ファイルではブロックベースのアドレス手法が使われています。この場 合、各ブロックのエクステントをユーザ空間に戻すのがとても非効率なため、カー ネルは殆どの隣接ブロックを『エクステント』としてマージしようとします。 #VFS -> File System Implementation VFS -> ファイルシステムの実装 ---------------------------- #File systems wishing to support fiemap must implement a ->fiemap callback on #their inode_operations structure. The fs ->fiemap call is responsible for #defining it's set of supported fiemap flags, and calling a helper function on #each discovered extent: fiemap をサポートしたいファイルシステムでは、inode_operaton 構造体に対し て ->fiemap コールバックを実装しなければいけません。fs の ->fiemap コー ルはサポートしている fiemap フラグの定義と、発見された各エクステントに対 するヘルパー関数の呼び出しに責任があります。 struct inode_operations { ... int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); #->fiemap is passed struct fiemap_extent_info which describes the #fiemap request: ->fiemap には、fiemap リクエストを記載した fiemap_extent_info 構造体が渡 されます。 #struct fiemap_extent_info { # unsigned int fi_flags; /* Flags as passed from user */ # unsigned int fi_extents_mapped; /* Number of mapped extents */ # unsigned int fi_extents_max; /* Size of fiemap_extent array */ # struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent array */ #}; struct fiemap_extent_info { unsigned int fi_flags; /* ユーザから渡されたフラグ群 */ unsigned int fi_extents_mapped; /* マップされたエクステント数 */ unsigned int fi_extents_max; /* fiemap_extent 配列のサイズ */ struct fiemap_extent *fi_extents_start; /* fiemap_extent 配列の */ /* 開始ポインタ */ }; #It is intended that the file system should not need to access any of this #structure directly. これは、ファイルシステムがこの構造体のどの要素にも直接アクセスする必要がな いようにすることを意図しています。 #Flag checking should be done at the beginning of the ->fiemap callback via the #fiemap_check_flags() helper: フラグ検査は、->fiemap コールバックの最初で fiemap_check_flags() ヘルパ ー関数を使って行うべきです。 int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); #The struct fieinfo should be passed in as received from ioctl_fiemap(). The #set of fiemap flags which the fs understands should be passed via fs_flags. If #fiemap_check_flags finds invalid user flags, it will place the bad values in #fieinfo->fi_flags and return -EBADR. If the file system gets -EBADR, from #fiemap_check_flags(), it should immediately exit, returning that error back to #ioctl_fiemap(). fieinfo 構造体は ioctl_fiemap() から渡されたまま転送すべきです。ファイル システムが理解している fiemap フラグの集合は、fs_flags を用いて渡すべきで す。fiemap_check_flags は不正なユーザフラグを見つけた場合、不正部の値を fieinfo->fi_flags に置き、-EBADR を返します。ファイルシステムが -EBADR を fiemap_check_flags から受けた場合、エラーを ioctl_fiemap() に返して 即座に戻るべきです。 #For each extent in the request range, the file system should call #the helper function, fiemap_fill_next_extent(): リクエスト範囲の各エクステントに対して、ファイルシステムはヘルパー関数 fiemap_fill_next_extent() を呼ぶべきです。 int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical, u64 phys, u64 len, u32 flags, u32 dev); #fiemap_fill_next_extent() will use the passed values to populate the #next free extent in the fm_extents array. 'General' extent flags will #automatically be set from specific flags on behalf of the calling file #system so that the userspace API is not broken. fiemap_fill_next_extent() は渡された値を、fm_extent 配列の次のフリーなエ クステントを埋めるために使います。『汎用の』エクステントフラグが、ユーザ 空間 API に違反しないようにファイルシステムを呼び出すため、所定のフラグ から自動的にセットされます。 #fiemap_fill_next_extent() returns 0 on success, and 1 when the #user-supplied fm_extents array is full. If an error is encountered #while copying the extent to user memory, -EFAULT will be returned. fiemap_fill_next_extent() は成功時に 0 を返し、ユーザの提供した fm_extent 配列が一杯だった場合には 1 を返します。エクステントのユーザメモ リへのコピー時にエラーになった場合には、-EFAULT を返します。