You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义系统调用中printk有无导致filp_write文件写入异常问题求助

问题分析与解决

核心原因是内核页缓存的延迟写入机制:

  • 你的kernel_write调用仅将数据写入内核页缓存,并未立刻同步到磁盘。
  • 保留printk时,该函数会触发内核调度或引入短暂延迟,给内核页缓存刷新线程(如pdflush、kswapd)足够时间将缓存数据刷入磁盘,因此能看到目标文件内容。
  • 移除printk后,复制流程执行极快,filp_close虽会清理文件资源,但不会强制同步页缓存到磁盘,此时立刻查看文件就会看不到写入内容(内核后续可能异步刷新,但无法即时呈现)。

你的代码还有几处需要修正的问题:

  1. 文件打开参数错误:用O_RDWR打开目标文件时,若文件不存在会直接失败,需添加O_CREAT标志并指定合法权限,例如:
    struct file *dest = filp_open(dest_filename, O_RDWR | O_CREAT, 0644);
    
  2. 缺失错误检查:未检查filp_open的返回值,若文件打开失败(如权限不足),后续操作会直接崩溃,需补充检查逻辑:
    if (IS_ERR(dest)) {
        return PTR_ERR(dest);
    }
    if (IS_ERR(src)) {
        filp_close(dest, NULL);
        return PTR_ERR(src);
    }
    
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:15:34