Linux块设备IO子系统(二)(2)

页高速缓存的核心结构就address_space对象,他是一个嵌入在页所有者的索引节点对象中的数据结构。高速缓存中的许多页都可能属于一个所有者,从而可能被链接到同一个address_space对象。该对象还在所有者的页和对这些页的操作之间建立起链接关系。

412 struct address_space { 413 struct inode *host; /* owner: inode, block_device */ 414 struct radix_tree_root page_tree; /* radix tree of all pages */ 415 spinlock_t tree_lock; /* and lock protecting it */ 416 unsigned int i_mmap_writable;/* count VM_SHARED mappings */ 417 struct rb_root i_mmap; /* tree of private and shared mappings */ 418 struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ 419 struct mutex i_mmap_mutex; /* protect tree, count, list */ 420 /* Protected by tree_lock together with the radix tree */ 421 unsigned long nrpages; /* number of total pages */ 422 pgoff_t writeback_index;/* writeback starts here */ 423 const struct address_space_operations *a_ops; /* methods */ 424 unsigned long flags; /* error bits/gfp mask */ 425 struct backing_dev_info *backing_dev_info; /* device readahead, etc */ 426 spinlock_t private_lock; /* for use by the address_space */ 427 struct list_head private_list; /* ditto */ 428 void *private_data; /* ditto */ 429 } __attribute__((aligned(sizeof(long))));

struct address_space
--413-->这个address_space对象所属的inode对象
--414-->这个address_space对象拥有的radix_tree_root对象
--425-->指向backing_dev_info对象,这个对象描述了所有者的数据所在的块设备,通常嵌入在块设备的请求队列描述符中。

radix_tree_root

描述一个radix树的根,内核使用这个数据结构快速的查找增删一个inode拥有的页高速缓存页

64 struct radix_tree_root { 65 unsigned int height; 66 gfp_t gfp_mask; 67 struct radix_tree_node __rcu *rnode; 68 }; 50 struct radix_tree_node { 51 unsigned int height; /* Height from the bottom */ 52 unsigned int count; 53 union { 54 struct radix_tree_node *parent; /* Used when ascending tree */ 55 struct rcu_head rcu_head; /* Used when freeing node */ 56 }; 57 void __rcu *slots[RADIX_TREE_MAP_SIZE]; 58 unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; 59 };

struct radix_tree_node
--51-->当前树的深度,不包括叶子节点的层数
--52-->记录节点中非空指针数量的计数器
--57-->slot是包含64个指针的数组,每个元素可以指向其他节点(struct radix_tree_node)或者页描述符(struct page),上层节点指向其他节点,底层节点指向页描述符(叶子节点)
--58-->tag二维数组用于对radix_tree_node基树进行标记,下面就是一个页可能的标志

74 enum pageflags { 75 PG_locked, /* Page is locked. Don't touch. */ 76 PG_error, 77 PG_referenced, 78 PG_uptodate, 79 PG_dirty, 80 PG_lru, 81 PG_active, 82 PG_slab, 83 PG_owner_priv_1, /* Owner use. If pagecache, fs may use*/ 84 PG_arch_1, 85 PG_reserved, 86 PG_private, /* If pagecache, has fs-private data */ 87 PG_private_2, /* If pagecache, has fs aux data */ 88 PG_writeback, /* Page is under writeback */ 93 PG_compound, /* A compound page */ 95 PG_swapcache, /* Swap page: swp_entry_t in private */ 96 PG_mappedtodisk, /* Has blocks allocated on-disk */ 97 PG_reclaim, /* To be reclaimed asap */ 98 PG_swapbacked, /* Page is backed by RAM/swap */ 99 PG_unevictable, /* Page is "unevictable" */ 112 __NR_PAGEFLAGS, 113 114 /* Filesystems */ 115 PG_checked = PG_owner_priv_1, 116 117 /* Two page bits are conscripted by FS-Cache to maintain local caching 118 * state. These bits are set on pages belonging to the netfs's inodes 119 * when those inodes are being locally cached. 120 */ 121 PG_fscache = PG_private_2, /* page backed by cache */ 122 123 /* XEN */ 124 PG_pinned = PG_owner_priv_1, 125 PG_savepinned = PG_dirty, 126 127 /* SLOB */ 128 PG_slob_free = PG_private, 129 }; page

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/4ca64b8b1a5f9dbca329cf4c31e7b0aa.html