open() / read() 関数の処理は O_DIRECT フラグを設定した場合を除いてページキャッシュというレイヤーに依存しています。
紛らわしいですがページキャッシュ内では inode オブジェクトのことをオーナー(所有者)と呼びます。
基本やってることは、
ですね。
例えば inode と inode 内のインデックス(添字)から検索する機能ですね。
このページキャッシュで最も重要なオブジェクトが struct address_space です。
struct address_space は inode オブジェクトのメンバーです。
// /usr/src/linux-headers-4.18.16-041816-generic/include/linux/fs.h
572 struct inode {
586 struct address_space *i_mapping;キャッシュ内の複数のページが同じ inode を参照し、と同時に address_space とリンクされることができます。
まあこの辺は inode と address_space 構造体のメンバーが相互にリンクをはっているので明らかだと思います。
そして address_space はページ記述子( page )のメンバーでもあります。
// /usr/src/linux-headers-4.18.16-041816-generic/include/linux/mm_types.h
70 struct page {
88 struct address_space *mapping;
89 pgoff_t index; /* Our offset within mapping. */mapping はページを所有する inode の struct address_space を指します。
index はオーナー( inode )のディスクイメージ内の位置、またはページ内のオフセットです。
次は address_space を見てみましょう。
// /usr/src/linux-headers-4.18.16-041816-generic/include/linux/fs.h
394 struct address_space {
395 struct inode *host; /* owner: inode, block_device */
396 struct radix_tree_root i_pages; /* cached pages */
397 atomic_t i_mmap_writable;/* count VM_SHARED mappings */
398 struct rb_root_cached i_mmap; /* tree of private and shared mappings */
399 struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */
400 /* Protected by the i_pages lock */
401 unsigned long nrpages; /* number of total pages */
402 /* number of shadow or DAX exceptional entries */
403 unsigned long nrexceptional;
404 pgoff_t writeback_index;/* writeback starts here */
405 const struct address_space_operations *a_ops; /* methods */
406 unsigned long flags; /* error bits */
407 spinlock_t private_lock; /* for use by the address_space */
408 gfp_t gfp_mask; /* implicit gfp mask for allocations */
409 struct list_head private_list; /* for use by the address_space */
410 void *private_data; /* ditto */
411 errseq_t wb_err;
412 } __attribute__((aligned(sizeof(long)))) __randomize_layout;この中で特に重要な行は以下です。
396 struct radix_tree_root i_pages; /* cached pages */ 398 struct rb_root_cached i_mmap; /* tree of private and shared mappings */
i_pages は基数木で整理されたページ記述子( struct page )とマップします。
i_pages は「 page_tree 」から変更されたようです。昔のマニュアルや書籍を見ると page_tree となってるものが多いですね。
rb_root_cached は赤黒木 ( red-black tree) ですね。
てなことで i_mmap には vm_area_struct がマップされます。

address_space の強さというのは inode オブジェクトへのポインターと、前述した page と file と inode オブジェクトと(メンバーポインターにより)リンクされている点ですかね。
まあページの読み書きにキャッシュを使うのは OS やコンピューターのアーキテクチャーからすれば至極当然なので、驚きはないでしょうがね。
ちなみに address_space に何らかの操作をするなら address_space_operations オブジェクト内の関数ポインターを見ると良いでしょう。
334 struct address_space_operations {
335 int (*writepage)(struct page *page, struct writeback_control *wbc);
336 int (*readpage)(struct file *, struct page *);
337
338 /* Write back some dirty pages from this mapping. */
339 int (*writepages)(struct address_space *, struct writeback_control *);
340
341 /* Set a page dirty. Return true if this dirtied it */
342 int (*set_page_dirty)(struct page *page);
343
344 int (*readpages)(struct file *filp, struct address_space *mapping,
345 struct list_head *pages, unsigned nr_pages);
346
347 int (*write_begin)(struct file *, struct address_space *mapping,
348 loff_t pos, unsigned len, unsigned flags,
349 struct page **pagep, void **fsdata);
350 int (*write_end)(struct file *, struct address_space *mapping,
351 loff_t pos, unsigned len, unsigned copied,
352 struct page *page, void *fsdata);
353
354 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
355 sector_t (*bmap)(struct address_space *, sector_t);
356 void (*invalidatepage) (struct page *, unsigned int, unsigned int);
357 int (*releasepage) (struct page *, gfp_t);
358 void (*freepage)(struct page *);
359 ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
360 /*
361 * migrate the contents of a page to the specified target. If
362 * migrate_mode is MIGRATE_ASYNC, it must not block.
363 */
364 int (*migratepage) (struct address_space *,
365 struct page *, struct page *, enum migrate_mode);
366 bool (*isolate_page)(struct page *, isolate_mode_t);
367 void (*putback_page)(struct page *);
368 int (*launder_page) (struct page *);
369 int (*is_partially_uptodate) (struct page *, unsigned long,
370 unsigned long);
371 void (*is_dirty_writeback) (struct page *, bool *, bool *);
372 int (*error_remove_page)(struct address_space *, struct page *);
373
374 /* swapfile support */
375 int (*swap_activate)(struct swap_info_struct *sis, struct file *file,
376 sector_t *span);
377 void (*swap_deactivate)(struct file *file);
378 };wirtepages とか readpages とか明らかにページと関係する名前の関数ポインターが宣言されてますよね。
Copyright 2018-2019, by Masaki Komatsu