Linux VFS中write系統呼叫實現原理
目錄
WORD裡面的目錄複製過來似乎不能直接用。。還是放在這裡當主線看吧..
使用者空間的write函式在核心裡面的服務例程為sys_write[email protected] ~]# grep write /usr/include/asm/unistd_64.h
#define __NR_write1
__SYSCALL(__NR_write, sys_write)
#define __NR_pwrite6418
__SYSCALL(__NR_pwrite64, sys_pwrite64)
#define __NR_writev20
__SYSCALL(__NR_writev, sys_writev)
#define __NR_pwritev296
__SYSCALL(__NR_pwritev, sys_pwritev)
#define __NR_process_vm_writev311
__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)
這裡根據經驗判斷,通常write呼叫應該是sys_write,這裡我們討論sys_write函式的核心實現
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,size_t, count)
{
{//這裡SYSCALL_DEFINE3 write
//這裡unsigned int fd表示使用者空間的檔案描述符
//char __user *buf是存放從檔案讀取內容的一個使用者空間記憶體區
struct file *file;
ssize_t ret = -EBADF;
int fput_needed;
file = fget_light(fd, &fput_needed);
if (file) {
loff_t pos = file_pos_read(file);
ret = vfs_write(file, buf, count, &pos);
file_pos_write(file, pos);
fput_light(file, fput_needed);
}
return ret;
}
可以看到,和sys_read系統呼叫不同的地方就是這裡呼叫了vfs_write函式來完成寫操作,所以這裡我們只看vfs_write都做了什麼,其餘部分請參看
Vfs_write函式實現原理ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
即把使用者空間的char __user* buf指向的記憶體地址裡面的內容寫入相應的裝置檔案
基本同vfs_read,不過這裡變成了
如果檔案系統沒有實現file_operation或者既沒有實現file_operation->write,也沒有實現file_operation->aio_write,則報錯。(即檔案系統即沒有實現同步寫,也沒有實現非同步寫,那就報錯返回錯誤了)
如果檔案系統實現了file->file_operation->write(還記得我嗎在open系統呼叫中講到的嗎,在open系統呼叫中file->file_operation設定為了inode->file_operation)函式,則呼叫它來完成。
否則(說明檔案系統沒有實現write,但是實現了file_operation->aio_write)呼叫核心的預設函式do_sync_write(file, buf, count, pos);來做同步讀寫操作;而核心的do_sync_write函式內部實現是
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos){
struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
for (;;) {
ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
if (ret != -EIOCBRETRY)
break;
wait_on_retry_sync_kiocb(&kiocb);
}
}
這裡和do_sync_read不同在於基本也就aio_read換成了aio_write了,do_sync_write最後呼叫的是file_operation->aio_write方法,但是iov陣列長度為1,並且寫入過程中如果寫入操作沒有完成則顯式呼叫程序排程函式,本程序可能被掛起來且程序狀態為TASK_UNINTERRUPTIBLE。直到最終寫入完成,讀取成功後進程狀態會變為TASK_RUNNING,且存放在使用者空間的buf記憶體區的內容已經寫入硬體上為止
參考:kernel 3.6.7
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script> 閱讀(188) | 評論(0) | 轉發(0) | 給主人留下些什麼吧!~~ 評論熱議相關推薦
Linux VFS中write系統呼叫實現原理
目錄 WORD裡面的目錄複製過來似乎不能直接用。。還是放在這裡當主線看吧.. 使用者空間的write函式在核心裡面的服務例程為sys_write [email protected]
Linux fsync和fdatasync系統呼叫實現分析(Ext4檔案系統)
參考:https://blog.csdn.net/luckyapple1028/article/details/61413724 在Linux系統中,對檔案系統上檔案的讀寫一般是通過頁快取(page cache)進行的(DirectIO除外),這樣設計的可以延時磁碟IO的操作,從而可以減少磁碟讀
Linux VFS 之mount系統呼叫
1. 我們知道,在對檔案的開啟,讀和寫操作之前,必須掛載檔案系統。那麼,核心如何掛載檔案系統,換句話說,在掛載檔案系統時核心都做了哪些事情。這是本文討論的事情。在掛載檔案系統之前,必須格式化檔案系統型別,通過mkfs命令實現。在Linux中,一個檔案系統型別包括多個檔案系統,如/dev/sda, /
linux中的read和write系統呼叫
linux中read和write系統呼叫 在這裡小koala著重於read()和write()來讀寫普通檔案,因為小koala在編寫實際檔案讀寫函式時,疏忽了一些重要的地方,造成無休止的向系統中寫資料,最後系統崩潰。當時瞬間“三觀”盡毀。現在較為詳細地分析錯誤
再探Linux核心write系統呼叫操作的原子性
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
amlogic平臺android 系統linux核心中新增i2c裝置實現i2c的讀寫
上一篇,我介紹瞭如何在uboot中新增i2c裝置,以及移植i2c的讀寫介面。簡單來說uboot階段使用i2c裝置和平臺關聯性比較大,但不同平臺套路是差不多的。你可以將uboot階段看作是引導androi
Linux下系統呼叫實現檔案操作
系統呼叫(系統呼叫是作業系統提供給使用者程式的一組“特殊”函式介面,使用者通過這組介面獲得作業系統提供的服務)中操作I/O的函式,都是針對檔案描述符的。 通過檔案描述符可以直接對相應檔案進行操作,如:open、close、write、read、ioctl #define STDIN_FIL
系統呼叫實現Linux命令 ls -al
二話不說直接上程式碼(這是我之前在網易部落格上寫的搬過來) ls.c 如下: #include "ls.h" /**********************************************************************/ //將路徑定位到
Linux(Android)系統Root實現原理
root原理 原理概述 1. 系統漏洞方案 主旨思想是查詢系統漏洞,讓本身具有root許可權的程序執行開啟root許可權的操作。 2. 重燒eng boot.img方案 Android版本有user版本和eng版本的區別,其中eng版本可以用於開發除錯,所以本身可以開啟r
Linux 系統呼叫實現機制
1. 提示:unable to copy the source file ./installer/services.sh to the destination file /etc/init.d/vmware-tools 錯誤原因: 我的解壓包的目錄是 /mnt/cd
64位Linux系統呼叫的新增以及系統呼叫的原理
使用者地址空間和核心地址空間 每個程序都會有一個固定大小的虛擬地址空間,大小較固定,視作業系統位數而定(位數同時也決定實體地址的大小)。例如32位作業系統,其實體地址也就是32位,表示的空間也就是2的32次方,即4GB。 大家都知道系統核心事關作業系統的穩定
Linux中listen()系統呼叫的backlog引數分析
這篇文章是對上一篇部落格網路程式設計常用介面的核心實現----sys_listen()的補充,上篇文章中我說listen()系統呼叫的backlog引數既是連線佇列的長度,也指定了半連線佇列的長度(不能說等於),而不是《Unix網路程式設計》中講到的是半連線佇列和連線佇列
linux下增加一個新的系統呼叫實現pstree功能
這是我們linux課程的一個作業。 首先得到init程序的task_struct,根據list_for_each可以迴圈遍歷可以的到其所有的子程序的 list_head,根據list_head使用li
Java網絡編程和NIO詳解7:淺談 Linux 中NIO Selector 的實現原理
fdt 重要 文件描述 block tor create size 註冊 comm Java網絡編程和NIO詳解7:淺談 Linux 中NIO Selector 的實現原理 轉自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首發於
C++多型呼叫實現原理(虛擬函式表詳解)
1.帶有虛擬函式的基類物件模型 我們先看段程式碼: #include<iostream> using namespace std; class B1 { public: void func1() {} int _b; }; class B2 { pub
基於接口回調詳解JUC中Callable和FutureTask實現原理
cnblogs blog 異步編程 但是 迷糊 對象 extend href 增加 Callable接口和FutureTask實現類,是JUC(Java Util Concurrent)包中很重要的兩個技術實現,它們使獲取多線程運行結果成為可能。它們底層的實現,就是基於接口
Linux : select()詳解 和 實現原理【轉】
https://www.cnblogs.com/sky-heaven/p/7205491.html#4119169 轉自:http://blog.csdn.net/huntinux/article/details/39289317 原文:http://blog.csdn.n
套介面層之socket系統呼叫實現
這篇筆記記錄了AF_INET協議族在套介面層對scoket()系統呼叫的實現,注意這裡只介紹了套介面層的實現,相比於完整的socket()系統呼叫實現,這裡缺少兩部分內容: 檔案系統相關的部分,比如檔案描述符的分配等; 傳輸層的實現,套接字的建立肯定是要傳輸層
基於介面回撥詳解JUC中Callable和FutureTask實現原理
Callable介面和FutureTask實現類,是JUC(Java Util Concurrent)包中很重要的兩個技術實現,它們使獲取多執行緒執行結果成為可能。它們底層的實現,就是基於介面回撥技術。介面回撥,許多程式設計師都耳熟能詳,這種技術被廣泛應用於非同步模組的開發中。它的實現原理並不複雜,但是對初學
STL中的sort函式實現原理
STL的sort()演算法,資料量大時採用Quick Sort,分段遞迴排序。一旦分段後的資料量小於某個閾值,為避免Quick Sort的遞迴呼叫帶來過大的額外開銷,就改用Insertion Sort(插入排序)。如果遞迴層次過深,還會改用Heap Sort。 STL中的sort並非只是