开发者

File write from linux kernel driver failed

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>

stati开发者_StackOverflow中文版c int __init hello_start(void)
{
    struct file* my_fd;

    my_fd = filp_open ("/tmp/foobar", O_WRONLY | O_APPEND, 0);
    if (IS_ERR (my_fd))
    {
    printk (KERN_ERR "Failed to open file. err: %d.\n", my_fd);
    }
    else
    {
    my_fd->f_op->write (my_fd, "some data", 10, &my_fd->f_pos);
    }

printk(KERN_INFO "Loading hello module...\n");
return 0;
}

static void __exit hello_end(void)
{
printk(KERN_INFO "hello_end.\n");
}

module_init(hello_start);
module_exit(hello_end);

the above code is giving error -14 while writing in the file. what am I doing wrong here?

Here is the dmesg output:

[19551.674999] Write returned: -14.
[19551.675004] Loading hello module...


The write member of struct file_operations (in include/linux/fs.h) is declared like this:

 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

Note the __user token on the second argument, which tells you it is expecting a user-space pointer. When you call it like you did from the kernel, you are passing a kernel-space pointer; hence your memory fault.

@ShinTakezou's link to the "acct.c" code is what you want to look at; in particular, the calls to set_fs to trick the kernel into using its own data segment as the "user" data segment.


First, do not ignore warnings: your %d is not good for my_fd.

Then, I think in general it is not a good idea to do file I/O from kernel, except in "special" cases.

I've tried with O_CREAT and everything is fine except if the file already exists. Everything else (in particular O_WRONLY | O_APPEND) gave me no chance.

I believe that in order to make file I/O in kernel "as" in user space requires to know more stuffs, and it is likely a bit tricky (or "dangerous").

However try to look at the acct.c code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜