Raw Disks

磁盘访问单位是扇区,每个扇区大小是512字节

磁盘I/O过程

控制器→寻道→旋转→传输

最直接的使用磁盘

只要向控制器中写柱面、磁头、扇区、缓存位置
notion image
notion image

通过盘块号(block)读写磁盘

notion image
block相邻的盘可以快速读出,图中的读取顺序是0扇区、1扇区、……6扇区,0扇区下面的7扇区
notion image
block = C*(Heads*Sectors)+H*Sectors+S
磁盘驱动负责从block计算出cyl、head、sec(CHS):
  • S = block % sectors
  • ……
磁盘访问时间 = 写入控制器时间 + 寻道时间 + 旋转时间 + 传输时间;(约10ms)
其中传输时间可以忽略不计。如果每次读写1K,碎片0.5K,读写速度是100K/秒;每次读写1M,碎片0.5M,读写速度约40M/秒;
notion image
因此从读写一个扇区到一个盘块(连续的几个扇区)可以提高读写速度
程序输出block:
static void make_request() { struct requset *req; req=request+NR_REQUEST; req->sector=bh->b_blocknr<<1; // block<<1,这里的盘块是2个扇区 add_request(major+blk_dev,req); }
void do_hd_request(void) { unsigned int block=CURRENT->sector; __asm__(“divl %4”:”=a”(block),”=d”(sec):”0”(block), “1”(0),”r”(hd_info[dev].sect)); __asm__(“divl %4”:”=a”(cyl),”=d”(head):”0”(block), “1”(0),”r”(hd_info[dev].head)); hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,...); ... }

多个进程通过队列使用磁盘

notion image

FCFS磁盘调度算法

磁头开始位置:53
请求队列: 98,183,37,22,14,124,65,67
notion image
移动了640磁道

SSTF磁盘调度(短寻道优先,Shortest-seek-time First)

notion image

SCAN磁盘调度(扫描调度)

SSTF + 中途不回折:每个请求都有处理机会
notion image

C-SCAN磁盘调度(电梯算法)

SCAN + 直接移动到另一端:两端的请求都能很快处理
notion image
代码实现:
static void make_request() { ... req->sector=bh->b_blocknr<<1; add_request(major+blk_dev,req); }
static void add_request(struct blk_dev_struct *dev, struct request *req) { struct requset *tmp=dev->current_request; req->next=NULL; cli(); //关中断(互斥) for(;tmp->next;tmp=tmp->next) if((IN_ORDER(tmp,req)||!IN_ORDER(tmp,tmp->next)) &&IN_ORDER(req,tmp->next)) break; req->next=tmp->next; tmp->next=req; sti(); }
#define IN_ORDER(s1, s2) \ ((s1)->dev<(s2)->dev)||((s1)->dev == (s2)->dev \ && (s1)->sector<(s2)->sector))
sector = C * (Heads ́Sectors) + H * Sectors + S