一,nfs-ganesha版本2.3.3 ,2.4.5cache分析
https://github.com/zanglinjie/nfs-ganesha點擊打開鏈接
mdcache在2.4.0之後放在了FSAL層,對應的目錄爲src\FSAL\Stackable_FSALs\FSAL_MDCACHE
2.4版本ganesha緩存配置塊
struct config_block mdcache_param_blk = {
.dbus_interface_name = "org.ganesha.nfsd.config.cache_inode",
.blk_desc.name = "CacheInode",
.blk_desc.type = CONFIG_BLOCK,
.blk_desc.u.blk.init = mdcache_param_init,
.blk_desc.u.blk.params = mdcache_params,
.blk_desc.u.blk.commit = noop_conf_commit
};
ganesha框架圖採用模塊化的設計不易實現,但易於維護
二,cache_inode_lookup 與mdcache_lookup
2.1cache_inode_lookup
2.2mdcahce_lookup
函數定義:
fsal_status_t mdc_lookup(mdcache_entry_t *mdc_parent, const char *name,
bool uncached, mdcache_entry_t **new_entry,
struct attrlist *attrs_out)
typedef struct mdcache_fsal_obj_handle mdcache_entry_t;
struct mdcache_fsal_obj_handle {
/** Reader-writer lock for attributes */
pthread_rwlock_t attr_lock;
/** MDCache FSAL Handle */
struct fsal_obj_handle obj_handle;
/** Sub-FSAL handle */
struct fsal_obj_handle *sub_handle;
/** Cached attributes */
struct attrlist attrs;
/** FH hash linkage */
struct {
struct avltree_node node_k; /*< AVL node in tree */
mdcache_key_t key; /*< Key of this entry */
bool inavl;
} fh_hk;
/** Flags for this entry */
uint32_t mde_flags;
/** Time at which we last refreshed attributes. */
time_t attr_time;
/** Time at which we last refreshed acl. */
time_t acl_time;
/** New style LRU link */
mdcache_lru_t lru;
/** Exports per entry (protected by attr_lock) */
struct glist_head export_list;
/** ID of the first mapped export for fast path
* This is an int32_t because we need it to be -1 to indicate
* no mapped export.
*/
int32_t first_export_id;
/** Lock on type-specific cached content. See locking
discipline for details. */
pthread_rwlock_t content_lock;
/** Filetype specific data, discriminated by the type field.
Note that data for special files is in
attributes.rawdev */
union mdcache_fsobj {
struct state_hdl hdl;
struct {
/** List of chunks in this directory, not ordered */
struct glist_head chunks;
/** List of detached directory entries. */
struct glist_head detached;
/** Spin lock to protect the detached list. */
pthread_spinlock_t spin;
/** Count of detached directory entries. */
int detached_count;
/** @todo FSF
*
* This is somewhat fragile, however, a reorganization
* is possible. If state_lock was to be moved into
* state_file and state_dir, and the state code was
* made clear which it was working with, dhdl could
* be replaced with a state_dir which would be
* smaller than state_file, and then the additional
* members of fsdir would basically overlay
* the larger state_file that hdl is.
*
* Such a reorg could save memory AND make for a
* crisper interface.
*/
struct state_hdl dhdl; /**< Storage for dir state */
/** The parent host-handle of this directory ('..') */
struct gsh_buffdesc parent;
/** The first dirent cookie in this directory.
* 0 if not known.
*/
fsal_cookie_t first_ck;
struct {
/** Children by name hash */
struct avltree t;
/** Table of dirents by FSAL cookie */
struct avltree ck;
/** Table of dirents in sorted order. */
struct avltree sorted;
/** Heuristic. Expect 0. */
uint32_t collisions;
} avl;
} fsdir; /**< DIRECTORY data */
} fsobj;
}
2.2.1 mdc_lookup_uncached函數,瞭解元數據怎麼加入cache中之後,就會理解怎麼查找。
在調用了FSAL文件系統(CEPH)的lookup之後,進行cache的創建操作,這裏主要看mdcache_alloc_and_check_handle流程:
2.2.2新建條目
struct cih_lookup_table {
GSH_CACHE_PAD(0);
cih_partition_t *partition;
uint32_t npart;
uint32_t cache_sz;
};
/* Support inline lookups */
extern struct cih_lookup_table cih_fhcache;