Exemple #1
0
/**
 * Create a copy of a write bio.
 */
struct bio* bio_deep_clone(struct bio *bio, gfp_t gfp_mask)
{
	uint size;
	struct bio *clone;

	ASSERT(bio);
	ASSERT(op_is_write(bio_op(bio)));
	ASSERT(!bio->bi_next);

	if (bio_has_data(bio))
		size = bio->bi_iter.bi_size;
	else
		size = 0;

	clone = bio_alloc_with_pages(size, bio->bi_bdev, gfp_mask);
	if (!clone)
		return NULL;

	clone->bi_opf = bio->bi_opf;
	clone->bi_iter.bi_sector = bio->bi_iter.bi_sector;

	if (size == 0) {
		/* This is for discard IOs. */
		clone->bi_iter.bi_size = bio->bi_iter.bi_size;
	} else {
		bio_copy_data(clone, bio);
	}
	return clone;
}
Exemple #2
0
static blk_status_t pmem_do_bvec(struct pmem_device *pmem, struct page *page,
			unsigned int len, unsigned int off, unsigned int op,
			sector_t sector)
{
	blk_status_t rc = BLK_STS_OK;
	bool bad_pmem = false;
	phys_addr_t pmem_off = sector * 512 + pmem->data_offset;
	void *pmem_addr = pmem->virt_addr + pmem_off;

	if (unlikely(is_bad_pmem(&pmem->bb, sector, len)))
		bad_pmem = true;

	if (!op_is_write(op)) {
		if (unlikely(bad_pmem))
			rc = BLK_STS_IOERR;
		else {
			rc = read_pmem(page, off, pmem_addr, len);
			flush_dcache_page(page);
		}
	} else {
		/*
		 * Note that we write the data both before and after
		 * clearing poison.  The write before clear poison
		 * handles situations where the latest written data is
		 * preserved and the clear poison operation simply marks
		 * the address range as valid without changing the data.
		 * In this case application software can assume that an
		 * interrupted write will either return the new good
		 * data or an error.
		 *
		 * However, if pmem_clear_poison() leaves the data in an
		 * indeterminate state we need to perform the write
		 * after clear poison.
		 */
		flush_dcache_page(page);
		write_pmem(pmem_addr, page, off, len);
		if (unlikely(bad_pmem)) {
			rc = pmem_clear_poison(pmem, pmem_off, len);
			write_pmem(pmem_addr, page, off, len);
		}
	}

	return rc;
}
Exemple #3
0
static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio)
{
	int rc = 0;
	bool do_acct;
	unsigned long start;
	struct bio_vec bvec;
	struct bvec_iter iter;
	struct pmem_device *pmem = q->queuedata;
	struct nd_region *nd_region = to_region(pmem);

	if (bio->bi_opf & REQ_FLUSH)
		nvdimm_flush(nd_region);

	do_acct = nd_iostat_start(bio, &start);
	bio_for_each_segment(bvec, bio, iter) {
		rc = pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len,
				bvec.bv_offset, op_is_write(bio_op(bio)),
				iter.bi_sector);
		if (rc) {
			bio->bi_error = rc;
			break;
		}
	}