从layout到extent的演变史(二)

来源:互联网 发布:喜马拉雅电台 知乎 编辑:程序博客网 时间:2024/06/05 06:36

从layout到extent的演变史(二)

  交流了一下,发现了理解这个过程的好流程。pnfs中读写操作的流程是,client先发送open的RPC,server返回open的结果(应该和fh相关),client再发送getlayout的RPC,client拿到layout后,直接从磁盘上读文件内容。我们做的优化是在发送open RPC时同时将layout也获取过来,这样可以节省一次getlayout的RPC的时间。

pnfs_open_layout

  pnfs中读文件过程,到函数_nfs4_do_open,如果inode->size不为0,文件不空,则调用pnfs_open_layout预取该文件的layout保存在nfs_inode里面中。下面开始讲解pnfs_open_layout的函数。
  根据inode获取到pnfs_layout_type(下文用变量名称lo代替),如果为空,则分配初始化锁上;如果非空,则引用计数加1,直接锁上。先根据inode获取到nfs_inode,nfs_inode中有pnfs_layout_type,每个文件对应一个lo。重点介绍一下分配并初始化lo的过程。

lo的初始化过程

  如果lo为空,会分配并初始化lo。那都初始化lo的什么内容呢?
lo结构体中有void *ld_data指针,这个是指向layout driver的私有数据,那这个私有数据就是指pnfs_block_layout。初始化struct layoutdriver_io_operations *io_ops,调用bl_alloc_layout分配和初始化pnfs_block_layout,这个结构体还是值得一看的。

struct pnfs_block_layout {    struct pnfs_inval_markings bl_inval; /* tracks INVAL->RW transition */    spinlock_t      bl_ext_lock;   /* Protects list manipulation */    struct list_head    bl_extents[EXTENT_LISTS]; /* R and RW extents */    struct list_head    bl_commit;  /* Needs layout commit */    unsigned int        bl_count;   /* entries in bl_commit */    sector_t        bl_blocksize;  /* Server blocksize in sectors */};

看到了吧,日思夜想的extent终于出现了,你会不会突然的出现,在街角的咖啡店。出现了,这里仅仅是初始化,初始化bl_extents[0]和bl_extent[1]两个list_head链表,初始化bl_commit链表,这是需要提交layout的链表,设置bl_count是0,设置bl_blocksize,再看它是什么作用。初始化结束后,返回这个pnfs_block_layout。lo->ld_data指向返回的pnfs_block_layout。
  给lo分配lseg。和struct pnfs_layoutdriver_type初始化相关。

/* Per-layout driver specific registration structure */struct pnfs_layoutdriver_type {    const u32 id;    const char *name;    struct layoutdriver_io_operations *ld_io_ops;    struct layoutdriver_policy_operations *ld_policy_ops;};

lo是有了,再分配struct pnfs_layout_segment *lseg。先看sruct layoutdriver_io_operations,真正的从磁盘上读写文件的函数(我的理解)。调用bl_alloc_lseg分配lseg。

static struct layoutdriver_io_operations blocklayout_io_operations = {    .commit             = bl_commit,    .read_pagelist          = bl_read_pagelist,    .write_pagelist         = bl_write_pagelist,    .write_begin            = bl_write_begin,    .write_end          = bl_write_end,    .write_end_cleanup      = bl_write_end_cleanup,    .alloc_layout           = bl_alloc_layout,    .free_layout            = bl_free_layout,    .alloc_lseg         = bl_alloc_lseg,    .free_lseg          = bl_free_lseg,    .setup_layoutcommit     = bl_setup_layoutcommit,    .encode_layoutcommit        = bl_encode_layoutcommit,    .cleanup_layoutcommit       = bl_cleanup_layoutcommit,};

bl_alloc_lseg()

原型:static struct pnfs_layout_segment *bl_alloc_lseg(struct pnfs_layout_type *lo, struct nfs4_pnfs_layoutget_res *lgr)
功能:根据server返回的lgr内容来初始化lseg。
实际上起作用的函数是nfs4_blk_process_layoutget。

0 0