2

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

General Grievance
  • 4,555
  • 31
  • 31
  • 45
VGG
  • 23
  • 4

1 Answers1

1

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

General Grievance
  • 4,555
  • 31
  • 31
  • 45