Ejemplo n.º 1
0
/* Simple round-robin Logical to physical address translation.
 *
 * Retrieve the mapping using the active append point. Then update the ap for
 * the next write to the disk.
 *
 * Returns rrpc_addr with the physical address and block. Remember to return to
 * rrpc->addr_cache when request is finished.
 */
static struct rrpc_addr *rrpc_map_page(struct rrpc *rrpc, sector_t laddr,
								int is_gc)
{
	struct rrpc_lun *rlun;
	struct rrpc_block *rblk;
	struct nvm_lun *lun;
	u64 paddr;

	rlun = rrpc_get_lun_rr(rrpc, is_gc);
	lun = rlun->parent;

	if (!is_gc && lun->nr_free_blocks < rrpc->nr_luns * 4)
		return NULL;

	spin_lock(&rlun->lock);

	rblk = rlun->cur;
retry:
	paddr = rrpc_alloc_addr(rrpc, rblk);

	if (paddr == ADDR_EMPTY) {
		rblk = rrpc_get_blk(rrpc, rlun, 0);
		if (rblk) {
			rrpc_set_lun_cur(rlun, rblk);
			goto retry;
		}

		if (is_gc) {
			/* retry from emergency gc block */
			paddr = rrpc_alloc_addr(rrpc, rlun->gc_cur);
			if (paddr == ADDR_EMPTY) {
				rblk = rrpc_get_blk(rrpc, rlun, 1);
				if (!rblk) {
					pr_err("rrpc: no more blocks");
					goto err;
				}

				rlun->gc_cur = rblk;
				paddr = rrpc_alloc_addr(rrpc, rlun->gc_cur);
			}
			rblk = rlun->gc_cur;
		}
	}

	spin_unlock(&rlun->lock);
	return rrpc_update_map(rrpc, laddr, rblk, paddr);
err:
	spin_unlock(&rlun->lock);
	return NULL;
}
Ejemplo n.º 2
0
	paddr = rrpc_alloc_addr(rrpc, rblk);

	if (paddr != ADDR_EMPTY)
		goto done;

	if (!list_empty(&rlun->wblk_list)) {
new_blk:
		rblk = list_first_entry(&rlun->wblk_list, struct rrpc_block,
									prio);
		rrpc_set_lun_cur(rlun, rblk, cur_rblk);
		list_del(&rblk->prio);
		goto retry;
	}
	spin_unlock(&rlun->lock);

	rblk = rrpc_get_blk(rrpc, rlun, gc_force);
	if (rblk) {
		spin_lock(&rlun->lock);
		list_add_tail(&rblk->prio, &rlun->wblk_list);
		/*
		 * another thread might already have added a new block,
		 * Therefore, make sure that one is used, instead of the
		 * one just added.
		 */
		goto new_blk;
	}

	if (unlikely(is_gc) && !gc_force) {
		/* retry from emergency gc block */
		cur_rblk = &rlun->gc_cur;
		rblk = rlun->gc_cur;