pnfs中的layout callback 实现分析

pnfs的call back代码梳理
call back  是服务器用来向客户端召回授权布局的一种机制。
从一个使用例子来研究layout的callback;
void exfs_dm_layout_recall(struct inode *inode, u64 off, u64 length, u32 iomode)
{
    struct nfsd4_pnfs_cb_layout cbl;
    int err;

    cbl.cbl_recall_type = RETURN_FILE;
    cbl.cbl_layoutchanged = 0;
    cbl.cbl_seg.clientid = 0;
    cbl.cbl_seg.layout_type = EXFS_SB(inode->i_sb)->pnfs_layout_type;
    cbl.cbl_seg.iomode = IOMODE_ANY;
    cbl.cbl_seg.offset = off;
    cbl.cbl_seg.length = length;

    err = EXFS_SB(inode->i_sb)->s_pnfs_ctl.cb_op->cb_layout_recall
        (inode->i_sb, inode, &cbl);

    if (err && err != -ENOENT)
        klog(inode->i_sb, ERROR, "%s call back layout failed, err = %d,"
                "ino = %lu!\n",
                __func__, err, inode->i_ino);
}

加粗的钩子函数在这里
static struct pnfsd_cb_operations pnfsd_cb_op = {
    .cb_layout_recall = nfsd_layout_recall_cb,
    .cb_device_notify = nfsd_device_notify_cb,

    .cb_get_state = nfs4_pnfs_cb_get_state,
    .cb_change_state = nfs4_pnfs_cb_change_state,
};
int nfsd_layout_recall_cb(struct super_block *sb, struct inode *inode,
              struct nfsd4_pnfs_cb_layout *cbl)
{
    int status;
    struct nfs4_file *lrfile = NULL;
    struct list_head todolist;
    unsigned todo_len = 0;

    nfs4_lock_state();
    status = -ENOENT;
    if (inode) {
        lrfile = find_file(inode);
    }

    INIT_LIST_HEAD(&todolist);

    /* If no cookie provided by FS, return a default one */
    if (!cbl->cbl_cookie)
        cbl->cbl_cookie = PNFS_LAST_LAYOUT_NO_RECALLS;

    status = create_layout_recall_list(&todolist, &todo_len, cbl, lrfile);
    int status2 = spawn_layout_recall(sb, &todolist, todo_len);
}

其中,find_file(),有个疑问:如果多个客户端打开一个文件,则会出现一个inode对应多个file,此时选择哪个file结构呢?
查数据结构得知,每个inode最多只有一个nfs4_file结构,此结构中,有state_id 和delegation_id的链表,当多个线程打开同一个文件时候,就链接到这个链表中。
在nfsd4_open2中,会用到此结构,进行一些检查。
struct nfs4_file *
find_file(struct inode *ino)
{
    unsigned int hashval = file_hashval(ino);
    struct nfs4_file *fp;

    spin_lock(&recall_lock);
    list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
        if (fp->fi_inode == ino) {
            get_nfs4_file(fp);
            spin_unlock(&recall_lock);
            return fp;
        }
    }
    spin_unlock(&recall_lock);
    return NULL;
}


create_layout_recall_list函数找到拥有此文件layout的所有client ,方法是对比state_id;这涉及到一些数据结构,可以参照张师兄给的数据结构图。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值