块设备调用逻辑(linux 5.4)

[ 2133.109595]  dump_stack+0x6d/0x8b
[ 2133.109596]  _rw_page+0xaf/0xbe [blk]
[ 2133.109597]  mem_blk_submit_bio.cold+0xc2/0x16d [blk]
[ 2133.109598]  generic_make_request+0xcf/0x320
[ 2133.109599]  submit_bio+0x48/0x1d0
[ 2133.109600]  ? bio_add_page+0x6a/0x90
[ 2133.109600]  submit_bh_wbc+0x182/0x1b0
[ 2133.109601]  __block_write_full_page+0x210/0x440
[ 2133.109602]  ? touch_buffer+0x70/0x70
[ 2133.109603]  block_write_full_page+0xb0/0x110
[ 2133.109604]  blkdev_writepage+0x18/0x20
[ 2133.109605]  __writepage+0x1d/0x50
[ 2133.109606]  write_cache_pages+0x1ae/0x4b0
[ 2133.109607]  ? __wb_calc_thresh+0x130/0x130
[ 2133.109608]  ? block_write_end+0x38/0x90
[ 2133.109609]  ? block_write_begin+0x4d/0xf0
[ 2133.109610]  ? balance_dirty_pages_ratelimited+0x259/0x390
[ 2133.109611]  ? generic_perform_write+0x13b/0x1c0
[ 2133.109612]  generic_writepages+0x57/0x90
[ 2133.109613]  blkdev_writepages+0xe/0x10
[ 2133.109614]  do_writepages+0x43/0xd0
[ 2133.109615]  ? blkdev_write_iter+0xcd/0x160
[ 2133.109616]  __filemap_fdatawrite_range+0xd5/0x110
[ 2133.109617]  file_write_and_wait_range+0x74/0xc0
[ 2133.109618]  blkdev_fsync+0x1b/0x50
[ 2133.109619]  vfs_fsync_range+0x49/0x80
[ 2133.109619]  do_fsync+0x3d/0x70
[ 2133.109620]  __x64_sys_fsync+0x14/0x20
[ 2133.109621]  do_syscall_64+0x57/0x190
[ 2133.109622]  entry_SYSCALL_64_after_hwframe+0x5c/0xc1
[ 2133.109623] RIP: 0033:0x7f68ba6bd1a7
[ 2133.109623] Code: 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 4a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 23 f4 f7 ff
[ 2133.109624] RSP: 002b:00007ffe75697478 EFLAGS: 00000246 ORIG_RAX: 000000000000004a
[ 2133.109624] RAX: ffffffffffffffda RBX: 000055a9657ad5b0 RCX: 00007f68ba6bd1a7
[ 2133.109625] RDX: 0000000000000000 RSI: 000055a9657ad5b0 RDI: 0000000000000003
[ 2133.109625] RBP: 0000000000000000 R08: 0000000000000000 R09: 00007f68ba7952f0
[ 2133.109625] R10: 000055a9657a7010 R11: 0000000000000246 R12: 0000000000000000
[ 2133.109626] R13: 0000000000000000 R14: 00007ffe756974f8 R15: 000055a9657ac770

[  282.777255] CPU: 0 PID: 2801 Comm: mount Tainted: G           OE     5.4.233-20230608 #11
[  282.777257] Hardware name: VMware, Inc. VMware20,1/440BX Desktop Reference Platform, BIOS VMW201.00V.20648489.B64.2210180829 10/18/2022
[  282.777258] Call Trace:
[  282.777262]  dump_stack+0x6d/0x8b
[  282.777265]  spu_mem_blk_rw_page+0x48/0x5f [spu_blk]
[  282.777269]  bdev_read_page+0x79/0xa0
[  282.777272]  do_mpage_readpage+0x626/0x810
[  282.777277]  ? lru_cache_add+0xe/0x10
[  282.777280]  mpage_readpages+0xe4/0x1a0
[  282.777284]  ? blkdev_direct_IO+0x4b0/0x4b0
[  282.777288]  blkdev_readpages+0x1d/0x20
[  282.777290]  read_pages+0x71/0x1a0
[  282.777293]  __do_page_cache_readahead+0x12f/0x1a0
[  282.777295]  force_page_cache_readahead+0x98/0x110
[  282.777297]  page_cache_sync_readahead+0xaf/0xc0
[  282.777300]  generic_file_read_iter+0x942/0xda0
[  282.777302]  ? lru_cache_add_active_or_unevictable+0x3a/0xb0
[  282.777304]  blkdev_read_iter+0x4a/0x60
[  282.777307]  new_sync_read+0x122/0x1b0
[  282.777310]  __vfs_read+0x29/0x40
[  282.777312]  vfs_read+0xab/0x160
[  282.777314]  ksys_read+0x67/0xe0
[  282.777317]  __x64_sys_read+0x1a/0x20
[  282.777320]  do_syscall_64+0x57/0x190
[  282.777323]  entry_SYSCALL_64_after_hwframe+0x5c/0xc1
[  282.777324] RIP: 0033:0x7f25b85c0fd2
[  282.777326] Code: c0 e9 c2 fe ff ff 50 48 8d 3d aa cb 0a 00 e8 d5 1a 02 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24
[  282.777327] RSP: 002b:00007ffd78506a58 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[  282.777328] RAX: ffffffffffffffda RBX: 00007f25b7f88028 RCX: 00007f25b85c0fd2
[  282.777329] RDX: 0000000000040000 RSI: 00007f25b7f88038 RDI: 0000000000000003
[  282.777330] RBP: 000055cabafa39a0 R08: 00007f25b7f88010 R09: 0000000000000000
[  282.777331] R10: 0000000000000022 R11: 0000000000000246 R12: 000000003ffc0000
[  282.777333] R13: 0000000000040000 R14: 00007f25b7f88010 R15: 000055cabafa39f0
[  282.777429] [spu_mem_blk_rw_page] cpu 0 pid 2801 comm mount             sector 2097032 page_address 0xffff987a23212000 op 0 page_idx 262129


static const struct block_device_operations xblk_fops = {
	.owner = THIS_MODULE,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
	.submit_bio = mem_blk_submit_bio,
#endif
	.rw_page = mem_blk_rw_page,
};

static int mem_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;
	}
#if LINUX_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);
#endif
	if (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

#if LINUX_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);
	return 0;
}
struct bio_vec {
	struct page	*bv_page;  //数据所在的页
	unsigned int	bv_len; //数据长度
	unsigned int	bv_offset;  //数据在页中的偏移
};

struct bvec_iter {
	sector_t		bi_sector;	/* 扇区号*/
	unsigned int		bi_size;	/* 数据段剩余个数*/

	unsigned int		bi_idx;		/* current index into bvl_vec */

	unsigned int            bi_bvec_done;	/* number of bytes completed in
						   current bvec */
};
static blk_qc_t mem_blk_submit_bio(struct request_queue *queue, struct bio *bio)
#endif
{
	sector_t sector = bio->bi_iter.bi_sector;
	struct bio_vec bvec;
	struct bvec_iter iter;

	bio_for_each_segment(bvec, bio, iter) {
		unsigned int len = bvec.bv_len;
		int err;
		// printk("[mem_blk_submit_bio] len %d offset %d sector %lld op %d\n", 
        //                         len, bvec.bv_offset, sector, bio_op(bio));
		if (len != PAGE_SIZE) {
			pr_info("[mem_blk_submit_bio] unexpected page size %d\n", len);
			goto io_error;
		}
		//数据读写操作
		if (err)
			goto io_error;
		sector += len >> SECTOR_SHIFT;
	}
	bio_endio(bio);
	return BLK_QC_T_NONE;
io_error:
	bio_io_error(bio);
	return BLK_QC_T_NONE;
}

你可能感兴趣的:(linux,运维,服务器)