Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 843e8ddb authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'for-4.2/core' into for-4.2/drivers

parents 75619bfa f26cdc85
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -361,7 +361,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)

	/* Restore original bio completion handler */
	bio->bi_end_io = bip->bip_end_io;
	bio_endio_nodec(bio, error);
	bio_endio(bio, error);
}

/**
@@ -388,7 +388,7 @@ void bio_integrity_endio(struct bio *bio, int error)
	 */
	if (error) {
		bio->bi_end_io = bip->bip_end_io;
		bio_endio_nodec(bio, error);
		bio_endio(bio, error);

		return;
	}
+14 −21
Original line number Diff line number Diff line
@@ -303,6 +303,17 @@ static void bio_chain_endio(struct bio *bio, int error)
	bio_put(bio);
}

/*
 * Increment chain count for the bio. Make sure the CHAIN flag update
 * is visible before the raised count.
 */
static inline void bio_inc_remaining(struct bio *bio)
{
	bio->bi_flags |= (1 << BIO_CHAIN);
	smp_mb__before_atomic();
	atomic_inc(&bio->__bi_remaining);
}

/**
 * bio_chain - chain bio completions
 * @bio: the target bio
@@ -1756,8 +1767,10 @@ static inline bool bio_remaining_done(struct bio *bio)

	BUG_ON(atomic_read(&bio->__bi_remaining) <= 0);

	if (atomic_dec_and_test(&bio->__bi_remaining))
	if (atomic_dec_and_test(&bio->__bi_remaining)) {
		clear_bit(BIO_CHAIN, &bio->bi_flags);
		return true;
	}

	return false;
}
@@ -1808,26 +1821,6 @@ void bio_endio(struct bio *bio, int error)
}
EXPORT_SYMBOL(bio_endio);

/**
 * bio_endio_nodec - end I/O on a bio, without decrementing bi_remaining
 * @bio:	bio
 * @error:	error, if any
 *
 * For code that has saved and restored bi_end_io; thing hard before using this
 * function, probably you should've cloned the entire bio.
 **/
void bio_endio_nodec(struct bio *bio, int error)
{
	/*
	 * If it's not flagged as a chain, we are not going to dec the count
	 */
	if (bio_flagged(bio, BIO_CHAIN))
		bio_inc_remaining(bio);

	bio_endio(bio, error);
}
EXPORT_SYMBOL(bio_endio_nodec);

/**
 * bio_split - split a bio
 * @bio:	bio to split
+11 −83
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ EXPORT_SYMBOL(blk_rq_init);
static void req_bio_endio(struct request *rq, struct bio *bio,
			  unsigned int nbytes, int error)
{
	if (error)
	if (error && !(rq->cmd_flags & REQ_CLONE))
		clear_bit(BIO_UPTODATE, &bio->bi_flags);
	else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
		error = -EIO;
@@ -128,7 +128,8 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
	bio_advance(bio, nbytes);

	/* don't actually finish bio if it's part of flush sequence */
	if (bio->bi_iter.bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
	if (bio->bi_iter.bi_size == 0 &&
	    !(rq->cmd_flags & (REQ_FLUSH_SEQ|REQ_CLONE)))
		bio_endio(bio, error);
}

@@ -2909,95 +2910,22 @@ int blk_lld_busy(struct request_queue *q)
}
EXPORT_SYMBOL_GPL(blk_lld_busy);

/**
 * blk_rq_unprep_clone - Helper function to free all bios in a cloned request
 * @rq: the clone request to be cleaned up
 *
 * Description:
 *     Free all bios in @rq for a cloned request.
 */
void blk_rq_unprep_clone(struct request *rq)
{
	struct bio *bio;

	while ((bio = rq->bio) != NULL) {
		rq->bio = bio->bi_next;

		bio_put(bio);
	}
}
EXPORT_SYMBOL_GPL(blk_rq_unprep_clone);

/*
 * Copy attributes of the original request to the clone request.
 * The actual data parts (e.g. ->cmd, ->sense) are not copied.
 */
static void __blk_rq_prep_clone(struct request *dst, struct request *src)
void blk_rq_prep_clone(struct request *dst, struct request *src)
{
	dst->cpu = src->cpu;
	dst->cmd_flags |= (src->cmd_flags & REQ_CLONE_MASK) | REQ_NOMERGE;
	dst->cmd_flags |= (src->cmd_flags & REQ_CLONE_MASK);
	dst->cmd_flags |= REQ_NOMERGE | REQ_CLONE;
	dst->cmd_type = src->cmd_type;
	dst->__sector = blk_rq_pos(src);
	dst->__data_len = blk_rq_bytes(src);
	dst->nr_phys_segments = src->nr_phys_segments;
	dst->ioprio = src->ioprio;
	dst->extra_len = src->extra_len;
}

/**
 * blk_rq_prep_clone - Helper function to setup clone request
 * @rq: the request to be setup
 * @rq_src: original request to be cloned
 * @bs: bio_set that bios for clone are allocated from
 * @gfp_mask: memory allocation mask for bio
 * @bio_ctr: setup function to be called for each clone bio.
 *           Returns %0 for success, non %0 for failure.
 * @data: private data to be passed to @bio_ctr
 *
 * Description:
 *     Clones bios in @rq_src to @rq, and copies attributes of @rq_src to @rq.
 *     The actual data parts of @rq_src (e.g. ->cmd, ->sense)
 *     are not copied, and copying such parts is the caller's responsibility.
 *     Also, pages which the original bios are pointing to are not copied
 *     and the cloned bios just point same pages.
 *     So cloned bios must be completed before original bios, which means
 *     the caller must complete @rq before @rq_src.
 */
int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
		      struct bio_set *bs, gfp_t gfp_mask,
		      int (*bio_ctr)(struct bio *, struct bio *, void *),
		      void *data)
{
	struct bio *bio, *bio_src;

	if (!bs)
		bs = fs_bio_set;

	__rq_for_each_bio(bio_src, rq_src) {
		bio = bio_clone_fast(bio_src, gfp_mask, bs);
		if (!bio)
			goto free_and_out;

		if (bio_ctr && bio_ctr(bio, bio_src, data))
			goto free_and_out;

		if (rq->bio) {
			rq->biotail->bi_next = bio;
			rq->biotail = bio;
		} else
			rq->bio = rq->biotail = bio;
	}

	__blk_rq_prep_clone(rq, rq_src);

	return 0;

free_and_out:
	if (bio)
		bio_put(bio);
	blk_rq_unprep_clone(rq);

	return -ENOMEM;
	dst->bio = src->bio;
	dst->biotail = src->biotail;
	dst->cmd = src->cmd;
	dst->cmd_len = src->cmd_len;
	dst->sense = src->sense;
}
EXPORT_SYMBOL_GPL(blk_rq_prep_clone);

+2 −1
Original line number Diff line number Diff line
@@ -589,7 +589,8 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
	    !blk_write_same_mergeable(rq->bio, bio))
		return false;

	if (q->queue_flags & (1 << QUEUE_FLAG_SG_GAPS)) {
	/* Only check gaps if the bio carries data */
	if (q->queue_flags & (1 << QUEUE_FLAG_SG_GAPS) && bio_has_data(bio)) {
		struct bio_vec *bprev;

		bprev = &rq->biotail->bi_io_vec[rq->biotail->bi_vcnt - 1];
+38 −0
Original line number Diff line number Diff line
@@ -438,6 +438,39 @@ static void bt_for_each(struct blk_mq_hw_ctx *hctx,
	}
}

static void bt_tags_for_each(struct blk_mq_tags *tags,
		struct blk_mq_bitmap_tags *bt, unsigned int off,
		busy_tag_iter_fn *fn, void *data, bool reserved)
{
	struct request *rq;
	int bit, i;

	if (!tags->rqs)
		return;
	for (i = 0; i < bt->map_nr; i++) {
		struct blk_align_bitmap *bm = &bt->map[i];

		for (bit = find_first_bit(&bm->word, bm->depth);
		     bit < bm->depth;
		     bit = find_next_bit(&bm->word, bm->depth, bit + 1)) {
			rq = blk_mq_tag_to_rq(tags, off + bit);
			fn(rq, data, reserved);
		}

		off += (1 << bt->bits_per_word);
	}
}

void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn,
		void *priv)
{
	if (tags->nr_reserved_tags)
		bt_tags_for_each(tags, &tags->breserved_tags, 0, fn, priv, true);
	bt_tags_for_each(tags, &tags->bitmap_tags, tags->nr_reserved_tags, fn, priv,
			false);
}
EXPORT_SYMBOL(blk_mq_all_tag_busy_iter);

void blk_mq_tag_busy_iter(struct blk_mq_hw_ctx *hctx, busy_iter_fn *fn,
		void *priv)
{
@@ -580,6 +613,11 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
	if (!tags)
		return NULL;

	if (!zalloc_cpumask_var(&tags->cpumask, GFP_KERNEL)) {
		kfree(tags);
		return NULL;
	}

	tags->nr_tags = total_tags;
	tags->nr_reserved_tags = reserved_tags;

Loading