MDモジュールの処理読み書きプロセス分析-1


mdは、ブロックデバイス駆動に属し、ブロックデバイス駆動の特徴を有する仮想デバイス駆動層と言える.だから、彼はブロックデバイスの操作インタフェースを実現しました.

   
   
   
   
  1. static struct block_device_operations md_fops =  
  2. {  
  3. .owner      = THIS_MODULE,  
  4. .open       = md_open,  
  5. .release    = md_release,  
  6. .ioctl      = md_ioctl,  
  7. .getgeo     = md_getgeo,  
  8. .media_changed  = md_media_changed,  
  9. .revalidate_disk= md_revalidate,  
  10. }; 

 
(MDのほとんどの動作はmd_ioctlインタフェースで実現され、少数の部分はsysファイルシステムで実現されてもよい)
私の理解では、MDモジュールを制御管理部とraidレベル実装部の2つの部分に分けることができます.制御管理セクションは大きなフレームワークであり、各raidレベルモジュールを制御します.彼らの間にはどのように関連していますか.コードを見たことのある人なら誰でも知っていると思いますが、md_です.k.hで定義された構造体struct mdk_personality、この構造体では主にいくつかの関数操作セット(ioスケジューリングでelevatorで定義されているように)が定義されています.これらの関数はそれぞれraidレベルで実現され、一部のraidレベルではいくつかの関数が実現されていません.この構造体の内容は以下の通りです.

  
  
  
  
  1. struct mdk_personality  
  2. {  
  3. char *name;  
  4. int level;  
  5. struct list_head list;  
  6. struct module *owner;  
  7. int (*make_request)(request_queue_t *q, struct bio *bio);  
  8. int (*run)(mddev_t *mddev);  
  9. int (*stop)(mddev_t *mddev);  
  10. void (*status)(struct seq_file *seq, mddev_t *mddev);  
  11. /* error_handler must set ->faulty and clear ->in_sync  
  12. * if appropriate, and should abort recovery if needed  
  13. */ 
  14. void (*error_handler)(mddev_t *mddev, mdk_rdev_t *rdev);  
  15. int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev);  
  16. int (*hot_remove_disk) (mddev_t *mddev, int number);  
  17. int (*spare_active) (mddev_t *mddev);  
  18. sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);  
  19. int (*resize) (mddev_t *mddev, sector_t sectors);  
  20. int (*check_reshape) (mddev_t *mddev);  
  21. int (*start_reshape) (mddev_t *mddev);  
  22. int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);  
  23. /* quiesce moves between quiescence states  
  24. * 0 - fully active  
  25. * 1 - no new requests allowed  
  26. * others - reserved  
  27. */ 
  28. void (*quiesce) (mddev_t *mddev, int state);  
  29. };  

 
       make_request:ブロックデバイスは要求関数を処理します.
run:各raidモジュール起動関数、例えばメモリの割り当て、スレッドの確立など.
stop:各raidモジュールは関数を停止し、リソースを解放します.
status:/procファイルシステムインタフェース
       error_handler:読み書きエラーを処理するインタフェース
       hot_add_disk:再構築中にホットスペアをアレイに追加します.
       hot_remove_disk:再構築中に失効ディスクインタフェースを削除する
       spare_Active:ホットスペアインタフェースをアクティブにする
       check_reshape:アレイ拡張チェックインタフェース
       start_reshape:拡張インタフェースの起動
 
これらの関数はraidモジュールのロード時に登録されます.
こんなにたくさん言ったのにまだ本題を話していないのに、ほほほ...次は本題に入ります.Linxuにおけるmdデバイスはファイルシステムを介してアクセス可能であり、MDデバイスを作成すると、ユーザ状態の読み書き要求がファイルシステムを介してMDデバイスに送信される.linxuカーネルに詳しい人は知っていますが、転送要求の関数はgeneric_です.make_request、この関数は最終的にキューのmakeを呼び出します.request_fnメソッドは、MDデバイスに送信されると、mdレイヤのmake_request関数は実装される(struct mdk_personalityで定義され、各raidモジュールによって実装される).raidアルゴリズムの定義が異なるためmake_requestの実装方法も異なります.本質的にはmd層のmake_requestとは,ファイルシステムから送信されたbioを各raidアルゴリズムに基づいて各ディスクに再配布することである.mdレイヤのmake_request関数は最終的にgeneric_を呼び出します.make_requestはbioを送信し、今回送信されたオブジェクトが具体的な物理デバイスであればmake_request_fnメソッドはシステムの__によってmake_requestが実装されるとioスケジューリングレイヤに入ります(後で専門的に分析します).
ここではraid 5を例にmake_を分析しますrequestはbioをどのように転送しますか.他のraidアルゴリズムはここでは紹介しません.の