Facebook
From U, 5 Years ago, written in C.
Embed
Download Paste or View Raw
Hits: 277
  1. #include<linux/module.h>
  2. #include<linux/genhd.h>
  3. #include<linux/vmalloc.h>
  4. #include<linux/fs.h>
  5. #include<linux/bio.h>
  6. #include<linux/blkdev.h>
  7.  
  8. static unsigned long long mem = 409600;
  9.  
  10. module_param(mem,ullong,0644);
  11. MODULE_PARM_DESC(mem,"parameter");
  12.  
  13. static int sector_size = 512;
  14. static int major = 0;
  15. static struct sbd_struct
  16. {
  17.         struct gendisk *gd;
  18.         void *memory;
  19. } sbd_dev;
  20.  
  21. static inline int transfer_single_bio(struct bio *bio)
  22. {
  23.         struct bvec_iter iter;
  24.         struct bio_vec vector;
  25.         sector_t sector = bio->bi_iter.bi_sector;
  26.         bool wirte = bio_data_dir(bio) == WRITE;
  27.        
  28.         bio_for_each_segment(vector,bio,iter) {
  29.                 unsigned int len = vector.bv_len;
  30.                 void *addr = kmap(vector.bv_page);
  31.                 if(wirte)
  32.                         memcpy(sbd_dev.memory+sector*sector_size,addr+vector.bv_offset,len);
  33.                 else
  34.                         memcpy(addr+vector.bv_offset,sbd_dev.memory+sector*sector_size,len);
  35.                 kunmap(addr);
  36.                 sector += len >> 9;
  37.         }
  38.         return 0;
  39. }
  40.  
  41. static blk_qc_t make_request(struct request_queue *q, struct bio *bio)
  42. {
  43.         int result=0;
  44.  
  45.         if(bio_end_sector(bio)>get_capacity(bio->bi_bdev->bd_disk))
  46.                 goto mrerr0;
  47.        
  48.         result = transfer_single_bio(bio);
  49.         if(unlikely(result!=0))
  50.                 goto mrerr0;
  51.  
  52.         bio_endio(bio);
  53.         return BLK_QC_T_NONE;
  54. mrerr0:
  55.         bio_io_error(bio);
  56.         return BLK_QC_T_NONE;
  57. }
  58.  
  59. static struct block_device_operations block_methods = {
  60.         .owner = THIS_MODULE
  61. };
  62.  
  63.  
  64. static int __init sbd_constructor(void)
  65. {
  66.         pr_info("mem= %lld \n",mem);
  67.         sbd_dev.memory = vmalloc(mem);
  68.         if(!sbd_dev.memory) {
  69.                 pr_alert("Memory allocation error!\n");
  70.                 goto ier1;
  71.         }
  72.         sbd_dev.gd = alloc_disk(1);
  73.         if(!sbd_dev.gd) {
  74.                 pr_alert("General disk structure allocation error!\n");
  75.                 goto ier2;
  76.         }
  77.         major = register_blkdev(major,"sbd");
  78.         if(major<=0) {
  79.                 pr_alert("Major number allocation error!\n");  
  80.                 goto ier3;
  81.         }
  82.         pr_info("[sbd] Major number allocated: %d.\n",major);
  83.         sbd_dev.gd->major = major;
  84.         sbd_dev.gd->first_minor = 0;
  85.         sbd_dev.gd->fops = &block_methods;
  86.         sbd_dev.gd->private_data = NULL;
  87.         sbd_dev.gd->flags|=GENHD_FL_SUPPRESS_PARTITION_INFO;
  88.         strcpy(sbd_dev.gd->disk_name,"sbd");
  89.         set_capacity(sbd_dev.gd,(mem)>>9);
  90.         sbd_dev.gd->queue = blk_alloc_queue(GFP_KERNEL);
  91.         if(!sbd_dev.gd->queue) {
  92.                 pr_alert("Request queue allocation error!\n");
  93.                 goto ier4;
  94.         }
  95.         blk_queue_make_request(sbd_dev.gd->queue,make_request);
  96.         pr_info("[sbd] Gendisk initialized.\n");
  97.         add_disk(sbd_dev.gd);
  98.         return 0;      
  99. ier4:
  100.         unregister_blkdev(major,"sbd");
  101. ier3:
  102.         put_disk(sbd_dev.gd);
  103. ier2:
  104.         vfree(sbd_dev.memory);
  105. ier1:
  106.         return -ENOMEM;
  107. }
  108.  
  109. static void __exit sbd_desctructor(void)
  110. {
  111.         del_gendisk(sbd_dev.gd);
  112.         blk_cleanup_queue(sbd_dev.gd->queue);
  113.         unregister_blkdev(major,"sbd");
  114.         put_disk(sbd_dev.gd);
  115.         vfree(sbd_dev.memory);
  116. }
  117.  
  118. module_init(sbd_constructor);
  119. module_exit(sbd_desctructor);
  120.  
  121. MODULE_LICENSE("GPL");
  122. MODULE_VERSION("1.0");