寄り道
という訳でもないのですが、とりあえず do_sync_read() から追い掛けてみる事に。
関数定義の先頭部分から
ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret;
引数をセットしている iov の struct iovec 型は include/linux/uio.h にて定義
struct iovec { void __user *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */ __kernel_size_t iov_len; /* Must be size_t (1003.1g) */ };
ちなみにはてなの伊藤直也さんのエントリにおいて_read が通常の同期 read 時。aio_read は非同期I/O (AIO) API で呼ばれたとき。_という記述がある。
今置いかけてる do_sync_read() はその名の通り、同期 read のはず。というナニで見てみるに以降の処理
init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; for (;;) { ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); }
では、kiocb を同期とって aio_read (おそらくインターフェース) を読んでいる。同期の所以はこれかな、と類推。kiocb という構造体も include/linux/aio.h にて定義されてます。(引用は略
とりあえず、iovec という構造体と kiocb という構造体についてもう少し確認しといた方が良さげな感じ。Linux カーネル 2.6 解読室方面にもこのあたりの記述があるみたいですが、連休でじっくり掘り返してみる予定。