0

I have given the permission to the file and the right path, and yet it fails to write.

Error: Failed to write the file: -22

Kernel version: 2.6.9-89.ELsmp


static int writeMsgToFile(const char *data) {
    struct file *file;
    mm_segment_t old_fs;
    loff_t pos;
    int ret;
    static loff_t file_size = 0; // Global variable to store the file size

    // Open the file for writing
    file = filp_open(SLID_FILE_PATH, O_WRONLY | O_CREAT | O_APPEND , 0666);
    if (IS_ERR(file)) {
        printk(KERN_ERR "Failed to open the file: %ld\n", PTR_ERR(file));
        return PTR_ERR(file);
    }

    old_fs = get_fs();
    set_fs(get_ds());

    ret = file->f_op->write(file, data, strlen(data), &pos);  //Write is failing here
    if (ret < 0) {
      printk(KERN_ERR "Failed to write the file: %d\n", ret);
    } else {
        printk(KERN_INFO "Values written to the file successfully\n");
       }

    set_fs(old_fs);
    file->f_pos = pos;

    filp_close(file, NULL);

    return ret;
}

This code is written in kernel level.

I also have a few more requirement to add to this code

  • need the file to be on 10Kb
  • Once the data is written to the file and it exceeds 10 kb, it should create a new file.old (let's call it file.old) and write all the data from file to file.old
  • After it is written to file.old, we should delete the content in file and make room for the next data to be loaded.

I'm new to programing in kernel level, thank you!

  • 1
    Use `strlen(data)` only if your data is a C-string. If your data is just raw bytes array, then use some `length` variable... – Jean-Baptiste Yunès Jul 31 '23 at 07:02
  • 1
    "it fails to write" is a poor description of the problem. Do you get errors when compile your code? Or do you get errors when run your code? Add **error message** to the question post. Also specify kernel version which you are using (this hint is noted when you cover on "linux-kernel" tag). You might want to read [that question](https://stackoverflow.com/questions/1184274/read-write-files-within-a-linux-kernel-module) about writing a file in the Linux kernel code. – Tsyvarev Jul 31 '23 at 08:08
  • 3
    Aside: `printk(KERN_ERR "Failed to write the file: %ld\n", PTR_ERR(file));` shoud be `printk(KERN_ERR "Failed to write the file: %d\n", ret);` because the error number is in `ret` and `file` does not contain an error number at that point. – Ian Abbott Jul 31 '23 at 09:24
  • Try removing `pos` and replacing `&pos` with `&file->f_pos`. – Ian Abbott Jul 31 '23 at 09:27
  • @Tsyvarev Failed to write the file: -2125921840 kernel version - 2.6.9-89.ELsmp I will add the information to the description – Sharon Deborah Jul 31 '23 at 09:35
  • @IanAbbott Could you please explain a bit more? – Sharon Deborah Jul 31 '23 at 09:43
  • @SharonDeborah: The value `-2125921840` which you get in your error message is useless for debugging, because it contains address of the file (`file`). But the **error code** of the `write` operation is stored in the `ret` variable, so you need to print that variable instead. – Tsyvarev Jul 31 '23 at 09:54
  • 2
    @SharonDeborah What is to explain? The return value from the `file->f_op->write(...)` function call has been assigned to the `ret` variable, not to the `file` variable. `file` contains a pointer to a `struct file` object, `file` does not contain an error number because that was already checked by `if (IS_ERR(file))` earlier. – Ian Abbott Jul 31 '23 at 10:13
  • Note that `IS_ERR(file)` and `PTR_ERR(file)` is nothing to do with files specifically. The Linux kernel code has a mechanism where a certain range of invalid pointer values is reserved to report a small, negative error number. For those interfaces that use the mechanism, `ERR_PTR(err)` converts a negative error number to such an invalid pointer value, `IS_ERR(ptr)` checks whether a pointer value encodes a negative error number, and `PTR_ERR(ptr)` converts those special invalid pointer values to a negative error number. – Ian Abbott Jul 31 '23 at 10:21
  • @Tsyvarev I printed ret and here's the error Error: Failed to write the file: -22 – Sharon Deborah Jul 31 '23 at 10:56
  • So you got `EINVAL` error code. If you have no ideas what parameter to write is invalid, then you could look into the implementation of the `write` callback which you call. That callback is defined in the driver for the filesystem, on which the file is created. You could find the filesystem to path mapping in the output of `mount`. – Tsyvarev Jul 31 '23 at 11:16
  • 3
    Even though the file is opened in append mode, I think the position in your `pos` variable will still get checked for validity, but you have not initialized the `pos` variable so it will contain a junk value. That's why I suggested replacing `&pos` with `&file->f_pos`, but you could also just initialize `pos` to 0 instead. – Ian Abbott Jul 31 '23 at 11:56
  • Look at the implementation of the default assigned `write` method and see when it returns `-22` (-EINVAL) – vmemmap Aug 04 '23 at 07:57

0 Answers0