linux内核编程-内核态文件操作

一、文件打开函数

struct file *filp_open(const char *filename, int flags, umode_t mode)

定义在:fs/open.c

头文件:

详解:

1.在用户态open函数是个变参函数,umode_t mode参数只有在O_CREAT标志指定时才出现。在内核态如果O_CREAT标志指定mode参数指定权限,否则为0

2.filename参数和flags和用户态一样,指定文件路径和打开标志

3.返回值,如果成功返回struct file 类型变量。失败时要注意,它失败了返回的不是NULL,而是一个错误码。所以对于返回值的判断应该用下面的方式

if(IS_ERR(file))

IS_ERR(file)为真打开失败,为假打开成功。linux内核为什么这么设计,可以参考https://blog.csdn.net/yaozhenguo2006/article/details/7967547

二、读写函数

用户态读写文件只提供了一种方法read、write。而在内核态读写文件可以有好几种,接下来分别看看这几张方法,并对其进行一下比较

方法1:当打开文件成功后,返回了struct file类型变量,此变量中包含了struct file_operations文件操作函数集所以可以如下操作

file->f_op->read(file,buf,size,&pos);

file->f_op->write(file,buf,size,&pos);

方法二:使用vfs_read、vfs_write函数,他是内核对file->f_op->read、write的封装。定义在fs/read_write.c,头文件

ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos);

ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos);

注意:以上两种方法中,函数对buf参数进行了__user限定,内核会对buf地址进行检测。也就是说buf的地址必须是用户空间的地址,如果在内核中使用会返回-EFAULT错误。所以在调用以上两种方法中的函数时可以使用set_fs()、get_fs()来解决。

使用方法:

mm_segmet_t old_fs;

.........

old_fs = get_fs();

set_fs(get_ds());

vfs_read(file,buf,size,&pos);

set_fs(old_fs);

进行了set_fs设置后,内核就不在对内存地址进行检测。关于set_fs()可以参考:https://www.cnblogs.com/soul-stone/p/6367696.html

方法三:先说读函数,可以使用kernel_read函数,这个函数其实就是加入了set_fs()、get_fs()函数。在4.14前

定义为int kernel_read(struct file *file, loff_t offset, char *addr, unsigned long conut),定义在fs/exec.c中,头文件

在4.14及之后的版本中定义为ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos),定义在fs/read_write.c中,头文件

接下来再说写函数,__kernel_write和kernel_write函数,在3.9之前没有这两个函数,3.9版本中定义了__kernel_write函数,但是没有导出符合,模块编程中也调用不了,我们可以仿照此函数编写一个自己的kern_write函数。在3.18版本后__kernel_write函数导出了。其定义:ssize_t __kernle_write(struct file *file, const char *buf, size_t count, loff_t *pos),定义在fs/read_write.c中,头文件。kernel_write函数在4.14版本开始定义和__kernel_write参数一样,且导出了此符合。

三、文件关闭

int filp_close(struct file *file, fl_owner_t id)。定义在fs/open.c,头文件

用法:一般为 filp_close(file,NULL);


你可能感兴趣的:(linux,内核,文件,linux,内核编程,文件读写,文件操作)