如下方式可以毕现。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
int fd1, fd2;
char *addr;
void *thr_fn(void *arg)
{
int ret;
printf("Submit read IO\n");
ret = read(fd2, addr, 4096);
printf("Read IO done %d\n", ret);
return ((void *)0);
}
int main(int argc, char *argv[])
{
pthread_t tid;
int err;
void *tret;
fd1 = open(argv[1], O_RDWR);
if (fd1 < 0) {
printf("Failed to open %s\n", argv[1]);
return -1;
}
fd2 = open(argv[2], O_RDWR | O_DIRECT);
if (fd2 < 0) {
printf("Failed to open %s\n", argv[2]);
return -1;
}
/* Map page from fileA */
addr = mmap(NULL, 4096, PROT_WRITE | PROT_READ, MAP_SHARED, fd1, 0);
if (addr == MAP_FAILED) {
printf("Failed to mmap\n");
return -1;
}
/* Write something, make sure the page is been created */
addr[0] = 'a';
fsync(fd1);
/* Thread direct read the fileB through the page of fileA */
err = pthread_create(&tid, NULL, thr_fn, NULL);
if (err != 0) {
printf("Failed to create thread\n");
return -1;
}
/* unmap the page and call fsync to make sure page is !dirty and !mapped */
sleep(1);
munmap(addr, 4096);
fsync(fd1);
system("echo 3 > /proc/sys/vm/drop_caches");
getchar();
pthread_join(tid, &tret);
close(fd1);
close(fd2);
return 0;
}
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index 933f234d5bec..d1098b64dede 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -10,6 +10,7 @@
#include <linux/backing-dev.h>
#include <linux/uio.h>
#include <linux/task_io_accounting_ops.h>
+#include <linux/delay.h>
#include "trace.h"
#include "../internal.h"
@@ -290,6 +291,12 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
bio_put(bio);
goto zero_tail;
}
if (iov_iter_rw(dio->submit.iter) == READ &&
!strncmp(inode->i_sb->s_type->name, "ext4", 4)) {
printk("[%s] submit direct read io, start to wait 10s\n", __func__);
msleep(10 * 1000);
}
n = bio->bi_iter.bi_size;
if (dio->flags & IOMAP_DIO_WRITE) {
gcc a.c -lpthread
mkfs.ext4 /dev/sda
mount /dev/sda /mnt
dd if=/dev/zero of=/mnt/fileA bs=4K count=1
dd if=/dev/zero of=/mnt/fileB bs=4K count=1
./a.out /mnt/fileA /mnt/fileB
即会出现BUG。
注意,必须用dd,用fallocate的话触发不了:
Hi yang-erkun, welcome to the openEuler Community.
I'm the Bot here serving you. You can find the instructions on how to interact with me at
https://gitee.com/openeuler/community/blob/master/en/sig-infrastructure/command.md.
If you have any questions, please contact the SIG: Kernel, and any of the maintainers: @Xie XiuQi, @YangYingliang, @成坚 (CHENG Jian).
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
登录 后才可以发表评论