Linux块设备读写测试-page cache/buffer cache

34 篇文章 2 订阅
5 篇文章 0 订阅

 测试用例:

#include <stdio.h>
#include <fcntl.h>
#include <linux/hdreg.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>

static void dump_identity (const struct hd_driveid *id);

int main(void)
{
    int fd = 0;
	unsigned char buf[512];

    fd = open("/dev/sda",O_RDONLY);
    static struct hd_driveid id;

    if (!ioctl(fd, HDIO_GET_IDENTITY, &id))
    {
        dump_identity(&id);
    }
    else
	{
        printf(" HDIO_GET_IDENTITY failed\n");
        perror("ioctl:");
	}

	memset(buf, 0x00, 512);

	if(read(fd, buf, 512) != 512)
	{
        perror("read error.\n");
	}

    return 0;
}

static void dump_identity (const struct hd_driveid *id)
{
    const unsigned short int *id_regs= (const void*) id;
    printf("Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n", id->model, id->fw_rev, id->serial_no);
}

内核加入log:

​

diff --git a/fs/block_dev.c b/fs/block_dev.c
index fa329c7ed..b0dcdb0b0 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -2034,6 +2034,10 @@ ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
 	if (pos >= size)
 		return 0;
 
+	if(!strcmp("blktest", current->comm))
+	{
+		printk("%s line %d.\n", __func__, __LINE__);
+	}
 	size -= pos;
 	if (iov_iter_count(to) > size) {
 		shorted = iov_iter_count(to) - size;
diff --git a/fs/read_write.c b/fs/read_write.c
index 7458fccc5..672e0bae1 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -421,6 +421,11 @@ static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, lo
 ssize_t __vfs_read(struct file *file, char __user *buf, size_t count,
 		   loff_t *pos)
 {
+	if(!strcmp("blktest", current->comm))
+	{
+		printk("%s line %d, read = 0x%lx. read_iter = 0x%lx.\n", __func__, __LINE__, (unsigned long)file->f_op->read, (unsigned long)file->f_op->read_iter);
+	}
+
 	if (file->f_op->read)
 		return file->f_op->read(file, buf, count, pos);
 	else if (file->f_op->read_iter)
@@ -447,6 +452,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
 {
 	ssize_t ret;
 
+
 	if (!(file->f_mode & FMODE_READ))
 		return -EBADF;
 	if (!(file->f_mode & FMODE_CAN_READ))
diff --git a/mm/filemap.c b/mm/filemap.c
index c10e237cc..916c325af 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2050,6 +2050,11 @@ static ssize_t generic_file_buffered_read(struct kiocb *iocb,
 	last_index = (*ppos + iter->count + PAGE_SIZE-1) >> PAGE_SHIFT;
 	offset = *ppos & ~PAGE_MASK;
 
+	if(!strcmp("blktest", current->comm))
+	{
+		printk("%s line %d.\n", __func__, __LINE__);
+	}
+
 	for (;;) {
 		struct page *page;
 		pgoff_t end_index;

[点击并拖拽以移动]
​

执行后:

caozilong@caozilong-Vostro-3268:~/Workspace/identiy$ ls
blktest  main.c
caozilong@caozilong-Vostro-3268:~/Workspace/identiy$ sudo ./blktest 
Model=Samsung SSD 860 EVO 500GB               , FwRev=RVT02B6Q, SerialNo=S3Z3NB0M420385X     
caozilong@caozilong-Vostro-3268:~/Workspace/identiy$ 

dmesg有如下log输出:

[   12.556973] IPv6: ADDRCONF(NETDEV_CHANGE): enp2s0: link becomes ready
[   19.604621] Bluetooth: RFCOMM TTY layer initialized
[   19.604625] Bluetooth: RFCOMM socket layer initialized
[   19.604631] Bluetooth: RFCOMM ver 1.11
[   20.405604] rfkill: input handler disabled
[   57.135125] __vfs_read line 426, read = 0x0. read_iter = 0xffffffffa279aea0.
[   57.135128] generic_file_buffered_read line 2055.
[   57.135567] __vfs_read line 426, read = 0x0. read_iter = 0xffffffffa2723370.
[   57.135569] blkdev_read_iter line 2039.
[   57.135570] generic_file_buffered_read line 2055.
[  438.531751] __vfs_read line 426, read = 0x0. read_iter = 0xffffffffa279aea0.
[  438.531753] generic_file_buffered_read line 2055.
[  438.531913] __vfs_read line 426, read = 0x0. read_iter = 0xffffffffa2723370.
[  438.531914] blkdev_read_iter line 2039.
[  438.531914] generic_file_buffered_read line 2055.
caozilong@caozilong-Vostro-3268:~/Workspace/linux-compile/linux-5.4.129$ 

证明Linux块设备的操作fops如下:

 


关于块设备读写的关键一步和最后一公里,是以下函数:

generic_make_request

一个O_DIRECT读写用例堆栈:

用普通方式带有page cache(非DIRECT模式)操作文件的调用堆栈


结束!

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

papaofdoudou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值