5.2:外设-块设备磁盘

磁盘工作过程

1)磁头移动,找到柱面
2)柱面中选择读写的磁道
3)旋转磁盘,将对应磁道中要读写的那个扇区转到磁头下方
4)都系扇区中的内容到缓存中

代码实现

1:第一层抽象-扇区到磁盘块请求
因为数据传输数据和寻道、旋转时间相比要小得多,所以寻道,旋转一次读写K个扇区的策略比只读写一个扇区的策略,读写速度会提供K倍。所以抽象处磁盘快后,磁盘的读写速度会有非常显著的提高。
当用户传入磁盘的盘块号时,就可以找到扇区号,然后加入传输请求中了。

static void make_request(int major,int rw, struct buffer_head * bh)
      	req->sector = bh->b_blocknr<<1;
        add_request(major+blk_dev,req);

2:第二层抽象-多进程的磁盘请求队列
电梯调度算法:先朝某个方向进行扫描,处理经过的所有磁盘请求,直到这个方向不再磁盘请求时,磁头迅速复位到另一个方向的最大请求位置,然后沿该方向进行扫描。

通过循环遍历和算法判断条件,找到可以插入的位置。

static void add_request(struct blk_dev_struct * dev, struct request * req)
{
        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();
}

3:第三层抽象-从磁盘请求到高速缓存
当用户需要读取100B的数据时,真正读入的数据是以扇区为大小,所以会大于100B,那么如果将多余的数据存放在内核态内存中,那么就会大幅度减少磁盘读写次数,提高磁盘使用效率。这就是磁盘高速缓存。

struct buffer_head * bread(int dev,int block)
{                       
        struct buffer_head * bh;
                
        if (!(bh=getblk(dev,block)))
                panic("bread: getblk returned NULL\n");
        if (bh->b_uptodate)
                return bh;      
        ll_rw_block(READ,bh);
        wait_on_buffer(bh);
        if (bh->b_uptodate)
                return bh;
        brelse(bh);
        return NULL;
}               
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值