針對打開文件的操做主要體如今struct file_operations數據結構中。在cephfs kernel client中具體實現以下:node
const struct file_operations ceph_file_fops = {數組
.open = ceph_open,數據結構
.release = ceph_release,app
.llseek = ceph_llseek,異步
.read_iter = ceph_read_iter,async
.write_iter = ceph_write_iter,函數
.mmap = ceph_mmap,orm
.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的