衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux塊層架構(gòu)介紹 塊層IO流程與塊層IO調(diào)度器詳解

Linux愛好者 ? 來源:奇伢云存儲 ? 作者:奇伢 ? 2022-05-16 12:12 ? 次閱讀

67d3d51e-d4cc-11ec-bce3-dac502259ad0.png

塊存儲沒那么神秘!

之前一直跟大家聊文件系統(tǒng),文件系統(tǒng)提供一層文件到物理塊層的映射轉(zhuǎn)換。這層邏輯可能非常復(fù)雜,依賴于文件系統(tǒng)的實現(xiàn)。今天則跟大家聊聊塊層,塊層位于 fs 層之下,大家可能平時不怎么接觸,看不見摸不著。其實沒有那么神秘,來看下塊設(shè)備的使用姿勢, Linux 經(jīng)??匆姷?sda,sdb 這樣的盤符文件其實就是塊設(shè)備。

我們來試一下對一個塊設(shè)備進行讀寫(注意,千萬找一個不用的塊設(shè)備,有寫操作):

funcmain(){
  //千萬注意:/dev/sdx1 盤,注意一定是要是不用的新盤哦。這里有寫操作,可千萬不要寫壞數(shù)據(jù)哦
  f,err:=os.OpenFile("/dev/sdx1",os.O_RDWR,0666)
  iferr!=nil{
    log.Fatalf("err:%v
",err)
  }
  //寫
  content:="helloworld"
  _,err=f.WriteAt([]byte(content),0)
  iferr!=nil{
    log.Fatalf("err:%v
",err)
  }
  //讀
  buffer:=make([]byte,len(content))
  n,err:=f.ReadAt(buffer,0)
  iferr!=nil{
    log.Fatalf("err:%v
",err)
  }

  fmt.Printf("content=%s,n=%v
",buffer,n)
}

以上就完成了對塊設(shè)備的一次讀寫,大家看用戶態(tài)操作一下塊設(shè)備是不是非常簡單呀。說白了,就是把它當一個線性的文件來使用即可。用戶態(tài)的文件系統(tǒng)經(jīng)常喜歡這樣去管理塊設(shè)備,來看一下塊層的架構(gòu)。

塊層架構(gòu)

塊設(shè)備的邏輯集中在 Linux 的塊層子系統(tǒng)中。由于塊設(shè)備有多種的類型,并且內(nèi)部關(guān)于不同的場景可能會有不同的調(diào)度需求,所以它的設(shè)計也必須滿足一定的抽象,塊層內(nèi)一般分為三層

  • 通用層 :抽象不同的塊設(shè)備,為上層建立統(tǒng)一的塊設(shè)備模型;
  • IO 調(diào)度層 :IO 請求入隊、出隊,并且按照特定的策略去調(diào)度(可配置);
  • 塊設(shè)備驅(qū)動層 :針對不同的塊設(shè)備類型有著不同驅(qū)動程序。比如 SCSI 設(shè)備,邏輯設(shè)備等;

聊聊這三層:

  • 通用層:給上層一個叫做 submit_bio 的函數(shù),并且和上層對齊的 IO 類型叫做 bio ,所有的塊 IO 請求封裝成 bio ,然后通過 submit_bio 遞交即可。這是統(tǒng)一的抽象界面;
  • IO 調(diào)度層:無非就是上層請求怎么入隊,然后怎么派發(fā)給底層。整體的塊 IO 調(diào)度器叫做電梯,它的架子也是電梯算法的架子,調(diào)度算法允許配置,常見的就是 cfq,deadline,noop 這三種算法;
  • 塊設(shè)備驅(qū)動層:針對不同塊設(shè)備的封裝,比如有順序訪問的塊設(shè)備,還有隨機訪問的,還有邏輯棧式設(shè)備;

塊層 IO 流程

今天走一小段代碼,省略復(fù)雜邏輯,只擼主干邏輯。

下面涉及到代碼,配合 Linux 3.10.1

1抽象界面 submit_bio

塊層的入口是 submit_bio 函數(shù),上層填裝 bio 結(jié)構(gòu)之后,調(diào)用 submit_bio 遞交到塊層。一切的開始都是從這個函數(shù)。bio 就是塊層和上層約定好的參數(shù)結(jié)構(gòu)。塊層的核心工作就是對這個結(jié)構(gòu)做處理,做變形,最終做轉(zhuǎn)發(fā)。

塊設(shè)備的讀寫都是通過這個接口和參數(shù)來表達。來看一下 submit_bio 的邏輯:

voidsubmit_bio(intrw,structbio*bio)
{
  //打上讀寫標記
  bio->bi_rw|=rw;
  //...
  //構(gòu)造request
  generic_make_request(bio);
}

一個小信息:FS 和 塊層交互的是 bio 類型,但是塊層內(nèi)部用的是 request 結(jié)構(gòu),由 bio 轉(zhuǎn)換而來。

2IO 請求入隊 make_request_fn

來看下 generic_make_request 中 實現(xiàn):

voidgeneric_make_request(structbio*bio)
{
  //保證make_requst核心的邏輯在同一個進城內(nèi)是串行之行的
  if(current->bio_list){
    bio_list_add(current->bio_list,bio);
    return;
  }

  bio_list_init(&bio_list_on_stack);
  current->bio_list=&bio_list_on_stack;
  //循環(huán)處理bio_list里的內(nèi)容
  do{
    //獲取到該塊設(shè)備的隊列
    structrequest_queue*q=bdev_get_queue(bio->bi_dev);
    //執(zhí)行make_request_fn回調(diào)
    q->make_request_fn(q,bio);
    bio=bio_list_pop(current->bio_list);
  }while(bio);
  current->bio_list=NULL;
}

塊設(shè)備都會有個 request_queue 結(jié)構(gòu)體。隊列這個很容易理解,用來掛請求的。排序、合并之后 IO 請求總得放在一個地方。

上面的核心是 request queue 的 make_request_fn 函數(shù)回調(diào)。合并和排序就是在該函數(shù)中實現(xiàn)。

思考:make_request_fn 又是什么呢?什么時候賦值的呢?

其實是設(shè)備創(chuàng)建之初,初始化結(jié)構(gòu)體的時候賦值好的。比如 SCSI 設(shè)備,那么 make_request_fn 就是 blk_queue_bio 。

注意:這里我們看到還有一個 request_fn 的回調(diào),SCSI 設(shè)備是初始化成 scsi_request_fn ,記住這個,后面會講。

//分配并初始化一個scsi設(shè)備
scsi_alloc_sdev
scsi_alloc_queue
//創(chuàng)建、初始化請求隊列,回調(diào)request_fn
__scsi_alloc_queue(sdev->host,scsi_request_fn);
blk_init_queue
blk_init_queue_node
blk_init_allocated_queue
//回調(diào)make_request_fn
blk_queue_make_request(q,blk_queue_bio);

排序、合并的邏輯則是在 make_request_fn 中完成,也就是 IO 請求入隊的過程就完成了。

思考:合并、排序究竟是什么意思?

  • 合并:將磁盤上扇區(qū)連續(xù)的多個請求合并成一個,然后作為一個 SCSI 請求命令下發(fā)
  • 排序:將多個 IO 請求按照磁盤扇區(qū)的位置進行排序,以便磁頭能夠盡可能的往一個方向擺動

合并和排序在 make_request_fn 中完成。來看一看調(diào)度器的邏輯:

voidblk_queue_bio(structrequest_queue*q,structbio*bio)
{
  el_ret=elv_merge(q,&req,bio);
  if(el_ret==ELEVATOR_BACK_MERGE){
    //往后合并
  }elseif(el_ret==ELEVATOR_FRONT_MERGE){
    //往前合并
  }

get_rq:
  //沒合并的新請求走這里

  plug=current->plug
  if(plug){
    list_add_tail(&req->queuelist,&plug->list);
  }else{
    add_acct_request(q,req,where);
    __blk_run_queue(q);
  }
}

elv_merge 會返回一個常量來標識向前或者向后合并。如果是向前或者向后合并,那么返回對應(yīng)的已經(jīng)存在的 request 結(jié)構(gòu)體。如果是不能合并,那么就創(chuàng)建的一個新的 request 請求。

思考:IO 請求在 make_request_fn 入隊,那什么時候派發(fā)呢?

是通過 request_fn 回調(diào)函數(shù)(往前看,設(shè)備初始化的時候賦值的)來處理。SCSI 設(shè)備的 request_fn 回調(diào)是 scsi_request_fn 函數(shù)。函數(shù)中有個 for 循環(huán),會按照策略逐個取出請求,封裝處理一下,然后丟到底層去執(zhí)行 ( 使用 scsi_dispatch_cmd )。

思考:有沒有想過能夠合并和排序的基礎(chǔ)條件是啥?

基礎(chǔ)是:有足夠多的請求。這個依賴于 Linux 的一個叫做蓄流/泄流的機制(Plugging / Unplugging)。蓄流/泄流什么意思?

Linux 塊層為了增加吞吐能力,對于來的請求,并不是立即下發(fā),而是 hold 一段時間,攢一會兒,超時了或者超閾值了,再一次性處理請求下發(fā)。類似于用塞子堵住一下(蓄流)池子,水滿了再拔掉塞子(泄流)。

很容易理解,塊層之所以不將每個請求都立馬下發(fā),就是為了實現(xiàn) IO 的調(diào)度。這種短暫的 hold 請求本質(zhì)上是優(yōu)化的基礎(chǔ)。如果每一個請求都不聚合,不把大家聚在一起,那么是無法找到優(yōu)化的時機的。

3IO 請求派發(fā) request_fn

request 的派發(fā)邏輯則是在 request_fn 中完成,SCSI 是 scsi_request_fn 函數(shù)。Unplug 的時候就會走到這里來。

staticvoidscsi_request_fn(structrequest_queue*q)
{
  for(;;){
    //按照IO調(diào)度策略取請求出來
    req=blk_peek_request(q);

    //派發(fā)命令到SCSI驅(qū)動層
    rtn=scsi_dispatch_cmd(cmd);
  }
}

這里的邏輯則是集中在 ”怎么取請求出來?“ 。

IO 調(diào)度算法的主要發(fā)揮時機就是在這里!(還有一個時機就是入隊的時候)

把 request 選出來之后,封裝成 scsi cmd 命令,通過 scsi_dispatch_cmd 函數(shù)下發(fā)到 SCSI 驅(qū)動層即可。這樣一個請求的派發(fā)就算完成了。

塊層 IO 調(diào)度器

接著上面,聊聊塊層 IO 調(diào)度器。首先塊層整體的 IO 調(diào)度器是一個電梯算法的架子,你會發(fā)現(xiàn) elevator 的縮寫到處都是。隨著 Linux 系統(tǒng)的持續(xù)發(fā)展還是衍生了不同于真正簡單電梯算法的調(diào)度算法。這個就是我們常見的 noop,deadline,cfq 等算法。這部分則是被抽象成一個界面,可以讓用戶來配置選擇。這個統(tǒng)一界面類型叫做 elevator_type :

structelevator_type{
  //最重要的是這個
  structelevator_opsops;
}

最重要就是 ops 字段,以 noop 算法為例:

staticstructelevator_typeelevator_noop={
  .ops={
    .elevator_merge_req_fn=noop_merged_requests,
    .elevator_dispatch_fn=noop_dispatch,
    .elevator_add_req_fn=noop_add_request,
    .elevator_former_req_fn=noop_former_request,
    .elevator_latter_req_fn=noop_latter_request,
    .elevator_init_fn=noop_init_queue,
    .elevator_exit_fn=noop_exit_queue,
  }
  .elevator_name="noop",
  .elevator_owner=THIS_MODULE,
}

也就是說,不同的調(diào)度算法只要實現(xiàn)了這個 elevator_type ,就可以在"電梯"的大框架里運行了。所以,其實“電梯”已經(jīng)不是“電梯”了。

調(diào)度算法主要做好兩個事情:

  1. bio 請求入隊:合并、排序?隨你。比如 noop 就沒有合并和排序
  2. request 請求出隊:電梯不電梯?隨你,目前就看 deadline 是變形的“電梯”。

調(diào)度算法的實現(xiàn)在:

  • noop 的實現(xiàn)在 block/noop-iosched.c ,及其簡單
  • deadline 的實現(xiàn)在 block/deadline-iosched.c ,主要加了一個超時,饑餓的考慮
  • cfq 的實現(xiàn)在 block/cfq-iosched.c ,號稱絕對公平算法,考慮到不同進程的性能公平,邏輯是最復(fù)雜的

今天先不給大家展開調(diào)度策略的實現(xiàn),只簡要梳理其作用。說白了,無論哪種調(diào)度策略,都只是選出一個 request 出來而已。

思考:linux 怎么查看調(diào)度策略?

cat/sys/block/{塊設(shè)備符}/queue/scheduler

1noop

它自身不帶任何邏輯。沒有合并、排序。請求按照 fifo 的方式入隊出隊。誰先進的誰先出,不區(qū)分請求。

這種簡單的算法,反而適用于超高性能的介質(zhì),比如 ssd ,因為 ssd 的性能已經(jīng)足夠高了,自身提供的并發(fā)能力也是夠的。不需要上層做順序化,批量化,它沒有磁頭擺動的問題。合并和排序等多余的邏輯對它來講就是累贅。

2deadline

最像電梯算法的 IO 調(diào)度算法。在電梯算法的基礎(chǔ)上,再加上請求超時的考慮,起到防止饑餓請求的作用。它內(nèi)部有兩部電梯:讀寫。讀請求優(yōu)先,但也會考慮寫?zhàn)囸I,同一時間只有一部電梯在運行。

3cfq

完全公平隊列,為每個進程單獨創(chuàng)建一個隊列來管理該進程所產(chǎn)生的請求,試圖給不同的進程分配相同的塊設(shè)備使用時間片,以此來保證每個進程都能被很好的分配到 IO 帶寬。該算法就屬于萬金油,通用場景用它是最保險的,是最通用的 IO 調(diào)度算法。它的邏輯實現(xiàn)也是最復(fù)雜的。noop 100 行代碼,deadline 460 行,cfq 4600 行代碼,由此可見。

總結(jié)

  • submit_bio 是塊層的統(tǒng)一接口函數(shù),bio 是統(tǒng)一 IO 結(jié)構(gòu)體
  • request 是塊層內(nèi)部的 IO 請求的結(jié)構(gòu)體,bio 到 request 有一層轉(zhuǎn)換,這層轉(zhuǎn)換就是排序、合并的時候;
  • make_request_fn 就是 bio 轉(zhuǎn)換成 request 的時機,IO 的排序、合并時機就在于此;
  • request_fn 是 request 派發(fā)的時機,IO 的調(diào)度算法也在此發(fā)揮作用。從 request 隊列中按照策略選一個 req 出來,封裝成底層想要的樣子,下發(fā)下去
  • IO 調(diào)度器合并、排序,包括按照電梯直上直下派發(fā)請求的目的是減少磁盤尋址時間,從而提高整體性能;
  • noop,cfq,deadline 三種派發(fā)請求的算法都有適用自己的場景。noop 是幾乎 bypass 請求,沒有重拍、合并。deadline 是電梯算法衍生了一下。cfq 是全新的一種公平算法,跟電梯沒啥關(guān)系;
  • 塊層最核心的邏輯是:bio 請求怎么入隊,request 請求怎么出隊而已,它遠比文件系統(tǒng)要簡單;

原文標題:Linux 塊層 IO 子系統(tǒng)|最核心的邏輯是什么?

文章出處:【微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11345

    瀏覽量

    210391
  • 文件系統(tǒng)
    +關(guān)注

    關(guān)注

    0

    文章

    287

    瀏覽量

    19978
  • 調(diào)度器
    +關(guān)注

    關(guān)注

    0

    文章

    98

    瀏覽量

    5298

原文標題:Linux 塊層 IO 子系統(tǒng)|最核心的邏輯是什么?

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    內(nèi)電分割時,能不能分割成多個不連續(xù)

    在進行內(nèi)電分割時,同一網(wǎng)絡(luò)必須是一個連續(xù)的整體,而不能分割成多個不連續(xù)么?
    發(fā)表于 09-29 08:37

    liunx下文件系統(tǒng),都會與設(shè)備交互嗎?

    下面這張圖大家應(yīng)該都很熟悉了,看起來linux下文件系統(tǒng)都要走設(shè)備。然后再與具體的存儲器件交互。那么,請問下,是否有例外呢?
    發(fā)表于 01-17 11:29

    EPA功能及用戶技術(shù)研究

    EPA功能及用戶技術(shù)研究 Research on EPA Functional Block and User Layer Technology
    發(fā)表于 03-17 09:14 ?16次下載

    基于三架構(gòu)流程模擬系統(tǒng)的設(shè)計與應(yīng)用_劉紅霞

    基于三架構(gòu)流程模擬系統(tǒng)的設(shè)計與應(yīng)用_劉紅霞
    發(fā)表于 01-19 21:54 ?0次下載

    Linux設(shè)備驅(qū)動開發(fā)詳解》第13章、Linux設(shè)備驅(qū)動

    Linux設(shè)備驅(qū)動開發(fā)詳解》第13章、Linux設(shè)備驅(qū)動
    發(fā)表于 10-27 11:24 ?18次下載
    《<b class='flag-5'>Linux</b>設(shè)備驅(qū)動開發(fā)<b class='flag-5'>詳解</b>》第13章、<b class='flag-5'>Linux</b><b class='flag-5'>塊</b>設(shè)備驅(qū)動

    基于的組成“bio”的詳細解析

    在深挖bio之前,很有必要先了解點背景知識,看看之上的天地。這里“之上”意思是靠近用戶空間(the top),遠離硬件(the bottom),包括所有使用
    的頭像 發(fā)表于 02-03 16:23 ?4179次閱讀
    基于<b class='flag-5'>塊</b><b class='flag-5'>層</b>的組成“bio<b class='flag-5'>層</b>”的詳細解析

    深度剖析基于的組成“request

    現(xiàn)在,"request"并存著兩種模型:單隊列(single-queue) 和 多隊列(multi-queue)。多隊列的出現(xiàn)也就是近幾年的事情,也許總有一天會完全取代單隊列的,但是目前來看兩者
    的頭像 發(fā)表于 02-03 16:29 ?4364次閱讀
    深度剖析基于<b class='flag-5'>塊</b><b class='flag-5'>層</b>的組成“request<b class='flag-5'>層</b>”

    Linux通用之deadline簡介及通用調(diào)度框架

    接口很簡單,首先判斷request的IO方向,根據(jù)IO方向通過deadline_add_rq_rb將request添加到讀/寫紅黑樹中,request在紅黑樹中以請求的起始扇區(qū)作為節(jié)點的key value,可以直接認為紅黑樹中的request是按扇區(qū)增加的方向排好了序。
    的頭像 發(fā)表于 04-29 16:40 ?5789次閱讀
    <b class='flag-5'>Linux</b>通用<b class='flag-5'>塊</b><b class='flag-5'>層</b>之deadline簡介及通用<b class='flag-5'>塊</b><b class='flag-5'>層</b><b class='flag-5'>調(diào)度</b><b class='flag-5'>器</b>框架

    Linux IO系統(tǒng)簡介和調(diào)度的工作流程詳細概述

    Linux內(nèi)核組件要讀寫一些數(shù)據(jù)時,并不是請求一發(fā)出,內(nèi)核便立即執(zhí)行該請求,而是將其推遲執(zhí)行。當傳輸一個新數(shù)據(jù)時,內(nèi)核需要檢查它能否通過。Linux IO
    的頭像 發(fā)表于 05-27 10:41 ?5148次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>IO</b>系統(tǒng)簡介和<b class='flag-5'>調(diào)度</b><b class='flag-5'>器</b>的工作<b class='flag-5'>流程</b>詳細概述

    pcb板各層畫什么?絲印 機械 阻焊 助焊 信號 鉆孔數(shù)據(jù)作用詳解

    pcb板在畫圖的時候大家都知道,電路板會有很多層,那么首先我們要知道都是PCB板子的哪些。通過對PCB的各個圖層的詳細解答,希望能夠?qū)Υ蠹疫M一步了解一PCB的組成與設(shè)計有幫助。下面我們多以
    的頭像 發(fā)表于 08-17 11:25 ?2.1w次閱讀

    邏輯接口的IO口如何使用

    上篇博文:【FPGA】SRIO IP核系統(tǒng)總覽以及端口介紹(一)(User Interfaces 之 I/O Port)根據(jù)數(shù)據(jù)手冊PG007,介紹到了邏輯接口的IO口,今天想研究下
    的頭像 發(fā)表于 08-18 09:35 ?5004次閱讀
    邏輯<b class='flag-5'>層</b>接口的<b class='flag-5'>IO</b>口如何使用

    CXL事務(wù)詳解

    CXL.ioIO設(shè)備提供非一致性的load/strore接口。事務(wù)類型、事務(wù)數(shù)據(jù)包格式、信用流量控制、虛擬通道管理、事務(wù)順序的規(guī)則等遵循PCIe協(xié)議。CXL.io的事務(wù)如下圖中的黃
    的頭像 發(fā)表于 10-10 16:02 ?2992次閱讀

    PCB阻焊與助焊的區(qū)別

    標準的印刷電路板 (PCB) 通常需要兩種不同類型的,即“罩 (mask)”。
    發(fā)表于 06-01 16:58 ?3084次閱讀
    PCB阻焊<b class='flag-5'>層</b>與助焊<b class='flag-5'>層</b>的區(qū)別

    查看linux系統(tǒng)磁盤io情況的辦法是什么

    談到 Linux 磁盤 I/O 的工作原理,我們了解到 Linux 存儲系統(tǒng) I/O 棧由文件系統(tǒng)(file system layer)、通用
    發(fā)表于 08-01 10:14 ?2445次閱讀

    SCP基本構(gòu)建介紹

    1-什么是SCP ? 將電源和系統(tǒng)管理任務(wù)從應(yīng)用處理(AP)中抽象出來。 ? 符合ARM系統(tǒng)控制和管理接口(SCMI)規(guī)范。 ? 執(zhí)行環(huán)境不固定??梢栽赗TOS或裸機環(huán)境中運行。 2-基本構(gòu)建
    的頭像 發(fā)表于 11-02 16:52 ?982次閱讀
    SCP基本構(gòu)建<b class='flag-5'>塊</b><b class='flag-5'>介紹</b>
    百家乐网站制作| 百家乐官网发牌的介绍| 皇冠网百家乐赢钱| E乐博娱乐城| 金博士百家乐官网娱乐城| 久盛娱乐城| 真人百家乐免费开户送钱| 建昌县| 百家乐赌场策略| 太阳城百家乐官网坡解| 盐城百家乐的玩法技巧和规则| 澳门赌百家乐官网能赢钱吗| 威尼斯人娱乐城活动lm0| 百家乐官网庄闲符号记| 大发888亚洲赌场| 百家乐官网缩水软件| 大发888娱乐城送白菜| 捷豹百家乐官网的玩法技巧和规则| qq德州扑克下载| 百家乐视频二人麻将| 百家乐官网破解的方法| 威尼斯人娱乐城送38| 狮威百家乐官网娱乐平台| 网上娱乐城| 皇冠百家乐赢钱皇冠| 百家乐官网智能投注系统| 豫游棋牌游戏中心| 百家乐平台下载| 三公百家乐官网玩法| 马牌| 百家乐赌场破解方法| 百家乐官网出千工具价格| bet365手机| 百家乐出千的高科技| 博彩百家乐官网带连线走势图| 澳门葡京赌场出台女| 怎样打百家乐的玩法技巧和规则| 百家乐官网扫瞄光纤洗牌机扑克洗牌机扑克洗牌机 | 大发888m摩卡游戏| 澳门百家乐娱乐城网址| 百家乐官网网站制作|