mkdir创建多级目录_cephfs:用户态客户端mkdir

mkdir就是创建目录,客户端并不直接创建目录,而是将mkdir的请求(op为CEPH_MDS_OP_MKDIR)发给MDS,然后MDS执行mkdir的操作,并返回创建的目录的元数据。客户端无非就是发送请求和处理回复。例子 mkdir /mnt/ceph-fuse/test

发送请求的流程

5bd4f22b6811c1070818f35612cedae1.png

发送请求的内容

两类请求:MetaRequest,MClientRequest。

MetaRequest的大部分内容都是在make_request和send_request中填充,所以各种op填充的内容都差不多,只研究不同的地方。

struct MetaRequest {
private:
  InodeRef _inode, _old_inode, _other_inode;       // _inode为创建目录的父目录的inode指针
                                                   // 这里_inode->ino = 1
  Dentry *_dentry;                                 //associated with path, _dentry->dir是父目录的Dir,_dentry->name = "test"
public:
  ceph_mds_request_head head;                      // head.op = CEPH_MDS_OP_MKDIR  
  filepath path, path2;                            // path.ino = 0x1(父目录的inode号), path.path = "test"
  ......
  int dentry_drop, dentry_unless;                  // dentry_drop = CEPH_CAP_FILE_SHARED = "Fs",在send_request过程中,会释放掉父目录的Inode的caps的"Fs"权限
                                                   // dentry_unless = CEPH_CAP_FILE_EXCL = "Fx"
  vector<MClientRequest::Release> cap_releases;    // cap_releases.push_back(MClientRequest::Release(rel,""))。?
  ......  
  ceph::cref_t<MClientReply> reply;                // the reply
  //possible responses
  bool got_unsafe;                                 // 收到unsafe的回复时,got_unsafe为true
 
  xlist<MetaRequest*>::item item;                  // 插入到session的requests链表中   
  xlist<MetaRequest*>::item unsafe_item;           // 收到unsafe回复后,插入到session的unsafe_requests链表中。
  xlist<MetaRequest*>::item unsafe_dir_item;       // 收到unsafe回复且涉及到父目录操作(在父目录下创建/删除文件/目录),插入到父目录Inode的unsafe_ops链表中
  xlist<MetaRequest*>::item unsafe_target_item;    // 收到unsafe回复且请求需要获取目的inode信息,插入到自己Inode的unsafe_ops链表中
                                                   // 上述4个链表节点,都在收到safe回复后,会将链表节点从各自的链表中删除
  InodeRef target;                                 // target是创建的目录的Inode指针,从mds的回复中组装而成。
}

MClientRequest的内容是在通用函数build_client_request和send_request函数中填充的,所以大部分内容都差不多

class MClientRequest : public Message {
public:
  mutable struct ceph_mds_request_head head;     // head.op = CEPH_MDS_OP_MKDIR
                                                 // head.flags = CEPH_MDS_FLAG_WANT_DENTRY                                                              
  // path arguments
  filepath path, path2;                          // path.ino = 0x1(父目录的inode号), path.path = "test"
  ......
}

从代码可以看出,发送给mds的请求最重要的就是两个:op,不同的op,处理机制不同;filepath path,path.ino是父目录的inode号,path.path就是需要创建的目录名。通过这两个,mds就知道在哪个目录下创建目录。

处理请求的流程

318a163c060002ed23b531f8ba244d8f.png
class MClientReply : public Message {
public:
  // reply data
  struct ceph_mds_reply_head head {};
      /* client reply */
    struct ceph_mds_reply_head {
	    __le32 op;
	    __le32 result;
	    __le32 mdsmap_epoch;
	    __u8 safe;                     /* true if committed to disk; 用来判断是否已经下刷了disk,或者不需要下刷时,safe就为1*/
	    __u8 is_dentry, is_target;     /* true if dentry, target inode records are included with reply; is_dentry = 1, is_target = 1*/
    } 
  bufferlist trace_bl;                // trace_bl里面存着真正的信息,用于更新目的inode
}

最后"test"目录inode的cap.issued == "pAsxLsXsxFsx", cap.implemented == "pAsxLsXsxFsx"

后记

在linux中同一目录下的子目录和文件名是不能相同的,如test/目录下就不能有"test1"的目录和"text1"的文件。这是为啥,在看过lookup之后,就知道答案了,举例说明:比如我们要mkdir /test/test1: 先进行索引,即lookup 0x1/test,获得test的inode,这里假设test的inode号为0x2, 接下来再lookup 0x2/test1, 即获取test目录下"test1"的Dentry,然后从Dentry中获得Inode,假设在mkdir /test/test1之前,已经有了一个test1的文件,那么这时lookup 0x2/test1会获得test1文件的Inode,lookup返回的结果是0,这是mkdir就报错:文件或目录已存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux中,使用mkdir命令可以创建多级目录。你可以使用-p选项来一次性创建多层次的目录,而不是一次只创建单独的目录。例如,如果你想在当前目录创建一个名为Projects的目录,并在其中创建一个名为a的子目录,再在a目录创建一个名为src的子目录,你可以使用以下命令: mkdir -p Projects/a/src \[1\] 另外,如果你想创建多层次、多维度的目录树,你可以使用mkdir命令的-p选项和shell的参数扩展来实现。例如,如果你想在当前目录创建一个名为Project的目录,并在其中创建四个子目录a、b、c、d,每个子目录下都有一个名为src的子目录,你可以使用以下命令: mkdir -p Project/{a,b,c,d}/src \[2\] 如果你希望在每次创建目录后自动切换到该目录,你可以在你的.bashrc文件中添加如下代码: ```shell mkdir -p mkr() { mkdir -p "$1" } mkdir -p && cd mkcd() { mkdir -p "$1" && cd "$1" } ``` 这样,你就可以使用mkr命令来创建多级目录,并使用mkcd命令来创建目录并切换到该目录。\[3\] #### 引用[.reference_title] - *1* *2* [linux 创建多级目录 mkdir -p](https://blog.csdn.net/helllochun/article/details/41543907)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Linux:mkdir 创建多级目录](https://blog.csdn.net/cd_yourheart/article/details/109327640)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值