staticconststructblock_device_operations xblk_fops ={.owner = THIS_MODULE,#ifLINUX_VERSION_CODE >=KERNEL_VERSION(5,9,0).submit_bio = mem_blk_submit_bio,#endif.rw_page = mem_blk_rw_page,};staticintmem_blk_disk_init(void){int err =0;
xblk.file =filp_open( BLK_FILE_PATH, O_RDWR | O_CREAT,0644);if(IS_ERR(xblk.file)){pr_err("Failed to open file\n");
err =PTR_ERR(xblk.file);return err;}
xblk_major =register_blkdev(0,"mem_blk");if(xblk_major <0){filp_close( xblk.file,NULL);pr_err("register_blkdev returns %d\n", xblk_major);return xblk_major;}#ifLINUX_VERSION_CODE >=KERNEL_VERSION(5,14,0)
xblk.mem_blk_disk =blk_alloc_disk(NUMA_NO_NODE);#else
xblk.mem_blk_disk =alloc_disk(1);#endifif(xblk.mem_blk_disk ==NULL){pr_err("alloc_disk failed.");filp_close( xblk.file,NULL);return-ENOMEM;}
xblk.mem_blk_disk->major = xblk_major;
xblk.mem_blk_disk->first_minor =0;
xblk.mem_blk_disk->minors =1;
xblk.mem_blk_disk->fops =&xblk_fops;
xblk.mem_blk_disk->private_data =&xblk;strlcpy(xblk.mem_blk_disk->disk_name,"mem_blk",12);set_capacity(xblk.mem_blk_disk, g_size_gb *1024*1024*2);// g_size_gb is in GB, sector size is 512B#ifLINUX_VERSION_CODE <KERNEL_VERSION(5,14,0)
xblk.mem_blk_disk->queue = xblk.mem_blk_queue;#endif/* align partitions on 4k */blk_queue_physical_block_size(xblk.mem_blk_disk->queue, PAGE_SIZE);/* Tell the block layer that this is not a rotational device */blk_queue_flag_set(QUEUE_FLAG_NONROT, xblk.mem_blk_disk->queue);blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, xblk.mem_blk_disk->queue);add_disk(xblk.mem_blk_disk);return0;}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
structbio_vec{structpage*bv_page;//数据所在的页unsignedint bv_len;//数据长度unsignedint bv_offset;//数据在页中的偏移};structbvec_iter{sector_t bi_sector;/* 扇区号*/unsignedint bi_size;/* 数据段剩余个数*/unsignedint bi_idx;/* current index into bvl_vec */unsignedint bi_bvec_done;/* number of bytes completed in
current bvec */};