自定义系统调用中printk有无导致filp_write文件写入异常问题求助
问题分析与解决
核心原因是内核页缓存的延迟写入机制:
- 你的
kernel_write调用仅将数据写入内核页缓存,并未立刻同步到磁盘。 - 保留
printk时,该函数会触发内核调度或引入短暂延迟,给内核页缓存刷新线程(如pdflush、kswapd)足够时间将缓存数据刷入磁盘,因此能看到目标文件内容。 - 移除
printk后,复制流程执行极快,filp_close虽会清理文件资源,但不会强制同步页缓存到磁盘,此时立刻查看文件就会看不到写入内容(内核后续可能异步刷新,但无法即时呈现)。
你的代码还有几处需要修正的问题:
- 文件打开参数错误:用
O_RDWR打开目标文件时,若文件不存在会直接失败,需添加O_CREAT标志并指定合法权限,例如:struct file *dest = filp_open(dest_filename, O_RDWR | O_CREAT, 0644); - 缺失错误检查:未检查
filp_open的返回值,若文件打开失败(如权限不足),后续操作会直接崩溃,需补充检查逻辑:if (IS_ERR(dest)) { return PTR_ERR(dest); } if (IS_ERR(src)) { filp_close(dest, NULL); return PTR_ERR(src); } kernel_read返回值处理不当:kernel_read返回读取的字节数,负数表示错误,你仅判断!flag(即返回0或负数),应区分EOF与错误场景,不过暂时不影响核心功能。
解决方法
在关闭目标文件前,调用vfs_fsync强制将页缓存同步到磁盘:
修改后的关键代码片段:
int copy_file(char* dest_filename, char* source_filename){ struct file *dest = filp_open(dest_filename, O_RDWR | O_CREAT, 0644); if (IS_ERR(dest)) { return PTR_ERR(dest); } struct file *src = filp_open(source_filename, O_RDWR, 0); if (IS_ERR(src)) { filp_close(dest, NULL); return PTR_ERR(src); } char buf[100]; long long dest_offset = 0; long long src_offset = 0; while (1){ int count = 0; int ch; ssize_t flag; while(1){ flag = kernel_read(src, &ch, 1, &src_offset); if (flag <= 0) break; buf[count++]=ch; if (ch == '\n') break; } if (flag <= 0) break; kernel_write(dest, buf, count, &dest_offset); } // 强制同步缓存到磁盘 vfs_fsync(dest, 0); filp_close(src, NULL); filp_close(dest, NULL); return 0; }
注意:内核编程中,绝不能依赖printk这类调试函数的副作用保证功能正常,它的调度延迟只是巧合触发了缓存刷新,并非正确解决方案。
内容的提问来源于stack exchange,提问作者Abhishek Ghosh
相关产品推荐
相关产品推荐

