第65章 ブロック I/O ( bio )

bio はブロック I/O の略のはずです。

まあ知らんですけど、名前の由来はそれ以外にないと思います。

struct bio は struct bio_vec というリストからページにマッピングされます。

// /usr/src/linux-headers-4.18.16-041816-generic/include/linux/blk_types.h
140 /*
141  * main unit of I/O for the block layer and lower layers (ie drivers and
142  * stacking drivers)
143  */
144 struct bio {
145   struct bio    *bi_next; /* request queue link */
146   struct gendisk    *bi_disk;
147   unsigned int    bi_opf;   /* bottom bits req flags,
148              * top bits REQ_OP. Use
149              * accessors.
150              */
151   unsigned short    bi_flags; /* status, etc and bvec pool number */
152   unsigned short    bi_ioprio;
153   unsigned short    bi_write_hint;
154   blk_status_t    bi_status;
155   u8      bi_partno;
156
157   /* Number of segments in this BIO after
158    * physical address coalescing is performed.
159    */
160   unsigned int    bi_phys_segments;
161
162   /*
163    * To keep track of the max segment size, we account for the
164    * sizes of the first and last mergeable segments in this bio.
165    */

166   unsigned int    bi_seg_front_size;
167   unsigned int    bi_seg_back_size;
168
169   struct bvec_iter  bi_iter;
170
171   atomic_t    __bi_remaining;
172   bio_end_io_t    *bi_end_io;
173
174   void      *bi_private;
175 #ifdef CONFIG_BLK_CGROUP
176   /*
177    * Optional ioc and css associated with this bio.  Put on bio
178    * release.  Read comment on top of bio_associate_current().
179    */
180   struct io_context *bi_ioc;
181   struct cgroup_subsys_state *bi_css;
182 #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
183   void      *bi_cg_private;
184   struct bio_issue  bi_issue;
185 #endif
186 #endif
187   union {
188 #if defined(CONFIG_BLK_DEV_INTEGRITY)
189     struct bio_integrity_payload *bi_integrity; /* data integrity */
190 #endif
191   };
192
193   unsigned short    bi_vcnt;  /* how many bio_vec's */
194
195   /*
196    * Everything starting with bi_max_vecs will be preserved by bio_reset()
197    */
198
199   unsigned short    bi_max_vecs;  /* max bvl_vecs we can hold */
200
201   atomic_t    __bi_cnt; /* pin count */
202
203   struct bio_vec    *bi_io_vec; /* the actual vec list */
204
205   struct bio_set    *bi_pool;
206
207   /*
208    * We can inline a number of vecs at the end of the bio, to avoid
209    * double allocations for a small number of bio_vecs. This member
210    * MUST obviously be kept at the very end of the bio.
211    */
212   struct bio_vec    bi_inline_vecs[0];
213 };

 図を見ながら説明したほうが早いので図を見てください。

img/bio.png

 ざっくり説明するとブロックとページがマップされているということです。

 さらに struct bio の他に struct bio_vec という構造体のリスト、イテレーターオブジェクトである struct bvec_iter がありますね。

struct bvec_iter
bio_vec のイテレーター
struct bio_vec
ページにマップされるブロックオブジェクト

 では宣言・定義を見てくださいね。

// /usr/src/linux-headers-4.18.16-041816-generic/include/linux/bvec.h
 30 struct bio_vec {
 31   struct page *bv_page;
 32   unsigned int  bv_len;
 33   unsigned int  bv_offset;
 34 };
 35
 36 struct bvec_iter {
 37   sector_t    bi_sector;  /* device address in 512 byte
 38                sectors */
 39   unsigned int    bi_size;  /* residual I/O count */
 40
 41   unsigned int    bi_idx;   /* current index into bvl_vec */
 42
 43   unsigned int            bi_done;  /* number of bytes completed */
 44
 45   unsigned int            bi_bvec_done; /* number of bytes completed in
 46                current bvec */
 47 };

 ブロック I/O は bio_vec の bv_page でページとリンクし bvec_iter の bi_idx がイテレーター・添字として機能するような感じですかね。

 まあ詳しくは bvec.h のソースを見てください。

Copyright 2018-2019, by Masaki Komatsu