nfs-ganesha的mdcache源碼分析----mdcache_readdir流程

2 mdcache_readdir

       在2.5.0之後的版本中,加入了readdir chunk,可以不完全將目錄存入cache中,默認每個chunk存128個條目(可以通過Dir_Chunk設置),整個系統chunk的水線爲10000(可以通過Chunks_HWMark設置)。chunk也有自己的lru列表,如果超過chunk的數目,就會被踢掉。

    if (test_mde_flags(directory, MDCACHE_BYPASS_DIRCACHE)) {
        /* Not caching dirents; pass through directly to FSAL */
        return mdcache_readdir_uncached(directory, whence, dir_state,
                        cb, attrmask, eod_met);
    }
    if (mdcache_param.dir.avl_chunk > 0) {
        /* Dirent chunking is enabled. */
        LogDebugAlt(COMPONENT_NFS_READDIR, COMPONENT_CACHE_INODE,
                "Calling mdcache_readdir_chunked whence=%"PRIx64,
                whence ? *whence : (uint64_t) 0);
        return mdcache_readdir_chunked(directory,
                           whence ? *whence : (uint64_t) 0,
                           dir_state, cb, attrmask,
                           eod_met);
    }

    MDCACHE_BYPASS_DIRCACHE標記目前只有在沒有開啓chunk的情況下,如果目錄過大,會打上此標記,不會被緩存,開啓了chunk,此標記永遠失效。除了這兩行之外,後面的操作是在沒有開啓chunk的情況下的流程,暫時不做分析。所以mdcache_readdir其實是執行了mdcache_readdir_chunked函數。

mdcache_readdir_chunked的流程如下:



還是和lookup一樣,我們先看沒有找到的流程。

2.1 mdcache_populate_dir_chunk

流程如下:



做了3件事情:
1、mdcache_get_chunk。
2、調用本地的readdir操作。
3、本地的readdir調用回調函數mdc_readdir_chunk_object。

2.1.1 mdcache_get_chunk
這個函數是獲取一個可用的chunk,如果全局的chunk數達到了閾值,就從lru中淘汰出一個。

2.1.2 調用本地的readdir操作
本地讀取數據

2.1.3 本地每讀取一個數據,調用一次mdc_readdir_chunk_object回調函數,我們照常看看mdc_readdir_chunk_object的流程


其實可以發現,很多事情和lookup類似的。與lookup不同的是,lookup如果沒有找到,會將chunk置無效(compute_readdir_cookie沒有實現的情況下,如果實現了,會加入chunk中),而在這裏,chunk的結構體中,存在一個dirents參數,這裏保存這個chunk的所有文件的鏈表。

2.2 mdcache_avl_lookup_ck
現在我們回頭看看直接在cache中找的函數,其實就是遍歷ck的過程。在mdcache_entry_t結構體中,存在一個first_ck的字段,作爲一個目錄ck的初始值,每個chunk中存這next_ck的字段,就可以進行ck的遍歷操作。

2.3 chunk->dirents的loop操作
針對每個ck查找到的chunk,對chunk->dirents 的loop操作,對每個cache條目,調用上層的回調函數,已完成readdir的操作。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章