Linux kernel_write function returns EFBIG when appending data to big file

Viewed 774

The task is to write simple character device that copies all the data written to the device to tmp a file.

I use kernel_write function to write data to file and its work fine most of the cases. But when the output file size is bigger than 2.1 GB, kernel_write function fails with return value -27.

To write to file I use this function:

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);
}

If the size of "/tmp/output" < 2.1 GB, this function works just fine.

If the size of "/tmp/output"> 2.1 GB, kernel_write starts to return -27.

How can I fix this?

Thanks

1 Answers

You need to enable Large File Support (LFS) with the O_LARGEFILE flag.

The below code worked for me. Sorry, I made some other changes for debugging, but I commented above the relevant line.

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;
}

To test it, I created a file with fallocate -l 3G /tmp/output, then removed the O_CREAT flag because it was giving the kernel permission errors.


I should add a disclaimer that a lot of folks says that File I/O from the kernel is a bad idea. Even while testing this out on my own, I accidentally crashed my computer twice due to dumb errors.

Maybe do this instead: Read/Write from /proc File

Related