暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

聊聊ZFS中IO框架之基础篇

482


作者时间QQ技术交流群
perrynzhou@gmail.com2022/11/18672152841





  • ZFS
    中的ZIO的流程中最上层是zfs操作入口,zpl
    是ZFS中的posix层,dmu
    是zfs中数据转换单元,这个设计和内核的虚拟地址类似,arc
    是数据缓存层,zio
    SPA
    模块中执行数据从缓存到具体的磁盘的IO过程,这个也是zfs中比较复杂的部分






  • ZFS
    中定义了多种IO类型,每一种IO操作对应zio
    中的一个或者多个函数。ZIO的类型具体定义在zio_type
    中.


typedef enum zio_type {
ZIO_TYPE_NULL = 0,
ZIO_TYPE_READ,
ZIO_TYPE_WRITE,
ZIO_TYPE_FREE,
ZIO_TYPE_CLAIM,
ZIO_TYPE_IOCTL,
ZIO_TYPE_TRIM,
ZIO_TYPES
} zio_type_t




  • ZFS
    中定义每种IO类型的实际doing
    时候的状态,实际的IO过程中最终是调用zio_execute(__zio_execute)
    开启IO的pipeline


enum zio_stage {
ZIO_STAGE_OPEN = 1 << 0, /* RWFCI */

ZIO_STAGE_READ_BP_INIT = 1 << 1, /* R---- */
ZIO_STAGE_WRITE_BP_INIT = 1 << 2, /* -W--- */
ZIO_STAGE_FREE_BP_INIT = 1 << 3, /* --F-- */
ZIO_STAGE_ISSUE_ASYNC = 1 << 4, /* RWF-- */
ZIO_STAGE_WRITE_COMPRESS = 1 << 5, /* -W--- */

ZIO_STAGE_ENCRYPT = 1 << 6, /* -W--- */
ZIO_STAGE_CHECKSUM_GENERATE = 1 << 7, /* -W--- */

ZIO_STAGE_NOP_WRITE = 1 << 8, /* -W--- */

ZIO_STAGE_DDT_READ_START = 1 << 9, /* R---- */
ZIO_STAGE_DDT_READ_DONE = 1 << 10, /* R---- */
ZIO_STAGE_DDT_WRITE = 1 << 11, /* -W--- */
ZIO_STAGE_DDT_FREE = 1 << 12, /* --F-- */

ZIO_STAGE_GANG_ASSEMBLE = 1 << 13, /* RWFC- */
ZIO_STAGE_GANG_ISSUE = 1 << 14, /* RWFC- */

ZIO_STAGE_DVA_THROTTLE = 1 << 15, /* -W--- */
ZIO_STAGE_DVA_ALLOCATE = 1 << 16, /* -W--- */
ZIO_STAGE_DVA_FREE = 1 << 17, /* --F-- */
ZIO_STAGE_DVA_CLAIM = 1 << 18, /* ---C- */

ZIO_STAGE_READY = 1 << 19, /* RWFCI */

ZIO_STAGE_VDEV_IO_START = 1 << 20, /* RW--I */
ZIO_STAGE_VDEV_IO_DONE = 1 << 21, /* RW--I */
ZIO_STAGE_VDEV_IO_ASSESS = 1 << 22, /* RW--I */

ZIO_STAGE_CHECKSUM_VERIFY = 1 << 23, /* R---- */

ZIO_STAGE_DONE = 1 << 24 /* RWFCI */
};

  • 每中IO类型的对应ZIO_TASKQ_ISSUE
    ZIO_TASKQ_ISSUE_HIGH
    ZIO_TASKQ_INTERRUPT
    ZIO_TASKQ_INTERRUPT_HIGH
    这4个队列,这些队列承载可执行zio
    的数据,具体定义在


// 每种IO的队列
typedef enum zio_taskq_type {
ZIO_TASKQ_ISSUE = 0,
ZIO_TASKQ_ISSUE_HIGH,
ZIO_TASKQ_INTERRUPT,
ZIO_TASKQ_INTERRUPT_HIGH,
ZIO_TASKQ_TYPES
} zio_taskq_type_t;

// 队列的初始化
spa_create_zio_taskqs(spa_t *spa)
{
for (int t = 0; t < ZIO_TYPES; t++) {
for (int q = 0; q < ZIO_TASKQ_TYPES; q++) {
spa_taskqs_init(spa, t, q);
}
}
}
  • ZFS
    中的IO Pipeline,每种类型的IO按照自己的流程执行Pipeline的函数.读请求和写请求的执行的Pipeline完全不同。


static zio_pipe_stage_t *zio_pipeline[] = {
NULL,
zio_read_bp_init,
zio_write_bp_init,
zio_free_bp_init,
zio_issue_async,
zio_write_compress,
zio_encrypt,
zio_checksum_generate,
zio_nop_write,
zio_ddt_read_start,
zio_ddt_read_done,
zio_ddt_write,
zio_ddt_free,
zio_gang_assemble,
zio_gang_issue,
zio_dva_throttle,
zio_dva_allocate,
zio_dva_free,
zio_dva_claim,
zio_ready,
zio_vdev_io_start,
zio_vdev_io_done,
zio_vdev_io_assess,
zio_checksum_verify,
zio_done
};


文章转载自存储内核技术交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论