从layout到extent的演变史(二)

从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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值