
|
フィールド |
説明 |
|---|---|
|
bi_sector |
I/Oを行う領域の先頭セクタ番号 |
|
bi_next |
bioのリスト。ブロックI/Oが既存のRequestにマージされていく時にチェーンされていく。 |
|
bi_dev |
I/Oを行うブロックデバイスの構造体へのポインタ |
|
bi_rw |
I/OがRead/Writeかを示す。ビットマップになっており、同期I/Oか非同期I/Oかの情報も持つ。 |
|
bi_vcnt |
bi_io_vecに格納されているエントリ数 |
|
bi_size |
I/Oの合計サイズ(Byte) この値を512で割ってセクタ数を求めている。 |
|
bi_max_vecs |
bi_io_vecに確保されている領域のエントリ数。 (1,4,16,64,128,BIO_MAX_PAGESのいずれか) |
|
bi_io_vec |
I/O対象のページを指すリスト。struct bio_vecの配列になっている。ここで指定されたページとの間で、ブロックデバイスとデータがRead/writeされる。 |
|
bi_end_io |
I/O完了時に呼び出されるハンドラ |
|
フィールド |
説明 |
|---|---|
|
bv_page |
ページのアドレス |
|
bv_len |
データ長 |
|
bv_offset |
データ開始位置のページ内のオフセット |

|
フィールド |
説明 |
|---|---|
|
sector |
I/Oを行う開始セクタ番号 |
|
nr_sector |
I/Oを行うセクタ数 |
|
current_nr_sectors |
現在処理中のbio_vec内でのセクタ数。 |
|
hard_sector |
次にI/Oが完了するセクタの番号。 I/Oが完了するとblk_recalc_rq_sectors()で更新されていく。 |
|
hard_nr_sectors |
I/Oが完了していないセクタの数。 I/Oが完了するとblk_recalc_rq_sectors()で更新されていく。 |
|
hard_cur_sectors |
現在処理中のbio_vec内での、I/Oが完了していない残りセクタ数。 |
|
bio |
bioのリスト。 |
|
biotail |
bioのリストの最後のbio |
|
buffer |
Read/Write用バッファのアドレス。 |
/* * パーティションサイズのチェック */ do { /* デバイスのRequestQueue(bdev->bd_disk->queue)取得 */ q = bdev_get_queue(bio->bi_bdev); : ret = q->make_request_fn(q, bio); // (*1) } while (ret);
if (barrier || elv_queue_empty(q))
goto get_rq;
/* 既にElevatorにあるRequestにマージできないかチェック */
el_ret = elv_merge(q, &req, bio);
switch (el_ret) {
case ELEVATOR_BACK_MERGE: /* 既存RequestにBackMerge可 */
if (!q->back_merge_fn(q, req, bio))
break;
/* Requestのマージ
* Requestのbiotailにbioを追加
* セクタ数を加算
*/
/* マージしたことでさらに次のRequestと
* マージしようとする */
if (!attempt_back_merge(q, req))
/* マージが無理ならさっき行ったマージ分をElevatorに通知 */
elv_merged_request(q, req);
goto out;
case ELEVATOR_FRONT_MERGE: /* 既存RequestにFrontMerge可 */
if (!q->front_merge_fn(q, req, bio))
break;
/* Requestのマージ
* Requestのbioリストの先頭に追加
* データの格納アドレスを更新
* セクタ数を加算
*/
if (!attempt_front_merge(q, req))
elv_merged_request(q, req);
goto out;
default:
/* マージできないので新規Requestを作成して投入 */
;
}
get_rq:
/*
* bioからRequestを作成する
*/
req = get_request_wait(q, rw, bio);
init_request_from_bio(req, bio);
/* Elevatorが空ならRequestQueueをPlug(封鎖)して
* Requestが細切れで発行されないようにする。
*/
if (elv_queue_empty(q))
blk_plug_device(q);
/* ElevatorにRequestを投入 */
add_request(q, req);
out:
/* 同期I/OならRequestQueueをUnplugして
* すぐにI/Oを実行させる
*/
if (sync)
__generic_unplug_device(q);
return 0;