当前位置: 首页 > 工具软件 > fatcache > 使用案例 >

fatcache源码阅读记录

卢阳成
2023-12-01

fatcache源码分析:

http://godorz.info/2013/03/fatcache/


想了解其内存,磁盘空间分配和使用

每个slab对应一个结构体slabinfo(slabinfo是永在内存中的)

Fc_slab.c 中slab_init开始初始化,初始化内存和磁盘两部分的空间,fd指向磁盘路径

路径在运行时配置

-D, --ssd-device=S          : set the path to the ssd device file (default: n/a)

内存部分空间大小为:

nmslab = MAX(nctable, settings.max_slab_memory / settings.slab_size);

mspace = nmslab * settings.slab_size;

mstart = fc_mmap(mspace); //映射内存空间

磁盘部分

 status = fc_device_size(settings.ssd_device, &size);


再看fc_device_size函数:

 int status;            /* return status */
    struct stat statinfo;  /* stat info */
    int fd;                /* file descriptor */

    status = stat(path, &statinfo); //通过文件名path获取文件信息,并保存在所指的结构体中
    if (status < 0) {
        log_error("stat '%s' failed: %s", path, strerror(errno));
        return FC_ERROR;
    }

status = ioctl(fd, BLKGETSIZE64, size);//   ioctl是设备驱动程序中对设备的I/O通道进行管理的函数

fc_device_size函数完成初始化时的一些处理,获得size为文件字节数,

 ndchunk = size / settings.slab_size;
    ASSERT(settings.server_n <= ndchunk);
    ndslab = ndchunk / settings.server_n;
    dspace = ndslab * settings.slab_size;
    dstart = (settings.server_id * ndslab) * settings.slab_size;
    dend = ((settings.server_id + 1) * ndslab) * settings.slab_size;

其中server_n server_id来源于设置:可能为多个实例

-s, --server-id=I/N         : set fatcache instance to be I out of total N instances (default: 0/1)

之后初始化其他几个数据结构,完成初始化


读取时,读取函数:slab_read_item

    sinfo = &stable[sid];
    c = &ctable[sinfo->cid];
    size = settings.slab_size;
    it = NULL;

    if (sinfo->mem) {
        off = (off_t)sinfo->addr * settings.slab_size + addr;
        fc_memcpy(readbuf, mstart + off, c->size);
        it = (struct item *)readbuf;
        goto done;
    }

    off = slab_to_daddr(sinfo) + addr;
    aligned_off = ROUND_DOWN(off, 512);
    aligned_size = ROUND_UP((c->size + (off - aligned_off)), 512);

    n = pread(fd, readbuf, aligned_size, aligned_off);
    if (n < aligned_size) {
        log_error("pread fd %d %zu bytes at offset %"PRIu64" failed: %s", fd,
                  aligned_size, (uint64_t)aligned_off, strerror(errno));
        return NULL;
    }
    it = (struct item *)(readbuf + (off - aligned_off));
获取到具体slab后,若是在内存中,则直接获取到it中,若是在磁盘中,先调用slab_to_daddr函数:

off = dstart + ((off_t)sinfo->addr * settings.slab_size);

其中,dstart根据所在的实例有所不同:
dstart = (settings.server_id * ndslab) * settings.slab_size;


获取到it之后将其返回





 类似资料: