Skip to content

Commit

Permalink
Merge remote-tracking branch 'jens/for-4.2/core' into dm-4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Snitzer committed May 29, 2015
2 parents 1c220c6 + f6454b0 commit 183f780
Show file tree
Hide file tree
Showing 54 changed files with 573 additions and 709 deletions.
4 changes: 2 additions & 2 deletions block/bio-integrity.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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;
}
Expand Down
77 changes: 47 additions & 30 deletions block/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ void bio_init(struct bio *bio)
{
memset(bio, 0, sizeof(*bio));
bio->bi_flags = 1 << BIO_UPTODATE;
atomic_set(&bio->bi_remaining, 1);
atomic_set(&bio->bi_cnt, 1);
atomic_set(&bio->__bi_remaining, 1);
atomic_set(&bio->__bi_cnt, 1);
}
EXPORT_SYMBOL(bio_init);

Expand All @@ -292,8 +292,8 @@ void bio_reset(struct bio *bio)
__bio_free(bio);

memset(bio, 0, BIO_RESET_BYTES);
bio->bi_flags = flags|(1 << BIO_UPTODATE);
atomic_set(&bio->bi_remaining, 1);
bio->bi_flags = flags | (1 << BIO_UPTODATE);
atomic_set(&bio->__bi_remaining, 1);
}
EXPORT_SYMBOL(bio_reset);

Expand All @@ -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
Expand All @@ -320,7 +331,7 @@ void bio_chain(struct bio *bio, struct bio *parent)

bio->bi_private = parent;
bio->bi_end_io = bio_chain_endio;
atomic_inc(&parent->bi_remaining);
bio_inc_remaining(parent);
}
EXPORT_SYMBOL(bio_chain);

Expand Down Expand Up @@ -524,13 +535,17 @@ EXPORT_SYMBOL(zero_fill_bio);
**/
void bio_put(struct bio *bio)
{
BIO_BUG_ON(!atomic_read(&bio->bi_cnt));

/*
* last put frees it
*/
if (atomic_dec_and_test(&bio->bi_cnt))
if (!bio_flagged(bio, BIO_REFFED))
bio_free(bio);
else {
BIO_BUG_ON(!atomic_read(&bio->__bi_cnt));

/*
* last put frees it
*/
if (atomic_dec_and_test(&bio->__bi_cnt))
bio_free(bio);
}
}
EXPORT_SYMBOL(bio_put);

Expand Down Expand Up @@ -1741,6 +1756,25 @@ void bio_flush_dcache_pages(struct bio *bi)
EXPORT_SYMBOL(bio_flush_dcache_pages);
#endif

static inline bool bio_remaining_done(struct bio *bio)
{
/*
* If we're not chaining, then ->__bi_remaining is always 1 and
* we always end io on the first invocation.
*/
if (!bio_flagged(bio, BIO_CHAIN))
return true;

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

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

return false;
}

/**
* bio_endio - end I/O on a bio
* @bio: bio
Expand All @@ -1758,15 +1792,13 @@ EXPORT_SYMBOL(bio_flush_dcache_pages);
void bio_endio(struct bio *bio, int error)
{
while (bio) {
BUG_ON(atomic_read(&bio->bi_remaining) <= 0);

if (error)
clear_bit(BIO_UPTODATE, &bio->bi_flags);
else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
error = -EIO;

if (!atomic_dec_and_test(&bio->bi_remaining))
return;
if (unlikely(!bio_remaining_done(bio)))
break;

/*
* Need to have a real endio function for chained bios,
Expand All @@ -1789,21 +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)
{
atomic_inc(&bio->bi_remaining);
bio_endio(bio, error);
}
EXPORT_SYMBOL(bio_endio_nodec);

/**
* bio_split - split a bio
* @bio: bio to split
Expand Down
136 changes: 36 additions & 100 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}

Expand Down Expand Up @@ -285,6 +286,7 @@ inline void __blk_run_queue_uncond(struct request_queue *q)
q->request_fn(q);
q->request_fn_active--;
}
EXPORT_SYMBOL_GPL(__blk_run_queue_uncond);

/**
* __blk_run_queue - run a single device queue
Expand Down Expand Up @@ -1525,7 +1527,8 @@ bool bio_attempt_front_merge(struct request_queue *q, struct request *req,
* Caller must ensure !blk_queue_nomerges(q) beforehand.
*/
bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
unsigned int *request_count)
unsigned int *request_count,
struct request **same_queue_rq)
{
struct blk_plug *plug;
struct request *rq;
Expand All @@ -1545,8 +1548,16 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
list_for_each_entry_reverse(rq, plug_list, queuelist) {
int el_ret;

if (rq->q == q)
if (rq->q == q) {
(*request_count)++;
/*
* Only blk-mq multiple hardware queues case checks the
* rq in the same queue, there should be only one such
* rq in a queue
**/
if (same_queue_rq)
*same_queue_rq = rq;
}

if (rq->q != q || !blk_rq_merge_ok(rq, bio))
continue;
Expand Down Expand Up @@ -1611,7 +1622,7 @@ static void blk_queue_bio(struct request_queue *q, struct bio *bio)
* any locks.
*/
if (!blk_queue_nomerges(q) &&
blk_attempt_plug_merge(q, bio, &request_count))
blk_attempt_plug_merge(q, bio, &request_count, NULL))
return;

spin_lock_irq(q->queue_lock);
Expand Down Expand Up @@ -1718,8 +1729,6 @@ static void handle_bad_sector(struct bio *bio)
bio->bi_rw,
(unsigned long long)bio_end_sector(bio),
(long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9));

set_bit(BIO_EOF, &bio->bi_flags);
}

#ifdef CONFIG_FAIL_MAKE_REQUEST
Expand Down Expand Up @@ -2904,95 +2913,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);

Expand Down Expand Up @@ -3034,21 +2970,20 @@ void blk_start_plug(struct blk_plug *plug)
{
struct task_struct *tsk = current;

/*
* If this is a nested plug, don't actually assign it.
*/
if (tsk->plug)
return;

INIT_LIST_HEAD(&plug->list);
INIT_LIST_HEAD(&plug->mq_list);
INIT_LIST_HEAD(&plug->cb_list);

/*
* If this is a nested plug, don't actually assign it. It will be
* flushed on its own.
* Store ordering should not be needed here, since a potential
* preempt will imply a full memory barrier
*/
if (!tsk->plug) {
/*
* Store ordering should not be needed here, since a potential
* preempt will imply a full memory barrier
*/
tsk->plug = plug;
}
tsk->plug = plug;
}
EXPORT_SYMBOL(blk_start_plug);

Expand Down Expand Up @@ -3195,10 +3130,11 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)

void blk_finish_plug(struct blk_plug *plug)
{
if (plug != current->plug)
return;
blk_flush_plug_list(plug, false);

if (plug == current->plug)
current->plug = NULL;
current->plug = NULL;
}
EXPORT_SYMBOL(blk_finish_plug);

Expand Down
Loading

0 comments on commit 183f780

Please sign in to comment.