fatcache分配空間閱讀記錄
阿新 • • 發佈:2018-11-09
slab_get_item(uint8_t cid) { rstatus_t status; struct slabclass *c; struct slabinfo *sinfo; struct slab *slab; ASSERT(cid >= SLABCLASS_MIN_ID && cid < nctable); c = &ctable[cid]; if (itemx_empty()) { status = slab_evict(); if (status != FC_OK) { return NULL; } } if (!TAILQ_EMPTY(&c->partial_msinfoq)) { return _slab_get_item(cid); }//這個class的partial_msinfoq不為空,取一個可用的item位置返回 if (!TAILQ_EMPTY(&free_msinfoq)) {//在free_msinfoq中取一個空的,初始化 /* move memory slab from free to partial q */ sinfo = TAILQ_FIRST(&free_msinfoq);//在free_msinfoq中取一個 ASSERT(nfree_msinfoq > 0); nfree_msinfoq--;//free的少一個 c->nmslab++;//這個class的記憶體中的slab多一個 TAILQ_REMOVE(&free_msinfoq, sinfo, tqe); /* init partial sinfo */ TAILQ_INSERT_HEAD(&c->partial_msinfoq, sinfo, tqe);//放入頭部並初始化 /* sid is already initialized by slab_init */ /* addr is already initialized by slab_init */ sinfo->nalloc = 0; sinfo->nfree = 0; sinfo->cid = cid; /* mem is already initialized by slab_init */ ASSERT(sinfo->mem == 1);//表明時記憶體中的slab /* init slab of partial sinfo */ slab = slab_from_maddr(sinfo->addr, false); slab->magic = SLAB_MAGIC; slab->cid = cid; /* unused[] is left uninitialized */ slab->sid = sinfo->sid; /* data[] is initialized on-demand */ return _slab_get_item(cid); } ASSERT(!TAILQ_EMPTY(&full_msinfoq)); ASSERT(nfull_msinfoq > 0); status = slab_drain(); if (status != FC_OK) { return NULL; } return slab_get_item(cid); }
若磁碟free非空,直接將記憶體的移至磁碟,返回,若為空,先slab_evict(),再把記憶體舊的移至磁碟,返回
slab_drain(void) { rstatus_t status; if (!TAILQ_EMPTY(&free_dsinfoq)) { ASSERT(nfree_dsinfoq > 0); return _slab_drain(); } status = slab_evict(); if (status != FC_OK) { return status; } ASSERT(!TAILQ_EMPTY(&free_dsinfoq)); ASSERT(nfree_dsinfoq > 0); return _slab_drain(); }
將記憶體中老的移至磁碟中free的位置
_slab_drain(void) { struct slabinfo *msinfo, *dsinfo; /* memory and disk slabinfo */ struct slab *slab; /* slab to write */ size_t size; /* bytes to write */ off_t off; /* offset to write at */ int n; /* written bytes */ ASSERT(!TAILQ_EMPTY(&full_msinfoq)); ASSERT(nfull_msinfoq > 0); ASSERT(!TAILQ_EMPTY(&free_dsinfoq)); ASSERT(nfree_dsinfoq > 0); /* get memory sinfo from full q */ msinfo = TAILQ_FIRST(&full_msinfoq);//從記憶體中滿的裡面取一個 nfull_msinfoq--; TAILQ_REMOVE(&full_msinfoq, msinfo, tqe); ASSERT(msinfo->mem); ASSERT(slab_full(msinfo)); /* get disk sinfo from free q */ dsinfo = TAILQ_FIRST(&free_dsinfoq);//從磁碟中取一個空的 nfree_dsinfoq--; TAILQ_REMOVE(&free_dsinfoq, dsinfo, tqe); ASSERT(!dsinfo->mem); /* drain the memory to disk slab */ slab = slab_from_maddr(msinfo->addr, true); size = settings.slab_size; off = slab_to_daddr(dsinfo); n = pwrite(fd, slab, size, off); if (n < size) { log_error("pwrite fd %d %zu bytes at offset %"PRId64" failed: %s", fd, size, off, strerror(errno)); return FC_ERROR; } ctable[msinfo->cid].nmslab--; ctable[msinfo->cid].ndslab++; log_debug(LOG_DEBUG, "drain slab at memory (sid %"PRIu32" addr %"PRIu32") " "to disk (sid %"PRIu32" addr %"PRIu32")", msinfo->sid, msinfo->addr, dsinfo->sid, dsinfo->addr); /* swap msinfo <> dsinfo addresses */ slab_swap_addr(msinfo, dsinfo); /* move dsinfo (now a memory sinfo) to free q */ nfree_msinfoq++; TAILQ_INSERT_TAIL(&free_msinfoq, dsinfo, tqe); /* move msinfo (now a disk sinfo) to full q */ nfull_dsinfoq++; TAILQ_INSERT_TAIL(&full_dsinfoq, msinfo, tqe); return FC_OK; }
在_slab_get_item(uint8_t cid)中,若partial_msinfoq中的slab滿了,則放進full_msinfoq中