参数指定
mount时候可以提供参数ac
或者noac
设置attribute cache参数。具体含义参考
mount -o noac #没有attribute cache
mount -o actimeo=60 #设置attribute cache为60s
Linux Kernel分析
为了避免频繁发送get attribe,Linux kernel在timeout之前,使用上次得到的结果。
int nfs_attribute_timeout(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}
当然在timeout之间,但cache数据需要更新时,也需要再次发送NFS请求
static bool nfs_need_revalidate_inode(struct inode *inode)
{
if (NFS_I(inode)->cache_validity &
(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
return true;
if (nfs_attribute_cache_expired(inode))
return true;
return false;
}
需要更新的几种情况
static void nfs_drop_nlink(struct inode *inode)
{
spin_lock(&inode->i_lock);
/* drop the inode if we're reasonably sure this is the last link */
if (inode->i_nlink == 1)
clear_nlink(inode);
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
spin_unlock(&inode->i_lock);
}
nfs-ganesha中类似Kernel的机制
在获取atttribte时候,会先先经过DCache层,如果mdcache_is_attrs_valid
返回true,直接从cache层拿以前的数据。可以通过修改参数Attr_Expiration_Time
为0,其默认值为60
static inline bool
mdcache_is_attrs_valid(mdcache_entry_t *entry, attrmask_t mask)
{
...
if ((mask & ATTR_ACL) != 0 && entry->attrs.expire_time_attr > 0) {
time_t current_time = time(NULL);
if (current_time - entry->acl_time >
entry->attrs.expire_time_attr)
return false;
}
return true;
}