溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

cephfs linux kernel client針對linux page cache的操作代碼

發布時間:2021-12-17 09:59:31 來源:億速云 閱讀:324 作者:小新 欄目:云計算

這篇文章主要介紹cephfs linux kernel client針對linux page cache的操作代碼,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

針對linux page cache的操作主要體現在struct address_space_operations數據結構中,cephfs處理linux page cache的函數集合如下:

const struct address_space_operations ceph_aops = {

        .readpage = ceph_readpage,

        .readpages = ceph_readpages,

        .writepage = ceph_writepage,

        .writepages = ceph_writepages_start,

        .write_begin = ceph_write_begin,

        .write_end = ceph_write_end,

        .set_page_dirty = ceph_set_page_dirty,

        .invalidatepage = ceph_invalidatepage,

        .releasepage = ceph_releasepage,

        .direct_IO = ceph_direct_io,

};

ceph_readpage(struct file *filp, struct page *page)

|__調用readpage_nounlock(filep, page)     在加鎖的情況下讀取一個物理內存頁的數據

    |__確定page的offset沒有超出inode的總長度

    |__調用ceph_readpage_from_fscache()函數嘗試從fscache中讀取一個物理內存頁的數據

        |__若讀取成功則直接返回

    |__調用ceph_osdc_readpages()函數從ceph集群中讀取一個物理內存頁的數據

        |__調用ceph_osdc_new_reqeust()函數創建一個讀請求

        |__調用osd_req_op_extent_osd_data_pages()函數為讀請求的返回內容分配內存空間

        |__調用ceph_osdc_start_request()函數將讀請求同步發送給ceph集群

    |__調用flush_dcache_page()函數刷page到dcache中

    |__調用SetPageUptodate()函數設置物理內存頁的狀態是update的

    |__調用ceph_readpage_to_fscache()函數將新讀到的物理內存頁更新到fscache中

|__調用unlock_page(page)

    |__調用clear_bit_unlock()函數為page解鎖

    |__調用wake_up_page()函數喚醒等待該page的相關進程

ceph_readpages(struct file *file, struct address_space *mapping, struct list_head *page_list, unsigned nr_pages)    讀取多個頁

|__調用ceph_readpages_from_fscache()函數嘗試從fscache中讀取多個物理內存頁的數據

    |__若讀取成功則直接返回

|__遍歷page_list

    |__調用start_read()函數讀取數據到page_list所包含的物理內存頁

        |__調用ceph_osdc_new_reqeust()函數創建一個讀請求

        |__調用calc_pages_for(0, len)函數得到讀取指定長度len的數據需要的物理內存頁數

        |__從page_list中摘下指定數量的物理內存頁

        |__調用osd_req_op_extent_osd_data_pages()函數將從page_list中摘下的物理內存頁作為讀請求的接收緩沖

        |__設置讀請求完成后的回調函數為finish_read()

        |__調用ceph_osdc_start_request()函數將讀請求同步發送給ceph集群

finish_read(struct ceph_osd_request *req)        從ceph集群中讀操作結束后的回調函數

|__遍歷讀取到的所有物理內存頁

    |__調用flush_dcache_page()函數將page中的內存刷到dcache中

    |__調用SetPageUptodate()函數設置page的狀態是uptodate的

    |__調用ceph_readpage_to_fscache()函數將讀取到的page內存同步到fscache中

ceph_writepage(struct page *page, struct writeback_control *wbc)

|__調用writepage_nounlock(page,wbc)函數同步page信息到ceph集群

    |__調用page_snap_context()函數得到page的snap context信息(page將CephSnapContext信息寫入到page的private中)

    |__調用set_page_writeback(page)函數設置page writeback標識

    |__調用ceph_osdc_writepages()函數將page信息同步寫到ceph集群

        |__調用ceph_osdc_new_reqeust()函數創建一個寫請求

        |__調用osd_req_op_extent_osd_data_pages()函數為寫請求設置寫內容物理內存頁

        |__調用ceph_osdc_start_request()函數將寫請求同步發送給ceph集群

    |__設置page->private=0,即:刪除page的CephSnapContext信息

    |__調用ClearPagePrivate(page)函數清空page的private

    |__調用end_page_writeback()函數

        |__調用wake_up_page(page, PG_writeback)函數喚醒在page上等待writeback完成的進程

ceph_writepages_start(struct address_space *mapping, struct writeback_control *wbc)

|__調用pagevec_init(&pvec, 0)函數初始化struct pagevec實例pvec

|__從wbc的range_start和range_end中得到start和end

|__調用pagevec_lookup_tag(&pvec, mapping, PAGECACHE_TAG_DIRTY…)函數從mapping中radix tree中找到tags==PAGECACHE_TAG_DIRTY的所有pages且將所有pages寫入到pvec中

|__遍歷所有PAGECACHE_TAG_DIRTY的pages

    |__調用page_offset()函數得到page所在的offset值

    |__調用ceph_calc_file_object_mapping()函數得到從offset開始,長度是len的文件所占用的objects個數以及在object中的偏移

    |__將page添加到pages數組中

|__從pages數組中得到offset值,即:offset=page_offset(pages[0])

|__調用ceph_osdc_new_request()函數創建一個寫數據請求

|__設置寫數據請求的回調函數為writepages_finish

|__調用osd_req_op_extent_osd_data_pages()函數添加寫請求額外的數據

|__調用ceph_osdc_start_request()函數將寫請求同步發送到ceph集群

writepages_finish(struct ceph_osd_request *req)

|__清除所有在發送寫請求過程中產生的內存

ceph_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigend flags, staruct page **pagep, void **fsdata)

|__得到pos所在的page位置,即:index=pos >> PAGE_SHIFT

|__調用grab_cache_page_write_begin(mapping, index, flags)函數在pagecache中指定位置index出獲取或創建一個物理內存頁page

    |__調用pagecache_get_page()函數在pagecache中指定位置index出獲取或創建一個物理內存頁page

    |__調用wait_for_stable_page(page)函數等待該page上的writeback函數返回

|__調用ceph_update_writeable_page(file, pos, len, page)函數只允許往clean page里寫入數據或者已經dirty的snap context里寫入數據

    |__調用wait_on_page_writeback(page)函數等待page的writeback完成

    |__調用page_snap_context(page)函數得到該page的snap context

    |__若snap context的seq > oldest->seq

        |__調用ceph_queue_writeback(inode)函數將inode放入到writeback隊列中

    |__調用clear_page_dirty_for_io(page)函數清除page上的dirty標識

    |__調用writepage_nounlock(page, NULL)函數將page數據同步的寫入到ceph集群

    |__調用PageUptodate(page)檢查page是否是uptodate的

        |__是則直接返回

    |__若page已經滿了

        |__直接返回

    |__調用i_size_read(inode)函數得到inode的讀數據的大小

    |__調用readpage_nounlock(file, page)函數從ceph集群中讀取數據到page中

ceph_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page **page, void *fsdata)

|__若copied < len

    |__調用zero_user_segment(page, from+copied, len)函數將page中從from+copied一直到from+copied+len的內存空間置0

|__若pos+copied > i_size_read(inode)

    |__調用ceph_inode_set_size()函數設置inode的size為pos+copied

|__若Page不是uptodate的

    |__調用SetPageUptodate(page)函數設置page是uptodate的

|__調用set_page_dirty(page)函數設置page是dirty的

ceph_set_page_dirty(struct page *page)

|__若PageDirty(page)

    |__直接返回

|__通過mapping的到struct ceph_inode_info結構

|__調用__ceph_have_pending_cap_snap()函數檢查cephfs是否有snaps

    |__從struct ceph_inode_info結構中的i_cap_snaps列表中得到struct ceph_cap_snap結構

    |__從struct ceph_cap_snap結構中得到struct ceph_snap_context結構

|__若cephfs沒有snaps

    |__調用ceph_get_snap_context()函數從struct ceph_inode_info的i_head_spapc中得到struct ceph_snap_context結構

|__將struct ceph_snap_context結構設置到page的private中,即:page->private=snapc

|__調用__set_page_dirty_nobuffers()函數將page在address_spaces中的radix tree中設置成dirty

ceph_invalidatepage(struct page *page, unsigned int offset, unsigned int length)

|__調用ceph_invalidate_fscache_page()函數使得page在fscache中無效

|__若page沒有private

    |__直接返回

|__設置page->private=0清除page的snaps

|__調用ClearPagePriavte(page)

ceph_releasepage(struct page *page, gfp_t g)

|__調用ceph_release_fscache_page()函數在fscache中刪除page

|__返回!PagePrivate(page)

ceph_direct_io(struct kiocb *iocb, struct iov_iter *iter)

|__返回-EINVAL

以上是“cephfs linux kernel client針對linux page cache的操作代碼”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女