亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

linux內核數(shù)據(jù)結構之鏈表

系統(tǒng) 1906 0

linux內核數(shù)據(jù)結構之鏈表

1、前言

   最近寫代碼需用到鏈表結構,正好公共庫有關于鏈表的。第一眼看時,覺得有點新鮮,和我之前見到的鏈表結構不一樣,只有前驅和后繼指針,而沒有數(shù)據(jù)域。后來看代碼注釋發(fā)現(xiàn)該代碼來自linux內核,在linux源代碼下include/Lish.h下。這個鏈表具備通用性,使用非常方便。只需要在結構定義一個鏈表結構就可以使用。

2、鏈表介紹

  鏈表是非常基本的數(shù)據(jù)結構,根據(jù)鏈個數(shù)分為單鏈表、雙鏈表,根據(jù)是否循環(huán)分為單向鏈表和循環(huán)鏈表。通常定義定義鏈表結構如下:

      
        typedef 
        
          struct
        
        
           node { ElemType data; 
          
            //數(shù)據(jù)域 
          
        
        
          struct
        
         node *
        
          next; 
          
            //指針域
          
           }node, 
        
        *list;
      
    

鏈表中包含數(shù)據(jù)域和指針域。鏈表通常包含一個頭結點,不存放數(shù)據(jù),方便鏈表操作。單向循環(huán)鏈表結構如下圖所示:

雙向循環(huán)鏈表結構如下圖所示:

linux內核數(shù)據(jù)結構之鏈表

  這樣帶數(shù)據(jù)域的鏈表降低了鏈表的通用性,不容易擴展。linux內核定義的鏈表結構不帶數(shù)據(jù)域,只需要兩個指針完成鏈表的操作。具備非常高的擴展性,通用性。鏈表結構定義如下所示:

      
        
          struct
        
        
           list_head { 
        
        
          struct
        
         list_head *next, *
        
          prev; };
        
      
    

鏈表結構如下所示:

  需要用鏈表結構時,只需要在結構體中定義一個鏈表類型的數(shù)據(jù)即可。例如定義一個app_info鏈表,

      
        
          1
        
         typedef 
        
          struct
        
        
           application_info 
        
        
          2
        
        
          { 
        
        
          3
        
        
           uint32_t app_id; 
        
        
          4
        
        
           uint32_t up_flow; 
        
        
          5
        
        
           uint32_t down_flow; 
        
        
          6
        
        
          struct
        
            list_head app_info_head;  
        
          //
        
        
          鏈表節(jié)點
        
        
          7
        
         }app_info;
      
    

定義一個app_info鏈表,app_info app_info_list;通過app_info_head進行鏈表操作。根據(jù)C語言指針操作,通過container_of和offsetof,可以根據(jù)app_info_head的地址找出app_info的起始地址,即一個完整ap_info結構的起始地址。可以參考: http://www.cnblogs.com/Anker/p/3472271.html

3、linux內核鏈表實現(xiàn)

  內核實現(xiàn)的是雙向循環(huán)鏈表,提供了鏈表操作的基本功能。

(1)初始化鏈表頭結點

      
        
          #define
        
         LIST_HEAD_INIT(name) { &(name), &(name) }




        
          #define
        
         LIST_HEAD(name) \

    
        
          struct
        
         list_head name =
        
           LIST_HEAD_INIT(name) 
        
        
          static
        
         inline 
        
          void
        
         INIT_LIST_HEAD(
        
          struct
        
         list_head *
        
          list) { list
        
        ->next =
        
           list; list
        
        ->prev =
        
           list; }
        
      
    

LIST_HEAD宏創(chuàng)建一個鏈表頭結點,并用LIST_HEAD_INIT宏對頭結點進行賦值,使得頭結點的前驅和后繼指向自己。

INIT_LIST_HEAD函數(shù)對鏈表進行初始化,使得前驅和后繼指針指針指向頭結點。

(2)插入節(jié)點

      
        
           1
        
        
          static
        
         inline 
        
          void
        
         __list_add(
        
          struct
        
         list_head *
        
          new
        
        
          , 
        
        
           2
        
        
          struct
        
         list_head *
        
          prev, 
        
        
           3
        
        
          struct
        
         list_head *
        
          next) 
        
        
           4
        
        
          { 
        
        
           5
        
             next->prev = 
        
          new
        
        
          ; 
        
        
           6
        
        
          new
        
        ->next =
        
           next; 
        
        
           7
        
        
          new
        
        ->prev =
        
           prev; 
        
        
           8
        
             prev->next = 
        
          new
        
        
          ; 
        
        
           9
        
        
          } 
        
        
          10
        
        
          11
        
        
          static
        
         inline 
        
          void
        
         list_add(
        
          struct
        
         list_head *
        
          new
        
        , 
        
          struct
        
         list_head *
        
          head) 
        
        
          12
        
        
          { 
        
        
          13
        
             __list_add(
        
          new
        
        , head, head->
        
          next); 
        
        
          14
        
        
          } 
        
        
          15
        
        
          16
        
        
          static
        
         inline 
        
          void
        
         list_add_tail(
        
          struct
        
         list_head *
        
          new
        
        , 
        
          struct
        
         list_head *
        
          head) 
        
        
          17
        
        
          { 
        
        
          18
        
             __list_add(
        
          new
        
        , head->
        
          prev, head); 
        
        
          19
        
         }
      
    

  插入節(jié)點分為從鏈表頭部插入list_add和鏈表尾部插入list_add_tail,通過調用__list_add函數(shù)進行實現(xiàn),head->next指向之一個節(jié)點,head->prev指向尾部節(jié)點。

(3)刪除節(jié)點

      
        
           1
        
        
          static
        
         inline 
        
          void
        
         __list_del(
        
          struct
        
         list_head * prev, 
        
          struct
        
         list_head *
        
           next) 
        
        
           2
        
        
          { 
        
        
           3
        
             next->prev =
        
           prev; 
        
        
           4
        
             prev->next =
        
           next; 
        
        
           5
        
        
          } 
        
        
           6
        
        
           7
        
        
          static
        
         inline 
        
          void
        
         list_del(
        
          struct
        
         list_head *
        
          entry) 
        
        
           8
        
        
          { 
        
        
           9
        
             __list_del(entry->prev, entry->
        
          next); 
        
        
          10
        
             entry->next =
        
           LIST_POISON1; 
        
        
          11
        
             entry->prev =
        
           LIST_POISON2; 
        
        
          12
        
         }
      
    

  從鏈表中刪除一個節(jié)點,需要改變該節(jié)點前驅節(jié)點的后繼結點和后繼結點的前驅節(jié)點。最后設置該節(jié)點的前驅節(jié)點和后繼結點指向 LIST_POSITION1和LIST_POSITION2兩個特殊值,這樣設置是為了保證不在鏈表中的節(jié)點項不可訪問,對LIST_POSITION1和LIST_POSITION2的訪問都將引起頁故障

      
        
          /*
        
        
           * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. 
        
        
          */
        
        
          #define
        
         LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)


        
          #define
        
         LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)
      
    

(4)移動節(jié)點

      
        
           1
        
        
          /*
        
        
          * 
        
        
           2
        
        
           * list_move - delete from one list and add as another's head 
        
        
           3
        
        
           * @list: the entry to move 
        
        
           4
        
        
           * @head: the head that will precede our entry 
        
        
           5
        
        
          */
        
        
           6
        
        
          static
        
         inline 
        
          void
        
         list_move(
        
          struct
        
         list_head *list, 
        
          struct
        
         list_head *
        
          head) 
        
        
           7
        
        
          { 
        
        
           8
        
             __list_del(list->prev, list->
        
          next); 
        
        
           9
        
        
           list_add(list, head); 
        
        
          10
        
        
          } 
        
        
          11
        
        
          12
        
        
          /*
        
        
          * 
        
        
          13
        
        
           * list_move_tail - delete from one list and add as another's tail 
        
        
          14
        
        
           * @list: the entry to move 
        
        
          15
        
        
           * @head: the head that will follow our entry 
        
        
          16
        
        
          */
        
        
          17
        
        
          static
        
         inline 
        
          void
        
         list_move_tail(
        
          struct
        
         list_head *
        
          list, 
        
        
          18
        
        
          struct
        
         list_head *
        
          head) 
        
        
          19
        
        
          { 
        
        
          20
        
             __list_del(list->prev, list->
        
          next); 
        
        
          21
        
        
           list_add_tail(list, head); 
        
        
          22
        
         }
      
    

move將一個節(jié)點移動到頭部或者尾部。

(5)判斷鏈表

      
        
           1
        
        
          /*
        
        
          * 
        
        
           2
        
        
           * list_is_last - tests whether @list is the last entry in list @head 
        
        
           3
        
        
           * @list: the entry to test 
        
        
           4
        
        
           * @head: the head of the list 
        
        
           5
        
        
          */
        
        
           6
        
        
          static
        
         inline 
        
          int
        
         list_is_last(
        
          const
        
        
          struct
        
         list_head *
        
          list, 
        
        
           7
        
        
          const
        
        
          struct
        
         list_head *
        
          head) 
        
        
           8
        
        
          { 
        
        
           9
        
        
          return
        
         list->next ==
        
           head; 
        
        
          10
        
        
          } 
        
        
          11
        
        
          12
        
        
          /*
        
        
          * 
        
        
          13
        
        
           * list_empty - tests whether a list is empty 
        
        
          14
        
        
           * @head: the list to test. 
        
        
          15
        
        
          */
        
        
          16
        
        
          static
        
         inline 
        
          int
        
         list_empty(
        
          const
        
        
          struct
        
         list_head *
        
          head) 
        
        
          17
        
        
          { 
        
        
          18
        
        
          return
        
         head->next ==
        
           head; 
        
        
          19
        
         }
      
    

list_is_last函數(shù)判斷節(jié)點是否為末尾節(jié)點,list_empty判斷鏈表是否為空。

(6)遍歷鏈表

      
        
           1
        
        
          /*
        
        
          * 
        
        
           2
        
        
           * list_entry - get the struct for this entry 
        
        
           3
        
        
           * @ptr: the &struct list_head pointer. 
        
        
           4
        
        
           * @type: the type of the struct this is embedded in. 
        
        
           5
        
        
           * @member: the name of the list_struct within the struct. 
        
        
           6
        
        
          */
        
        
           7
        
        
          #define
        
         list_entry(ptr, type, member) \


        
           8
        
        
           container_of(ptr, type, member) 
        
        
           9
        
        
          10
        
        
          /*
        
        
          * 
        
        
          11
        
        
           * list_first_entry - get the first element from a list 
        
        
          12
        
        
           * @ptr: the list head to take the element from. 
        
        
          13
        
        
           * @type: the type of the struct this is embedded in. 
        
        
          14
        
        
           * @member: the name of the list_struct within the struct. 
        
        
          15
        
        
           * 
        
        
          16
        
        
           * Note, that list is expected to be not empty. 
        
        
          17
        
        
          */
        
        
          18
        
        
          #define
        
         list_first_entry(ptr, type, member) \


        
          19
        
             list_entry((ptr)->
        
          next, type, member) 
        
        
          20
        
        
          21
        
        
          /*
        
        
          * 
        
        
          22
        
        
           * list_for_each - iterate over a list 
        
        
          23
        
        
           * @pos: the &struct list_head to use as a loop cursor. 
        
        
          24
        
        
           * @head: the head for your list. 
        
        
          25
        
        
          */
        
        
          26
        
        
          #define
        
         list_for_each(pos, head) \


        
          27
        
        
          for
        
         (pos = (head)->next; prefetch(pos->next), pos !=
        
           (head); \ 
        
        
          28
        
                     pos = pos->next)
      
    

宏list_entity獲取鏈表的結構,包括數(shù)據(jù)域。list_first_entry獲取鏈表第一個節(jié)點,包括數(shù)據(jù)源。list_for_each宏對鏈表節(jié)點進行遍歷。

4、測試例子

編寫一個簡單使用鏈表的程序,從而掌握鏈表的使用。

自定義個類似的list結構如下所示:mylist.h

      
        
           1
        
         # define POISON_POINTER_DELTA 
        
          0
        
        
           2
        
        
           3
        
        
          #define
        
         LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)


        
           4
        
        
          #define
        
         LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)


        
           5
        
        
           6
        
        
          //
        
        
          計算member在type中的位置
        
        
           7
        
        
          #define
        
         offsetof(type, member)  (size_t)(&((type*)0)->member)


        
           8
        
        
          //
        
        
          根據(jù)member的地址獲取type的起始地址
        
        
           9
        
        
          #define
        
         container_of(ptr, type, member) ({          \


        
          10
        
        
          const
        
        
          typeof
        
        (((type *)
        
          0
        
        )->member)*__mptr =
        
           (ptr); \ 
        
        
          11
        
             (type *)((
        
          char
        
         *)__mptr -
        
           offsetof(type, member)); }) 
        
        
          12
        
        
          13
        
        
          //
        
        
          鏈表結構
        
        
          14
        
        
          struct
        
        
           list_head 
        
        
          15
        
        
          { 
        
        
          16
        
        
          struct
        
         list_head *
        
          prev; 
        
        
          17
        
        
          struct
        
         list_head *
        
          next; 
        
        
          18
        
        
          }; 
        
        
          19
        
        
          20
        
        
          static
        
         inline 
        
          void
        
         init_list_head(
        
          struct
        
         list_head *
        
          list) 
        
        
          21
        
        
          { 
        
        
          22
        
             list->prev =
        
           list; 
        
        
          23
        
             list->next =
        
           list; 
        
        
          24
        
        
          } 
        
        
          25
        
        
          26
        
        
          static
        
         inline 
        
          void
        
         __list_add(
        
          struct
        
         list_head *
        
          new
        
        
          , 
        
        
          27
        
        
          struct
        
         list_head *prev, 
        
          struct
        
         list_head *
        
          next) 
        
        
          28
        
        
          { 
        
        
          29
        
             prev->next = 
        
          new
        
        
          ; 
        
        
          30
        
        
          new
        
        ->prev =
        
           prev; 
        
        
          31
        
        
          new
        
        ->next =
        
           next; 
        
        
          32
        
             next->prev = 
        
          new
        
        
          ; 
        
        
          33
        
        
          } 
        
        
          34
        
        
          35
        
        
          //
        
        
          從頭部添加
        
        
          36
        
        
          static
        
         inline 
        
          void
        
         list_add(
        
          struct
        
         list_head *
        
          new
        
         , 
        
          struct
        
         list_head *
        
          head) 
        
        
          37
        
        
          { 
        
        
          38
        
             __list_add(
        
          new
        
        , head, head->
        
          next); 
        
        
          39
        
        
          } 
        
        
          40
        
        
          //
        
        
          從尾部添加
        
        
          41
        
        
          static
        
         inline 
        
          void
        
         list_add_tail(
        
          struct
        
         list_head *
        
          new
        
        , 
        
          struct
        
         list_head *
        
          head) 
        
        
          42
        
        
          { 
        
        
          43
        
             __list_add(
        
          new
        
        , head->
        
          prev, head); 
        
        
          44
        
        
          } 
        
        
          45
        
        
          46
        
        
          static
        
         inline  
        
          void
        
         __list_del(
        
          struct
        
         list_head *prev, 
        
          struct
        
         list_head *
        
          next) 
        
        
          47
        
        
          { 
        
        
          48
        
             prev->next =
        
           next; 
        
        
          49
        
             next->prev =
        
           prev; 
        
        
          50
        
        
          } 
        
        
          51
        
        
          52
        
        
          static
        
         inline 
        
          void
        
         list_del(
        
          struct
        
         list_head *
        
          entry) 
        
        
          53
        
        
          { 
        
        
          54
        
             __list_del(entry->prev, entry->
        
          next); 
        
        
          55
        
             entry->next =
        
           LIST_POISON1; 
        
        
          56
        
             entry->prev =
        
           LIST_POISON2; 
        
        
          57
        
        
          } 
        
        
          58
        
        
          59
        
        
          static
        
         inline 
        
          void
        
         list_move(
        
          struct
        
         list_head *list, 
        
          struct
        
         list_head *
        
          head) 
        
        
          60
        
        
          { 
        
        
          61
        
                 __list_del(list->prev, list->
        
          next); 
        
        
          62
        
        
           list_add(list, head); 
        
        
          63
        
        
          } 
        
        
          64
        
        
          65
        
        
          static
        
         inline 
        
          void
        
         list_move_tail(
        
          struct
        
         list_head *
        
          list, 
        
        
          66
        
        
          struct
        
         list_head *
        
          head) 
        
        
          67
        
        
          { 
        
        
          68
        
                 __list_del(list->prev, list->
        
          next); 
        
        
          69
        
        
           list_add_tail(list, head); 
        
        
          70
        
        
          } 
        
        
          71
        
        
          #define
        
         list_entry(ptr, type, member) \


        
          72
        
        
           container_of(ptr, type, member) 
        
        
          73
        
        
          74
        
        
          #define
        
         list_first_entry(ptr, type, member) \


        
          75
        
             list_entry((ptr)->
        
          next, type, member) 
        
        
          76
        
        
          77
        
        
          #define
        
         list_for_each(pos, head) \


        
          78
        
        
          for
        
         (pos = (head)->next; pos != (head); pos = pos->next)
      
    

mylist.c如下所示:

      
        
           1
        
        
          /*
        
        
          *@brief 練習使用linux內核鏈表,功能包括: 
        
        
           2
        
        
           * 定義鏈表結構,創(chuàng)建鏈表、插入節(jié)點、刪除節(jié)點、移動節(jié)點、遍歷節(jié)點 
        
        
           3
        
        
           * 
        
        
           4
        
        
           *@auther Anker @date 2013-12-15 
        
        
           5
        
        
           *
        
        
          */
        
        
           6
        
         #include <stdio.h>


        
           7
        
         #include <inttypes.h>


        
           8
        
         #include <stdlib.h>


        
           9
        
         #include <errno.h>


        
          10
        
         #include 
        
          "
        
        
          mylist.h
        
        
          "
        
        
          11
        
        
          //
        
        
          定義app_info鏈表結構
        
        
          12
        
         typedef 
        
          struct
        
        
           application_info 
        
        
          13
        
        
          { 
        
        
          14
        
        
           uint32_t app_id; 
        
        
          15
        
        
           uint32_t up_flow; 
        
        
          16
        
        
           uint32_t down_flow; 
        
        
          17
        
        
          struct
        
            list_head app_info_node;
        
          //
        
        
          鏈表節(jié)點
        
        
          18
        
        
          }app_info; 
        
        
          19
        
        
          20
        
        
          21
        
         app_info*
        
           get_app_info(uint32_t app_id, uint32_t up_flow, uint32_t down_flow) 
        
        
          22
        
        
          { 
        
        
          23
        
             app_info *app = (app_info*)malloc(
        
          sizeof
        
        
          (app_info)); 
        
        
          24
        
        
          if
        
         (app ==
        
           NULL) 
        
        
          25
        
        
           { 
        
        
          26
        
             fprintf(stderr, 
        
          "
        
        
          Failed to malloc memory, errno:%u, reason:%s\n
        
        
          "
        
        
          , 
        
        
          27
        
        
           errno, strerror(errno)); 
        
        
          28
        
        
          return
        
        
           NULL; 
        
        
          29
        
        
           } 
        
        
          30
        
             app->app_id =
        
           app_id; 
        
        
          31
        
             app->up_flow =
        
           up_flow; 
        
        
          32
        
             app->down_flow =
        
           down_flow; 
        
        
          33
        
        
          return
        
        
           app; 
        
        
          34
        
        
          } 
        
        
          35
        
        
          static
        
        
          void
        
         for_each_app(
        
          const
        
        
          struct
        
         list_head *
        
          head) 
        
        
          36
        
        
          { 
        
        
          37
        
        
          struct
        
         list_head *
        
          pos; 
        
        
          38
        
             app_info *
        
          app; 
        
        
          39
        
        
          //
        
        
          遍歷鏈表
        
        
          40
        
        
           list_for_each(pos, head) 
        
        
          41
        
        
           { 
        
        
          42
        
             app =
        
           list_entry(pos, app_info, app_info_node); 
        
        
          43
        
             printf(
        
          "
        
        
          ap_id: %u\tup_flow: %u\tdown_flow: %u\n
        
        
          "
        
        
          , 
        
        
          44
        
                 app->app_id, app->up_flow, app->
        
          down_flow); 
        
        
          45
        
        
          46
        
        
           } 
        
        
          47
        
        
          } 
        
        
          48
        
        
          49
        
        
          void
        
         destroy_app_list(
        
          struct
        
         list_head *
        
          head) 
        
        
          50
        
        
          { 
        
        
          51
        
        
          struct
        
         list_head *pos = head->
        
          next; 
        
        
          52
        
        
          struct
        
         list_head *tmp =
        
           NULL; 
        
        
          53
        
        
          while
        
         (pos !=
        
           head) 
        
        
          54
        
        
           { 
        
        
          55
        
             tmp = pos->
        
          next; 
        
        
          56
        
        
           list_del(pos); 
        
        
          57
        
             pos =
        
           tmp; 
        
        
          58
        
        
           } 
        
        
          59
        
        
          } 
        
        
          60
        
        
          61
        
        
          62
        
        
          int
        
        
           main() 
        
        
          63
        
        
          { 
        
        
          64
        
        
          //
        
        
          創(chuàng)建一個app_info
        
        
          65
        
             app_info * app_info_list = (app_info*)malloc(
        
          sizeof
        
        
          (app_info)); 
        
        
          66
        
             app_info *
        
          app; 
        
        
          67
        
        
          if
        
         (app_info_list ==
        
           NULL) 
        
        
          68
        
        
           { 
        
        
          69
        
             fprintf(stderr, 
        
          "
        
        
          Failed to malloc memory, errno:%u, reason:%s\n
        
        
          "
        
        
          , 
        
        
          70
        
        
           errno, strerror(errno)); 
        
        
          71
        
        
          return
        
         -
        
          1
        
        
          ; 
        
        
          72
        
        
           } 
        
        
          73
        
        
          //
        
        
          初始化鏈表頭部
        
        
          74
        
        
          struct
        
         list_head *head = &app_info_list->
        
          app_info_node; 
        
        
          75
        
        
           init_list_head(head); 
        
        
          76
        
        
          //
        
        
          插入三個app_info
        
        
          77
        
             app = get_app_info(
        
          1001
        
        , 
        
          100
        
        , 
        
          200
        
        
          ); 
        
        
          78
        
             list_add_tail(&app->
        
          app_info_node, head); 
        
        
          79
        
             app = get_app_info(
        
          1002
        
        , 
        
          80
        
        , 
        
          100
        
        
          ); 
        
        
          80
        
             list_add_tail(&app->
        
          app_info_node, head); 
        
        
          81
        
             app = get_app_info(
        
          1003
        
        , 
        
          90
        
        , 
        
          120
        
        
          ); 
        
        
          82
        
             list_add_tail(&app->
        
          app_info_node, head); 
        
        
          83
        
             printf(
        
          "
        
        
          After insert three app_info: \n
        
        
          "
        
        
          ); 
        
        
          84
        
        
           for_each_app(head); 
        
        
          85
        
        
          //
        
        
          將第一個節(jié)點移到末尾
        
        
          86
        
             printf(
        
          "
        
        
          Move first node to tail:\n
        
        
          "
        
        
          ); 
        
        
          87
        
             list_move_tail(head->
        
          next, head); 
        
        
          88
        
        
           for_each_app(head); 
        
        
          89
        
        
          //
        
        
          刪除最后一個節(jié)點
        
        
          90
        
             printf(
        
          "
        
        
          Delete the last node:\n
        
        
          "
        
        
          ); 
        
        
          91
        
             list_del(head->
        
          prev); 
        
        
          92
        
        
           for_each_app(head); 
        
        
          93
        
        
           destroy_app_list(head); 
        
        
          94
        
        
           free(app_info_list); 
        
        
          95
        
        
          return
        
        
          0
        
        
          ; 
        
        
          96
        
         }
      
    

測試結果如下所示:

linux內核數(shù)據(jù)結構之鏈表

參考網址:

https://www.ibm.com/developerworks/cn/linux/kernel/l-chain/

冷靜思考,勇敢面對,把握未來!
?

linux內核數(shù)據(jù)結構之鏈表


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 奇米狠狠操 | 色噜噜狠狠狠狠色综合久一 | 免费观看四虎精品成人 | 日日操操 | 中文字幕第13亚洲另类 | 猫咪www免费人成在线观看网址 | 亚洲区欧美区 | bbw下身丰满18ⅹxxⅹ | 久热精品视频在线观看 | 麻豆国产高清精品国在线 | 中文字幕一区在线 | 亚洲国产婷婷综合在线精品 | 尹人香蕉久久99天天拍欧美p7 | 视频一区色眯眯视频在线 | 91aaa在线观看 | 韩国网站爱久久 | 91最新入口| 久久精品亚洲精品国产欧美 | 亚洲激情在线观看 | 天天爱天天操 | 精品国产精品久久一区免费式 | 手机看片一区二区 | 精品国产影院 | 九九热视频在线观看 | 亚洲qingse中文久久网 | 国产成人一区二区三区视频免费蜜 | 欧洲色网 | 青青青青手机在线视频观看国产 | 国产精品一区二区三区四区五区 | 国产日韩欧美中文字幕 | 毛片一 | 免费特黄一级欧美大片在线看 | 九九九精品午夜在线观看 | 精品一区二区久久 | 激情五月综合网 | 亚洲一区二区三区麻豆 | 91色综合| 久久国产亚洲 | 国产精品亚洲高清一区二区 | 日韩av片免费播放 | 日本一级毛片片在线播放 |