linux内核编程-内核态文件操作
一、文件打開函數
struct file *filp_open(const char *filename, int flags, umode_t mode)
定義在:fs/open.c
頭文件:<linux/fs.h>
詳解:
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,頭文件<linux/fs.h>
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中,頭文件<linux/fs.h>
在4.14及之后的版本中定義為ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos),定義在fs/read_write.c中,頭文件<linux/fs.h>
接下來再說寫函數,__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中,頭文件<linux/fs.h>。kernel_write函數在4.14版本開始定義和__kernel_write參數一樣,且導出了此符合。
三、文件關閉
int filp_close(struct file *file, fl_owner_t id)。定義在fs/open.c,頭文件<linux/fs>
用法:一般為 filp_close(file,NULL);
總結
以上是生活随笔為你收集整理的linux内核编程-内核态文件操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 判断一个数是偶数还是奇数
- 下一篇: python可以测试java的代码吗_使