·¢²©ÎÄ
¸öÈË×ÊÁÏ
  • ²©¿Í·ÃÎÊ£º101625
  • ²©ÎÄÊýÁ¿£º42
  • ²©¿Í»ý·Ö£º1400
  • ²©¿ÍµÈ¼¶£ºÉÏξ
  • ×¢²áʱ¼ä£º2008-07-23 13:16:48
¶©ÔÄÎҵIJ©¿Í
  • ¶©ÔÄ
  • ¶©Ôĵ½Ïʹû
  • ¶©Ôĵ½×¥Ïº
  • ¶©Ôĵ½Google
×ÖÌå´óС£º´ó ÖРС²©ÎÄ
·ÖÀࣺ Linux


Ò»¡¢±¾ÎÄ·ÖÎöÎļþµÄ¶Áд¹ý³Ì¡£µ±Óû§½ø³Ì·¢³öÒ»¸ö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ÖµµÄ×ÓÊ÷£¬ÕâÑù¾ÍÌá¸ßÁ˲éÕÒЧÂÊ¡£

Ç×£¬Äú»¹Ã»ÓеǼ,Çë[µÇ¼]»ò[×¢²á]ºóÔÙ½øÐÐÆÀÂÛ