У пользователя пространство, это можно сделать, передав флаг O_DIRECT в open(). Вот мой код пользовательского пространства (и он отлично работает):
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
int main()
{
int fd = open(filepath, O_RDONLY | O_DIRECT);
if (fd == -1) {
perror("open");
return 1;
}
struct stat fstat;
stat("musl-hello", &fstat);
int blksize = (int)fstat.st_blksize;
int align = blksize-1;
const char *big_buf = (char *) malloc(blksize + align);
unsigned char *buff = (char *)( (unsigned long)(big_buf+align) & ~align );
if(read(fd, buff, (size_t)blksize) < 1)
{
//Error handling
free(big_buf);
return -1;
}
return 0;
}
- буфер должен поступать из пользовательского пространства
- буфер должен быть выровнен по размеру блока
Код: Выделить всё
mm_segment_t old_fs;
struct file *fp;
int rv = 0;
old_fs = get_fs();
set_fs(KERNEL_DS);
fp = filp_open(fpath, O_RDONLY | O_DIRECT, 0); // fpath is the path to the file to be read
if (IS_ERR(fp))
{
printk("filp_open failed\n");
}
else
{
loff_t pos = 0;
unsigned char *big_buf = kmalloc(0x2000, GFP_KERNEL);
if(big_buf == NULL)
{
printk("bad kmalloc\n");
}
// it seems kmalloc already aligned big_buf
unsigned char *aligned_buf = (unsigned char *)((unsigned long)(big_buf + 0xfff) & ~0xfff);
rv = vfs_read(fp, (void __user *)aligned_buf, 0x1000, &pos);
if (rv < 0)
{
printk("vfs_read() err, rv: %d\n", rv);
}
kfree(big_buf);
filp_close(fp, NULL);
}
set_fs(old_fs);
Любая помощь или предложения приветствуются и очень ценятся!
Подробнее здесь: https://stackoverflow.com/questions/787 ... pace-fails