共計 5010 個字符,預計需要花費 13 分鐘才能閱讀完成。
這篇文章給大家分享的是有關 cephfs kernel client 針對打開文件的操作代碼的內容。丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,一起跟隨丸趣 TV 小編過來看看吧。
針對打開文件的操作主要體現在 struct file_operations 數據結構中。在 cephfs kernel client 中具體實現如下:
const struct file_operations ceph_file_fops = {
.open = ceph_open,
.release = ceph_release,
.llseek = ceph_llseek,
.read_iter = ceph_read_iter,
.write_iter = ceph_write_iter,
.mmap = ceph_mmap,
.fsync = ceph_fsync,
.lock = ceph_lock,
.flock = ceph_flock,
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.unlocked_ioctl = ceph_ioctl,
.compat_ioctl = ceph_ioctl,
.fallocate = ceph_fallocate,
};
ceph_open(struct inode *inode, struct file *file) 該函數在打開文件時被調用
|__調用 prepare_open_request() 函數來創建 ceph_mds_request 請求
|__調用 ceph_mdsc_do_request() 函數將 ceph_mds_request 請求同步的發送給 mds 進程
|__調用 ceph_init_file() 函數創建 ceph_file_info 數據結構且將該數據結構放入到 file- private_data 中
ceph_release(struct inode *inode, struct file *file) 該函數在關閉文件時被調用
|__調用 ceph_put_fmode() 函數減少打開文件的引用次數,若引用次數為 0,則從本地 cache 中刪除該文件
ceph_llseek(struct file *file, loff_t offset, int whence)
|__若 whence 是 SEEK_END|SEEK_DATA|SEEK_HOLE
|__調用 ceph_do_getattr() 函數從 mds 集群中獲取指定 inode 的 attrs 屬性
|__調用 i_size_read() 函數得到當前 inode 的實際大小
|__根據 whence 的值調整 offset 的值
|__調用 vfs_setpos() 函數設置文件的當前位置為 offset
ceph_read_iter(struct kiocb *iocb, struct iov_iter *to) 該函數在讀取文件內容的時候被調用
|__調用 ceph_get_caps() 函數得到 caps
|__對于同步讀數據操作來說
|__若 iocb- ki_flags IOCB_DIRECT
|__調用 ceph_direct_read_write() 函數從 osds 集群中讀取數據
|__若!iocb- ki_flags IOCB_DIRECT
|__調用 ceph_sync_read() 函數從 osds 集群中讀取數據
|__對于非同步讀取數據操作來說
|__調用 generic_file_read_iter() 函數實現異步數據的讀取操作
ceph_write_iter(structd kiocb *iocb, struct iov_iter *from) 執行寫操作時調用該函數執行
|__調用 generic_write_check() 函數在實際寫之前進行必要的檢查
|__調用 ceph_get_caps() 得到寫權限
|__對于同步寫操作
|__對于 iocb- ki_flags IOCB_DIRECT
|__調用 ceph_direct_read_write() 函數向 osds 集群中寫入數據
|__對于! iocb- ki_flags IOCB_DIRECT
|__調用 ceph_sync_write() 函數向 osds 集群中紅寫入數據
|__對于非同步寫操作
|__調用 generic_perform_write() 函數執行寫操作
ceph_mmap(struct file *file, struct vm_area_struct *vma) 將文件內容影射到內存的操作時調用該函數執行
|__設置 vma 的 vm_ops=ceph_vmops
ceph_fsync(struct file *file, loff_t start , loff_t end, int datasync)
|__調用 ceph_sync_write_wait() 函數等待 inode 上所有未完成的 osd 請求執行完畢
|__調用 try_flush_caps() 函數將所有 dirty 的 caps 刷回到 mds
|__調用 unsafe_request_wait() 函數等待 inode 上所有針對 mds 請求執行完畢
ceph_lock(struct file *file, int cmd, struct file_lock *fl) 當用戶態程序執行 fcntl lock 時調用該函數執行
|__調用 ceph_lock_message() 函數創建文件鎖命令請求后,將該請求發送給 mds 集群
ceph_flock(struct file *file, int cmd, struct file_lock *fl)
|__調用 ceph_lock_message() 函數創建文件鎖命令請求后,將該請求發送給 mds 集群
ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|__根據 cmd 的值做不同的處理
|__cmd==CEPH_IOC_GET_LAYOUT
|__ceph_ioctl_get_layout()
|__ceph_do_getattr(CEPH_STAT_CAP_LAYOUT) 從 mds 集群中讀取 file 對應的 inode 的 layout 信息到 ceph_inode_info 的 i_layout 中
|__將 i_layout 信息寫入到 struct ceph_ioctl_layout 數據結構中且通過 copy_to_user() 函數將數據返回給用戶態
|__cmd==CEPH_IOC_SET_LAYOUT
|__ceph_ioctl_set_layout()
|__調用 copy_from_user() 函數將新的 layout 信息從用戶態復制到內核態
|__調用 ceph_do_getattr() 函數從 mds 集群中讀取當前的 layout 信息
|__調用__validate_layout() 函數檢查新設置的 layout 是否有效
|__調用 ceph_mdsc_create_request() 函數創建 request 請求
|__調用 ceph_mdsc_do_request() 函數同步的發送 request 請求到 mds 集群
|__cmd==CEPH_IOC_SET_LAYOUT_POLICY
|__ceph_ioctl_set_layout_policy()
|__調用 copy_from_user() 函數將新的 layout 信息從用戶態復制到內核態
|__調用__validate_layout() 函數檢查新設置的 layout 是否有效
|__調用 ceph_mdsc_create_request() 函數創建 request 請求
|__調用 ceph_mdsc_do_request() 函數同步的發送 request 請求到 mds 集群
|__cmd==CEPH_IOC_GET_DATALOC 計算 data 所在的 ceph 集群中的位置信息
|__ceph_ioctl_get_dataloc()
|__調用 copy_from_user() 函數將 ceph_ioctl_dataloc 信息復制到內核態
|__調用 ceph_calc_file_object_mapping() 函數計算 ceph_ioctl_dataloc 信息中指定文件所在的 oid 等信息
|__調用 ceph_object_locator_to_pg() 函數計算出 oid 所在的 pg 信息
|__調用 ceph_pg_to_acting_primary() 函數計算出 pg 所在的主 osd 信息
|__調用 copy_to_user() 函數將計算出來的信息發送回給用戶態
|__cmd==CEPH_IOC_LAZYIO 設置 LAZYIO 標識
|__ceph_ioctl_lazyio()
|__ 判斷 struct ceph_file_info 中的 fmode 是否未設置 CEPH_FILE_MODE_LAZY
|__設置 struct ceph_file_info 中的 fmode 擁有 CEPH_FILE_MODE_LAZY 標識
|__更新 ceph_inode_info 中的 i_nr_by_mode 數組
|__調用 ceph_check_caps() 函數更新 caps
|__cmd==CEPH_IOC_SYNCIO
|__ceph_ioctl_syncio()
|__設置 struct ceph_file_info 結構中的 flags 的 CEPH_F_SYNC 位
ceph_fallocate(struct file *file, int mode, loff_t offset, loff_t length)
|__若 mode==FALLOC_FL_PUNCH_HOLE
|__調用 ceph_zero_object() 函數在文件的指定 offset 開始到 offset+length 結束的地方設置文件內容為 0
|__若 offset+length size
|__調用 ceph_inode_set_size() 將文件的大小設置為 offset+length
|__調用 ceph_check_caps() 函數校驗文件 caps 的認證是否有效
針對文件映射到內存的相關操作主要體現在 struct vm_operations_struct 數據結構中,具體內容如下:
static const struct vm_operations_struct ceph_vmops = {
.fault = ceph_filemap_fault,
.page_mkwrite = ceph_page_mkwrite,
};
ceph_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 該函數在讀取內存中的數據時發生內存缺頁的時候被調用
|__調用 find_or_create_page() 函數從物理內存中獲取到物理內存頁
|__調用__ceph_do_getattr(CEPH_STAT_CAP_INLINE_DATA) 函數從 mds 集群中讀取到數據
|__調用 flush_dcache_page() 函數將讀取到的數據寫入到物理內存頁
|__調用 SetPageUptodate() 函數設置該物理內存頁已經被更新
|__設置 vmf- page=page,即:將物理內存頁添加到虛擬內存中
ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) 當頁面從 readonly 狀態變遷到 writeable 狀態時該函數被調用
|__調用 ceph_update_writeable_page() 函數來設置 vmf- page 頁為 writeable
|__調用 set_page_diry() 函數設置該物理內存頁為 dirty 的
感謝各位的閱讀!關于“cephfs kernel client 針對打開文件的操作代碼”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!