Ò»¡¢±¾ÎÄ·ÖÎöÎļþµÄ¶Áд¹ý³Ì¡£µ±Óû§½ø³Ì·¢³öÒ»¸öread()ϵͳµ÷ÓÃʱ£¬ËüÊ×ÏÈͨ¹ýVFS´Ódisk cacheÖÐÈ¥²éÕÒÏàÓ¦µÄÎļþ¿éÓÐûÓÐÒѾ±»»º´æÆðÀ´£¬Èç¹ûÓУ¬Ôò²»ÐèÒªÔٴδÓÉ豸ÖÐÈ¥¶Á£¬Ö±½Ó´ÓCACHEÖÐÈ¥¿½±´¸øÓû§»º³åÇø¾Í¿ÉÒÔÁË£¬·ñÔòËü¾ÍÒªÏÈ·ÖÅäÒ»¸ö»º³åÒ³Ãæ£¬²¢ÇÒ½«Æä¼ÓÈëµ½¶ÔÓ¦µÄinode½ÚµãµÄaddress_spaceÖУ¬ÔÙµ÷ÓÃaddress_spaceµÄreadpage()º¯Êý£¬Í¨¹ýsubmit_bio()ÏòÉ豸·¢ËÍÒ»¸öÇëÇ󣬽«ËùÐèµÄÎļþ¿é´ÓÉ豸ÖжÁÈ¡³öÀ´´æ·ÅÔÚÏÈǰ·ÖÅäµÄ»º³åÒ³ÃæÖУ¬×îºóÔÙ´Ó¸ÃÒ³ÃæÖн«ËùÐèÊý¾Ý¿½±´µ½Óû§»º³åÇø¡£

ͼ1
¶þ¡¢Ò³Ã滺³å(Page Cache)µÄ¹ÜÀí
Ò³Ãæ»º³åµÄºËÐÄÊý¾Ý½á¹¹ÊÇstruct address_space £º
struct backing_dev_info;
struct address_space {
struct inode *host; /* owner: inode, block_device */
struct radix_tree_root page_tree; /* radix tree of all pages */
rwlock_t tree_lock; /* and rwlock protecting it */
unsigned int i_mmap_writable;/* count VM_SHARED mappings */
struct prio_tree_root i_mmap; /* tree of private and shared mappings */
struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
spinlock_t i_mmap_lock; /* protect tree, count, list */
unsigned int truncate_count; /* Cover race condition with truncate */
unsigned long nrpages; /* number of total pages */
pgoff_t writeback_index;/* writeback starts here */
const struct address_space_operations *a_ops; /* methods */
unsigned long flags; /* error bits/gfp mask */
struct backing_dev_info *backing_dev_info; /* device readahead, etc */
spinlock_t private_lock; /* for use by the address_space */
struct list_head private_list; /* ditto */
struct address_space *assoc_mapping; /* ditto */
} __attribute__((aligned(sizeof(long))));
ÈçÏÂͼ2£¬»º³åÒ³ÃæµÄÊÇͨ¹ýÒ»¸ö»ùÊýÊ÷£¨Radix Tree£©À´¹ÜÀíµÄ£¬ÕâÊÇÒ»¸ö¼òµ¥µ«·Ç³£¸ßЧµÄÊ÷½á¹¹¡£

ͼ2
ÓÉͼ2¿ÉÒÔ¿´µ½£¬µ±RADIX_TREE_MAP_SHIFTΪ6£¨¼´Ã¿¸ö½ÚµãÓÐ2^6£½64¸öslot£©ÇÒÊ÷¸ßÊÇ1ʱ£¬Ëü¿ÉÒÔѰַ´óСΪ64¸öÒ³Ãæ£¨256kb£©µÄÎļþ£¬Í¬Ñù£¬µ±Ê÷¸ßΪ2ʱ£¬Ëü¿ÉÒÔѰַ64*64¸öÒ³Ãæ(16M)´óСµÄÎļþ£¬Èç´ËÏÂÈ¥£¬ÔÚ32λµÄϵͳÖУ¬Ê÷¸ßΪ6¼¶£¬£¨×î¸ß¼¶Ö»ÓÐ2λ£º32-6*5£©£¬ËùÒÔËü¿ÉÒÔѰַ2^32-1¸öÒ³Ãæ´óСµÄÎļþ£¬Ô¼Îª16TB´óС£¬ËùÒÔĿǰÀ´ËµÒѾ×ã¹»ÁË¡£
»ùÊýÊ÷µÄ±éÀúÒ²ÊǺܼòµ¥£¬ÇÒÀàËÆÓÚÐéÄâÏßÐÔµØÖ·µÄת»»¹ý³Ì¡£Ö»Òª¸ø¶¨Ê÷¸ù¼°ÎļþÆ«ÒÆ£¬¾Í¿ÉÒÔÕÒµ½ÏàÓ¦µÄ»º´æÒ³Ãæ¡£ÔÙÈçͼ2ÓÒ£¬Èç¹ûÔÚÎļþÖÐµÄÆ«ÒÆÎª131¸öÒ³Ãæ£¬Õâ¸öÆ«ÒÆÖµµÄ¸ß6λ¾ÍÊǵÚÒ»¼¶Æ«ÒÆ£¬¶øµÍ6λ¾ÍÊÇÔÚµÚ¶þ¼¶µÄÆ«ÒÆ£¬ÒÀ´ËÀàÍÆ¡£Èç¶ÔÓÚÆ«ÒÆÖµ131(10000011)£¬¸ß6λֵÊÇ131>>6 = 2£¬ËùÒÔËüÔÚµÚÒ»¼¶µÄÆ«ÒÆÊÇ2£¬¶øÔÚµÚ2¼¶µÄÁìÏξÍÊǵÍ6λ£¬ÖµÎª3£¬¼´Æ«ÒÆÎª3£¬ËùÒԵõ½µÄ½á¹ûÈçͼ2ÓÒ·½Ëùʾ¡£
#define RADIX_TREE_MAP_SHIFT (CONFIG_BASE_SMALL ? 4 : 6)
#define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT)
#define RADIX_TREE_MAX_TAGS 2
#define RADIX_TREE_TAG_LONGS \ //ÆäֵΪ64
((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG)
struct radix_tree_node {
unsigned int height; /* Height from the bottom */
unsigned int count;
struct rcu_head rcu_head;
void *slots[RADIX_TREE_MAP_SIZE];
unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS];
};
struct radix_tree_path {
struct radix_tree_node *node;
int offset;
};
ÒÔÉÏÊÇÏà¹ØµÄ¼¸¸öÊý¾Ý½á¹¹£¬µÚÒ»¸öΪÊ÷µÄ½áµã½á¹¹£¬µÚ¶þ¸öÓÃÓÚ·¾¶²éÕÒ¡£
×¢Òâ½Úµã½á¹¹ÖеÄtagsÓò£¬Õâ¸öÒ»¸öµäÐ͵ÄÓÿռ任ʱ¼äµÄÓ¦Óá£ËüÊÇÒ»¸ö¶þάÊý×飬ÓÃÓڼǼ¸Ã½ÚµãÏÂÃæµÄ×Ó½ÚµãÓÐûÓÐÏàÓ¦µÄ±êÖ¾¡£Ä¿Ç°RADIX_TREE_MAX_TAGSΪ2£¬±íʾֻ¼Ç¼Á½¸ö±êÖ¾£¬ÆäÖÐtags[0]ΪPAGE_CACHE_DIRTY£¬tags[1]ΪPAGE_CACHE_WRITEBACK¡£Ëü±íʾ£¬Èç¹ûµ±Ç°½ÚµãµÄtags[0]ֵΪ1£¬ÄÇôËüµÄ×ÓÊ÷½Úµã¾Í´æÔÚPAGE_CACHE_DIRTY½Úµã£¬·ñÔòÕâ¸ö×ÓÊ÷·ÖÖ¦¾Í²»´æÔÚ×ÅÕâÑùµÄ½Úµã£¬¾Í²»±ØÔÙ²éÕÒÕâ¸ö×ÓÊ÷ÁË¡£±ÈÈçÔÚ²éÕÒPG_dirtyµÄÒ³ÃæÊ±£¬¾Í²»ÐèÒª±éÀúÕû¸öÊ÷£¬¶ø¿ÉÒÔÌø¹ýÄÇЩtags[0]Ϊ0ÖµµÄ×ÓÊ÷£¬ÕâÑù¾ÍÌá¸ßÁ˲éÕÒЧÂÊ¡£

