Advertisement
ALTEK

SO2LAB9ZAD1

Jun 21st, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.94 KB | None | 0 0
  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. #define DEVICE_SIZE 4*1024*1024
  9.  
  10. static int sector_size = 512;
  11. static int major = 0;
  12. static struct sbd_struct
  13. {
  14. struct gendisk *gd;
  15. void *memory;
  16. } sbd_dev;
  17.  
  18. static inline int transfer_single_bio(struct bio *bio)
  19. {
  20. struct bvec_iter iter;
  21. struct bio_vec vector;
  22. sector_t sector = bio->bi_iter.bi_sector;
  23. bool wirte = bio_data_dir(bio) == WRITE;
  24. bio_for_each_segment(vector,bio,iter) {
  25. unsigned int len = vector.bv_len;
  26. void *addr = kmap(vector.bv_page);
  27. if(wirte)
  28. memcpy(sbd_dev.memory+sector*sector_size,addr+vector.bv_offset,len);
  29. else
  30. memcpy(addr+vector.bv_offset,sbd_dev.memory+sector*sector_size,len);
  31. kunmap(addr);
  32. sector += len >> 9;
  33. }
  34. return 0;
  35. }
  36.  
  37. static blk_qc_t make_request(struct request_queue *q, struct bio *bio)
  38. {
  39. int result=0;
  40.  
  41. if(bio_end_sector(bio)>get_capacity(bio->bi_bdev->bd_disk))
  42. {bio_io_error(bio);
  43. return BLK_QC_T_NONE;}
  44.  
  45. result = transfer_single_bio(bio);
  46. if(unlikely(result!=0)){
  47. bio_io_error(bio);
  48. return BLK_QC_T_NONE;
  49. }
  50.  
  51. bio_endio(bio);
  52. return BLK_QC_T_NONE;
  53. }
  54.  
  55. static struct block_device_operations block_methods = {
  56. .owner = THIS_MODULE
  57. };
  58.  
  59.  
  60. static int __init sbd_constructor(void)
  61. {
  62. sbd_dev.memory = vmalloc(DEVICE_SIZE);
  63. if(!sbd_dev.memory) {
  64. pr_alert("Memory allocation error!\n");
  65. return -ENOMEM;
  66. }
  67. sbd_dev.gd = alloc_disk(1);
  68. if(!sbd_dev.gd) {
  69. pr_alert("General disk structure allocation error!\n");
  70. vfree(sbd_dev.memory);
  71. return -ENOMEM;
  72. }
  73. major = register_blkdev(major,"sbd");
  74. if(major<=0){
  75. pr_alert("Major number allocation error!\n");
  76. put_disk(sbd_dev.gd);
  77. return -ENOMEM;
  78. }
  79. pr_info("[sbd] Major number allocated: %d.\n",major);
  80. sbd_dev.gd->major = major;
  81. sbd_dev.gd->first_minor = 0;
  82. sbd_dev.gd->fops = &block_methods;
  83. sbd_dev.gd->private_data = NULL;
  84. sbd_dev.gd->flags|=GENHD_FL_SUPPRESS_PARTITION_INFO;
  85. strcpy(sbd_dev.gd->disk_name,"sbd");
  86. set_capacity(sbd_dev.gd,(DEVICE_SIZE)>>9);
  87. sbd_dev.gd->queue = blk_alloc_queue(GFP_KERNEL);
  88. if(!sbd_dev.gd->queue) {
  89. pr_alert("Request queue allocation error!\n");
  90. unregister_blkdev(major,"sbd");
  91. return -ENOMEM;
  92. }
  93. blk_queue_make_request(sbd_dev.gd->queue,make_request);
  94. pr_info("[sbd] Gendisk initialized.\n");
  95. add_disk(sbd_dev.gd);
  96. return 0;
  97. }
  98.  
  99. static void __exit sbd_desctructor(void)
  100. {
  101. del_gendisk(sbd_dev.gd);
  102. blk_cleanup_queue(sbd_dev.gd->queue);
  103. unregister_blkdev(major,"sbd");
  104. put_disk(sbd_dev.gd);
  105. vfree(sbd_dev.memory);
  106. }
  107.  
  108. module_init(sbd_constructor);
  109. module_exit(sbd_desctructor);
  110.  
  111. MODULE_LICENSE("GPL");
  112. MODULE_AUTHOR("Piotr Nowakowski | Michał Mazur");
  113. MODULE_DESCRIPTION("A pseudo block device.");
  114. MODULE_VERSION("1.0");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement