【ceph】cephfs内核客户端到MDS的Lookup流程分析--未消化

本文详细介绍了CephFS中,内核客户端在未缓存情况下,通过Lookup命令获取文件inode信息的过程。从客户端创建请求、发送到MDS服务端,再到服务端处理和回复,深入剖析了lookup操作的内部机制,包括mds端的处理逻辑和元数据预读策略。
摘要由CSDN通过智能技术生成

在文件系统中读写文件时,一般需要先得到操作对象的索引inode信息,在客户端未缓存的情况下,除了调用open外,客户端也会下发lookup或者getattr命令到服务端去获取操作对象的inode。Lookup和getattr IO的mds端流程几乎一致,所以以lookup流程为例进行介绍。

客户端以linux 4.18内核源码(cephfs的内核客户端在linux内核中实现)进行分析,服务端使用单活冷备的3节点集群。

1. 内核客户端处理发送

假设lookup的路径是/mnt/cephfs/testdir/1  (/mnt/cephfs是内核挂载根目录)
 

函数入口:

static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,     unsigned int flags)
    {
    ...
    入参分析:dir包含了父目录的inode索引号; dentry里面包含了d_name表示文件名’1’,可以获得    len;flag变量cephfs没有用到
    ...

    /* 判断lookup的是否是快照来决定opcode,这里为opcode当然为CEPH_MDS_OP_LOOKUP*/
    op = ceph_snap(dir) == CEPH_SNAPDIR ?CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; 

    /* 新建一个req请求。*/    
    req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
    if (IS_ERR(req))
        return ERR_CAST(req);
    /* 赋予dentry到请求r_dentry */
    req->r_dentry = dget(dentry);
    req->r_num_caps = 2;

    /* 需要去mds端获取的inode cap和auth shard cap */    
    mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED; 
    ...
    /* 赋父目录的inode号给请求的r_parent */
    req->r_parent = dir; 
    ...
    /* 发送请求处理,等待请求完成 */
    err = ceph_mdsc_do_request(mdsc, NULL, req); 
    ...
    /* 获取dentry (这时dentry已经拼接好了对应inode了)*/
    dentry = ceph_finish_lookup(req, dentry, err); 

    /* 减请求计数,释放请求 */
    ceph_mdsc_put_request(req);  /* will dput(dentry) */ 
    dout("lookup result=%p\n", dentry);
    return dentry;
    } 

大体流程为创建输入父目录testdir的inode和文件1的名字,创建请求发送到mds处理,等待mds处理完成后回请求返回文件1的inode和dentry结构,返回带有inode链接的dentry给vfs。

ceph_mdsc_do_request处理了较为复杂的逻辑,涉及到消息发送的框架,下面重点分析下入参相关的转换。
调用关系如下:
|__ ceph_mdsc_do_request
|__ __do_request
|__ ____prepare_send_request
|__ ______create_request_message

由于mds端处理的函数是直接使用了filepath结构体承接客户端传来的参数,所以在创建请求消息create_request_message这里客户端转换之前填充req的入参为filepath结构体。

Mds端的filepath结构体:

    Class filepath {
        inodeno_t ino;
        string path;
    } 

create_request_message函数里使用了set_request_path_attr,如下图所示,由于本次是使用了lookup,所以只用了第一次的set_request_path_attr,rename的情况才需要记录old的dentry和新的dentry所在。

set_request_path_attr中由于lookup只填了目标的dentry,所以走图中标记的红框流程,build_dentry_path主要是将之前填入req中的父目录testdir的inode和文件1的dentry的名字和长度转填到filepath结构体中。

 

2. MDS服务端

服务端通过消息通信框架机制Messager来处理请求,由于消息的收发都是异步的,所以需要单独的模块来处理,这块本文就简单略说,调用堆栈如下:
|___ Server::handle_client_request
|__ __Server::dispatch
|__ ____MDSRank::handle_deferrable_message
|__ ______MDSRank::_dispatch
|__ ________MDSRank::retry_dispatch
|__ ____

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值