linux内核源码阅读之facebook硬盘加速flashcache之八
前面我们的分析中重点关注正常的数据流程,这一小节关注如果有异常,那么流程是怎么走完的呢?1)创建新任务时kcached_job申请不到2)读写命中时cache块为忙3)系统关机时处理,系统开机时处理,系统异常掉电后的处理首先来看第1种情况,申请kcached_job是在函数flashcache_lookup中,
294static void295flashcache_do_pending_noerror(struct kcached_job *job)296{297 struct cache_c *dmc = job->dmc;298 int index = job->index;299 unsigned long flags;300 struct pending_job *pending_job;301 int queued;302 struct cacheblock *cacheblk = &dmc->cache[index];303304 spin_lock_irqsave(&dmc->cache_spin_lock, flags);305 if (cacheblk->cache_state & DIRTY) {306 cacheblk->cache_state &= ~(BLOCK_IO_INPROG);307 cacheblk->cache_state |= DISKWRITEINPROG;308 spin_unlock_irqrestore(&dmc->cache_spin_lock, flags);309 flashcache_dirty_writeback(dmc, index);310 goto out;311 }312 DPRINTK("flashcache_do_pending: Index %d %lx",313 index, cacheblk->cache_state);314 VERIFY(cacheblk->cache_state & VALID);315 dmc->cached_blocks--;316 dmc->pending_inval++;317 cacheblk->cache_state &= ~VALID;318 cacheblk->cache_state |= INVALID;319 while (cacheblk->head) {320 VERIFY(!(cacheblk->cache_state & DIRTY));321 pending_job = cacheblk->head;322 cacheblk->head = pending_job->next;323 VERIFY(cacheblk->nr_queued > 0);324 cacheblk->nr_queued--;325 if (pending_job->action == INVALIDATE) {326 DPRINTK("flashcache_do_pending: INVALIDATE %llu",327 next_job->bio->bi_sector);328 VERIFY(pending_job->bio != NULL);329 queued = flashcache_inval_blocks(dmc, pending_job->bio);330 if (queued) {331 if (unlikely(queued < 0)) {332 /*333 * Memory allocation failure inside inval_blocks.334 * Fail this io.335 */336 flashcache_bio_endio(pending_job->bio, -EIO);337 }338 flashcache_free_pending_job(pending_job);339 continue;340 }341 }342 spin_unlock_irqrestore(&dmc->cache_spin_lock, flags);343 DPRINTK("flashcache_do_pending: Sending down IO %llu",344 pending_job->bio->bi_sector);345 /* Start uncached IO */346 flashcache_start_uncached_io(dmc, pending_job->bio);347 flashcache_free_pending_job(pending_job);348 spin_lock_irqsave(&dmc->cache_spin_lock, flags);349 }350 VERIFY(cacheblk->nr_queued == 0);351 cacheblk->cache_state &= ~(BLOCK_IO_INPROG);352 spin_unlock_irqrestore(&dmc->cache_spin_lock, flags);353out:354 flashcache_free_cache_job(job);355 if (atomic_dec_and_test(&dmc->nr_jobs))356 wake_up(&dmc->destroyq);357}