Linux kernel_write 函数 returns EFBIG 将数据追加到大文件时

Linux kernel_write function returns EFBIG when appending data to big file

任务是编写简单的字符设备,将写入设备的所有数据复制到 tmp 文件中。

我使用 kernel_write 函数将数据写入文件,并且在大多数情况下工作正常。但是当输出文件大小大于 2.1 GB 时,kernel_write 函数失败,return 值为 -27。

要写入文件,我使用这个函数:

void writeToFile(void* buf, size_t size, loff_t *offset) {
    struct file* destFile;
    char* filePath = "/tmp/output";
    destFile = filp_open(filePath,  O_CREAT|O_WRONLY|O_APPEND, 0666);
    if (IS_ERR(destFile) || destFile == NULL) {
      printk("Cannot open destination file");
      return;
    }
    size_t res = kernel_write(destFile, buf, size, offset);
    printk("%ld", res);
    filp_close(destFile, NULL);
}

如果“/tmp/output”的大小 < 2.1 GB,这个函数就可以正常工作。

如果“/tmp/output”的大小> 2.1 GB,kernel_write开始为return -27

我该如何解决这个问题?

谢谢

您需要使用 O_LARGEFILE 标志启用 Large File Support (LFS)。

下面的代码对我有用。抱歉,为了调试,我做了一些其他的修改,但是我在相关行上面评论了。

struct file* writeToFile(void* buf, size_t size, loff_t *offset) 
{
    struct file* destFile;
    char* filePath = "/tmp/output";
    size_t res;
    
    // Add the O_LARGEFILE flag here
    destFile = filp_open(filePath, O_CREAT | O_WRONLY | O_APPEND | O_LARGEFILE, 0666);
    if (IS_ERR(destFile)) 
    {
        printk("Error in opening: <%ld>", (long)destFile);
        return destFile;
    }
    if (destFile == NULL)
    {
        printk("Error in opening: null");
        return destFile;
    }
    
    res = kernel_write(destFile, buf, size, offset);
    printk("CODE: <%ld>", res);
    filp_close(destFile, NULL);

    return destFile;
}

为了测试它,我用 fallocate -l 3G /tmp/output 创建了一个文件,然后删除了 O_CREAT 标志,因为它给出了内核权限错误。


我应该添加一个免责声明,很多人说内核中的文件 I/O 是 bad idea。即使在我自己测试时,由于愚蠢的错误,我不小心让我的电脑崩溃了两次。

也许可以这样做:Read/Write from /proc File