免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1364 | 回复: 0
打印 上一主题 下一主题

Linux块设备(4)-IO请求处理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-01 23:29 |只看该作者 |倒序浏览
块设备的IO请求处理
void request(request_queue_t *queue);由内核在适时读写时调用。
static  void xxx_request(request_queue_t *q)
{
struct request *req;
  while ((req=elv_next_request(q))!=NULL)
{
struct xxx_dev  *dev = req->rq_disk->private_data;
if(!blk_fs_request(req))
   {printk(KERN_NOTIC "skip no fs request \n");
    end_request(req,0);
    continue;
   }
         xxx_transfer(dev,req->sector, req->current_nr_sectors,
  req->buffer, rq_data_dir(req));
end_request(req,1);
      }
}
static void xxx_transfer(struct xxx_dev *dev, unsigned long sector,
  unsigned long nsector, char *buffer, int write)
{
unsigned long offset = sector*KERNEL_SECTOR_SIZE;
unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE;
if((offset + nbytes) >dev->size)
  {prink(KERN_NOTICE "Beyond end write (%ld %ld) \n, offset, nbytes); return ;}
if(write)
  { write_dev(offset, buffer, nbytes);}
else read_dev(offset, bufferm nbytes);
}
void end_request(struct request *req, int update)
{
if(!end_that_request_first(req, uptodate, req->hard_sectors))
{
add_disk_randomness(req->rq_disks);
blkdev_dequeue_request(req);
end_that_request_last(req);
}
}
当一个设备完成一个IO请求的部分或全部扇区后,它必须告知设备层已经完成的扇区数目。
int end_that_request_first(struct request *req, int success, int count);
void end_that_request_last(struct request *req);告知所有等待这个请求完成的对象并回收
请求结构体。
==========================
遍历请求,BIO 段
static void xxx_full_request(request_queue_t *q)
{
  struct request *req;
  int sectors_xferred;
  struct xxx_dev *dev = q->queuedata;
   while((req=elv_next_request(q))!=NULL)
     {
if(!blk_fs_request(req))
   {printk(KERN_NOTIC "skip no fs request \n");
    end_request(req,0);
    continue;
   }
sectors_xferred=xxx_xfer_request(dev,req);
if(!end_that_request_first(req, 1, sectors_xferred))
  {blkdev_dequeue_request(req);
   end_that_request_last(req);
   }
}
}
static int xxx_xfer_request(struct xxx_dev *dev,struct request *req)
{
  struct bio *bio;
  int nsec=0;
rq_for_each_bio(bio, req)
{
xxx_xfer_bio(dev,bio);
nsect += bio->bi_size;
}
return nsect;
}
static int xxx_xfer_bio(struct xxx_dev *dev, struct bio *bio)
{
int i;
struct bio_vec *bvec;
sectors_t sector =bio->bi_sector;
bio_for_each_segment(bvec,bio, i)
{
char *buffer = __bio_map_atomic(bio, i, KM_USER0);
xxx_transfer(dev, sector, bio_cur_sectors(bio), buffer, bio_data_dir(bio) ==WRITE)
sector += bio_cur_sectors(bio);
__bio_kunmap(bio,KM_USER0);
}
return 0
}
======================
不使用请求队列
typedef int (make_request_fn) (request_queue_t *q, struct bio *bio);
完成后通知处理结束
void bio_endio(struct bio *bio, unsigned int bytes, int error)
bytes为已经传送的字节数。
static int xx_make_request(request_queue_t *q,struct bio *bio)
{
struct xxx_dev *dev = q->queuedata;
int status ;
status = xxx_xfer_bio(dec,bio);
bio_endio(bio,bio_bi_size, status);
return 0;
}
有请求队列 使用blk_init_queue(xxx_request,xxx_lock)
无 blk_alloc_queue  blk_queue_make_request


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/69624/showart_1070882.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP