/*
 * Some low level IO code, and hacks for various block layer limitations
 *
 * Copyright 2010, 2011 Kent Overstreet <kent.overstreet@gmail.com>
 * Copyright 2012 Google, Inc.
 */

#include "bcache.h"
#include "bset.h"
#include "debug.h"

static void bch_bi_idx_hack_endio(struct bio *bio, int error)
{
	struct bio *p = bio->bi_private;

	bio_endio(p, error);
	bio_put(bio);
}

static void bch_generic_make_request_hack(struct bio *bio)
{
	if (bio->bi_idx) {
		struct bio *clone = bio_alloc(GFP_NOIO, bio_segments(bio));

		memcpy(clone->bi_io_vec,
		       bio_iovec(bio),
		       bio_segments(bio) * sizeof(struct bio_vec));

		clone->bi_sector	= bio->bi_sector;
		clone->bi_bdev		= bio->bi_bdev;
		clone->bi_rw		= bio->bi_rw;
		clone->bi_vcnt		= bio_segments(bio);
		clone->bi_size		= bio->bi_size;

		clone->bi_private	= bio;
		clone->bi_end_io	= bch_bi_idx_hack_endio;

		bio = clone;
	}

	/*
	 * Hack, since drivers that clone bios clone up to bi_max_vecs, but our
	 * bios might have had more than that (before we split them per device
	 * limitations).
	 *
	 * To be taken out once immutable bvec stuff is in.
	 */
	bio->bi_max_vecs = bio->bi_vcnt;

	generic_make_request(bio);
}

/**
 * bch_bio_split - split a bio
 * @bio:	bio to split
 * @sectors:	number of sectors to split from the front of @bio
 * @gfp:	gfp mask
 * @bs:		bio set to allocate from
 *
 * Allocates and returns a new bio which represents @sectors from the start of
 * @bio, and updates @bio to represent the remaining sectors.
 *
 * If bio_sectors(@bio) was less than or equal to @sectors, returns @bio
 * unchanged.
 *
 * The newly allocated bio will point to @bio's bi_io_vec, if the split was on a
 * bvec boundry; it is the caller's responsibility to ensure that @bio is not
 * freed before the split.
 *
 * If bch_bio_split() is running under generic_make_request(), it's not safe to
 * allocate more than one bio from the same bio set. Therefore, if it is running
 * under generic_make_request() it masks out __GFP_WAIT when doing the
 * allocation. The caller must check for failure if there's any possibility of
 * it being called from under generic_make_request(); it is then the caller's
 * responsibility to retry from a safe context (by e.g. punting to workqueue).
 */
struct bio *bch_bio_split(struct bio *bio, int sectors,
			  gfp_t gfp, struct bio_set *bs)
{
	unsigned idx = bio->bi_idx, vcnt = 0, nbytes = sectors << 9;
	struct bio_vec *bv;
	struct bio *ret = NULL;

	BUG_ON(sectors <= 0);

	/*
	 * If we're being called from underneath generic_make_request() and we
	 * already allocated any bios from this bio set, we risk deadlock if we
	 * use the mempool. So instead, we possibly fail and let the caller punt
	 * to workqueue or somesuch and retry in a safe context.
	 */
	if (current->bio_list)
		gfp &= ~__GFP_WAIT;

	if (sectors >= bio_sectors(bio))
		return bio;

	if (bio->bi_rw & REQ_DISCARD) {
		ret = bio_alloc_bioset(gfp, 1, bs);
		idx = 0;
		goto out;
	}

	bio_for_each_segment(bv, bio, idx) {
		vcnt = idx - bio->bi_idx;

		if (!nbytes) {
			ret = bio_alloc_bioset(gfp, vcnt, bs);
			if (!ret)
				return NULL;

			memcpy(ret->bi_io_vec, bio_iovec(bio),
			       sizeof(struct bio_vec) * vcnt);

			break;
		} else if (nbytes < bv->bv_len) {
			ret = bio_alloc_bioset(gfp, ++vcnt, bs);
			if (!ret)
				return NULL;

			memcpy(ret->bi_io_vec, bio_iovec(bio),
			       sizeof(struct bio_vec) * vcnt);

			ret->bi_io_vec[vcnt - 1].bv_len = nbytes;
			bv->bv_offset	+= nbytes;
			bv->bv_len	-= nbytes;
			break;
		}

		nbytes -= bv->bv_len;
	}
out:
	ret->bi_bdev	= bio->bi_bdev;
	ret->bi_sector	= bio->bi_sector;
	ret->bi_size	= sectors << 9;
	ret->bi_rw	= bio->bi_rw;
	ret->bi_vcnt	= vcnt;
	ret->bi_max_vecs = vcnt;

	bio->bi_sector	+= sectors;
	bio->bi_size	-= sectors << 9;
	bio->bi_idx	 = idx;

	if (bio_integrity(bio)) {
		if (bio_integrity_clone(ret, bio, gfp)) {
			bio_put(ret);
			return NULL;
		}

		bio_integrity_trim(ret, 0, bio_sectors(ret));
		bio_integrity_trim(bio, bio_sectors(ret), bio_sectors(bio));
	}

	return ret;
}

static unsigned bch_bio_max_sectors(struct bio *bio)
{
	unsigned ret = bio_sectors(bio);
	struct request_queue *q = bdev_get_queue(bio->bi_bdev);
	unsigned max_segments = min_t(unsigned, BIO_MAX_PAGES,
				      queue_max_segments(q));
	struct bio_vec *bv, *end = bio_iovec(bio) +
		min_t(int, bio_segments(bio), max_segments);

	if (bio->bi_rw & REQ_DISCARD)
		return min(ret, q->limits.max_discard_sectors);

	if (bio_segments(bio) > max_segments ||
	    q->merge_bvec_fn) {
		ret = 0;

		for (bv = bio_iovec(bio); bv < end; bv++) {
			struct bvec_merge_data bvm = {
				.bi_bdev	= bio->bi_bdev,
				.bi_sector	= bio->bi_sector,
				.bi_size	= ret << 9,
				.bi_rw		= bio->bi_rw,
			};

			if (q->merge_bvec_fn &&
			    q->merge_bvec_fn(q, &bvm, bv) < (int) bv->bv_len)
				break;

			ret += bv->bv_len >> 9;
		}
	}

	ret = min(ret, queue_max_sectors(q));

	WARN_ON(!ret);
	ret = max_t(int, ret, bio_iovec(bio)->bv_len >> 9);

	return ret;
}

static void bch_bio_submit_split_done(struct closure *cl)
{
	struct bio_split_hook *s = container_of(cl, struct bio_split_hook, cl);

	s->bio->bi_end_io = s->bi_end_io;
	s->bio->bi_private = s->bi_private;
	bio_endio(s->bio, 0);

	closure_debug_destroy(&s->cl);
	mempool_free(s, s->p->bio_split_hook);
}

static void bch_bio_submit_split_endio(struct bio *bio, int error)
{
	struct closure *cl = bio->bi_private;
	struct bio_split_hook *s = container_of(cl, struct bio_split_hook, cl);

	if (error)
		clear_bit(BIO_UPTODATE, &s->bio->bi_flags);

	bio_put(bio);
	closure_put(cl);
}

static void __bch_bio_submit_split(struct closure *cl)
{
	struct bio_split_hook *s = container_of(cl, struct bio_split_hook, cl);
	struct bio *bio = s->bio, *n;

	do {
		n = bch_bio_split(bio, bch_bio_max_sectors(bio),
				  GFP_NOIO, s->p->bio_split);
		if (!n)
			continue_at(cl, __bch_bio_submit_split, system_wq);

		n->bi_end_io	= bch_bio_submit_split_endio;
		n->bi_private	= cl;

		closure_get(cl);
		bch_generic_make_request_hack(n);
	} while (n != bio);

	continue_at(cl, bch_bio_submit_split_done, NULL);
}

void bch_generic_make_request(struct bio *bio, struct bio_split_pool *p)
{
	struct bio_split_hook *s;

	if (!bio_has_data(bio) && !(bio->bi_rw & REQ_DISCARD))
		goto submit;

	if (bio_sectors(bio) <= bch_bio_max_sectors(bio))
		goto submit;

	s = mempool_alloc(p->bio_split_hook, GFP_NOIO);

	s->bio		= bio;
	s->p		= p;
	s->bi_end_io	= bio->bi_end_io;
	s->bi_private	= bio->bi_private;
	bio_get(bio);

	closure_call(&s->cl, __bch_bio_submit_split, NULL, NULL);
	return;
submit:
	bch_generic_make_request_hack(bio);
}

/* Bios with headers */

void bch_bbio_free(struct bio *bio, struct cache_set *c)
{
	struct bbio *b = container_of(bio, struct bbio, bio);
	mempool_free(b, c->bio_meta);
}

struct bio *bch_bbio_alloc(struct cache_set *c)
{
	struct bbio *b = mempool_alloc(c->bio_meta, GFP_NOIO);
	struct bio *bio = &b->bio;

	bio_init(bio);
	bio->bi_flags		|= BIO_POOL_NONE << BIO_POOL_OFFSET;
	bio->bi_max_vecs	 = bucket_pages(c);
	bio->bi_io_vec		 = bio->bi_inline_vecs;

	return bio;
}

void __bch_submit_bbio(struct bio *bio, struct cache_set *c)
{
	struct bbio *b = container_of(bio, struct bbio, bio);

	bio->bi_sector	= PTR_OFFSET(&b->key, 0);
	bio->bi_bdev	= PTR_CACHE(c, &b->key, 0)->bdev;

	b->submit_time_us = local_clock_us();
	closure_bio_submit(bio, bio->bi_private, PTR_CACHE(c, &b->key, 0));
}

void bch_submit_bbio(struct bio *bio, struct cache_set *c,
		     struct bkey *k, unsigned ptr)
{
	struct bbio *b = container_of(bio, struct bbio, bio);
	bch_bkey_copy_single_ptr(&b->key, k, ptr);
	__bch_submit_bbio(bio, c);
}

/* IO errors */

void bch_count_io_errors(struct cache *ca, int error, const char *m)
{
	/*
	 * The halflife of an error is:
	 * log2(1/2)/log2(127/128) * refresh ~= 88 * refresh
	 */

	if (ca->set->error_decay) {
		unsigned count = atomic_inc_return(&ca->io_count);

		while (count > ca->set->error_decay) {
			unsigned errors;
			unsigned old = count;
			unsigned new = count - ca->set->error_decay;

			/*
			 * First we subtract refresh from count; each time we
			 * succesfully do so, we rescale the errors once:
			 */

			count = atomic_cmpxchg(&ca->io_count, old, new);

			if (count == old) {
				count = new;

				errors = atomic_read(&ca->io_errors);
				do {
					old = errors;
					new = ((uint64_t) errors * 127) / 128;
					errors = atomic_cmpxchg(&ca->io_errors,
								old, new);
				} while (old != errors);
			}
		}
	}

	if (error) {
		char buf[BDEVNAME_SIZE];
		unsigned errors = atomic_add_return(1 << IO_ERROR_SHIFT,
						    &ca->io_errors);
		errors >>= IO_ERROR_SHIFT;

		if (errors < ca->set->error_limit)
			pr_err("%s: IO error on %s, recovering",
			       bdevname(ca->bdev, buf), m);
		else
			bch_cache_set_error(ca->set,
					    "%s: too many IO errors %s",
					    bdevname(ca->bdev, buf), m);
	}
}

void bch_bbio_count_io_errors(struct cache_set *c, struct bio *bio,
			      int error, const char *m)
{
	struct bbio *b = container_of(bio, struct bbio, bio);
	struct cache *ca = PTR_CACHE(c, &b->key, 0);

	unsigned threshold = bio->bi_rw & REQ_WRITE
		? c->congested_write_threshold_us
		: c->congested_read_threshold_us;

	if (threshold) {
		unsigned t = local_clock_us();

		int us = t - b->submit_time_us;
		int congested = atomic_read(&c->congested);

		if (us > (int) threshold) {
			int ms = us / 1024;
			c->congested_last_us = t;

			ms = min(ms, CONGESTED_MAX + congested);
			atomic_sub(ms, &c->congested);
		} else if (congested < 0)
			atomic_inc(&c->congested);
	}

	bch_count_io_errors(ca, error, m);
}

void bch_bbio_endio(struct cache_set *c, struct bio *bio,
		    int error, const char *m)
{
	struct closure *cl = bio->bi_private;

	bch_bbio_count_io_errors(c, bio, error, m);
	bio_put(bio);
	closure_put(cl);
}
