我编写了一个读取函数来将文件读入内核空间的缓冲区。
int readfile(const char *filename, void *buf, int len, int offset)
{
struct file *filp;
mm_segment_t oldfs;
int bytes;
filp = NULL;
filp = filp_open(filename, O_RDONLY, 0);
if(!filp || IS_ERR(filp)) {
printk(" Error in reading file %s. Error = %d\n", filename, \
(int) PTR_ERR(filp));
return -1;
}
filp->f_pos = offset;
oldfs = get_fs();
set_fs(get_ds());
bytes = vfs_read(filp, buf, len, &filp->f_pos);
set_fs(oldfs);
filp_close(filp, NULL);
return bytes;
}
现在,这个功能运行得很好,我可以通过从系统调用中调用此函数将文件内容读入buf
char *firstbuffer;
firstbuffer = kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL);
bytesread = readfile(firstfile, firstbuffer, len, 0);
// Null terminate read string
firstbuffer[bytesread] = '\0';
printk("first buffer = %s\n",firstbuffer);
然后,我再次调用此函数将secondfile的内容读入secondbuffer。
char *secondbuffer;
secondbuffer = kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL);
bytesread2 = readfile(secondfile, secondbuffer, len, 0);
// Null terminate read string
secondbuffer[bytesread2] = '\0';
printk("second buffer %s", secondbuffer);
问题是在第二个文件上调用read函数后,我的firstbuffer的内容被第二个缓冲区的内容覆盖了。
例如:如果firstfile的内容是
A
B
C
和secondfile的内容是
X
Y
Z
然后在第一次读取文件调用后,firstbuffer的内容为:
A
B
C
然后在第二次读取文件调用之后,firstbuffer的内容为:
A
X
Y
Z
现在,我不确定这里出了什么问题,但是在第二次读取函数调用之后,firstbuffer的内容将与secondbuffer的内容合并。我该如何解决这个问题?
声明:
我知道我们不应该在内核空间中进行文件I / O.这纯粹是为了了解读取函数在内核空间中的工作原理。
答案 0 :(得分:1)
kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL)
这会分配sizeof(PAGE_SIZE)
个字节。现在,PAGE_SIZE
是一个整数,所以它可能长4个字节,所以你分配了4个字节。
如果要分配PAGE_SIZE
个字节,请使用:
kmalloc(PAGE_SIZE, GFP_KERNEL)
答案 1 :(得分:-1)
int readfile(const char *filename, void *buf, int len, int offset)
{
struct file *filp;
mm_segment_t oldfs;
int bytes;
filp = NULL;
为什么呢?这会立即被覆盖在下面。
filp = filp_open(filename, O_RDONLY, 0);
if(!filp || IS_ERR(filp)) {
filp_open不会返回NULL。
printk(" Error in reading file %s. Error = %d\n", filename, \
(int) PTR_ERR(filp));
缺少日志级别(例如KERN_WARNING)。错误消息,它表明实际读取失败。 PTR_ERR已经返回一个int。
return -1;
为什么这会返回-1而不是PTR_ERR(filp)?
}
filp->f_pos = offset;
现在这是一种奇怪的滥用行为。为什么要在文件对象中设置 f_pos ?如果你像pread一样检查消费者,你会发现你应该有一个专用的偏移变量并且只留下该字段。
oldfs = get_fs();
set_fs(get_ds());
bytes = vfs_read(filp, buf, len, &filp->f_pos);
set_fs(oldfs);
filp_close(filp, NULL);
return bytes;
}
现在另一部分:
char *firstbuffer;
firstbuffer = kmalloc(sizeof(PAGE_SIZE), GFP_KERNEL);
已经提到过sizeof bug。缺少错误检查,但我们假设它是为了简洁而被删除。
bytesread = readfile(firstfile, firstbuffer, len, 0);
为什么要分配 PAGE_SIZE ,但是读取 len ?
// Null terminate read string
无用的评论。
firstbuffer[bytesread] = '\0';
如果bytesread == PAGE_SIZE,这是一个一个接一个。
printk("first buffer = %s\n",firstbuffer);
[snip]
printk("second buffer %s", secondbuffer);
调试printfs错误。如果你需要转储这些东西,你应该以某种方式将它包起来,例如“[%S]”。在 firstbuffer 之前缺少空格。消息不一致 - 一个有“=”而另一个没有。