Merge branch 'for-4.14/block' of git://git.kernel.dk/linux-block
Pull block layer updates from Jens Axboe: "This is the first pull request for 4.14, containing most of the code changes. It's a quiet series this round, which I think we needed after the churn of the last few series. This contains: - Fix for a registration race in loop, from Anton Volkov. - Overflow complaint fix from Arnd for DAC960. - Series of drbd changes from the usual suspects. - Conversion of the stec/skd driver to blk-mq. From Bart. - A few BFQ improvements/fixes from Paolo. - CFQ improvement from Ritesh, allowing idling for group idle. - A few fixes found by Dan's smatch, courtesy of Dan. - A warning fixup for a race between changing the IO scheduler and device remova. From David Jeffery. - A few nbd fixes from Josef. - Support for cgroup info in blktrace, from Shaohua. - Also from Shaohua, new features in the null_blk driver to allow it to actually hold data, among other things. - Various corner cases and error handling fixes from Weiping Zhang. - Improvements to the IO stats tracking for blk-mq from me. Can drastically improve performance for fast devices and/or big machines. - Series from Christoph removing bi_bdev as being needed for IO submission, in preparation for nvme multipathing code. - Series from Bart, including various cleanups and fixes for switch fall through case complaints" * 'for-4.14/block' of git://git.kernel.dk/linux-block: (162 commits) kernfs: checking for IS_ERR() instead of NULL drbd: remove BIOSET_NEED_RESCUER flag from drbd_{md_,}io_bio_set drbd: Fix allyesconfig build, fix recent commit drbd: switch from kmalloc() to kmalloc_array() drbd: abort drbd_start_resync if there is no connection drbd: move global variables to drbd namespace and make some static drbd: rename "usermode_helper" to "drbd_usermode_helper" drbd: fix race between handshake and admin disconnect/down drbd: fix potential deadlock when trying to detach during handshake drbd: A single dot should be put into a sequence. drbd: fix rmmod cleanup, remove _all_ debugfs entries drbd: Use setup_timer() instead of init_timer() to simplify the code. drbd: fix potential get_ldev/put_ldev refcount imbalance during attach drbd: new disk-option disable-write-same drbd: Fix resource role for newly created resources in events2 drbd: mark symbols static where possible drbd: Send P_NEG_ACK upon write error in protocol != C drbd: add explicit plugging when submitting batches drbd: change list_for_each_safe to while(list_first_entry_or_null) drbd: introduce drbd_recv_header_maybe_unplug ...
This commit is contained in:
commit
a0725ab0c7
|
@ -12561,6 +12561,12 @@ M: Ion Badulescu <ionut@badula.org>
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: drivers/net/ethernet/adaptec/starfire*
|
F: drivers/net/ethernet/adaptec/starfire*
|
||||||
|
|
||||||
|
STEC S1220 SKD DRIVER
|
||||||
|
M: Bart Van Assche <bart.vanassche@wdc.com>
|
||||||
|
L: linux-block@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/block/skd*[ch]
|
||||||
|
|
||||||
STI CEC DRIVER
|
STI CEC DRIVER
|
||||||
M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
|
M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
|
@ -110,7 +110,7 @@ axon_ram_irq_handler(int irq, void *dev)
|
||||||
static blk_qc_t
|
static blk_qc_t
|
||||||
axon_ram_make_request(struct request_queue *queue, struct bio *bio)
|
axon_ram_make_request(struct request_queue *queue, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
|
struct axon_ram_bank *bank = bio->bi_disk->private_data;
|
||||||
unsigned long phys_mem, phys_end;
|
unsigned long phys_mem, phys_end;
|
||||||
void *user_mem;
|
void *user_mem;
|
||||||
struct bio_vec vec;
|
struct bio_vec vec;
|
||||||
|
|
|
@ -128,7 +128,7 @@ BFQ_BFQQ_FNS(busy);
|
||||||
BFQ_BFQQ_FNS(wait_request);
|
BFQ_BFQQ_FNS(wait_request);
|
||||||
BFQ_BFQQ_FNS(non_blocking_wait_rq);
|
BFQ_BFQQ_FNS(non_blocking_wait_rq);
|
||||||
BFQ_BFQQ_FNS(fifo_expire);
|
BFQ_BFQQ_FNS(fifo_expire);
|
||||||
BFQ_BFQQ_FNS(idle_window);
|
BFQ_BFQQ_FNS(has_short_ttime);
|
||||||
BFQ_BFQQ_FNS(sync);
|
BFQ_BFQQ_FNS(sync);
|
||||||
BFQ_BFQQ_FNS(IO_bound);
|
BFQ_BFQQ_FNS(IO_bound);
|
||||||
BFQ_BFQQ_FNS(in_large_burst);
|
BFQ_BFQQ_FNS(in_large_burst);
|
||||||
|
@ -731,10 +731,10 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
|
||||||
unsigned int old_wr_coeff = bfqq->wr_coeff;
|
unsigned int old_wr_coeff = bfqq->wr_coeff;
|
||||||
bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq);
|
bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq);
|
||||||
|
|
||||||
if (bic->saved_idle_window)
|
if (bic->saved_has_short_ttime)
|
||||||
bfq_mark_bfqq_idle_window(bfqq);
|
bfq_mark_bfqq_has_short_ttime(bfqq);
|
||||||
else
|
else
|
||||||
bfq_clear_bfqq_idle_window(bfqq);
|
bfq_clear_bfqq_has_short_ttime(bfqq);
|
||||||
|
|
||||||
if (bic->saved_IO_bound)
|
if (bic->saved_IO_bound)
|
||||||
bfq_mark_bfqq_IO_bound(bfqq);
|
bfq_mark_bfqq_IO_bound(bfqq);
|
||||||
|
@ -2012,7 +2012,7 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bic->saved_ttime = bfqq->ttime;
|
bic->saved_ttime = bfqq->ttime;
|
||||||
bic->saved_idle_window = bfq_bfqq_idle_window(bfqq);
|
bic->saved_has_short_ttime = bfq_bfqq_has_short_ttime(bfqq);
|
||||||
bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
|
bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
|
||||||
bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
|
bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
|
||||||
bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
|
bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
|
||||||
|
@ -3038,8 +3038,8 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||||
}
|
}
|
||||||
|
|
||||||
bfq_log_bfqq(bfqd, bfqq,
|
bfq_log_bfqq(bfqd, bfqq,
|
||||||
"expire (%d, slow %d, num_disp %d, idle_win %d)", reason,
|
"expire (%d, slow %d, num_disp %d, short_ttime %d)", reason,
|
||||||
slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq));
|
slow, bfqq->dispatched, bfq_bfqq_has_short_ttime(bfqq));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Increase, decrease or leave budget unchanged according to
|
* Increase, decrease or leave budget unchanged according to
|
||||||
|
@ -3114,35 +3114,56 @@ static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
|
||||||
static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
|
static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
|
||||||
{
|
{
|
||||||
struct bfq_data *bfqd = bfqq->bfqd;
|
struct bfq_data *bfqd = bfqq->bfqd;
|
||||||
bool idling_boosts_thr, idling_boosts_thr_without_issues,
|
bool rot_without_queueing =
|
||||||
|
!blk_queue_nonrot(bfqd->queue) && !bfqd->hw_tag,
|
||||||
|
bfqq_sequential_and_IO_bound,
|
||||||
|
idling_boosts_thr, idling_boosts_thr_without_issues,
|
||||||
idling_needed_for_service_guarantees,
|
idling_needed_for_service_guarantees,
|
||||||
asymmetric_scenario;
|
asymmetric_scenario;
|
||||||
|
|
||||||
if (bfqd->strict_guarantees)
|
if (bfqd->strict_guarantees)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Idling is performed only if slice_idle > 0. In addition, we
|
||||||
|
* do not idle if
|
||||||
|
* (a) bfqq is async
|
||||||
|
* (b) bfqq is in the idle io prio class: in this case we do
|
||||||
|
* not idle because we want to minimize the bandwidth that
|
||||||
|
* queues in this class can steal to higher-priority queues
|
||||||
|
*/
|
||||||
|
if (bfqd->bfq_slice_idle == 0 || !bfq_bfqq_sync(bfqq) ||
|
||||||
|
bfq_class_idle(bfqq))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bfqq_sequential_and_IO_bound = !BFQQ_SEEKY(bfqq) &&
|
||||||
|
bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_has_short_ttime(bfqq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The next variable takes into account the cases where idling
|
* The next variable takes into account the cases where idling
|
||||||
* boosts the throughput.
|
* boosts the throughput.
|
||||||
*
|
*
|
||||||
* The value of the variable is computed considering, first, that
|
* The value of the variable is computed considering, first, that
|
||||||
* idling is virtually always beneficial for the throughput if:
|
* idling is virtually always beneficial for the throughput if:
|
||||||
* (a) the device is not NCQ-capable, or
|
* (a) the device is not NCQ-capable and rotational, or
|
||||||
* (b) regardless of the presence of NCQ, the device is rotational
|
* (b) regardless of the presence of NCQ, the device is rotational and
|
||||||
* and the request pattern for bfqq is I/O-bound and sequential.
|
* the request pattern for bfqq is I/O-bound and sequential, or
|
||||||
|
* (c) regardless of whether it is rotational, the device is
|
||||||
|
* not NCQ-capable and the request pattern for bfqq is
|
||||||
|
* I/O-bound and sequential.
|
||||||
*
|
*
|
||||||
* Secondly, and in contrast to the above item (b), idling an
|
* Secondly, and in contrast to the above item (b), idling an
|
||||||
* NCQ-capable flash-based device would not boost the
|
* NCQ-capable flash-based device would not boost the
|
||||||
* throughput even with sequential I/O; rather it would lower
|
* throughput even with sequential I/O; rather it would lower
|
||||||
* the throughput in proportion to how fast the device
|
* the throughput in proportion to how fast the device
|
||||||
* is. Accordingly, the next variable is true if any of the
|
* is. Accordingly, the next variable is true if any of the
|
||||||
* above conditions (a) and (b) is true, and, in particular,
|
* above conditions (a), (b) or (c) is true, and, in
|
||||||
* happens to be false if bfqd is an NCQ-capable flash-based
|
* particular, happens to be false if bfqd is an NCQ-capable
|
||||||
* device.
|
* flash-based device.
|
||||||
*/
|
*/
|
||||||
idling_boosts_thr = !bfqd->hw_tag ||
|
idling_boosts_thr = rot_without_queueing ||
|
||||||
(!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) &&
|
((!blk_queue_nonrot(bfqd->queue) || !bfqd->hw_tag) &&
|
||||||
bfq_bfqq_idle_window(bfqq));
|
bfqq_sequential_and_IO_bound);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The value of the next variable,
|
* The value of the next variable,
|
||||||
|
@ -3313,16 +3334,13 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
|
||||||
asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq);
|
asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have now all the components we need to compute the return
|
* We have now all the components we need to compute the
|
||||||
* value of the function, which is true only if both the following
|
* return value of the function, which is true only if idling
|
||||||
* conditions hold:
|
* either boosts the throughput (without issues), or is
|
||||||
* 1) bfqq is sync, because idling make sense only for sync queues;
|
* necessary to preserve service guarantees.
|
||||||
* 2) idling either boosts the throughput (without issues), or
|
|
||||||
* is necessary to preserve service guarantees.
|
|
||||||
*/
|
*/
|
||||||
return bfq_bfqq_sync(bfqq) &&
|
return idling_boosts_thr_without_issues ||
|
||||||
(idling_boosts_thr_without_issues ||
|
idling_needed_for_service_guarantees;
|
||||||
idling_needed_for_service_guarantees);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3338,10 +3356,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
|
||||||
*/
|
*/
|
||||||
static bool bfq_bfqq_must_idle(struct bfq_queue *bfqq)
|
static bool bfq_bfqq_must_idle(struct bfq_queue *bfqq)
|
||||||
{
|
{
|
||||||
struct bfq_data *bfqd = bfqq->bfqd;
|
return RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_may_idle(bfqq);
|
||||||
|
|
||||||
return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 &&
|
|
||||||
bfq_bfqq_may_idle(bfqq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3783,7 +3798,6 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
|
||||||
case IOPRIO_CLASS_IDLE:
|
case IOPRIO_CLASS_IDLE:
|
||||||
bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE;
|
bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE;
|
||||||
bfqq->new_ioprio = 7;
|
bfqq->new_ioprio = 7;
|
||||||
bfq_clear_bfqq_idle_window(bfqq);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3843,8 +3857,14 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
bfq_set_next_ioprio_data(bfqq, bic);
|
bfq_set_next_ioprio_data(bfqq, bic);
|
||||||
|
|
||||||
if (is_sync) {
|
if (is_sync) {
|
||||||
|
/*
|
||||||
|
* No need to mark as has_short_ttime if in
|
||||||
|
* idle_class, because no device idling is performed
|
||||||
|
* for queues in idle class
|
||||||
|
*/
|
||||||
if (!bfq_class_idle(bfqq))
|
if (!bfq_class_idle(bfqq))
|
||||||
bfq_mark_bfqq_idle_window(bfqq);
|
/* tentatively mark as has_short_ttime */
|
||||||
|
bfq_mark_bfqq_has_short_ttime(bfqq);
|
||||||
bfq_mark_bfqq_sync(bfqq);
|
bfq_mark_bfqq_sync(bfqq);
|
||||||
bfq_mark_bfqq_just_created(bfqq);
|
bfq_mark_bfqq_just_created(bfqq);
|
||||||
} else
|
} else
|
||||||
|
@ -3985,18 +4005,19 @@ bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
blk_rq_sectors(rq) < BFQQ_SECT_THR_NONROT);
|
blk_rq_sectors(rq) < BFQQ_SECT_THR_NONROT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void bfq_update_has_short_ttime(struct bfq_data *bfqd,
|
||||||
* Disable idle window if the process thinks too long or seeks so much that
|
struct bfq_queue *bfqq,
|
||||||
* it doesn't matter.
|
struct bfq_io_cq *bic)
|
||||||
*/
|
|
||||||
static void bfq_update_idle_window(struct bfq_data *bfqd,
|
|
||||||
struct bfq_queue *bfqq,
|
|
||||||
struct bfq_io_cq *bic)
|
|
||||||
{
|
{
|
||||||
int enable_idle;
|
bool has_short_ttime = true;
|
||||||
|
|
||||||
/* Don't idle for async or idle io prio class. */
|
/*
|
||||||
if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq))
|
* No need to update has_short_ttime if bfqq is async or in
|
||||||
|
* idle io prio class, or if bfq_slice_idle is zero, because
|
||||||
|
* no device idling is performed for bfqq in this case.
|
||||||
|
*/
|
||||||
|
if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq) ||
|
||||||
|
bfqd->bfq_slice_idle == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Idle window just restored, statistics are meaningless. */
|
/* Idle window just restored, statistics are meaningless. */
|
||||||
|
@ -4004,27 +4025,22 @@ static void bfq_update_idle_window(struct bfq_data *bfqd,
|
||||||
bfqd->bfq_wr_min_idle_time))
|
bfqd->bfq_wr_min_idle_time))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
enable_idle = bfq_bfqq_idle_window(bfqq);
|
/* Think time is infinite if no process is linked to
|
||||||
|
* bfqq. Otherwise check average think time to
|
||||||
|
* decide whether to mark as has_short_ttime
|
||||||
|
*/
|
||||||
if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
|
if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
|
||||||
bfqd->bfq_slice_idle == 0 ||
|
(bfq_sample_valid(bfqq->ttime.ttime_samples) &&
|
||||||
(bfqd->hw_tag && BFQQ_SEEKY(bfqq) &&
|
bfqq->ttime.ttime_mean > bfqd->bfq_slice_idle))
|
||||||
bfqq->wr_coeff == 1))
|
has_short_ttime = false;
|
||||||
enable_idle = 0;
|
|
||||||
else if (bfq_sample_valid(bfqq->ttime.ttime_samples)) {
|
|
||||||
if (bfqq->ttime.ttime_mean > bfqd->bfq_slice_idle &&
|
|
||||||
bfqq->wr_coeff == 1)
|
|
||||||
enable_idle = 0;
|
|
||||||
else
|
|
||||||
enable_idle = 1;
|
|
||||||
}
|
|
||||||
bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d",
|
|
||||||
enable_idle);
|
|
||||||
|
|
||||||
if (enable_idle)
|
bfq_log_bfqq(bfqd, bfqq, "update_has_short_ttime: has_short_ttime %d",
|
||||||
bfq_mark_bfqq_idle_window(bfqq);
|
has_short_ttime);
|
||||||
|
|
||||||
|
if (has_short_ttime)
|
||||||
|
bfq_mark_bfqq_has_short_ttime(bfqq);
|
||||||
else
|
else
|
||||||
bfq_clear_bfqq_idle_window(bfqq);
|
bfq_clear_bfqq_has_short_ttime(bfqq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4040,14 +4056,12 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
bfqq->meta_pending++;
|
bfqq->meta_pending++;
|
||||||
|
|
||||||
bfq_update_io_thinktime(bfqd, bfqq);
|
bfq_update_io_thinktime(bfqd, bfqq);
|
||||||
|
bfq_update_has_short_ttime(bfqd, bfqq, bic);
|
||||||
bfq_update_io_seektime(bfqd, bfqq, rq);
|
bfq_update_io_seektime(bfqd, bfqq, rq);
|
||||||
if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
|
|
||||||
!BFQQ_SEEKY(bfqq))
|
|
||||||
bfq_update_idle_window(bfqd, bfqq, bic);
|
|
||||||
|
|
||||||
bfq_log_bfqq(bfqd, bfqq,
|
bfq_log_bfqq(bfqd, bfqq,
|
||||||
"rq_enqueued: idle_window=%d (seeky %d)",
|
"rq_enqueued: has_short_ttime=%d (seeky %d)",
|
||||||
bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq));
|
bfq_bfqq_has_short_ttime(bfqq), BFQQ_SEEKY(bfqq));
|
||||||
|
|
||||||
bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
|
bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
|
||||||
|
|
||||||
|
@ -4787,16 +4801,13 @@ static ssize_t bfq_var_show(unsigned int var, char *page)
|
||||||
return sprintf(page, "%u\n", var);
|
return sprintf(page, "%u\n", var);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t bfq_var_store(unsigned long *var, const char *page,
|
static void bfq_var_store(unsigned long *var, const char *page)
|
||||||
size_t count)
|
|
||||||
{
|
{
|
||||||
unsigned long new_val;
|
unsigned long new_val;
|
||||||
int ret = kstrtoul(page, 10, &new_val);
|
int ret = kstrtoul(page, 10, &new_val);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
*var = new_val;
|
*var = new_val;
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
||||||
|
@ -4838,7 +4849,7 @@ __FUNC(struct elevator_queue *e, const char *page, size_t count) \
|
||||||
{ \
|
{ \
|
||||||
struct bfq_data *bfqd = e->elevator_data; \
|
struct bfq_data *bfqd = e->elevator_data; \
|
||||||
unsigned long uninitialized_var(__data); \
|
unsigned long uninitialized_var(__data); \
|
||||||
int ret = bfq_var_store(&__data, (page), count); \
|
bfq_var_store(&__data, (page)); \
|
||||||
if (__data < (MIN)) \
|
if (__data < (MIN)) \
|
||||||
__data = (MIN); \
|
__data = (MIN); \
|
||||||
else if (__data > (MAX)) \
|
else if (__data > (MAX)) \
|
||||||
|
@ -4849,7 +4860,7 @@ __FUNC(struct elevator_queue *e, const char *page, size_t count) \
|
||||||
*(__PTR) = (u64)__data * NSEC_PER_MSEC; \
|
*(__PTR) = (u64)__data * NSEC_PER_MSEC; \
|
||||||
else \
|
else \
|
||||||
*(__PTR) = __data; \
|
*(__PTR) = __data; \
|
||||||
return ret; \
|
return count; \
|
||||||
}
|
}
|
||||||
STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
|
STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
|
||||||
INT_MAX, 2);
|
INT_MAX, 2);
|
||||||
|
@ -4866,13 +4877,13 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)\
|
||||||
{ \
|
{ \
|
||||||
struct bfq_data *bfqd = e->elevator_data; \
|
struct bfq_data *bfqd = e->elevator_data; \
|
||||||
unsigned long uninitialized_var(__data); \
|
unsigned long uninitialized_var(__data); \
|
||||||
int ret = bfq_var_store(&__data, (page), count); \
|
bfq_var_store(&__data, (page)); \
|
||||||
if (__data < (MIN)) \
|
if (__data < (MIN)) \
|
||||||
__data = (MIN); \
|
__data = (MIN); \
|
||||||
else if (__data > (MAX)) \
|
else if (__data > (MAX)) \
|
||||||
__data = (MAX); \
|
__data = (MAX); \
|
||||||
*(__PTR) = (u64)__data * NSEC_PER_USEC; \
|
*(__PTR) = (u64)__data * NSEC_PER_USEC; \
|
||||||
return ret; \
|
return count; \
|
||||||
}
|
}
|
||||||
USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0,
|
USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0,
|
||||||
UINT_MAX);
|
UINT_MAX);
|
||||||
|
@ -4883,7 +4894,8 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
|
||||||
{
|
{
|
||||||
struct bfq_data *bfqd = e->elevator_data;
|
struct bfq_data *bfqd = e->elevator_data;
|
||||||
unsigned long uninitialized_var(__data);
|
unsigned long uninitialized_var(__data);
|
||||||
int ret = bfq_var_store(&__data, (page), count);
|
|
||||||
|
bfq_var_store(&__data, (page));
|
||||||
|
|
||||||
if (__data == 0)
|
if (__data == 0)
|
||||||
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
|
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
|
||||||
|
@ -4895,7 +4907,7 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
|
||||||
|
|
||||||
bfqd->bfq_user_max_budget = __data;
|
bfqd->bfq_user_max_budget = __data;
|
||||||
|
|
||||||
return ret;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4907,7 +4919,8 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
|
||||||
{
|
{
|
||||||
struct bfq_data *bfqd = e->elevator_data;
|
struct bfq_data *bfqd = e->elevator_data;
|
||||||
unsigned long uninitialized_var(__data);
|
unsigned long uninitialized_var(__data);
|
||||||
int ret = bfq_var_store(&__data, (page), count);
|
|
||||||
|
bfq_var_store(&__data, (page));
|
||||||
|
|
||||||
if (__data < 1)
|
if (__data < 1)
|
||||||
__data = 1;
|
__data = 1;
|
||||||
|
@ -4918,7 +4931,7 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
|
||||||
if (bfqd->bfq_user_max_budget == 0)
|
if (bfqd->bfq_user_max_budget == 0)
|
||||||
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
|
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
|
||||||
|
|
||||||
return ret;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
|
static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
|
||||||
|
@ -4926,7 +4939,8 @@ static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
|
||||||
{
|
{
|
||||||
struct bfq_data *bfqd = e->elevator_data;
|
struct bfq_data *bfqd = e->elevator_data;
|
||||||
unsigned long uninitialized_var(__data);
|
unsigned long uninitialized_var(__data);
|
||||||
int ret = bfq_var_store(&__data, (page), count);
|
|
||||||
|
bfq_var_store(&__data, (page));
|
||||||
|
|
||||||
if (__data > 1)
|
if (__data > 1)
|
||||||
__data = 1;
|
__data = 1;
|
||||||
|
@ -4936,7 +4950,7 @@ static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
|
||||||
|
|
||||||
bfqd->strict_guarantees = __data;
|
bfqd->strict_guarantees = __data;
|
||||||
|
|
||||||
return ret;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t bfq_low_latency_store(struct elevator_queue *e,
|
static ssize_t bfq_low_latency_store(struct elevator_queue *e,
|
||||||
|
@ -4944,7 +4958,8 @@ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
|
||||||
{
|
{
|
||||||
struct bfq_data *bfqd = e->elevator_data;
|
struct bfq_data *bfqd = e->elevator_data;
|
||||||
unsigned long uninitialized_var(__data);
|
unsigned long uninitialized_var(__data);
|
||||||
int ret = bfq_var_store(&__data, (page), count);
|
|
||||||
|
bfq_var_store(&__data, (page));
|
||||||
|
|
||||||
if (__data > 1)
|
if (__data > 1)
|
||||||
__data = 1;
|
__data = 1;
|
||||||
|
@ -4952,7 +4967,7 @@ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
|
||||||
bfq_end_wr(bfqd);
|
bfq_end_wr(bfqd);
|
||||||
bfqd->low_latency = __data;
|
bfqd->low_latency = __data;
|
||||||
|
|
||||||
return ret;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BFQ_ATTR(name) \
|
#define BFQ_ATTR(name) \
|
||||||
|
@ -4998,6 +5013,7 @@ static struct elevator_type iosched_bfq_mq = {
|
||||||
.elevator_name = "bfq",
|
.elevator_name = "bfq",
|
||||||
.elevator_owner = THIS_MODULE,
|
.elevator_owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
MODULE_ALIAS("bfq-iosched");
|
||||||
|
|
||||||
static int __init bfq_init(void)
|
static int __init bfq_init(void)
|
||||||
{
|
{
|
||||||
|
@ -5048,10 +5064,12 @@ static int __init bfq_init(void)
|
||||||
|
|
||||||
ret = elv_register(&iosched_bfq_mq);
|
ret = elv_register(&iosched_bfq_mq);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_pol_unreg;
|
goto slab_kill;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
slab_kill:
|
||||||
|
bfq_slab_kill();
|
||||||
err_pol_unreg:
|
err_pol_unreg:
|
||||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
blkcg_policy_unregister(&blkcg_policy_bfq);
|
blkcg_policy_unregister(&blkcg_policy_bfq);
|
||||||
|
|
|
@ -360,11 +360,11 @@ struct bfq_io_cq {
|
||||||
uint64_t blkcg_serial_nr; /* the current blkcg serial */
|
uint64_t blkcg_serial_nr; /* the current blkcg serial */
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* Snapshot of the idle window before merging; taken to
|
* Snapshot of the has_short_time flag before merging; taken
|
||||||
* remember this value while the queue is merged, so as to be
|
* to remember its value while the queue is merged, so as to
|
||||||
* able to restore it in case of split.
|
* be able to restore it in case of split.
|
||||||
*/
|
*/
|
||||||
bool saved_idle_window;
|
bool saved_has_short_ttime;
|
||||||
/*
|
/*
|
||||||
* Same purpose as the previous two fields for the I/O bound
|
* Same purpose as the previous two fields for the I/O bound
|
||||||
* classification of a queue.
|
* classification of a queue.
|
||||||
|
@ -638,7 +638,7 @@ enum bfqq_state_flags {
|
||||||
* without idling the device
|
* without idling the device
|
||||||
*/
|
*/
|
||||||
BFQQF_fifo_expire, /* FIFO checked in this slice */
|
BFQQF_fifo_expire, /* FIFO checked in this slice */
|
||||||
BFQQF_idle_window, /* slice idling enabled */
|
BFQQF_has_short_ttime, /* queue has a short think time */
|
||||||
BFQQF_sync, /* synchronous queue */
|
BFQQF_sync, /* synchronous queue */
|
||||||
BFQQF_IO_bound, /*
|
BFQQF_IO_bound, /*
|
||||||
* bfqq has timed-out at least once
|
* bfqq has timed-out at least once
|
||||||
|
@ -667,7 +667,7 @@ BFQ_BFQQ_FNS(busy);
|
||||||
BFQ_BFQQ_FNS(wait_request);
|
BFQ_BFQQ_FNS(wait_request);
|
||||||
BFQ_BFQQ_FNS(non_blocking_wait_rq);
|
BFQ_BFQQ_FNS(non_blocking_wait_rq);
|
||||||
BFQ_BFQQ_FNS(fifo_expire);
|
BFQ_BFQQ_FNS(fifo_expire);
|
||||||
BFQ_BFQQ_FNS(idle_window);
|
BFQ_BFQQ_FNS(has_short_ttime);
|
||||||
BFQ_BFQQ_FNS(sync);
|
BFQ_BFQQ_FNS(sync);
|
||||||
BFQ_BFQQ_FNS(IO_bound);
|
BFQ_BFQQ_FNS(IO_bound);
|
||||||
BFQ_BFQQ_FNS(in_large_burst);
|
BFQ_BFQQ_FNS(in_large_burst);
|
||||||
|
@ -929,13 +929,16 @@ void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq);
|
||||||
struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
||||||
|
|
||||||
#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \
|
#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \
|
||||||
blk_add_trace_msg((bfqd)->queue, "bfq%d%c %s " fmt, (bfqq)->pid,\
|
blk_add_cgroup_trace_msg((bfqd)->queue, \
|
||||||
bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \
|
bfqg_to_blkg(bfqq_group(bfqq))->blkcg, \
|
||||||
bfqq_group(bfqq)->blkg_path, ##args); \
|
"bfq%d%c " fmt, (bfqq)->pid, \
|
||||||
|
bfq_bfqq_sync((bfqq)) ? 'S' : 'A', ##args); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) \
|
#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do { \
|
||||||
blk_add_trace_msg((bfqd)->queue, "%s " fmt, (bfqg)->blkg_path, ##args)
|
blk_add_cgroup_trace_msg((bfqd)->queue, \
|
||||||
|
bfqg_to_blkg(bfqg)->blkcg, fmt, ##args); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#else /* CONFIG_BFQ_GROUP_IOSCHED */
|
#else /* CONFIG_BFQ_GROUP_IOSCHED */
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
|
||||||
iv = bip->bip_vec + bip->bip_vcnt;
|
iv = bip->bip_vec + bip->bip_vcnt;
|
||||||
|
|
||||||
if (bip->bip_vcnt &&
|
if (bip->bip_vcnt &&
|
||||||
bvec_gap_to_prev(bdev_get_queue(bio->bi_bdev),
|
bvec_gap_to_prev(bio->bi_disk->queue,
|
||||||
&bip->bip_vec[bip->bip_vcnt - 1], offset))
|
&bip->bip_vec[bip->bip_vcnt - 1], offset))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
|
||||||
static blk_status_t bio_integrity_process(struct bio *bio,
|
static blk_status_t bio_integrity_process(struct bio *bio,
|
||||||
struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn)
|
struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn)
|
||||||
{
|
{
|
||||||
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
|
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
|
||||||
struct blk_integrity_iter iter;
|
struct blk_integrity_iter iter;
|
||||||
struct bvec_iter bviter;
|
struct bvec_iter bviter;
|
||||||
struct bio_vec bv;
|
struct bio_vec bv;
|
||||||
|
@ -199,7 +199,7 @@ static blk_status_t bio_integrity_process(struct bio *bio,
|
||||||
void *prot_buf = page_address(bip->bip_vec->bv_page) +
|
void *prot_buf = page_address(bip->bip_vec->bv_page) +
|
||||||
bip->bip_vec->bv_offset;
|
bip->bip_vec->bv_offset;
|
||||||
|
|
||||||
iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
|
iter.disk_name = bio->bi_disk->disk_name;
|
||||||
iter.interval = 1 << bi->interval_exp;
|
iter.interval = 1 << bi->interval_exp;
|
||||||
iter.seed = proc_iter->bi_sector;
|
iter.seed = proc_iter->bi_sector;
|
||||||
iter.prot_buf = prot_buf;
|
iter.prot_buf = prot_buf;
|
||||||
|
@ -236,8 +236,8 @@ static blk_status_t bio_integrity_process(struct bio *bio,
|
||||||
bool bio_integrity_prep(struct bio *bio)
|
bool bio_integrity_prep(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_integrity_payload *bip;
|
struct bio_integrity_payload *bip;
|
||||||
struct blk_integrity *bi;
|
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
|
||||||
struct request_queue *q;
|
struct request_queue *q = bio->bi_disk->queue;
|
||||||
void *buf;
|
void *buf;
|
||||||
unsigned long start, end;
|
unsigned long start, end;
|
||||||
unsigned int len, nr_pages;
|
unsigned int len, nr_pages;
|
||||||
|
@ -245,8 +245,9 @@ bool bio_integrity_prep(struct bio *bio)
|
||||||
unsigned int intervals;
|
unsigned int intervals;
|
||||||
blk_status_t status;
|
blk_status_t status;
|
||||||
|
|
||||||
bi = bdev_get_integrity(bio->bi_bdev);
|
if (!bi)
|
||||||
q = bdev_get_queue(bio->bi_bdev);
|
return true;
|
||||||
|
|
||||||
if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE)
|
if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -257,9 +258,6 @@ bool bio_integrity_prep(struct bio *bio)
|
||||||
if (bio_integrity(bio))
|
if (bio_integrity(bio))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (bi == NULL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (bio_data_dir(bio) == READ) {
|
if (bio_data_dir(bio) == READ) {
|
||||||
if (!bi->profile->verify_fn ||
|
if (!bi->profile->verify_fn ||
|
||||||
!(bi->flags & BLK_INTEGRITY_VERIFY))
|
!(bi->flags & BLK_INTEGRITY_VERIFY))
|
||||||
|
@ -354,7 +352,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
|
||||||
struct bio_integrity_payload *bip =
|
struct bio_integrity_payload *bip =
|
||||||
container_of(work, struct bio_integrity_payload, bip_work);
|
container_of(work, struct bio_integrity_payload, bip_work);
|
||||||
struct bio *bio = bip->bip_bio;
|
struct bio *bio = bip->bip_bio;
|
||||||
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
|
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
|
||||||
struct bvec_iter iter = bio->bi_iter;
|
struct bvec_iter iter = bio->bi_iter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -387,7 +385,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
|
||||||
*/
|
*/
|
||||||
bool __bio_integrity_endio(struct bio *bio)
|
bool __bio_integrity_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
|
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
|
||||||
struct bio_integrity_payload *bip = bio_integrity(bio);
|
struct bio_integrity_payload *bip = bio_integrity(bio);
|
||||||
|
|
||||||
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
|
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
|
||||||
|
@ -413,7 +411,7 @@ bool __bio_integrity_endio(struct bio *bio)
|
||||||
void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
|
void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
|
||||||
{
|
{
|
||||||
struct bio_integrity_payload *bip = bio_integrity(bio);
|
struct bio_integrity_payload *bip = bio_integrity(bio);
|
||||||
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
|
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
|
||||||
unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
|
unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
|
||||||
|
|
||||||
bip->bip_iter.bi_sector += bytes_done >> 9;
|
bip->bip_iter.bi_sector += bytes_done >> 9;
|
||||||
|
@ -430,7 +428,7 @@ EXPORT_SYMBOL(bio_integrity_advance);
|
||||||
void bio_integrity_trim(struct bio *bio)
|
void bio_integrity_trim(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_integrity_payload *bip = bio_integrity(bio);
|
struct bio_integrity_payload *bip = bio_integrity(bio);
|
||||||
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
|
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
|
||||||
|
|
||||||
bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio));
|
bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio));
|
||||||
}
|
}
|
||||||
|
|
30
block/bio.c
30
block/bio.c
|
@ -593,10 +593,10 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
|
||||||
BUG_ON(bio->bi_pool && BVEC_POOL_IDX(bio));
|
BUG_ON(bio->bi_pool && BVEC_POOL_IDX(bio));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* most users will be overriding ->bi_bdev with a new target,
|
* most users will be overriding ->bi_disk with a new target,
|
||||||
* so we don't set nor calculate new physical/hw segment counts here
|
* so we don't set nor calculate new physical/hw segment counts here
|
||||||
*/
|
*/
|
||||||
bio->bi_bdev = bio_src->bi_bdev;
|
bio->bi_disk = bio_src->bi_disk;
|
||||||
bio_set_flag(bio, BIO_CLONED);
|
bio_set_flag(bio, BIO_CLONED);
|
||||||
bio->bi_opf = bio_src->bi_opf;
|
bio->bi_opf = bio_src->bi_opf;
|
||||||
bio->bi_write_hint = bio_src->bi_write_hint;
|
bio->bi_write_hint = bio_src->bi_write_hint;
|
||||||
|
@ -681,7 +681,7 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
|
||||||
bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
|
bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
|
||||||
if (!bio)
|
if (!bio)
|
||||||
return NULL;
|
return NULL;
|
||||||
bio->bi_bdev = bio_src->bi_bdev;
|
bio->bi_disk = bio_src->bi_disk;
|
||||||
bio->bi_opf = bio_src->bi_opf;
|
bio->bi_opf = bio_src->bi_opf;
|
||||||
bio->bi_write_hint = bio_src->bi_write_hint;
|
bio->bi_write_hint = bio_src->bi_write_hint;
|
||||||
bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
|
bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
|
||||||
|
@ -936,6 +936,10 @@ static void submit_bio_wait_endio(struct bio *bio)
|
||||||
*
|
*
|
||||||
* Simple wrapper around submit_bio(). Returns 0 on success, or the error from
|
* Simple wrapper around submit_bio(). Returns 0 on success, or the error from
|
||||||
* bio_endio() on failure.
|
* bio_endio() on failure.
|
||||||
|
*
|
||||||
|
* WARNING: Unlike to how submit_bio() is usually used, this function does not
|
||||||
|
* result in bio reference to be consumed. The caller must drop the reference
|
||||||
|
* on his own.
|
||||||
*/
|
*/
|
||||||
int submit_bio_wait(struct bio *bio)
|
int submit_bio_wait(struct bio *bio)
|
||||||
{
|
{
|
||||||
|
@ -1732,29 +1736,29 @@ void bio_check_pages_dirty(struct bio *bio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_start_io_acct(int rw, unsigned long sectors,
|
void generic_start_io_acct(struct request_queue *q, int rw,
|
||||||
struct hd_struct *part)
|
unsigned long sectors, struct hd_struct *part)
|
||||||
{
|
{
|
||||||
int cpu = part_stat_lock();
|
int cpu = part_stat_lock();
|
||||||
|
|
||||||
part_round_stats(cpu, part);
|
part_round_stats(q, cpu, part);
|
||||||
part_stat_inc(cpu, part, ios[rw]);
|
part_stat_inc(cpu, part, ios[rw]);
|
||||||
part_stat_add(cpu, part, sectors[rw], sectors);
|
part_stat_add(cpu, part, sectors[rw], sectors);
|
||||||
part_inc_in_flight(part, rw);
|
part_inc_in_flight(q, part, rw);
|
||||||
|
|
||||||
part_stat_unlock();
|
part_stat_unlock();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(generic_start_io_acct);
|
EXPORT_SYMBOL(generic_start_io_acct);
|
||||||
|
|
||||||
void generic_end_io_acct(int rw, struct hd_struct *part,
|
void generic_end_io_acct(struct request_queue *q, int rw,
|
||||||
unsigned long start_time)
|
struct hd_struct *part, unsigned long start_time)
|
||||||
{
|
{
|
||||||
unsigned long duration = jiffies - start_time;
|
unsigned long duration = jiffies - start_time;
|
||||||
int cpu = part_stat_lock();
|
int cpu = part_stat_lock();
|
||||||
|
|
||||||
part_stat_add(cpu, part, ticks[rw], duration);
|
part_stat_add(cpu, part, ticks[rw], duration);
|
||||||
part_round_stats(cpu, part);
|
part_round_stats(q, cpu, part);
|
||||||
part_dec_in_flight(part, rw);
|
part_dec_in_flight(q, part, rw);
|
||||||
|
|
||||||
part_stat_unlock();
|
part_stat_unlock();
|
||||||
}
|
}
|
||||||
|
@ -1826,8 +1830,8 @@ again:
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
|
if (bio->bi_disk && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
|
||||||
trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), bio,
|
trace_block_bio_complete(bio->bi_disk->queue, bio,
|
||||||
blk_status_to_errno(bio->bi_status));
|
blk_status_to_errno(bio->bi_status));
|
||||||
bio_clear_flag(bio, BIO_TRACE_COMPLETION);
|
bio_clear_flag(bio, BIO_TRACE_COMPLETION);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1067,7 +1067,7 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
|
||||||
blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
|
blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
|
||||||
if (!blkcg) {
|
if (!blkcg) {
|
||||||
ret = ERR_PTR(-ENOMEM);
|
ret = ERR_PTR(-ENOMEM);
|
||||||
goto free_blkcg;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1111,8 +1111,10 @@ free_pd_blkcg:
|
||||||
for (i--; i >= 0; i--)
|
for (i--; i >= 0; i--)
|
||||||
if (blkcg->cpd[i])
|
if (blkcg->cpd[i])
|
||||||
blkcg_policy[i]->cpd_free_fn(blkcg->cpd[i]);
|
blkcg_policy[i]->cpd_free_fn(blkcg->cpd[i]);
|
||||||
free_blkcg:
|
|
||||||
kfree(blkcg);
|
if (blkcg != &blkcg_root)
|
||||||
|
kfree(blkcg);
|
||||||
|
unlock:
|
||||||
mutex_unlock(&blkcg_pol_mutex);
|
mutex_unlock(&blkcg_pol_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
153
block/blk-core.c
153
block/blk-core.c
|
@ -280,7 +280,7 @@ EXPORT_SYMBOL(blk_start_queue_async);
|
||||||
void blk_start_queue(struct request_queue *q)
|
void blk_start_queue(struct request_queue *q)
|
||||||
{
|
{
|
||||||
lockdep_assert_held(q->queue_lock);
|
lockdep_assert_held(q->queue_lock);
|
||||||
WARN_ON(!irqs_disabled());
|
WARN_ON(!in_interrupt() && !irqs_disabled());
|
||||||
WARN_ON_ONCE(q->mq_ops);
|
WARN_ON_ONCE(q->mq_ops);
|
||||||
|
|
||||||
queue_flag_clear(QUEUE_FLAG_STOPPED, q);
|
queue_flag_clear(QUEUE_FLAG_STOPPED, q);
|
||||||
|
@ -1469,15 +1469,10 @@ static void add_acct_request(struct request_queue *q, struct request *rq,
|
||||||
__elv_add_request(q, rq, where);
|
__elv_add_request(q, rq, where);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void part_round_stats_single(int cpu, struct hd_struct *part,
|
static void part_round_stats_single(struct request_queue *q, int cpu,
|
||||||
unsigned long now)
|
struct hd_struct *part, unsigned long now,
|
||||||
|
unsigned int inflight)
|
||||||
{
|
{
|
||||||
int inflight;
|
|
||||||
|
|
||||||
if (now == part->stamp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
inflight = part_in_flight(part);
|
|
||||||
if (inflight) {
|
if (inflight) {
|
||||||
__part_stat_add(cpu, part, time_in_queue,
|
__part_stat_add(cpu, part, time_in_queue,
|
||||||
inflight * (now - part->stamp));
|
inflight * (now - part->stamp));
|
||||||
|
@ -1488,6 +1483,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* part_round_stats() - Round off the performance stats on a struct disk_stats.
|
* part_round_stats() - Round off the performance stats on a struct disk_stats.
|
||||||
|
* @q: target block queue
|
||||||
* @cpu: cpu number for stats access
|
* @cpu: cpu number for stats access
|
||||||
* @part: target partition
|
* @part: target partition
|
||||||
*
|
*
|
||||||
|
@ -1502,13 +1498,31 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
|
||||||
* /proc/diskstats. This accounts immediately for all queue usage up to
|
* /proc/diskstats. This accounts immediately for all queue usage up to
|
||||||
* the current jiffies and restarts the counters again.
|
* the current jiffies and restarts the counters again.
|
||||||
*/
|
*/
|
||||||
void part_round_stats(int cpu, struct hd_struct *part)
|
void part_round_stats(struct request_queue *q, int cpu, struct hd_struct *part)
|
||||||
{
|
{
|
||||||
|
struct hd_struct *part2 = NULL;
|
||||||
unsigned long now = jiffies;
|
unsigned long now = jiffies;
|
||||||
|
unsigned int inflight[2];
|
||||||
|
int stats = 0;
|
||||||
|
|
||||||
if (part->partno)
|
if (part->stamp != now)
|
||||||
part_round_stats_single(cpu, &part_to_disk(part)->part0, now);
|
stats |= 1;
|
||||||
part_round_stats_single(cpu, part, now);
|
|
||||||
|
if (part->partno) {
|
||||||
|
part2 = &part_to_disk(part)->part0;
|
||||||
|
if (part2->stamp != now)
|
||||||
|
stats |= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stats)
|
||||||
|
return;
|
||||||
|
|
||||||
|
part_in_flight(q, part, inflight);
|
||||||
|
|
||||||
|
if (stats & 2)
|
||||||
|
part_round_stats_single(q, cpu, part2, now, inflight[1]);
|
||||||
|
if (stats & 1)
|
||||||
|
part_round_stats_single(q, cpu, part, now, inflight[0]);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(part_round_stats);
|
EXPORT_SYMBOL_GPL(part_round_stats);
|
||||||
|
|
||||||
|
@ -1896,40 +1910,15 @@ out_unlock:
|
||||||
return BLK_QC_T_NONE;
|
return BLK_QC_T_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If bio->bi_dev is a partition, remap the location
|
|
||||||
*/
|
|
||||||
static inline void blk_partition_remap(struct bio *bio)
|
|
||||||
{
|
|
||||||
struct block_device *bdev = bio->bi_bdev;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Zone reset does not include bi_size so bio_sectors() is always 0.
|
|
||||||
* Include a test for the reset op code and perform the remap if needed.
|
|
||||||
*/
|
|
||||||
if (bdev != bdev->bd_contains &&
|
|
||||||
(bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)) {
|
|
||||||
struct hd_struct *p = bdev->bd_part;
|
|
||||||
|
|
||||||
bio->bi_iter.bi_sector += p->start_sect;
|
|
||||||
bio->bi_bdev = bdev->bd_contains;
|
|
||||||
|
|
||||||
trace_block_bio_remap(bdev_get_queue(bio->bi_bdev), bio,
|
|
||||||
bdev->bd_dev,
|
|
||||||
bio->bi_iter.bi_sector - p->start_sect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_bad_sector(struct bio *bio)
|
static void handle_bad_sector(struct bio *bio)
|
||||||
{
|
{
|
||||||
char b[BDEVNAME_SIZE];
|
char b[BDEVNAME_SIZE];
|
||||||
|
|
||||||
printk(KERN_INFO "attempt to access beyond end of device\n");
|
printk(KERN_INFO "attempt to access beyond end of device\n");
|
||||||
printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n",
|
printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n",
|
||||||
bdevname(bio->bi_bdev, b),
|
bio_devname(bio, b), bio->bi_opf,
|
||||||
bio->bi_opf,
|
|
||||||
(unsigned long long)bio_end_sector(bio),
|
(unsigned long long)bio_end_sector(bio),
|
||||||
(long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9));
|
(long long)get_capacity(bio->bi_disk));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FAIL_MAKE_REQUEST
|
#ifdef CONFIG_FAIL_MAKE_REQUEST
|
||||||
|
@ -1967,6 +1956,38 @@ static inline bool should_fail_request(struct hd_struct *part,
|
||||||
|
|
||||||
#endif /* CONFIG_FAIL_MAKE_REQUEST */
|
#endif /* CONFIG_FAIL_MAKE_REQUEST */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remap block n of partition p to block n+start(p) of the disk.
|
||||||
|
*/
|
||||||
|
static inline int blk_partition_remap(struct bio *bio)
|
||||||
|
{
|
||||||
|
struct hd_struct *p;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zone reset does not include bi_size so bio_sectors() is always 0.
|
||||||
|
* Include a test for the reset op code and perform the remap if needed.
|
||||||
|
*/
|
||||||
|
if (!bio->bi_partno ||
|
||||||
|
(!bio_sectors(bio) && bio_op(bio) != REQ_OP_ZONE_RESET))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
p = __disk_get_part(bio->bi_disk, bio->bi_partno);
|
||||||
|
if (likely(p && !should_fail_request(p, bio->bi_iter.bi_size))) {
|
||||||
|
bio->bi_iter.bi_sector += p->start_sect;
|
||||||
|
bio->bi_partno = 0;
|
||||||
|
trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
|
||||||
|
bio->bi_iter.bi_sector - p->start_sect);
|
||||||
|
} else {
|
||||||
|
printk("%s: fail for partition %d\n", __func__, bio->bi_partno);
|
||||||
|
ret = -EIO;
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether this bio extends beyond the end of the device.
|
* Check whether this bio extends beyond the end of the device.
|
||||||
*/
|
*/
|
||||||
|
@ -1978,7 +1999,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Test device or partition size, when known. */
|
/* Test device or partition size, when known. */
|
||||||
maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9;
|
maxsector = get_capacity(bio->bi_disk);
|
||||||
if (maxsector) {
|
if (maxsector) {
|
||||||
sector_t sector = bio->bi_iter.bi_sector;
|
sector_t sector = bio->bi_iter.bi_sector;
|
||||||
|
|
||||||
|
@ -2003,20 +2024,18 @@ generic_make_request_checks(struct bio *bio)
|
||||||
int nr_sectors = bio_sectors(bio);
|
int nr_sectors = bio_sectors(bio);
|
||||||
blk_status_t status = BLK_STS_IOERR;
|
blk_status_t status = BLK_STS_IOERR;
|
||||||
char b[BDEVNAME_SIZE];
|
char b[BDEVNAME_SIZE];
|
||||||
struct hd_struct *part;
|
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
if (bio_check_eod(bio, nr_sectors))
|
if (bio_check_eod(bio, nr_sectors))
|
||||||
goto end_io;
|
goto end_io;
|
||||||
|
|
||||||
q = bdev_get_queue(bio->bi_bdev);
|
q = bio->bi_disk->queue;
|
||||||
if (unlikely(!q)) {
|
if (unlikely(!q)) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"generic_make_request: Trying to access "
|
"generic_make_request: Trying to access "
|
||||||
"nonexistent block-device %s (%Lu)\n",
|
"nonexistent block-device %s (%Lu)\n",
|
||||||
bdevname(bio->bi_bdev, b),
|
bio_devname(bio, b), (long long)bio->bi_iter.bi_sector);
|
||||||
(long long) bio->bi_iter.bi_sector);
|
|
||||||
goto end_io;
|
goto end_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2028,17 +2047,11 @@ generic_make_request_checks(struct bio *bio)
|
||||||
if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_rq_based(q))
|
if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_rq_based(q))
|
||||||
goto not_supported;
|
goto not_supported;
|
||||||
|
|
||||||
part = bio->bi_bdev->bd_part;
|
if (should_fail_request(&bio->bi_disk->part0, bio->bi_iter.bi_size))
|
||||||
if (should_fail_request(part, bio->bi_iter.bi_size) ||
|
|
||||||
should_fail_request(&part_to_disk(part)->part0,
|
|
||||||
bio->bi_iter.bi_size))
|
|
||||||
goto end_io;
|
goto end_io;
|
||||||
|
|
||||||
/*
|
if (blk_partition_remap(bio))
|
||||||
* If this device has partitions, remap block n
|
goto end_io;
|
||||||
* of partition p to block n+start(p) of the disk.
|
|
||||||
*/
|
|
||||||
blk_partition_remap(bio);
|
|
||||||
|
|
||||||
if (bio_check_eod(bio, nr_sectors))
|
if (bio_check_eod(bio, nr_sectors))
|
||||||
goto end_io;
|
goto end_io;
|
||||||
|
@ -2067,16 +2080,16 @@ generic_make_request_checks(struct bio *bio)
|
||||||
goto not_supported;
|
goto not_supported;
|
||||||
break;
|
break;
|
||||||
case REQ_OP_WRITE_SAME:
|
case REQ_OP_WRITE_SAME:
|
||||||
if (!bdev_write_same(bio->bi_bdev))
|
if (!q->limits.max_write_same_sectors)
|
||||||
goto not_supported;
|
goto not_supported;
|
||||||
break;
|
break;
|
||||||
case REQ_OP_ZONE_REPORT:
|
case REQ_OP_ZONE_REPORT:
|
||||||
case REQ_OP_ZONE_RESET:
|
case REQ_OP_ZONE_RESET:
|
||||||
if (!bdev_is_zoned(bio->bi_bdev))
|
if (!blk_queue_is_zoned(q))
|
||||||
goto not_supported;
|
goto not_supported;
|
||||||
break;
|
break;
|
||||||
case REQ_OP_WRITE_ZEROES:
|
case REQ_OP_WRITE_ZEROES:
|
||||||
if (!bdev_write_zeroes_sectors(bio->bi_bdev))
|
if (!q->limits.max_write_zeroes_sectors)
|
||||||
goto not_supported;
|
goto not_supported;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2183,7 +2196,7 @@ blk_qc_t generic_make_request(struct bio *bio)
|
||||||
bio_list_init(&bio_list_on_stack[0]);
|
bio_list_init(&bio_list_on_stack[0]);
|
||||||
current->bio_list = bio_list_on_stack;
|
current->bio_list = bio_list_on_stack;
|
||||||
do {
|
do {
|
||||||
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
struct request_queue *q = bio->bi_disk->queue;
|
||||||
|
|
||||||
if (likely(blk_queue_enter(q, bio->bi_opf & REQ_NOWAIT) == 0)) {
|
if (likely(blk_queue_enter(q, bio->bi_opf & REQ_NOWAIT) == 0)) {
|
||||||
struct bio_list lower, same;
|
struct bio_list lower, same;
|
||||||
|
@ -2201,7 +2214,7 @@ blk_qc_t generic_make_request(struct bio *bio)
|
||||||
bio_list_init(&lower);
|
bio_list_init(&lower);
|
||||||
bio_list_init(&same);
|
bio_list_init(&same);
|
||||||
while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL)
|
while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL)
|
||||||
if (q == bdev_get_queue(bio->bi_bdev))
|
if (q == bio->bi_disk->queue)
|
||||||
bio_list_add(&same, bio);
|
bio_list_add(&same, bio);
|
||||||
else
|
else
|
||||||
bio_list_add(&lower, bio);
|
bio_list_add(&lower, bio);
|
||||||
|
@ -2244,7 +2257,7 @@ blk_qc_t submit_bio(struct bio *bio)
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
|
if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
|
||||||
count = bdev_logical_block_size(bio->bi_bdev) >> 9;
|
count = queue_logical_block_size(bio->bi_disk->queue);
|
||||||
else
|
else
|
||||||
count = bio_sectors(bio);
|
count = bio_sectors(bio);
|
||||||
|
|
||||||
|
@ -2261,8 +2274,7 @@ blk_qc_t submit_bio(struct bio *bio)
|
||||||
current->comm, task_pid_nr(current),
|
current->comm, task_pid_nr(current),
|
||||||
op_is_write(bio_op(bio)) ? "WRITE" : "READ",
|
op_is_write(bio_op(bio)) ? "WRITE" : "READ",
|
||||||
(unsigned long long)bio->bi_iter.bi_sector,
|
(unsigned long long)bio->bi_iter.bi_sector,
|
||||||
bdevname(bio->bi_bdev, b),
|
bio_devname(bio, b), count);
|
||||||
count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2431,8 +2443,8 @@ void blk_account_io_done(struct request *req)
|
||||||
|
|
||||||
part_stat_inc(cpu, part, ios[rw]);
|
part_stat_inc(cpu, part, ios[rw]);
|
||||||
part_stat_add(cpu, part, ticks[rw], duration);
|
part_stat_add(cpu, part, ticks[rw], duration);
|
||||||
part_round_stats(cpu, part);
|
part_round_stats(req->q, cpu, part);
|
||||||
part_dec_in_flight(part, rw);
|
part_dec_in_flight(req->q, part, rw);
|
||||||
|
|
||||||
hd_struct_put(part);
|
hd_struct_put(part);
|
||||||
part_stat_unlock();
|
part_stat_unlock();
|
||||||
|
@ -2489,8 +2501,8 @@ void blk_account_io_start(struct request *rq, bool new_io)
|
||||||
part = &rq->rq_disk->part0;
|
part = &rq->rq_disk->part0;
|
||||||
hd_struct_get(part);
|
hd_struct_get(part);
|
||||||
}
|
}
|
||||||
part_round_stats(cpu, part);
|
part_round_stats(rq->q, cpu, part);
|
||||||
part_inc_in_flight(part, rw);
|
part_inc_in_flight(rq->q, part, rw);
|
||||||
rq->part = part;
|
rq->part = part;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2603,7 +2615,7 @@ struct request *blk_peek_request(struct request_queue *q)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blk_peek_request);
|
EXPORT_SYMBOL(blk_peek_request);
|
||||||
|
|
||||||
void blk_dequeue_request(struct request *rq)
|
static void blk_dequeue_request(struct request *rq)
|
||||||
{
|
{
|
||||||
struct request_queue *q = rq->q;
|
struct request_queue *q = rq->q;
|
||||||
|
|
||||||
|
@ -2630,9 +2642,6 @@ void blk_dequeue_request(struct request *rq)
|
||||||
* Description:
|
* Description:
|
||||||
* Dequeue @req and start timeout timer on it. This hands off the
|
* Dequeue @req and start timeout timer on it. This hands off the
|
||||||
* request to the driver.
|
* request to the driver.
|
||||||
*
|
|
||||||
* Block internal functions which don't want to start timer should
|
|
||||||
* call blk_dequeue_request().
|
|
||||||
*/
|
*/
|
||||||
void blk_start_request(struct request *req)
|
void blk_start_request(struct request *req)
|
||||||
{
|
{
|
||||||
|
@ -3035,8 +3044,8 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
|
||||||
rq->__data_len = bio->bi_iter.bi_size;
|
rq->__data_len = bio->bi_iter.bi_size;
|
||||||
rq->bio = rq->biotail = bio;
|
rq->bio = rq->biotail = bio;
|
||||||
|
|
||||||
if (bio->bi_bdev)
|
if (bio->bi_disk)
|
||||||
rq->rq_disk = bio->bi_bdev->bd_disk;
|
rq->rq_disk = bio->bi_disk;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
|
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* Functions to sequence FLUSH and FUA writes.
|
* Functions to sequence PREFLUSH and FUA writes.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Max Planck Institute for Gravitational Physics
|
* Copyright (C) 2011 Max Planck Institute for Gravitational Physics
|
||||||
* Copyright (C) 2011 Tejun Heo <tj@kernel.org>
|
* Copyright (C) 2011 Tejun Heo <tj@kernel.org>
|
||||||
*
|
*
|
||||||
* This file is released under the GPLv2.
|
* This file is released under the GPLv2.
|
||||||
*
|
*
|
||||||
* REQ_{FLUSH|FUA} requests are decomposed to sequences consisted of three
|
* REQ_{PREFLUSH|FUA} requests are decomposed to sequences consisted of three
|
||||||
* optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request
|
* optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request
|
||||||
* properties and hardware capability.
|
* properties and hardware capability.
|
||||||
*
|
*
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
* REQ_FUA means that the data must be on non-volatile media on request
|
* REQ_FUA means that the data must be on non-volatile media on request
|
||||||
* completion.
|
* completion.
|
||||||
*
|
*
|
||||||
* If the device doesn't have writeback cache, FLUSH and FUA don't make any
|
* If the device doesn't have writeback cache, PREFLUSH and FUA don't make any
|
||||||
* difference. The requests are either completed immediately if there's no
|
* difference. The requests are either completed immediately if there's no data
|
||||||
* data or executed as normal requests otherwise.
|
* or executed as normal requests otherwise.
|
||||||
*
|
*
|
||||||
* If the device has writeback cache and supports FUA, REQ_PREFLUSH is
|
* If the device has writeback cache and supports FUA, REQ_PREFLUSH is
|
||||||
* translated to PREFLUSH but REQ_FUA is passed down directly with DATA.
|
* translated to PREFLUSH but REQ_FUA is passed down directly with DATA.
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
* fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a
|
* fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a
|
||||||
* REQ_OP_FLUSH is issued and the pending_idx is toggled. When the flush
|
* REQ_OP_FLUSH is issued and the pending_idx is toggled. When the flush
|
||||||
* completes, all the requests which were pending are proceeded to the next
|
* completes, all the requests which were pending are proceeded to the next
|
||||||
* step. This allows arbitrary merging of different types of FLUSH/FUA
|
* step. This allows arbitrary merging of different types of PREFLUSH/FUA
|
||||||
* requests.
|
* requests.
|
||||||
*
|
*
|
||||||
* Currently, the following conditions are used to determine when to issue
|
* Currently, the following conditions are used to determine when to issue
|
||||||
|
@ -47,19 +47,19 @@
|
||||||
* C3. The second condition is ignored if there is a request which has
|
* C3. The second condition is ignored if there is a request which has
|
||||||
* waited longer than FLUSH_PENDING_TIMEOUT. This is to avoid
|
* waited longer than FLUSH_PENDING_TIMEOUT. This is to avoid
|
||||||
* starvation in the unlikely case where there are continuous stream of
|
* starvation in the unlikely case where there are continuous stream of
|
||||||
* FUA (without FLUSH) requests.
|
* FUA (without PREFLUSH) requests.
|
||||||
*
|
*
|
||||||
* For devices which support FUA, it isn't clear whether C2 (and thus C3)
|
* For devices which support FUA, it isn't clear whether C2 (and thus C3)
|
||||||
* is beneficial.
|
* is beneficial.
|
||||||
*
|
*
|
||||||
* Note that a sequenced FLUSH/FUA request with DATA is completed twice.
|
* Note that a sequenced PREFLUSH/FUA request with DATA is completed twice.
|
||||||
* Once while executing DATA and again after the whole sequence is
|
* Once while executing DATA and again after the whole sequence is
|
||||||
* complete. The first completion updates the contained bio but doesn't
|
* complete. The first completion updates the contained bio but doesn't
|
||||||
* finish it so that the bio submitter is notified only after the whole
|
* finish it so that the bio submitter is notified only after the whole
|
||||||
* sequence is complete. This is implemented by testing RQF_FLUSH_SEQ in
|
* sequence is complete. This is implemented by testing RQF_FLUSH_SEQ in
|
||||||
* req_bio_endio().
|
* req_bio_endio().
|
||||||
*
|
*
|
||||||
* The above peculiarity requires that each FLUSH/FUA request has only one
|
* The above peculiarity requires that each PREFLUSH/FUA request has only one
|
||||||
* bio attached to it, which is guaranteed as they aren't allowed to be
|
* bio attached to it, which is guaranteed as they aren't allowed to be
|
||||||
* merged in the usual way.
|
* merged in the usual way.
|
||||||
*/
|
*/
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
#include "blk-mq-tag.h"
|
#include "blk-mq-tag.h"
|
||||||
#include "blk-mq-sched.h"
|
#include "blk-mq-sched.h"
|
||||||
|
|
||||||
/* FLUSH/FUA sequences */
|
/* PREFLUSH/FUA sequences */
|
||||||
enum {
|
enum {
|
||||||
REQ_FSEQ_PREFLUSH = (1 << 0), /* pre-flushing in progress */
|
REQ_FSEQ_PREFLUSH = (1 << 0), /* pre-flushing in progress */
|
||||||
REQ_FSEQ_DATA = (1 << 1), /* data write in progress */
|
REQ_FSEQ_DATA = (1 << 1), /* data write in progress */
|
||||||
|
@ -148,7 +148,7 @@ static bool blk_flush_queue_rq(struct request *rq, bool add_front)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* blk_flush_complete_seq - complete flush sequence
|
* blk_flush_complete_seq - complete flush sequence
|
||||||
* @rq: FLUSH/FUA request being sequenced
|
* @rq: PREFLUSH/FUA request being sequenced
|
||||||
* @fq: flush queue
|
* @fq: flush queue
|
||||||
* @seq: sequences to complete (mask of %REQ_FSEQ_*, can be zero)
|
* @seq: sequences to complete (mask of %REQ_FSEQ_*, can be zero)
|
||||||
* @error: whether an error occurred
|
* @error: whether an error occurred
|
||||||
|
@ -406,7 +406,7 @@ static void mq_flush_data_end_io(struct request *rq, blk_status_t error)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* blk_insert_flush - insert a new FLUSH/FUA request
|
* blk_insert_flush - insert a new PREFLUSH/FUA request
|
||||||
* @rq: request to insert
|
* @rq: request to insert
|
||||||
*
|
*
|
||||||
* To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions.
|
* To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions.
|
||||||
|
@ -525,7 +525,7 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
bio = bio_alloc(gfp_mask, 0);
|
bio = bio_alloc(gfp_mask, 0);
|
||||||
bio->bi_bdev = bdev;
|
bio_set_dev(bio, bdev);
|
||||||
bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||||
|
|
||||||
ret = submit_bio_wait(bio);
|
ret = submit_bio_wait(bio);
|
||||||
|
|
|
@ -77,7 +77,7 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
||||||
|
|
||||||
bio = next_bio(bio, 0, gfp_mask);
|
bio = next_bio(bio, 0, gfp_mask);
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = bdev;
|
bio_set_dev(bio, bdev);
|
||||||
bio_set_op_attrs(bio, op, 0);
|
bio_set_op_attrs(bio, op, 0);
|
||||||
|
|
||||||
bio->bi_iter.bi_size = req_sects << 9;
|
bio->bi_iter.bi_size = req_sects << 9;
|
||||||
|
@ -168,7 +168,7 @@ static int __blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
|
||||||
while (nr_sects) {
|
while (nr_sects) {
|
||||||
bio = next_bio(bio, 1, gfp_mask);
|
bio = next_bio(bio, 1, gfp_mask);
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = bdev;
|
bio_set_dev(bio, bdev);
|
||||||
bio->bi_vcnt = 1;
|
bio->bi_vcnt = 1;
|
||||||
bio->bi_io_vec->bv_page = page;
|
bio->bi_io_vec->bv_page = page;
|
||||||
bio->bi_io_vec->bv_offset = 0;
|
bio->bi_io_vec->bv_offset = 0;
|
||||||
|
@ -241,7 +241,7 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
|
||||||
while (nr_sects) {
|
while (nr_sects) {
|
||||||
bio = next_bio(bio, 0, gfp_mask);
|
bio = next_bio(bio, 0, gfp_mask);
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = bdev;
|
bio_set_dev(bio, bdev);
|
||||||
bio->bi_opf = REQ_OP_WRITE_ZEROES;
|
bio->bi_opf = REQ_OP_WRITE_ZEROES;
|
||||||
if (flags & BLKDEV_ZERO_NOUNMAP)
|
if (flags & BLKDEV_ZERO_NOUNMAP)
|
||||||
bio->bi_opf |= REQ_NOUNMAP;
|
bio->bi_opf |= REQ_NOUNMAP;
|
||||||
|
@ -323,7 +323,7 @@ int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
|
||||||
bio = next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects),
|
bio = next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects),
|
||||||
gfp_mask);
|
gfp_mask);
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = bdev;
|
bio_set_dev(bio, bdev);
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||||
|
|
||||||
while (nr_sects != 0) {
|
while (nr_sects != 0) {
|
||||||
|
|
|
@ -633,8 +633,8 @@ static void blk_account_io_merge(struct request *req)
|
||||||
cpu = part_stat_lock();
|
cpu = part_stat_lock();
|
||||||
part = req->part;
|
part = req->part;
|
||||||
|
|
||||||
part_round_stats(cpu, part);
|
part_round_stats(req->q, cpu, part);
|
||||||
part_dec_in_flight(part, rq_data_dir(req));
|
part_dec_in_flight(req->q, part, rq_data_dir(req));
|
||||||
|
|
||||||
hd_struct_put(part);
|
hd_struct_put(part);
|
||||||
part_stat_unlock();
|
part_stat_unlock();
|
||||||
|
@ -786,7 +786,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* must be same device and not a special request */
|
/* must be same device and not a special request */
|
||||||
if (rq->rq_disk != bio->bi_bdev->bd_disk || req_no_special_merge(rq))
|
if (rq->rq_disk != bio->bi_disk || req_no_special_merge(rq))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* only merge integrity protected bio into ditto rq */
|
/* only merge integrity protected bio into ditto rq */
|
||||||
|
|
|
@ -48,8 +48,6 @@ static int blk_flags_show(struct seq_file *m, const unsigned long flags,
|
||||||
static const char *const blk_queue_flag_name[] = {
|
static const char *const blk_queue_flag_name[] = {
|
||||||
QUEUE_FLAG_NAME(QUEUED),
|
QUEUE_FLAG_NAME(QUEUED),
|
||||||
QUEUE_FLAG_NAME(STOPPED),
|
QUEUE_FLAG_NAME(STOPPED),
|
||||||
QUEUE_FLAG_NAME(SYNCFULL),
|
|
||||||
QUEUE_FLAG_NAME(ASYNCFULL),
|
|
||||||
QUEUE_FLAG_NAME(DYING),
|
QUEUE_FLAG_NAME(DYING),
|
||||||
QUEUE_FLAG_NAME(BYPASS),
|
QUEUE_FLAG_NAME(BYPASS),
|
||||||
QUEUE_FLAG_NAME(BIDI),
|
QUEUE_FLAG_NAME(BIDI),
|
||||||
|
@ -744,7 +742,7 @@ static int blk_mq_debugfs_release(struct inode *inode, struct file *file)
|
||||||
return seq_release(inode, file);
|
return seq_release(inode, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct file_operations blk_mq_debugfs_fops = {
|
static const struct file_operations blk_mq_debugfs_fops = {
|
||||||
.open = blk_mq_debugfs_open,
|
.open = blk_mq_debugfs_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.write = blk_mq_debugfs_write,
|
.write = blk_mq_debugfs_write,
|
||||||
|
|
|
@ -214,7 +214,11 @@ static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
|
||||||
bitnr += tags->nr_reserved_tags;
|
bitnr += tags->nr_reserved_tags;
|
||||||
rq = tags->rqs[bitnr];
|
rq = tags->rqs[bitnr];
|
||||||
|
|
||||||
if (rq->q == hctx->queue)
|
/*
|
||||||
|
* We can hit rq == NULL here, because the tagging functions
|
||||||
|
* test and set the bit before assining ->rqs[].
|
||||||
|
*/
|
||||||
|
if (rq && rq->q == hctx->queue)
|
||||||
iter_data->fn(hctx, rq, iter_data->data, reserved);
|
iter_data->fn(hctx, rq, iter_data->data, reserved);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -248,9 +252,15 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
|
||||||
|
|
||||||
if (!reserved)
|
if (!reserved)
|
||||||
bitnr += tags->nr_reserved_tags;
|
bitnr += tags->nr_reserved_tags;
|
||||||
rq = tags->rqs[bitnr];
|
|
||||||
|
|
||||||
iter_data->fn(rq, iter_data->data, reserved);
|
/*
|
||||||
|
* We can hit rq == NULL here, because the tagging functions
|
||||||
|
* test and set the bit before assining ->rqs[].
|
||||||
|
*/
|
||||||
|
rq = tags->rqs[bitnr];
|
||||||
|
if (rq)
|
||||||
|
iter_data->fn(rq, iter_data->data, reserved);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,11 +298,12 @@ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blk_mq_tagset_busy_iter);
|
EXPORT_SYMBOL(blk_mq_tagset_busy_iter);
|
||||||
|
|
||||||
int blk_mq_reinit_tagset(struct blk_mq_tag_set *set)
|
int blk_mq_reinit_tagset(struct blk_mq_tag_set *set,
|
||||||
|
int (reinit_request)(void *, struct request *))
|
||||||
{
|
{
|
||||||
int i, j, ret = 0;
|
int i, j, ret = 0;
|
||||||
|
|
||||||
if (!set->ops->reinit_request)
|
if (WARN_ON_ONCE(!reinit_request))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for (i = 0; i < set->nr_hw_queues; i++) {
|
for (i = 0; i < set->nr_hw_queues; i++) {
|
||||||
|
@ -305,8 +316,8 @@ int blk_mq_reinit_tagset(struct blk_mq_tag_set *set)
|
||||||
if (!tags->static_rqs[j])
|
if (!tags->static_rqs[j])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = set->ops->reinit_request(set->driver_data,
|
ret = reinit_request(set->driver_data,
|
||||||
tags->static_rqs[j]);
|
tags->static_rqs[j]);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,41 @@ static void blk_mq_hctx_clear_pending(struct blk_mq_hw_ctx *hctx,
|
||||||
sbitmap_clear_bit(&hctx->ctx_map, ctx->index_hw);
|
sbitmap_clear_bit(&hctx->ctx_map, ctx->index_hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mq_inflight {
|
||||||
|
struct hd_struct *part;
|
||||||
|
unsigned int *inflight;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void blk_mq_check_inflight(struct blk_mq_hw_ctx *hctx,
|
||||||
|
struct request *rq, void *priv,
|
||||||
|
bool reserved)
|
||||||
|
{
|
||||||
|
struct mq_inflight *mi = priv;
|
||||||
|
|
||||||
|
if (test_bit(REQ_ATOM_STARTED, &rq->atomic_flags) &&
|
||||||
|
!test_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags)) {
|
||||||
|
/*
|
||||||
|
* index[0] counts the specific partition that was asked
|
||||||
|
* for. index[1] counts the ones that are active on the
|
||||||
|
* whole device, so increment that if mi->part is indeed
|
||||||
|
* a partition, and not a whole device.
|
||||||
|
*/
|
||||||
|
if (rq->part == mi->part)
|
||||||
|
mi->inflight[0]++;
|
||||||
|
if (mi->part->partno)
|
||||||
|
mi->inflight[1]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
|
||||||
|
unsigned int inflight[2])
|
||||||
|
{
|
||||||
|
struct mq_inflight mi = { .part = part, .inflight = inflight, };
|
||||||
|
|
||||||
|
inflight[0] = inflight[1] = 0;
|
||||||
|
blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi);
|
||||||
|
}
|
||||||
|
|
||||||
void blk_freeze_queue_start(struct request_queue *q)
|
void blk_freeze_queue_start(struct request_queue *q)
|
||||||
{
|
{
|
||||||
int freeze_depth;
|
int freeze_depth;
|
||||||
|
@ -624,11 +659,10 @@ static void blk_mq_requeue_work(struct work_struct *work)
|
||||||
container_of(work, struct request_queue, requeue_work.work);
|
container_of(work, struct request_queue, requeue_work.work);
|
||||||
LIST_HEAD(rq_list);
|
LIST_HEAD(rq_list);
|
||||||
struct request *rq, *next;
|
struct request *rq, *next;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&q->requeue_lock, flags);
|
spin_lock_irq(&q->requeue_lock);
|
||||||
list_splice_init(&q->requeue_list, &rq_list);
|
list_splice_init(&q->requeue_list, &rq_list);
|
||||||
spin_unlock_irqrestore(&q->requeue_lock, flags);
|
spin_unlock_irq(&q->requeue_lock);
|
||||||
|
|
||||||
list_for_each_entry_safe(rq, next, &rq_list, queuelist) {
|
list_for_each_entry_safe(rq, next, &rq_list, queuelist) {
|
||||||
if (!(rq->rq_flags & RQF_SOFTBARRIER))
|
if (!(rq->rq_flags & RQF_SOFTBARRIER))
|
||||||
|
@ -1102,9 +1136,19 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
|
||||||
{
|
{
|
||||||
int srcu_idx;
|
int srcu_idx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We should be running this queue from one of the CPUs that
|
||||||
|
* are mapped to it.
|
||||||
|
*/
|
||||||
WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) &&
|
WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) &&
|
||||||
cpu_online(hctx->next_cpu));
|
cpu_online(hctx->next_cpu));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can't run the queue inline with ints disabled. Ensure that
|
||||||
|
* we catch bad users of this early.
|
||||||
|
*/
|
||||||
|
WARN_ON_ONCE(in_interrupt());
|
||||||
|
|
||||||
if (!(hctx->flags & BLK_MQ_F_BLOCKING)) {
|
if (!(hctx->flags & BLK_MQ_F_BLOCKING)) {
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
blk_mq_sched_dispatch_requests(hctx);
|
blk_mq_sched_dispatch_requests(hctx);
|
||||||
|
@ -1218,7 +1262,7 @@ EXPORT_SYMBOL(blk_mq_queue_stopped);
|
||||||
/*
|
/*
|
||||||
* This function is often used for pausing .queue_rq() by driver when
|
* This function is often used for pausing .queue_rq() by driver when
|
||||||
* there isn't enough resource or some conditions aren't satisfied, and
|
* there isn't enough resource or some conditions aren't satisfied, and
|
||||||
* BLK_MQ_RQ_QUEUE_BUSY is usually returned.
|
* BLK_STS_RESOURCE is usually returned.
|
||||||
*
|
*
|
||||||
* We do not guarantee that dispatch can be drained or blocked
|
* We do not guarantee that dispatch can be drained or blocked
|
||||||
* after blk_mq_stop_hw_queue() returns. Please use
|
* after blk_mq_stop_hw_queue() returns. Please use
|
||||||
|
@ -1235,7 +1279,7 @@ EXPORT_SYMBOL(blk_mq_stop_hw_queue);
|
||||||
/*
|
/*
|
||||||
* This function is often used for pausing .queue_rq() by driver when
|
* This function is often used for pausing .queue_rq() by driver when
|
||||||
* there isn't enough resource or some conditions aren't satisfied, and
|
* there isn't enough resource or some conditions aren't satisfied, and
|
||||||
* BLK_MQ_RQ_QUEUE_BUSY is usually returned.
|
* BLK_STS_RESOURCE is usually returned.
|
||||||
*
|
*
|
||||||
* We do not guarantee that dispatch can be drained or blocked
|
* We do not guarantee that dispatch can be drained or blocked
|
||||||
* after blk_mq_stop_hw_queues() returns. Please use
|
* after blk_mq_stop_hw_queues() returns. Please use
|
||||||
|
|
|
@ -133,4 +133,7 @@ static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx)
|
||||||
return hctx->nr_ctx && hctx->tags;
|
return hctx->nr_ctx && hctx->tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
|
||||||
|
unsigned int inflight[2]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -68,6 +68,7 @@ EXPORT_SYMBOL_GPL(blk_queue_rq_timeout);
|
||||||
|
|
||||||
void blk_queue_rq_timed_out(struct request_queue *q, rq_timed_out_fn *fn)
|
void blk_queue_rq_timed_out(struct request_queue *q, rq_timed_out_fn *fn)
|
||||||
{
|
{
|
||||||
|
WARN_ON_ONCE(q->mq_ops);
|
||||||
q->rq_timed_out_fn = fn;
|
q->rq_timed_out_fn = fn;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(blk_queue_rq_timed_out);
|
EXPORT_SYMBOL_GPL(blk_queue_rq_timed_out);
|
||||||
|
|
|
@ -931,7 +931,9 @@ void blk_unregister_queue(struct gendisk *disk)
|
||||||
if (WARN_ON(!q))
|
if (WARN_ON(!q))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mutex_lock(&q->sysfs_lock);
|
||||||
queue_flag_clear_unlocked(QUEUE_FLAG_REGISTERED, q);
|
queue_flag_clear_unlocked(QUEUE_FLAG_REGISTERED, q);
|
||||||
|
mutex_unlock(&q->sysfs_lock);
|
||||||
|
|
||||||
wbt_exit(q);
|
wbt_exit(q);
|
||||||
|
|
||||||
|
|
|
@ -290,7 +290,6 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
|
||||||
*/
|
*/
|
||||||
clear_bit_unlock(tag, bqt->tag_map);
|
clear_bit_unlock(tag, bqt->tag_map);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blk_queue_end_tag);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* blk_queue_start_tag - find a free tag and assign it
|
* blk_queue_start_tag - find a free tag and assign it
|
||||||
|
|
|
@ -373,10 +373,8 @@ static unsigned int tg_iops_limit(struct throtl_grp *tg, int rw)
|
||||||
if (likely(!blk_trace_note_message_enabled(__td->queue))) \
|
if (likely(!blk_trace_note_message_enabled(__td->queue))) \
|
||||||
break; \
|
break; \
|
||||||
if ((__tg)) { \
|
if ((__tg)) { \
|
||||||
char __pbuf[128]; \
|
blk_add_cgroup_trace_msg(__td->queue, \
|
||||||
\
|
tg_to_blkg(__tg)->blkcg, "throtl " fmt, ##args);\
|
||||||
blkg_path(tg_to_blkg(__tg), __pbuf, sizeof(__pbuf)); \
|
|
||||||
blk_add_trace_msg(__td->queue, "throtl %s " fmt, __pbuf, ##args); \
|
|
||||||
} else { \
|
} else { \
|
||||||
blk_add_trace_msg(__td->queue, "throtl " fmt, ##args); \
|
blk_add_trace_msg(__td->queue, "throtl " fmt, ##args); \
|
||||||
} \
|
} \
|
||||||
|
@ -2114,14 +2112,9 @@ static inline void throtl_update_latency_buckets(struct throtl_data *td)
|
||||||
static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio)
|
static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BLK_DEV_THROTTLING_LOW
|
#ifdef CONFIG_BLK_DEV_THROTTLING_LOW
|
||||||
int ret;
|
if (bio->bi_css)
|
||||||
|
|
||||||
ret = bio_associate_current(bio);
|
|
||||||
if (ret == 0 || ret == -EBUSY)
|
|
||||||
bio->bi_cg_private = tg;
|
bio->bi_cg_private = tg;
|
||||||
blk_stat_set_issue(&bio->bi_issue_stat, bio_sectors(bio));
|
blk_stat_set_issue(&bio->bi_issue_stat, bio_sectors(bio));
|
||||||
#else
|
|
||||||
bio_associate_current(bio);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ int blkdev_report_zones(struct block_device *bdev,
|
||||||
if (!bio)
|
if (!bio)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
bio->bi_bdev = bdev;
|
bio_set_dev(bio, bdev);
|
||||||
bio->bi_iter.bi_sector = blk_zone_start(q, sector);
|
bio->bi_iter.bi_sector = blk_zone_start(q, sector);
|
||||||
bio_set_op_attrs(bio, REQ_OP_ZONE_REPORT, 0);
|
bio_set_op_attrs(bio, REQ_OP_ZONE_REPORT, 0);
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ int blkdev_reset_zones(struct block_device *bdev,
|
||||||
|
|
||||||
bio = bio_alloc(gfp_mask, 0);
|
bio = bio_alloc(gfp_mask, 0);
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = bdev;
|
bio_set_dev(bio, bdev);
|
||||||
bio_set_op_attrs(bio, REQ_OP_ZONE_RESET, 0);
|
bio_set_op_attrs(bio, REQ_OP_ZONE_RESET, 0);
|
||||||
|
|
||||||
ret = submit_bio_wait(bio);
|
ret = submit_bio_wait(bio);
|
||||||
|
|
|
@ -64,7 +64,6 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
|
||||||
struct bio *bio);
|
struct bio *bio);
|
||||||
void blk_queue_bypass_start(struct request_queue *q);
|
void blk_queue_bypass_start(struct request_queue *q);
|
||||||
void blk_queue_bypass_end(struct request_queue *q);
|
void blk_queue_bypass_end(struct request_queue *q);
|
||||||
void blk_dequeue_request(struct request *rq);
|
|
||||||
void __blk_queue_free_tags(struct request_queue *q);
|
void __blk_queue_free_tags(struct request_queue *q);
|
||||||
void blk_freeze_queue(struct request_queue *q);
|
void blk_freeze_queue(struct request_queue *q);
|
||||||
|
|
||||||
|
@ -204,6 +203,8 @@ static inline void elv_deactivate_rq(struct request_queue *q, struct request *rq
|
||||||
e->type->ops.sq.elevator_deactivate_req_fn(q, rq);
|
e->type->ops.sq.elevator_deactivate_req_fn(q, rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct hd_struct *__disk_get_part(struct gendisk *disk, int partno);
|
||||||
|
|
||||||
#ifdef CONFIG_FAIL_IO_TIMEOUT
|
#ifdef CONFIG_FAIL_IO_TIMEOUT
|
||||||
int blk_should_fake_timeout(struct request_queue *);
|
int blk_should_fake_timeout(struct request_queue *);
|
||||||
ssize_t part_timeout_show(struct device *, struct device_attribute *, char *);
|
ssize_t part_timeout_show(struct device *, struct device_attribute *, char *);
|
||||||
|
|
|
@ -932,15 +932,8 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* block device ioctls
|
|
||||||
*/
|
|
||||||
default:
|
default:
|
||||||
#if 0
|
|
||||||
return ioctl_by_bdev(bd->bdev, cmd, arg);
|
|
||||||
#else
|
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -656,20 +656,17 @@ static inline void cfqg_put(struct cfq_group *cfqg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) do { \
|
#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) do { \
|
||||||
char __pbuf[128]; \
|
blk_add_cgroup_trace_msg((cfqd)->queue, \
|
||||||
\
|
cfqg_to_blkg((cfqq)->cfqg)->blkcg, \
|
||||||
blkg_path(cfqg_to_blkg((cfqq)->cfqg), __pbuf, sizeof(__pbuf)); \
|
"cfq%d%c%c " fmt, (cfqq)->pid, \
|
||||||
blk_add_trace_msg((cfqd)->queue, "cfq%d%c%c %s " fmt, (cfqq)->pid, \
|
|
||||||
cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \
|
cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \
|
||||||
cfqq_type((cfqq)) == SYNC_NOIDLE_WORKLOAD ? 'N' : ' ',\
|
cfqq_type((cfqq)) == SYNC_NOIDLE_WORKLOAD ? 'N' : ' ',\
|
||||||
__pbuf, ##args); \
|
##args); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define cfq_log_cfqg(cfqd, cfqg, fmt, args...) do { \
|
#define cfq_log_cfqg(cfqd, cfqg, fmt, args...) do { \
|
||||||
char __pbuf[128]; \
|
blk_add_cgroup_trace_msg((cfqd)->queue, \
|
||||||
\
|
cfqg_to_blkg(cfqg)->blkcg, fmt, ##args); \
|
||||||
blkg_path(cfqg_to_blkg(cfqg), __pbuf, sizeof(__pbuf)); \
|
|
||||||
blk_add_trace_msg((cfqd)->queue, "%s " fmt, __pbuf, ##args); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static inline void cfqg_stats_update_io_add(struct cfq_group *cfqg,
|
static inline void cfqg_stats_update_io_add(struct cfq_group *cfqg,
|
||||||
|
@ -2937,7 +2934,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
|
||||||
* for devices that support queuing, otherwise we still have a problem
|
* for devices that support queuing, otherwise we still have a problem
|
||||||
* with sync vs async workloads.
|
* with sync vs async workloads.
|
||||||
*/
|
*/
|
||||||
if (blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag)
|
if (blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag &&
|
||||||
|
!cfqd->cfq_group_idle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WARN_ON(!RB_EMPTY_ROOT(&cfqq->sort_list));
|
WARN_ON(!RB_EMPTY_ROOT(&cfqq->sort_list));
|
||||||
|
@ -4714,13 +4712,12 @@ cfq_var_show(unsigned int var, char *page)
|
||||||
return sprintf(page, "%u\n", var);
|
return sprintf(page, "%u\n", var);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static void
|
||||||
cfq_var_store(unsigned int *var, const char *page, size_t count)
|
cfq_var_store(unsigned int *var, const char *page)
|
||||||
{
|
{
|
||||||
char *p = (char *) page;
|
char *p = (char *) page;
|
||||||
|
|
||||||
*var = simple_strtoul(p, &p, 10);
|
*var = simple_strtoul(p, &p, 10);
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
||||||
|
@ -4766,7 +4763,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
|
||||||
{ \
|
{ \
|
||||||
struct cfq_data *cfqd = e->elevator_data; \
|
struct cfq_data *cfqd = e->elevator_data; \
|
||||||
unsigned int __data; \
|
unsigned int __data; \
|
||||||
int ret = cfq_var_store(&__data, (page), count); \
|
cfq_var_store(&__data, (page)); \
|
||||||
if (__data < (MIN)) \
|
if (__data < (MIN)) \
|
||||||
__data = (MIN); \
|
__data = (MIN); \
|
||||||
else if (__data > (MAX)) \
|
else if (__data > (MAX)) \
|
||||||
|
@ -4775,7 +4772,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
|
||||||
*(__PTR) = (u64)__data * NSEC_PER_MSEC; \
|
*(__PTR) = (u64)__data * NSEC_PER_MSEC; \
|
||||||
else \
|
else \
|
||||||
*(__PTR) = __data; \
|
*(__PTR) = __data; \
|
||||||
return ret; \
|
return count; \
|
||||||
}
|
}
|
||||||
STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0);
|
STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0);
|
||||||
STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1,
|
STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1,
|
||||||
|
@ -4800,13 +4797,13 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
|
||||||
{ \
|
{ \
|
||||||
struct cfq_data *cfqd = e->elevator_data; \
|
struct cfq_data *cfqd = e->elevator_data; \
|
||||||
unsigned int __data; \
|
unsigned int __data; \
|
||||||
int ret = cfq_var_store(&__data, (page), count); \
|
cfq_var_store(&__data, (page)); \
|
||||||
if (__data < (MIN)) \
|
if (__data < (MIN)) \
|
||||||
__data = (MIN); \
|
__data = (MIN); \
|
||||||
else if (__data > (MAX)) \
|
else if (__data > (MAX)) \
|
||||||
__data = (MAX); \
|
__data = (MAX); \
|
||||||
*(__PTR) = (u64)__data * NSEC_PER_USEC; \
|
*(__PTR) = (u64)__data * NSEC_PER_USEC; \
|
||||||
return ret; \
|
return count; \
|
||||||
}
|
}
|
||||||
USEC_STORE_FUNCTION(cfq_slice_idle_us_store, &cfqd->cfq_slice_idle, 0, UINT_MAX);
|
USEC_STORE_FUNCTION(cfq_slice_idle_us_store, &cfqd->cfq_slice_idle, 0, UINT_MAX);
|
||||||
USEC_STORE_FUNCTION(cfq_group_idle_us_store, &cfqd->cfq_group_idle, 0, UINT_MAX);
|
USEC_STORE_FUNCTION(cfq_group_idle_us_store, &cfqd->cfq_group_idle, 0, UINT_MAX);
|
||||||
|
|
|
@ -373,13 +373,12 @@ deadline_var_show(int var, char *page)
|
||||||
return sprintf(page, "%d\n", var);
|
return sprintf(page, "%d\n", var);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static void
|
||||||
deadline_var_store(int *var, const char *page, size_t count)
|
deadline_var_store(int *var, const char *page)
|
||||||
{
|
{
|
||||||
char *p = (char *) page;
|
char *p = (char *) page;
|
||||||
|
|
||||||
*var = simple_strtol(p, &p, 10);
|
*var = simple_strtol(p, &p, 10);
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
||||||
|
@ -403,7 +402,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
|
||||||
{ \
|
{ \
|
||||||
struct deadline_data *dd = e->elevator_data; \
|
struct deadline_data *dd = e->elevator_data; \
|
||||||
int __data; \
|
int __data; \
|
||||||
int ret = deadline_var_store(&__data, (page), count); \
|
deadline_var_store(&__data, (page)); \
|
||||||
if (__data < (MIN)) \
|
if (__data < (MIN)) \
|
||||||
__data = (MIN); \
|
__data = (MIN); \
|
||||||
else if (__data > (MAX)) \
|
else if (__data > (MAX)) \
|
||||||
|
@ -412,7 +411,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
|
||||||
*(__PTR) = msecs_to_jiffies(__data); \
|
*(__PTR) = msecs_to_jiffies(__data); \
|
||||||
else \
|
else \
|
||||||
*(__PTR) = __data; \
|
*(__PTR) = __data; \
|
||||||
return ret; \
|
return count; \
|
||||||
}
|
}
|
||||||
STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
|
STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
|
||||||
STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);
|
STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);
|
||||||
|
|
|
@ -1055,6 +1055,10 @@ static int __elevator_change(struct request_queue *q, const char *name)
|
||||||
char elevator_name[ELV_NAME_MAX];
|
char elevator_name[ELV_NAME_MAX];
|
||||||
struct elevator_type *e;
|
struct elevator_type *e;
|
||||||
|
|
||||||
|
/* Make sure queue is not in the middle of being removed */
|
||||||
|
if (!test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case for mq, turn off scheduling
|
* Special case for mq, turn off scheduling
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -45,6 +45,52 @@ static void disk_add_events(struct gendisk *disk);
|
||||||
static void disk_del_events(struct gendisk *disk);
|
static void disk_del_events(struct gendisk *disk);
|
||||||
static void disk_release_events(struct gendisk *disk);
|
static void disk_release_events(struct gendisk *disk);
|
||||||
|
|
||||||
|
void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
|
||||||
|
{
|
||||||
|
if (q->mq_ops)
|
||||||
|
return;
|
||||||
|
|
||||||
|
atomic_inc(&part->in_flight[rw]);
|
||||||
|
if (part->partno)
|
||||||
|
atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
|
||||||
|
{
|
||||||
|
if (q->mq_ops)
|
||||||
|
return;
|
||||||
|
|
||||||
|
atomic_dec(&part->in_flight[rw]);
|
||||||
|
if (part->partno)
|
||||||
|
atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void part_in_flight(struct request_queue *q, struct hd_struct *part,
|
||||||
|
unsigned int inflight[2])
|
||||||
|
{
|
||||||
|
if (q->mq_ops) {
|
||||||
|
blk_mq_in_flight(q, part, inflight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
inflight[0] = atomic_read(&part->in_flight[0]) +
|
||||||
|
atomic_read(&part->in_flight[1]);
|
||||||
|
if (part->partno) {
|
||||||
|
part = &part_to_disk(part)->part0;
|
||||||
|
inflight[1] = atomic_read(&part->in_flight[0]) +
|
||||||
|
atomic_read(&part->in_flight[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hd_struct *__disk_get_part(struct gendisk *disk, int partno)
|
||||||
|
{
|
||||||
|
struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl);
|
||||||
|
|
||||||
|
if (unlikely(partno < 0 || partno >= ptbl->len))
|
||||||
|
return NULL;
|
||||||
|
return rcu_dereference(ptbl->part[partno]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* disk_get_part - get partition
|
* disk_get_part - get partition
|
||||||
* @disk: disk to look partition from
|
* @disk: disk to look partition from
|
||||||
|
@ -61,21 +107,12 @@ static void disk_release_events(struct gendisk *disk);
|
||||||
*/
|
*/
|
||||||
struct hd_struct *disk_get_part(struct gendisk *disk, int partno)
|
struct hd_struct *disk_get_part(struct gendisk *disk, int partno)
|
||||||
{
|
{
|
||||||
struct hd_struct *part = NULL;
|
struct hd_struct *part;
|
||||||
struct disk_part_tbl *ptbl;
|
|
||||||
|
|
||||||
if (unlikely(partno < 0))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
part = __disk_get_part(disk, partno);
|
||||||
ptbl = rcu_dereference(disk->part_tbl);
|
if (part)
|
||||||
if (likely(partno < ptbl->len)) {
|
get_device(part_to_dev(part));
|
||||||
part = rcu_dereference(ptbl->part[partno]);
|
|
||||||
if (part)
|
|
||||||
get_device(part_to_dev(part));
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
return part;
|
return part;
|
||||||
|
@ -1098,12 +1135,13 @@ static const struct attribute_group *disk_attr_groups[] = {
|
||||||
* original ptbl is freed using RCU callback.
|
* original ptbl is freed using RCU callback.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Matching bd_mutx locked.
|
* Matching bd_mutex locked or the caller is the only user of @disk.
|
||||||
*/
|
*/
|
||||||
static void disk_replace_part_tbl(struct gendisk *disk,
|
static void disk_replace_part_tbl(struct gendisk *disk,
|
||||||
struct disk_part_tbl *new_ptbl)
|
struct disk_part_tbl *new_ptbl)
|
||||||
{
|
{
|
||||||
struct disk_part_tbl *old_ptbl = disk->part_tbl;
|
struct disk_part_tbl *old_ptbl =
|
||||||
|
rcu_dereference_protected(disk->part_tbl, 1);
|
||||||
|
|
||||||
rcu_assign_pointer(disk->part_tbl, new_ptbl);
|
rcu_assign_pointer(disk->part_tbl, new_ptbl);
|
||||||
|
|
||||||
|
@ -1122,14 +1160,16 @@ static void disk_replace_part_tbl(struct gendisk *disk,
|
||||||
* uses RCU to allow unlocked dereferencing for stats and other stuff.
|
* uses RCU to allow unlocked dereferencing for stats and other stuff.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Matching bd_mutex locked, might sleep.
|
* Matching bd_mutex locked or the caller is the only user of @disk.
|
||||||
|
* Might sleep.
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* 0 on success, -errno on failure.
|
* 0 on success, -errno on failure.
|
||||||
*/
|
*/
|
||||||
int disk_expand_part_tbl(struct gendisk *disk, int partno)
|
int disk_expand_part_tbl(struct gendisk *disk, int partno)
|
||||||
{
|
{
|
||||||
struct disk_part_tbl *old_ptbl = disk->part_tbl;
|
struct disk_part_tbl *old_ptbl =
|
||||||
|
rcu_dereference_protected(disk->part_tbl, 1);
|
||||||
struct disk_part_tbl *new_ptbl;
|
struct disk_part_tbl *new_ptbl;
|
||||||
int len = old_ptbl ? old_ptbl->len : 0;
|
int len = old_ptbl ? old_ptbl->len : 0;
|
||||||
int i, target;
|
int i, target;
|
||||||
|
@ -1212,6 +1252,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
|
||||||
struct disk_part_iter piter;
|
struct disk_part_iter piter;
|
||||||
struct hd_struct *hd;
|
struct hd_struct *hd;
|
||||||
char buf[BDEVNAME_SIZE];
|
char buf[BDEVNAME_SIZE];
|
||||||
|
unsigned int inflight[2];
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1225,8 +1266,9 @@ static int diskstats_show(struct seq_file *seqf, void *v)
|
||||||
disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0);
|
disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0);
|
||||||
while ((hd = disk_part_iter_next(&piter))) {
|
while ((hd = disk_part_iter_next(&piter))) {
|
||||||
cpu = part_stat_lock();
|
cpu = part_stat_lock();
|
||||||
part_round_stats(cpu, hd);
|
part_round_stats(gp->queue, cpu, hd);
|
||||||
part_stat_unlock();
|
part_stat_unlock();
|
||||||
|
part_in_flight(gp->queue, hd, inflight);
|
||||||
seq_printf(seqf, "%4d %7d %s %lu %lu %lu "
|
seq_printf(seqf, "%4d %7d %s %lu %lu %lu "
|
||||||
"%u %lu %lu %lu %u %u %u %u\n",
|
"%u %lu %lu %lu %u %u %u %u\n",
|
||||||
MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
|
MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
|
||||||
|
@ -1239,7 +1281,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
|
||||||
part_stat_read(hd, merges[WRITE]),
|
part_stat_read(hd, merges[WRITE]),
|
||||||
part_stat_read(hd, sectors[WRITE]),
|
part_stat_read(hd, sectors[WRITE]),
|
||||||
jiffies_to_msecs(part_stat_read(hd, ticks[WRITE])),
|
jiffies_to_msecs(part_stat_read(hd, ticks[WRITE])),
|
||||||
part_in_flight(hd),
|
inflight[0],
|
||||||
jiffies_to_msecs(part_stat_read(hd, io_ticks)),
|
jiffies_to_msecs(part_stat_read(hd, io_ticks)),
|
||||||
jiffies_to_msecs(part_stat_read(hd, time_in_queue))
|
jiffies_to_msecs(part_stat_read(hd, time_in_queue))
|
||||||
);
|
);
|
||||||
|
@ -1321,6 +1363,14 @@ EXPORT_SYMBOL(alloc_disk);
|
||||||
struct gendisk *alloc_disk_node(int minors, int node_id)
|
struct gendisk *alloc_disk_node(int minors, int node_id)
|
||||||
{
|
{
|
||||||
struct gendisk *disk;
|
struct gendisk *disk;
|
||||||
|
struct disk_part_tbl *ptbl;
|
||||||
|
|
||||||
|
if (minors > DISK_MAX_PARTS) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"block: can't allocated more than %d partitions\n",
|
||||||
|
DISK_MAX_PARTS);
|
||||||
|
minors = DISK_MAX_PARTS;
|
||||||
|
}
|
||||||
|
|
||||||
disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
|
disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
|
||||||
if (disk) {
|
if (disk) {
|
||||||
|
@ -1334,7 +1384,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
|
||||||
kfree(disk);
|
kfree(disk);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
disk->part_tbl->part[0] = &disk->part0;
|
ptbl = rcu_dereference_protected(disk->part_tbl, 1);
|
||||||
|
rcu_assign_pointer(ptbl->part[0], &disk->part0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_capacity() and get_capacity() currently don't use
|
* set_capacity() and get_capacity() currently don't use
|
||||||
|
|
|
@ -457,13 +457,12 @@ deadline_var_show(int var, char *page)
|
||||||
return sprintf(page, "%d\n", var);
|
return sprintf(page, "%d\n", var);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static void
|
||||||
deadline_var_store(int *var, const char *page, size_t count)
|
deadline_var_store(int *var, const char *page)
|
||||||
{
|
{
|
||||||
char *p = (char *) page;
|
char *p = (char *) page;
|
||||||
|
|
||||||
*var = simple_strtol(p, &p, 10);
|
*var = simple_strtol(p, &p, 10);
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
|
||||||
|
@ -487,7 +486,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
|
||||||
{ \
|
{ \
|
||||||
struct deadline_data *dd = e->elevator_data; \
|
struct deadline_data *dd = e->elevator_data; \
|
||||||
int __data; \
|
int __data; \
|
||||||
int ret = deadline_var_store(&__data, (page), count); \
|
deadline_var_store(&__data, (page)); \
|
||||||
if (__data < (MIN)) \
|
if (__data < (MIN)) \
|
||||||
__data = (MIN); \
|
__data = (MIN); \
|
||||||
else if (__data > (MAX)) \
|
else if (__data > (MAX)) \
|
||||||
|
@ -496,7 +495,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
|
||||||
*(__PTR) = msecs_to_jiffies(__data); \
|
*(__PTR) = msecs_to_jiffies(__data); \
|
||||||
else \
|
else \
|
||||||
*(__PTR) = __data; \
|
*(__PTR) = __data; \
|
||||||
return ret; \
|
return count; \
|
||||||
}
|
}
|
||||||
STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
|
STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
|
||||||
STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);
|
STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);
|
||||||
|
@ -660,6 +659,7 @@ static struct elevator_type mq_deadline = {
|
||||||
.elevator_name = "mq-deadline",
|
.elevator_name = "mq-deadline",
|
||||||
.elevator_owner = THIS_MODULE,
|
.elevator_owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
MODULE_ALIAS("mq-deadline-iosched");
|
||||||
|
|
||||||
static int __init deadline_init(void)
|
static int __init deadline_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -112,11 +112,14 @@ ssize_t part_stat_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct hd_struct *p = dev_to_part(dev);
|
struct hd_struct *p = dev_to_part(dev);
|
||||||
|
struct request_queue *q = dev_to_disk(dev)->queue;
|
||||||
|
unsigned int inflight[2];
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
cpu = part_stat_lock();
|
cpu = part_stat_lock();
|
||||||
part_round_stats(cpu, p);
|
part_round_stats(q, cpu, p);
|
||||||
part_stat_unlock();
|
part_stat_unlock();
|
||||||
|
part_in_flight(q, p, inflight);
|
||||||
return sprintf(buf,
|
return sprintf(buf,
|
||||||
"%8lu %8lu %8llu %8u "
|
"%8lu %8lu %8llu %8u "
|
||||||
"%8lu %8lu %8llu %8u "
|
"%8lu %8lu %8llu %8u "
|
||||||
|
@ -130,7 +133,7 @@ ssize_t part_stat_show(struct device *dev,
|
||||||
part_stat_read(p, merges[WRITE]),
|
part_stat_read(p, merges[WRITE]),
|
||||||
(unsigned long long)part_stat_read(p, sectors[WRITE]),
|
(unsigned long long)part_stat_read(p, sectors[WRITE]),
|
||||||
jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
|
jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
|
||||||
part_in_flight(p),
|
inflight[0],
|
||||||
jiffies_to_msecs(part_stat_read(p, io_ticks)),
|
jiffies_to_msecs(part_stat_read(p, io_ticks)),
|
||||||
jiffies_to_msecs(part_stat_read(p, time_in_queue)));
|
jiffies_to_msecs(part_stat_read(p, time_in_queue)));
|
||||||
}
|
}
|
||||||
|
@ -249,15 +252,20 @@ void __delete_partition(struct percpu_ref *ref)
|
||||||
call_rcu(&part->rcu_head, delete_partition_rcu_cb);
|
call_rcu(&part->rcu_head, delete_partition_rcu_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called either with bd_mutex held, before a disk can be opened or
|
||||||
|
* after all disk users are gone.
|
||||||
|
*/
|
||||||
void delete_partition(struct gendisk *disk, int partno)
|
void delete_partition(struct gendisk *disk, int partno)
|
||||||
{
|
{
|
||||||
struct disk_part_tbl *ptbl = disk->part_tbl;
|
struct disk_part_tbl *ptbl =
|
||||||
|
rcu_dereference_protected(disk->part_tbl, 1);
|
||||||
struct hd_struct *part;
|
struct hd_struct *part;
|
||||||
|
|
||||||
if (partno >= ptbl->len)
|
if (partno >= ptbl->len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
part = ptbl->part[partno];
|
part = rcu_dereference_protected(ptbl->part[partno], 1);
|
||||||
if (!part)
|
if (!part)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -277,6 +285,10 @@ static ssize_t whole_disk_show(struct device *dev,
|
||||||
static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH,
|
static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH,
|
||||||
whole_disk_show, NULL);
|
whole_disk_show, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called either with bd_mutex held, before a disk can be opened or
|
||||||
|
* after all disk users are gone.
|
||||||
|
*/
|
||||||
struct hd_struct *add_partition(struct gendisk *disk, int partno,
|
struct hd_struct *add_partition(struct gendisk *disk, int partno,
|
||||||
sector_t start, sector_t len, int flags,
|
sector_t start, sector_t len, int flags,
|
||||||
struct partition_meta_info *info)
|
struct partition_meta_info *info)
|
||||||
|
@ -292,7 +304,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
|
||||||
err = disk_expand_part_tbl(disk, partno);
|
err = disk_expand_part_tbl(disk, partno);
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
ptbl = disk->part_tbl;
|
ptbl = rcu_dereference_protected(disk->part_tbl, 1);
|
||||||
|
|
||||||
if (ptbl->part[partno])
|
if (ptbl->part[partno])
|
||||||
return ERR_PTR(-EBUSY);
|
return ERR_PTR(-EBUSY);
|
||||||
|
@ -391,7 +403,6 @@ out_del:
|
||||||
device_del(pdev);
|
device_del(pdev);
|
||||||
out_put:
|
out_put:
|
||||||
put_device(pdev);
|
put_device(pdev);
|
||||||
blk_free_devt(devt);
|
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1678,9 +1678,12 @@ static bool DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
|
||||||
Enquiry2->FirmwareID.FirmwareType = '0';
|
Enquiry2->FirmwareID.FirmwareType = '0';
|
||||||
Enquiry2->FirmwareID.TurnID = 0;
|
Enquiry2->FirmwareID.TurnID = 0;
|
||||||
}
|
}
|
||||||
sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
|
snprintf(Controller->FirmwareVersion, sizeof(Controller->FirmwareVersion),
|
||||||
Enquiry2->FirmwareID.MajorVersion, Enquiry2->FirmwareID.MinorVersion,
|
"%d.%02d-%c-%02d",
|
||||||
Enquiry2->FirmwareID.FirmwareType, Enquiry2->FirmwareID.TurnID);
|
Enquiry2->FirmwareID.MajorVersion,
|
||||||
|
Enquiry2->FirmwareID.MinorVersion,
|
||||||
|
Enquiry2->FirmwareID.FirmwareType,
|
||||||
|
Enquiry2->FirmwareID.TurnID);
|
||||||
if (!((Controller->FirmwareVersion[0] == '5' &&
|
if (!((Controller->FirmwareVersion[0] == '5' &&
|
||||||
strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
|
strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
|
||||||
(Controller->FirmwareVersion[0] == '4' &&
|
(Controller->FirmwareVersion[0] == '4' &&
|
||||||
|
@ -6588,7 +6591,8 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
|
||||||
&dac960_proc_fops);
|
&dac960_proc_fops);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
|
snprintf(Controller->ControllerName, sizeof(Controller->ControllerName),
|
||||||
|
"c%d", Controller->ControllerNumber);
|
||||||
ControllerProcEntry = proc_mkdir(Controller->ControllerName,
|
ControllerProcEntry = proc_mkdir(Controller->ControllerName,
|
||||||
DAC960_ProcDirectoryEntry);
|
DAC960_ProcDirectoryEntry);
|
||||||
proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller);
|
proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller);
|
||||||
|
|
|
@ -17,6 +17,7 @@ if BLK_DEV
|
||||||
|
|
||||||
config BLK_DEV_NULL_BLK
|
config BLK_DEV_NULL_BLK
|
||||||
tristate "Null test block driver"
|
tristate "Null test block driver"
|
||||||
|
depends on CONFIGFS_FS
|
||||||
|
|
||||||
config BLK_DEV_FD
|
config BLK_DEV_FD
|
||||||
tristate "Normal floppy disk support"
|
tristate "Normal floppy disk support"
|
||||||
|
|
|
@ -294,14 +294,13 @@ out:
|
||||||
|
|
||||||
static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio)
|
static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct block_device *bdev = bio->bi_bdev;
|
struct brd_device *brd = bio->bi_disk->private_data;
|
||||||
struct brd_device *brd = bdev->bd_disk->private_data;
|
|
||||||
struct bio_vec bvec;
|
struct bio_vec bvec;
|
||||||
sector_t sector;
|
sector_t sector;
|
||||||
struct bvec_iter iter;
|
struct bvec_iter iter;
|
||||||
|
|
||||||
sector = bio->bi_iter.bi_sector;
|
sector = bio->bi_iter.bi_sector;
|
||||||
if (bio_end_sector(bio) > get_capacity(bdev->bd_disk))
|
if (bio_end_sector(bio) > get_capacity(bio->bi_disk))
|
||||||
goto io_error;
|
goto io_error;
|
||||||
|
|
||||||
bio_for_each_segment(bvec, bio, iter) {
|
bio_for_each_segment(bvec, bio, iter) {
|
||||||
|
|
|
@ -151,7 +151,7 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
|
||||||
op_flags |= REQ_SYNC;
|
op_flags |= REQ_SYNC;
|
||||||
|
|
||||||
bio = bio_alloc_drbd(GFP_NOIO);
|
bio = bio_alloc_drbd(GFP_NOIO);
|
||||||
bio->bi_bdev = bdev->md_bdev;
|
bio_set_dev(bio, bdev->md_bdev);
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
if (bio_add_page(bio, device->md_io.page, size, 0) != size)
|
if (bio_add_page(bio, device->md_io.page, size, 0) != size)
|
||||||
|
|
|
@ -1019,7 +1019,7 @@ static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_ho
|
||||||
bm_store_page_idx(page, page_nr);
|
bm_store_page_idx(page, page_nr);
|
||||||
} else
|
} else
|
||||||
page = b->bm_pages[page_nr];
|
page = b->bm_pages[page_nr];
|
||||||
bio->bi_bdev = device->ldev->md_bdev;
|
bio_set_dev(bio, device->ldev->md_bdev);
|
||||||
bio->bi_iter.bi_sector = on_disk_sector;
|
bio->bi_iter.bi_sector = on_disk_sector;
|
||||||
/* bio_add_page of a single page to an empty bio will always succeed,
|
/* bio_add_page of a single page to an empty bio will always succeed,
|
||||||
* according to api. Do we want to assert that? */
|
* according to api. Do we want to assert that? */
|
||||||
|
|
|
@ -63,19 +63,15 @@
|
||||||
# define __must_hold(x)
|
# define __must_hold(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* module parameter, defined in drbd_main.c */
|
/* shared module parameters, defined in drbd_main.c */
|
||||||
extern unsigned int minor_count;
|
|
||||||
extern bool disable_sendpage;
|
|
||||||
extern bool allow_oos;
|
|
||||||
void tl_abort_disk_io(struct drbd_device *device);
|
|
||||||
|
|
||||||
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
||||||
extern int enable_faults;
|
extern int drbd_enable_faults;
|
||||||
extern int fault_rate;
|
extern int drbd_fault_rate;
|
||||||
extern int fault_devs;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char usermode_helper[];
|
extern unsigned int drbd_minor_count;
|
||||||
|
extern char drbd_usermode_helper[];
|
||||||
|
extern int drbd_proc_details;
|
||||||
|
|
||||||
|
|
||||||
/* This is used to stop/restart our threads.
|
/* This is used to stop/restart our threads.
|
||||||
|
@ -181,8 +177,8 @@ _drbd_insert_fault(struct drbd_device *device, unsigned int type);
|
||||||
static inline int
|
static inline int
|
||||||
drbd_insert_fault(struct drbd_device *device, unsigned int type) {
|
drbd_insert_fault(struct drbd_device *device, unsigned int type) {
|
||||||
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
||||||
return fault_rate &&
|
return drbd_fault_rate &&
|
||||||
(enable_faults & (1<<type)) &&
|
(drbd_enable_faults & (1<<type)) &&
|
||||||
_drbd_insert_fault(device, type);
|
_drbd_insert_fault(device, type);
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -745,6 +741,8 @@ struct drbd_connection {
|
||||||
unsigned current_tle_writes; /* writes seen within this tl epoch */
|
unsigned current_tle_writes; /* writes seen within this tl epoch */
|
||||||
|
|
||||||
unsigned long last_reconnect_jif;
|
unsigned long last_reconnect_jif;
|
||||||
|
/* empty member on older kernels without blk_start_plug() */
|
||||||
|
struct blk_plug receiver_plug;
|
||||||
struct drbd_thread receiver;
|
struct drbd_thread receiver;
|
||||||
struct drbd_thread worker;
|
struct drbd_thread worker;
|
||||||
struct drbd_thread ack_receiver;
|
struct drbd_thread ack_receiver;
|
||||||
|
@ -1131,7 +1129,8 @@ extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_sta
|
||||||
extern int drbd_send_rs_deallocated(struct drbd_peer_device *, struct drbd_peer_request *);
|
extern int drbd_send_rs_deallocated(struct drbd_peer_device *, struct drbd_peer_request *);
|
||||||
extern void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev);
|
extern void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev);
|
||||||
extern void drbd_device_cleanup(struct drbd_device *device);
|
extern void drbd_device_cleanup(struct drbd_device *device);
|
||||||
void drbd_print_uuids(struct drbd_device *device, const char *text);
|
extern void drbd_print_uuids(struct drbd_device *device, const char *text);
|
||||||
|
extern void drbd_queue_unplug(struct drbd_device *device);
|
||||||
|
|
||||||
extern void conn_md_sync(struct drbd_connection *connection);
|
extern void conn_md_sync(struct drbd_connection *connection);
|
||||||
extern void drbd_md_write(struct drbd_device *device, void *buffer);
|
extern void drbd_md_write(struct drbd_device *device, void *buffer);
|
||||||
|
@ -1463,8 +1462,6 @@ extern struct drbd_resource *drbd_find_resource(const char *name);
|
||||||
extern void drbd_destroy_resource(struct kref *kref);
|
extern void drbd_destroy_resource(struct kref *kref);
|
||||||
extern void conn_free_crypto(struct drbd_connection *connection);
|
extern void conn_free_crypto(struct drbd_connection *connection);
|
||||||
|
|
||||||
extern int proc_details;
|
|
||||||
|
|
||||||
/* drbd_req */
|
/* drbd_req */
|
||||||
extern void do_submit(struct work_struct *ws);
|
extern void do_submit(struct work_struct *ws);
|
||||||
extern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long);
|
extern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long);
|
||||||
|
@ -1628,8 +1625,8 @@ static inline void drbd_generic_make_request(struct drbd_device *device,
|
||||||
int fault_type, struct bio *bio)
|
int fault_type, struct bio *bio)
|
||||||
{
|
{
|
||||||
__release(local);
|
__release(local);
|
||||||
if (!bio->bi_bdev) {
|
if (!bio->bi_disk) {
|
||||||
drbd_err(device, "drbd_generic_make_request: bio->bi_bdev == NULL\n");
|
drbd_err(device, "drbd_generic_make_request: bio->bi_disk == NULL\n");
|
||||||
bio->bi_status = BLK_STS_IOERR;
|
bio->bi_status = BLK_STS_IOERR;
|
||||||
bio_endio(bio);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -77,41 +77,41 @@ MODULE_PARM_DESC(minor_count, "Approximate number of drbd devices ("
|
||||||
MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR);
|
MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR);
|
||||||
|
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
/* allow_open_on_secondary */
|
|
||||||
MODULE_PARM_DESC(allow_oos, "DONT USE!");
|
|
||||||
/* thanks to these macros, if compiled into the kernel (not-module),
|
/* thanks to these macros, if compiled into the kernel (not-module),
|
||||||
* this becomes the boot parameter drbd.minor_count */
|
* these become boot parameters (e.g., drbd.minor_count) */
|
||||||
module_param(minor_count, uint, 0444);
|
|
||||||
module_param(disable_sendpage, bool, 0644);
|
|
||||||
module_param(allow_oos, bool, 0);
|
|
||||||
module_param(proc_details, int, 0644);
|
|
||||||
|
|
||||||
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
||||||
int enable_faults;
|
int drbd_enable_faults;
|
||||||
int fault_rate;
|
int drbd_fault_rate;
|
||||||
static int fault_count;
|
static int drbd_fault_count;
|
||||||
int fault_devs;
|
static int drbd_fault_devs;
|
||||||
/* bitmap of enabled faults */
|
/* bitmap of enabled faults */
|
||||||
module_param(enable_faults, int, 0664);
|
module_param_named(enable_faults, drbd_enable_faults, int, 0664);
|
||||||
/* fault rate % value - applies to all enabled faults */
|
/* fault rate % value - applies to all enabled faults */
|
||||||
module_param(fault_rate, int, 0664);
|
module_param_named(fault_rate, drbd_fault_rate, int, 0664);
|
||||||
/* count of faults inserted */
|
/* count of faults inserted */
|
||||||
module_param(fault_count, int, 0664);
|
module_param_named(fault_count, drbd_fault_count, int, 0664);
|
||||||
/* bitmap of devices to insert faults on */
|
/* bitmap of devices to insert faults on */
|
||||||
module_param(fault_devs, int, 0644);
|
module_param_named(fault_devs, drbd_fault_devs, int, 0644);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* module parameter, defined */
|
/* module parameters we can keep static */
|
||||||
unsigned int minor_count = DRBD_MINOR_COUNT_DEF;
|
static bool drbd_allow_oos; /* allow_open_on_secondary */
|
||||||
bool disable_sendpage;
|
static bool drbd_disable_sendpage;
|
||||||
bool allow_oos;
|
MODULE_PARM_DESC(allow_oos, "DONT USE!");
|
||||||
int proc_details; /* Detail level in proc drbd*/
|
module_param_named(allow_oos, drbd_allow_oos, bool, 0);
|
||||||
|
module_param_named(disable_sendpage, drbd_disable_sendpage, bool, 0644);
|
||||||
|
|
||||||
|
/* module parameters we share */
|
||||||
|
int drbd_proc_details; /* Detail level in proc drbd*/
|
||||||
|
module_param_named(proc_details, drbd_proc_details, int, 0644);
|
||||||
|
/* module parameters shared with defaults */
|
||||||
|
unsigned int drbd_minor_count = DRBD_MINOR_COUNT_DEF;
|
||||||
/* Module parameter for setting the user mode helper program
|
/* Module parameter for setting the user mode helper program
|
||||||
* to run. Default is /sbin/drbdadm */
|
* to run. Default is /sbin/drbdadm */
|
||||||
char usermode_helper[80] = "/sbin/drbdadm";
|
char drbd_usermode_helper[80] = "/sbin/drbdadm";
|
||||||
|
module_param_named(minor_count, drbd_minor_count, uint, 0444);
|
||||||
module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644);
|
module_param_string(usermode_helper, drbd_usermode_helper, sizeof(drbd_usermode_helper), 0644);
|
||||||
|
|
||||||
/* in 2.6.x, our device mapping and config info contains our virtual gendisks
|
/* in 2.6.x, our device mapping and config info contains our virtual gendisks
|
||||||
* as member "struct gendisk *vdisk;"
|
* as member "struct gendisk *vdisk;"
|
||||||
|
@ -923,7 +923,9 @@ void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *peer_device)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* communicated if (agreed_features & DRBD_FF_WSAME) */
|
/* communicated if (agreed_features & DRBD_FF_WSAME) */
|
||||||
void assign_p_sizes_qlim(struct drbd_device *device, struct p_sizes *p, struct request_queue *q)
|
static void
|
||||||
|
assign_p_sizes_qlim(struct drbd_device *device, struct p_sizes *p,
|
||||||
|
struct request_queue *q)
|
||||||
{
|
{
|
||||||
if (q) {
|
if (q) {
|
||||||
p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q));
|
p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q));
|
||||||
|
@ -1560,7 +1562,7 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
|
||||||
* put_page(); and would cause either a VM_BUG directly, or
|
* put_page(); and would cause either a VM_BUG directly, or
|
||||||
* __page_cache_release a page that would actually still be referenced
|
* __page_cache_release a page that would actually still be referenced
|
||||||
* by someone, leading to some obscure delayed Oops somewhere else. */
|
* by someone, leading to some obscure delayed Oops somewhere else. */
|
||||||
if (disable_sendpage || (page_count(page) < 1) || PageSlab(page))
|
if (drbd_disable_sendpage || (page_count(page) < 1) || PageSlab(page))
|
||||||
return _drbd_no_send_page(peer_device, page, offset, size, msg_flags);
|
return _drbd_no_send_page(peer_device, page, offset, size, msg_flags);
|
||||||
|
|
||||||
msg_flags |= MSG_NOSIGNAL;
|
msg_flags |= MSG_NOSIGNAL;
|
||||||
|
@ -1932,7 +1934,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
|
||||||
if (device->state.role != R_PRIMARY) {
|
if (device->state.role != R_PRIMARY) {
|
||||||
if (mode & FMODE_WRITE)
|
if (mode & FMODE_WRITE)
|
||||||
rv = -EROFS;
|
rv = -EROFS;
|
||||||
else if (!allow_oos)
|
else if (!drbd_allow_oos)
|
||||||
rv = -EMEDIUMTYPE;
|
rv = -EMEDIUMTYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1952,6 +1954,19 @@ static void drbd_release(struct gendisk *gd, fmode_t mode)
|
||||||
mutex_unlock(&drbd_main_mutex);
|
mutex_unlock(&drbd_main_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* need to hold resource->req_lock */
|
||||||
|
void drbd_queue_unplug(struct drbd_device *device)
|
||||||
|
{
|
||||||
|
if (device->state.pdsk >= D_INCONSISTENT && device->state.conn >= C_CONNECTED) {
|
||||||
|
D_ASSERT(device, device->state.role == R_PRIMARY);
|
||||||
|
if (test_and_clear_bit(UNPLUG_REMOTE, &device->flags)) {
|
||||||
|
drbd_queue_work_if_unqueued(
|
||||||
|
&first_peer_device(device)->connection->sender_work,
|
||||||
|
&device->unplug_work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void drbd_set_defaults(struct drbd_device *device)
|
static void drbd_set_defaults(struct drbd_device *device)
|
||||||
{
|
{
|
||||||
/* Beware! The actual layout differs
|
/* Beware! The actual layout differs
|
||||||
|
@ -2008,18 +2023,14 @@ void drbd_init_set_defaults(struct drbd_device *device)
|
||||||
device->unplug_work.cb = w_send_write_hint;
|
device->unplug_work.cb = w_send_write_hint;
|
||||||
device->bm_io_work.w.cb = w_bitmap_io;
|
device->bm_io_work.w.cb = w_bitmap_io;
|
||||||
|
|
||||||
init_timer(&device->resync_timer);
|
setup_timer(&device->resync_timer, resync_timer_fn,
|
||||||
init_timer(&device->md_sync_timer);
|
(unsigned long)device);
|
||||||
init_timer(&device->start_resync_timer);
|
setup_timer(&device->md_sync_timer, md_sync_timer_fn,
|
||||||
init_timer(&device->request_timer);
|
(unsigned long)device);
|
||||||
device->resync_timer.function = resync_timer_fn;
|
setup_timer(&device->start_resync_timer, start_resync_timer_fn,
|
||||||
device->resync_timer.data = (unsigned long) device;
|
(unsigned long)device);
|
||||||
device->md_sync_timer.function = md_sync_timer_fn;
|
setup_timer(&device->request_timer, request_timer_fn,
|
||||||
device->md_sync_timer.data = (unsigned long) device;
|
(unsigned long)device);
|
||||||
device->start_resync_timer.function = start_resync_timer_fn;
|
|
||||||
device->start_resync_timer.data = (unsigned long) device;
|
|
||||||
device->request_timer.function = request_timer_fn;
|
|
||||||
device->request_timer.data = (unsigned long) device;
|
|
||||||
|
|
||||||
init_waitqueue_head(&device->misc_wait);
|
init_waitqueue_head(&device->misc_wait);
|
||||||
init_waitqueue_head(&device->state_wait);
|
init_waitqueue_head(&device->state_wait);
|
||||||
|
@ -2131,7 +2142,7 @@ static void drbd_destroy_mempools(void)
|
||||||
static int drbd_create_mempools(void)
|
static int drbd_create_mempools(void)
|
||||||
{
|
{
|
||||||
struct page *page;
|
struct page *page;
|
||||||
const int number = (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count;
|
const int number = (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * drbd_minor_count;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* prepare our caches and mempools */
|
/* prepare our caches and mempools */
|
||||||
|
@ -2167,13 +2178,12 @@ static int drbd_create_mempools(void)
|
||||||
goto Enomem;
|
goto Enomem;
|
||||||
|
|
||||||
/* mempools */
|
/* mempools */
|
||||||
drbd_io_bio_set = bioset_create(BIO_POOL_SIZE, 0, BIOSET_NEED_RESCUER);
|
drbd_io_bio_set = bioset_create(BIO_POOL_SIZE, 0, 0);
|
||||||
if (drbd_io_bio_set == NULL)
|
if (drbd_io_bio_set == NULL)
|
||||||
goto Enomem;
|
goto Enomem;
|
||||||
|
|
||||||
drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0,
|
drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0,
|
||||||
BIOSET_NEED_BVECS |
|
BIOSET_NEED_BVECS);
|
||||||
BIOSET_NEED_RESCUER);
|
|
||||||
if (drbd_md_io_bio_set == NULL)
|
if (drbd_md_io_bio_set == NULL)
|
||||||
goto Enomem;
|
goto Enomem;
|
||||||
|
|
||||||
|
@ -2409,7 +2419,6 @@ static void drbd_cleanup(void)
|
||||||
destroy_workqueue(retry.wq);
|
destroy_workqueue(retry.wq);
|
||||||
|
|
||||||
drbd_genl_unregister();
|
drbd_genl_unregister();
|
||||||
drbd_debugfs_cleanup();
|
|
||||||
|
|
||||||
idr_for_each_entry(&drbd_devices, device, i)
|
idr_for_each_entry(&drbd_devices, device, i)
|
||||||
drbd_delete_device(device);
|
drbd_delete_device(device);
|
||||||
|
@ -2420,6 +2429,8 @@ static void drbd_cleanup(void)
|
||||||
drbd_free_resource(resource);
|
drbd_free_resource(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drbd_debugfs_cleanup();
|
||||||
|
|
||||||
drbd_destroy_mempools();
|
drbd_destroy_mempools();
|
||||||
unregister_blkdev(DRBD_MAJOR, "drbd");
|
unregister_blkdev(DRBD_MAJOR, "drbd");
|
||||||
|
|
||||||
|
@ -2972,12 +2983,12 @@ static int __init drbd_init(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
|
if (drbd_minor_count < DRBD_MINOR_COUNT_MIN || drbd_minor_count > DRBD_MINOR_COUNT_MAX) {
|
||||||
pr_err("invalid minor_count (%d)\n", minor_count);
|
pr_err("invalid minor_count (%d)\n", drbd_minor_count);
|
||||||
#ifdef MODULE
|
#ifdef MODULE
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
#else
|
#else
|
||||||
minor_count = DRBD_MINOR_COUNT_DEF;
|
drbd_minor_count = DRBD_MINOR_COUNT_DEF;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3900,12 +3911,12 @@ _drbd_insert_fault(struct drbd_device *device, unsigned int type)
|
||||||
static struct fault_random_state rrs = {0, 0};
|
static struct fault_random_state rrs = {0, 0};
|
||||||
|
|
||||||
unsigned int ret = (
|
unsigned int ret = (
|
||||||
(fault_devs == 0 ||
|
(drbd_fault_devs == 0 ||
|
||||||
((1 << device_to_minor(device)) & fault_devs) != 0) &&
|
((1 << device_to_minor(device)) & drbd_fault_devs) != 0) &&
|
||||||
(((_drbd_fault_random(&rrs) % 100) + 1) <= fault_rate));
|
(((_drbd_fault_random(&rrs) % 100) + 1) <= drbd_fault_rate));
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
fault_count++;
|
drbd_fault_count++;
|
||||||
|
|
||||||
if (__ratelimit(&drbd_ratelimit_state))
|
if (__ratelimit(&drbd_ratelimit_state))
|
||||||
drbd_warn(device, "***Simulating %s failure\n",
|
drbd_warn(device, "***Simulating %s failure\n",
|
||||||
|
|
|
@ -344,7 +344,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
|
||||||
(char[60]) { }, /* address */
|
(char[60]) { }, /* address */
|
||||||
NULL };
|
NULL };
|
||||||
char mb[14];
|
char mb[14];
|
||||||
char *argv[] = {usermode_helper, cmd, mb, NULL };
|
char *argv[] = {drbd_usermode_helper, cmd, mb, NULL };
|
||||||
struct drbd_connection *connection = first_peer_device(device)->connection;
|
struct drbd_connection *connection = first_peer_device(device)->connection;
|
||||||
struct sib_info sib;
|
struct sib_info sib;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -359,19 +359,19 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
|
||||||
* write out any unsynced meta data changes now */
|
* write out any unsynced meta data changes now */
|
||||||
drbd_md_sync(device);
|
drbd_md_sync(device);
|
||||||
|
|
||||||
drbd_info(device, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
|
drbd_info(device, "helper command: %s %s %s\n", drbd_usermode_helper, cmd, mb);
|
||||||
sib.sib_reason = SIB_HELPER_PRE;
|
sib.sib_reason = SIB_HELPER_PRE;
|
||||||
sib.helper_name = cmd;
|
sib.helper_name = cmd;
|
||||||
drbd_bcast_event(device, &sib);
|
drbd_bcast_event(device, &sib);
|
||||||
notify_helper(NOTIFY_CALL, device, connection, cmd, 0);
|
notify_helper(NOTIFY_CALL, device, connection, cmd, 0);
|
||||||
ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
|
ret = call_usermodehelper(drbd_usermode_helper, argv, envp, UMH_WAIT_PROC);
|
||||||
if (ret)
|
if (ret)
|
||||||
drbd_warn(device, "helper command: %s %s %s exit code %u (0x%x)\n",
|
drbd_warn(device, "helper command: %s %s %s exit code %u (0x%x)\n",
|
||||||
usermode_helper, cmd, mb,
|
drbd_usermode_helper, cmd, mb,
|
||||||
(ret >> 8) & 0xff, ret);
|
(ret >> 8) & 0xff, ret);
|
||||||
else
|
else
|
||||||
drbd_info(device, "helper command: %s %s %s exit code %u (0x%x)\n",
|
drbd_info(device, "helper command: %s %s %s exit code %u (0x%x)\n",
|
||||||
usermode_helper, cmd, mb,
|
drbd_usermode_helper, cmd, mb,
|
||||||
(ret >> 8) & 0xff, ret);
|
(ret >> 8) & 0xff, ret);
|
||||||
sib.sib_reason = SIB_HELPER_POST;
|
sib.sib_reason = SIB_HELPER_POST;
|
||||||
sib.helper_exit_code = ret;
|
sib.helper_exit_code = ret;
|
||||||
|
@ -396,24 +396,24 @@ enum drbd_peer_state conn_khelper(struct drbd_connection *connection, char *cmd)
|
||||||
(char[60]) { }, /* address */
|
(char[60]) { }, /* address */
|
||||||
NULL };
|
NULL };
|
||||||
char *resource_name = connection->resource->name;
|
char *resource_name = connection->resource->name;
|
||||||
char *argv[] = {usermode_helper, cmd, resource_name, NULL };
|
char *argv[] = {drbd_usermode_helper, cmd, resource_name, NULL };
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
setup_khelper_env(connection, envp);
|
setup_khelper_env(connection, envp);
|
||||||
conn_md_sync(connection);
|
conn_md_sync(connection);
|
||||||
|
|
||||||
drbd_info(connection, "helper command: %s %s %s\n", usermode_helper, cmd, resource_name);
|
drbd_info(connection, "helper command: %s %s %s\n", drbd_usermode_helper, cmd, resource_name);
|
||||||
/* TODO: conn_bcast_event() ?? */
|
/* TODO: conn_bcast_event() ?? */
|
||||||
notify_helper(NOTIFY_CALL, NULL, connection, cmd, 0);
|
notify_helper(NOTIFY_CALL, NULL, connection, cmd, 0);
|
||||||
|
|
||||||
ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
|
ret = call_usermodehelper(drbd_usermode_helper, argv, envp, UMH_WAIT_PROC);
|
||||||
if (ret)
|
if (ret)
|
||||||
drbd_warn(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
|
drbd_warn(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
|
||||||
usermode_helper, cmd, resource_name,
|
drbd_usermode_helper, cmd, resource_name,
|
||||||
(ret >> 8) & 0xff, ret);
|
(ret >> 8) & 0xff, ret);
|
||||||
else
|
else
|
||||||
drbd_info(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
|
drbd_info(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
|
||||||
usermode_helper, cmd, resource_name,
|
drbd_usermode_helper, cmd, resource_name,
|
||||||
(ret >> 8) & 0xff, ret);
|
(ret >> 8) & 0xff, ret);
|
||||||
/* TODO: conn_bcast_event() ?? */
|
/* TODO: conn_bcast_event() ?? */
|
||||||
notify_helper(NOTIFY_RESPONSE, NULL, connection, cmd, ret);
|
notify_helper(NOTIFY_RESPONSE, NULL, connection, cmd, ret);
|
||||||
|
@ -1236,12 +1236,18 @@ static void fixup_discard_if_not_supported(struct request_queue *q)
|
||||||
|
|
||||||
static void decide_on_write_same_support(struct drbd_device *device,
|
static void decide_on_write_same_support(struct drbd_device *device,
|
||||||
struct request_queue *q,
|
struct request_queue *q,
|
||||||
struct request_queue *b, struct o_qlim *o)
|
struct request_queue *b, struct o_qlim *o,
|
||||||
|
bool disable_write_same)
|
||||||
{
|
{
|
||||||
struct drbd_peer_device *peer_device = first_peer_device(device);
|
struct drbd_peer_device *peer_device = first_peer_device(device);
|
||||||
struct drbd_connection *connection = peer_device->connection;
|
struct drbd_connection *connection = peer_device->connection;
|
||||||
bool can_do = b ? b->limits.max_write_same_sectors : true;
|
bool can_do = b ? b->limits.max_write_same_sectors : true;
|
||||||
|
|
||||||
|
if (can_do && disable_write_same) {
|
||||||
|
can_do = false;
|
||||||
|
drbd_info(peer_device, "WRITE_SAME disabled by config\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) {
|
if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) {
|
||||||
can_do = false;
|
can_do = false;
|
||||||
drbd_info(peer_device, "peer does not support WRITE_SAME\n");
|
drbd_info(peer_device, "peer does not support WRITE_SAME\n");
|
||||||
|
@ -1302,6 +1308,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
|
||||||
struct request_queue *b = NULL;
|
struct request_queue *b = NULL;
|
||||||
struct disk_conf *dc;
|
struct disk_conf *dc;
|
||||||
bool discard_zeroes_if_aligned = true;
|
bool discard_zeroes_if_aligned = true;
|
||||||
|
bool disable_write_same = false;
|
||||||
|
|
||||||
if (bdev) {
|
if (bdev) {
|
||||||
b = bdev->backing_bdev->bd_disk->queue;
|
b = bdev->backing_bdev->bd_disk->queue;
|
||||||
|
@ -1311,6 +1318,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
|
||||||
dc = rcu_dereference(device->ldev->disk_conf);
|
dc = rcu_dereference(device->ldev->disk_conf);
|
||||||
max_segments = dc->max_bio_bvecs;
|
max_segments = dc->max_bio_bvecs;
|
||||||
discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned;
|
discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned;
|
||||||
|
disable_write_same = dc->disable_write_same;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
blk_set_stacking_limits(&q->limits);
|
blk_set_stacking_limits(&q->limits);
|
||||||
|
@ -1321,7 +1329,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
|
||||||
blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
|
blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
|
||||||
blk_queue_segment_boundary(q, PAGE_SIZE-1);
|
blk_queue_segment_boundary(q, PAGE_SIZE-1);
|
||||||
decide_on_discard_support(device, q, b, discard_zeroes_if_aligned);
|
decide_on_discard_support(device, q, b, discard_zeroes_if_aligned);
|
||||||
decide_on_write_same_support(device, q, b, o);
|
decide_on_write_same_support(device, q, b, o, disable_write_same);
|
||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
blk_queue_stack_limits(q, b);
|
blk_queue_stack_limits(q, b);
|
||||||
|
@ -1612,7 +1620,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (write_ordering_changed(old_disk_conf, new_disk_conf))
|
if (write_ordering_changed(old_disk_conf, new_disk_conf))
|
||||||
drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH);
|
drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH);
|
||||||
|
|
||||||
if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned)
|
if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned
|
||||||
|
|| old_disk_conf->disable_write_same != new_disk_conf->disable_write_same)
|
||||||
drbd_reconsider_queue_parameters(device, device->ldev, NULL);
|
drbd_reconsider_queue_parameters(device, device->ldev, NULL);
|
||||||
|
|
||||||
drbd_md_sync(device);
|
drbd_md_sync(device);
|
||||||
|
@ -2140,34 +2149,13 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
|
||||||
|
|
||||||
static int adm_detach(struct drbd_device *device, int force)
|
static int adm_detach(struct drbd_device *device, int force)
|
||||||
{
|
{
|
||||||
enum drbd_state_rv retcode;
|
|
||||||
void *buffer;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (force) {
|
if (force) {
|
||||||
set_bit(FORCE_DETACH, &device->flags);
|
set_bit(FORCE_DETACH, &device->flags);
|
||||||
drbd_force_state(device, NS(disk, D_FAILED));
|
drbd_force_state(device, NS(disk, D_FAILED));
|
||||||
retcode = SS_SUCCESS;
|
return SS_SUCCESS;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */
|
return drbd_request_detach_interruptible(device);
|
||||||
buffer = drbd_md_get_buffer(device, __func__); /* make sure there is no in-flight meta-data IO */
|
|
||||||
if (buffer) {
|
|
||||||
retcode = drbd_request_state(device, NS(disk, D_FAILED));
|
|
||||||
drbd_md_put_buffer(device);
|
|
||||||
} else /* already <= D_FAILED */
|
|
||||||
retcode = SS_NOTHING_TO_DO;
|
|
||||||
/* D_FAILED will transition to DISKLESS. */
|
|
||||||
drbd_resume_io(device);
|
|
||||||
ret = wait_event_interruptible(device->misc_wait,
|
|
||||||
device->state.disk != D_FAILED);
|
|
||||||
if ((int)retcode == (int)SS_IS_DISKLESS)
|
|
||||||
retcode = SS_NOTHING_TO_DO;
|
|
||||||
if (ret)
|
|
||||||
retcode = ERR_INTR;
|
|
||||||
out:
|
|
||||||
return retcode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detaching the disk is a process in multiple stages. First we need to lock
|
/* Detaching the disk is a process in multiple stages. First we need to lock
|
||||||
|
|
|
@ -127,7 +127,7 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se
|
||||||
seq_putc(seq, '=');
|
seq_putc(seq, '=');
|
||||||
seq_putc(seq, '>');
|
seq_putc(seq, '>');
|
||||||
for (i = 0; i < y; i++)
|
for (i = 0; i < y; i++)
|
||||||
seq_printf(seq, ".");
|
seq_putc(seq, '.');
|
||||||
seq_puts(seq, "] ");
|
seq_puts(seq, "] ");
|
||||||
|
|
||||||
if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
|
if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
|
||||||
|
@ -179,7 +179,7 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se
|
||||||
seq_printf_with_thousands_grouping(seq, dbdt);
|
seq_printf_with_thousands_grouping(seq, dbdt);
|
||||||
seq_puts(seq, " (");
|
seq_puts(seq, " (");
|
||||||
/* ------------------------- ~3s average ------------------------ */
|
/* ------------------------- ~3s average ------------------------ */
|
||||||
if (proc_details >= 1) {
|
if (drbd_proc_details >= 1) {
|
||||||
/* this is what drbd_rs_should_slow_down() uses */
|
/* this is what drbd_rs_should_slow_down() uses */
|
||||||
i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
|
i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
|
||||||
dt = (jiffies - device->rs_mark_time[i]) / HZ;
|
dt = (jiffies - device->rs_mark_time[i]) / HZ;
|
||||||
|
@ -209,7 +209,7 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se
|
||||||
}
|
}
|
||||||
seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
|
seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
|
||||||
|
|
||||||
if (proc_details >= 1) {
|
if (drbd_proc_details >= 1) {
|
||||||
/* 64 bit:
|
/* 64 bit:
|
||||||
* we convert to sectors in the display below. */
|
* we convert to sectors in the display below. */
|
||||||
unsigned long bm_bits = drbd_bm_bits(device);
|
unsigned long bm_bits = drbd_bm_bits(device);
|
||||||
|
@ -332,13 +332,13 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
|
||||||
state.conn == C_VERIFY_T)
|
state.conn == C_VERIFY_T)
|
||||||
drbd_syncer_progress(device, seq, state);
|
drbd_syncer_progress(device, seq, state);
|
||||||
|
|
||||||
if (proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
|
if (drbd_proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
|
||||||
lc_seq_printf_stats(seq, device->resync);
|
lc_seq_printf_stats(seq, device->resync);
|
||||||
lc_seq_printf_stats(seq, device->act_log);
|
lc_seq_printf_stats(seq, device->act_log);
|
||||||
put_ldev(device);
|
put_ldev(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc_details >= 2)
|
if (drbd_proc_details >= 2)
|
||||||
seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
|
seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
|
@ -332,7 +332,7 @@ static void drbd_free_pages(struct drbd_device *device, struct page *page, int i
|
||||||
if (page == NULL)
|
if (page == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count)
|
if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * drbd_minor_count)
|
||||||
i = page_chain_free(page);
|
i = page_chain_free(page);
|
||||||
else {
|
else {
|
||||||
struct page *tmp;
|
struct page *tmp;
|
||||||
|
@ -1100,7 +1100,10 @@ randomize:
|
||||||
idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
|
idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
|
||||||
mutex_lock(peer_device->device->state_mutex);
|
mutex_lock(peer_device->device->state_mutex);
|
||||||
|
|
||||||
|
/* avoid a race with conn_request_state( C_DISCONNECTING ) */
|
||||||
|
spin_lock_irq(&connection->resource->req_lock);
|
||||||
set_bit(STATE_SENT, &connection->flags);
|
set_bit(STATE_SENT, &connection->flags);
|
||||||
|
spin_unlock_irq(&connection->resource->req_lock);
|
||||||
|
|
||||||
idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
|
idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
|
||||||
mutex_unlock(peer_device->device->state_mutex);
|
mutex_unlock(peer_device->device->state_mutex);
|
||||||
|
@ -1194,6 +1197,14 @@ static int decode_header(struct drbd_connection *connection, void *header, struc
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drbd_unplug_all_devices(struct drbd_connection *connection)
|
||||||
|
{
|
||||||
|
if (current->plug == &connection->receiver_plug) {
|
||||||
|
blk_finish_plug(&connection->receiver_plug);
|
||||||
|
blk_start_plug(&connection->receiver_plug);
|
||||||
|
} /* else: maybe just schedule() ?? */
|
||||||
|
}
|
||||||
|
|
||||||
static int drbd_recv_header(struct drbd_connection *connection, struct packet_info *pi)
|
static int drbd_recv_header(struct drbd_connection *connection, struct packet_info *pi)
|
||||||
{
|
{
|
||||||
void *buffer = connection->data.rbuf;
|
void *buffer = connection->data.rbuf;
|
||||||
|
@ -1209,6 +1220,36 @@ static int drbd_recv_header(struct drbd_connection *connection, struct packet_in
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int drbd_recv_header_maybe_unplug(struct drbd_connection *connection, struct packet_info *pi)
|
||||||
|
{
|
||||||
|
void *buffer = connection->data.rbuf;
|
||||||
|
unsigned int size = drbd_header_size(connection);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = drbd_recv_short(connection->data.socket, buffer, size, MSG_NOSIGNAL|MSG_DONTWAIT);
|
||||||
|
if (err != size) {
|
||||||
|
/* If we have nothing in the receive buffer now, to reduce
|
||||||
|
* application latency, try to drain the backend queues as
|
||||||
|
* quickly as possible, and let remote TCP know what we have
|
||||||
|
* received so far. */
|
||||||
|
if (err == -EAGAIN) {
|
||||||
|
drbd_tcp_quickack(connection->data.socket);
|
||||||
|
drbd_unplug_all_devices(connection);
|
||||||
|
}
|
||||||
|
if (err > 0) {
|
||||||
|
buffer += err;
|
||||||
|
size -= err;
|
||||||
|
}
|
||||||
|
err = drbd_recv_all_warn(connection, buffer, size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = decode_header(connection, connection->data.rbuf, pi);
|
||||||
|
connection->last_received = jiffies;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
/* This is blkdev_issue_flush, but asynchronous.
|
/* This is blkdev_issue_flush, but asynchronous.
|
||||||
* We want to submit to all component volumes in parallel,
|
* We want to submit to all component volumes in parallel,
|
||||||
* then wait for all completions.
|
* then wait for all completions.
|
||||||
|
@ -1223,7 +1264,7 @@ struct one_flush_context {
|
||||||
struct issue_flush_context *ctx;
|
struct issue_flush_context *ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
void one_flush_endio(struct bio *bio)
|
static void one_flush_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct one_flush_context *octx = bio->bi_private;
|
struct one_flush_context *octx = bio->bi_private;
|
||||||
struct drbd_device *device = octx->device;
|
struct drbd_device *device = octx->device;
|
||||||
|
@ -1265,7 +1306,7 @@ static void submit_one_flush(struct drbd_device *device, struct issue_flush_cont
|
||||||
|
|
||||||
octx->device = device;
|
octx->device = device;
|
||||||
octx->ctx = ctx;
|
octx->ctx = ctx;
|
||||||
bio->bi_bdev = device->ldev->backing_bdev;
|
bio_set_dev(bio, device->ldev->backing_bdev);
|
||||||
bio->bi_private = octx;
|
bio->bi_private = octx;
|
||||||
bio->bi_end_io = one_flush_endio;
|
bio->bi_end_io = one_flush_endio;
|
||||||
bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
|
bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
|
||||||
|
@ -1548,7 +1589,7 @@ next_bio:
|
||||||
}
|
}
|
||||||
/* > peer_req->i.sector, unless this is the first bio */
|
/* > peer_req->i.sector, unless this is the first bio */
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = device->ldev->backing_bdev;
|
bio_set_dev(bio, device->ldev->backing_bdev);
|
||||||
bio_set_op_attrs(bio, op, op_flags);
|
bio_set_op_attrs(bio, op, op_flags);
|
||||||
bio->bi_private = peer_req;
|
bio->bi_private = peer_req;
|
||||||
bio->bi_end_io = drbd_peer_request_endio;
|
bio->bi_end_io = drbd_peer_request_endio;
|
||||||
|
@ -4085,7 +4126,7 @@ static int receive_uuids(struct drbd_connection *connection, struct packet_info
|
||||||
return config_unknown_volume(connection, pi);
|
return config_unknown_volume(connection, pi);
|
||||||
device = peer_device->device;
|
device = peer_device->device;
|
||||||
|
|
||||||
p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO);
|
p_uuid = kmalloc_array(UI_EXTENDED_SIZE, sizeof(*p_uuid), GFP_NOIO);
|
||||||
if (!p_uuid) {
|
if (!p_uuid) {
|
||||||
drbd_err(device, "kmalloc of p_uuid failed\n");
|
drbd_err(device, "kmalloc of p_uuid failed\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -4882,8 +4923,8 @@ static void drbdd(struct drbd_connection *connection)
|
||||||
struct data_cmd const *cmd;
|
struct data_cmd const *cmd;
|
||||||
|
|
||||||
drbd_thread_current_set_cpu(&connection->receiver);
|
drbd_thread_current_set_cpu(&connection->receiver);
|
||||||
update_receiver_timing_details(connection, drbd_recv_header);
|
update_receiver_timing_details(connection, drbd_recv_header_maybe_unplug);
|
||||||
if (drbd_recv_header(connection, &pi))
|
if (drbd_recv_header_maybe_unplug(connection, &pi))
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
cmd = &drbd_cmd_handler[pi.cmd];
|
cmd = &drbd_cmd_handler[pi.cmd];
|
||||||
|
@ -5375,8 +5416,11 @@ int drbd_receiver(struct drbd_thread *thi)
|
||||||
}
|
}
|
||||||
} while (h == 0);
|
} while (h == 0);
|
||||||
|
|
||||||
if (h > 0)
|
if (h > 0) {
|
||||||
|
blk_start_plug(&connection->receiver_plug);
|
||||||
drbdd(connection);
|
drbdd(connection);
|
||||||
|
blk_finish_plug(&connection->receiver_plug);
|
||||||
|
}
|
||||||
|
|
||||||
conn_disconnect(connection);
|
conn_disconnect(connection);
|
||||||
|
|
||||||
|
|
|
@ -36,14 +36,18 @@ static bool drbd_may_do_local_read(struct drbd_device *device, sector_t sector,
|
||||||
/* Update disk stats at start of I/O request */
|
/* Update disk stats at start of I/O request */
|
||||||
static void _drbd_start_io_acct(struct drbd_device *device, struct drbd_request *req)
|
static void _drbd_start_io_acct(struct drbd_device *device, struct drbd_request *req)
|
||||||
{
|
{
|
||||||
generic_start_io_acct(bio_data_dir(req->master_bio), req->i.size >> 9,
|
struct request_queue *q = device->rq_queue;
|
||||||
&device->vdisk->part0);
|
|
||||||
|
generic_start_io_acct(q, bio_data_dir(req->master_bio),
|
||||||
|
req->i.size >> 9, &device->vdisk->part0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update disk stats when completing request upwards */
|
/* Update disk stats when completing request upwards */
|
||||||
static void _drbd_end_io_acct(struct drbd_device *device, struct drbd_request *req)
|
static void _drbd_end_io_acct(struct drbd_device *device, struct drbd_request *req)
|
||||||
{
|
{
|
||||||
generic_end_io_acct(bio_data_dir(req->master_bio),
|
struct request_queue *q = device->rq_queue;
|
||||||
|
|
||||||
|
generic_end_io_acct(q, bio_data_dir(req->master_bio),
|
||||||
&device->vdisk->part0, req->start_jif);
|
&device->vdisk->part0, req->start_jif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,7 +1179,7 @@ drbd_submit_req_private_bio(struct drbd_request *req)
|
||||||
else
|
else
|
||||||
type = DRBD_FAULT_DT_RD;
|
type = DRBD_FAULT_DT_RD;
|
||||||
|
|
||||||
bio->bi_bdev = device->ldev->backing_bdev;
|
bio_set_dev(bio, device->ldev->backing_bdev);
|
||||||
|
|
||||||
/* State may have changed since we grabbed our reference on the
|
/* State may have changed since we grabbed our reference on the
|
||||||
* ->ldev member. Double check, and short-circuit to endio.
|
* ->ldev member. Double check, and short-circuit to endio.
|
||||||
|
@ -1275,6 +1279,57 @@ static bool may_do_writes(struct drbd_device *device)
|
||||||
return s.disk == D_UP_TO_DATE || s.pdsk == D_UP_TO_DATE;
|
return s.disk == D_UP_TO_DATE || s.pdsk == D_UP_TO_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct drbd_plug_cb {
|
||||||
|
struct blk_plug_cb cb;
|
||||||
|
struct drbd_request *most_recent_req;
|
||||||
|
/* do we need more? */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void drbd_unplug(struct blk_plug_cb *cb, bool from_schedule)
|
||||||
|
{
|
||||||
|
struct drbd_plug_cb *plug = container_of(cb, struct drbd_plug_cb, cb);
|
||||||
|
struct drbd_resource *resource = plug->cb.data;
|
||||||
|
struct drbd_request *req = plug->most_recent_req;
|
||||||
|
|
||||||
|
kfree(cb);
|
||||||
|
if (!req)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_irq(&resource->req_lock);
|
||||||
|
/* In case the sender did not process it yet, raise the flag to
|
||||||
|
* have it followed with P_UNPLUG_REMOTE just after. */
|
||||||
|
req->rq_state |= RQ_UNPLUG;
|
||||||
|
/* but also queue a generic unplug */
|
||||||
|
drbd_queue_unplug(req->device);
|
||||||
|
kref_put(&req->kref, drbd_req_destroy);
|
||||||
|
spin_unlock_irq(&resource->req_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct drbd_plug_cb* drbd_check_plugged(struct drbd_resource *resource)
|
||||||
|
{
|
||||||
|
/* A lot of text to say
|
||||||
|
* return (struct drbd_plug_cb*)blk_check_plugged(); */
|
||||||
|
struct drbd_plug_cb *plug;
|
||||||
|
struct blk_plug_cb *cb = blk_check_plugged(drbd_unplug, resource, sizeof(*plug));
|
||||||
|
|
||||||
|
if (cb)
|
||||||
|
plug = container_of(cb, struct drbd_plug_cb, cb);
|
||||||
|
else
|
||||||
|
plug = NULL;
|
||||||
|
return plug;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drbd_update_plug(struct drbd_plug_cb *plug, struct drbd_request *req)
|
||||||
|
{
|
||||||
|
struct drbd_request *tmp = plug->most_recent_req;
|
||||||
|
/* Will be sent to some peer.
|
||||||
|
* Remember to tag it with UNPLUG_REMOTE on unplug */
|
||||||
|
kref_get(&req->kref);
|
||||||
|
plug->most_recent_req = req;
|
||||||
|
if (tmp)
|
||||||
|
kref_put(&tmp->kref, drbd_req_destroy);
|
||||||
|
}
|
||||||
|
|
||||||
static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request *req)
|
static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request *req)
|
||||||
{
|
{
|
||||||
struct drbd_resource *resource = device->resource;
|
struct drbd_resource *resource = device->resource;
|
||||||
|
@ -1347,6 +1402,12 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request
|
||||||
no_remote = true;
|
no_remote = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (no_remote == false) {
|
||||||
|
struct drbd_plug_cb *plug = drbd_check_plugged(resource);
|
||||||
|
if (plug)
|
||||||
|
drbd_update_plug(plug, req);
|
||||||
|
}
|
||||||
|
|
||||||
/* If it took the fast path in drbd_request_prepare, add it here.
|
/* If it took the fast path in drbd_request_prepare, add it here.
|
||||||
* The slow path has added it already. */
|
* The slow path has added it already. */
|
||||||
if (list_empty(&req->req_pending_master_completion))
|
if (list_empty(&req->req_pending_master_completion))
|
||||||
|
@ -1395,7 +1456,10 @@ void __drbd_make_request(struct drbd_device *device, struct bio *bio, unsigned l
|
||||||
|
|
||||||
static void submit_fast_path(struct drbd_device *device, struct list_head *incoming)
|
static void submit_fast_path(struct drbd_device *device, struct list_head *incoming)
|
||||||
{
|
{
|
||||||
|
struct blk_plug plug;
|
||||||
struct drbd_request *req, *tmp;
|
struct drbd_request *req, *tmp;
|
||||||
|
|
||||||
|
blk_start_plug(&plug);
|
||||||
list_for_each_entry_safe(req, tmp, incoming, tl_requests) {
|
list_for_each_entry_safe(req, tmp, incoming, tl_requests) {
|
||||||
const int rw = bio_data_dir(req->master_bio);
|
const int rw = bio_data_dir(req->master_bio);
|
||||||
|
|
||||||
|
@ -1413,6 +1477,7 @@ static void submit_fast_path(struct drbd_device *device, struct list_head *incom
|
||||||
list_del_init(&req->tl_requests);
|
list_del_init(&req->tl_requests);
|
||||||
drbd_send_and_submit(device, req);
|
drbd_send_and_submit(device, req);
|
||||||
}
|
}
|
||||||
|
blk_finish_plug(&plug);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool prepare_al_transaction_nonblock(struct drbd_device *device,
|
static bool prepare_al_transaction_nonblock(struct drbd_device *device,
|
||||||
|
@ -1420,12 +1485,12 @@ static bool prepare_al_transaction_nonblock(struct drbd_device *device,
|
||||||
struct list_head *pending,
|
struct list_head *pending,
|
||||||
struct list_head *later)
|
struct list_head *later)
|
||||||
{
|
{
|
||||||
struct drbd_request *req, *tmp;
|
struct drbd_request *req;
|
||||||
int wake = 0;
|
int wake = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
spin_lock_irq(&device->al_lock);
|
spin_lock_irq(&device->al_lock);
|
||||||
list_for_each_entry_safe(req, tmp, incoming, tl_requests) {
|
while ((req = list_first_entry_or_null(incoming, struct drbd_request, tl_requests))) {
|
||||||
err = drbd_al_begin_io_nonblock(device, &req->i);
|
err = drbd_al_begin_io_nonblock(device, &req->i);
|
||||||
if (err == -ENOBUFS)
|
if (err == -ENOBUFS)
|
||||||
break;
|
break;
|
||||||
|
@ -1442,17 +1507,20 @@ static bool prepare_al_transaction_nonblock(struct drbd_device *device,
|
||||||
return !list_empty(pending);
|
return !list_empty(pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_and_submit_pending(struct drbd_device *device, struct list_head *pending)
|
static void send_and_submit_pending(struct drbd_device *device, struct list_head *pending)
|
||||||
{
|
{
|
||||||
struct drbd_request *req, *tmp;
|
struct blk_plug plug;
|
||||||
|
struct drbd_request *req;
|
||||||
|
|
||||||
list_for_each_entry_safe(req, tmp, pending, tl_requests) {
|
blk_start_plug(&plug);
|
||||||
|
while ((req = list_first_entry_or_null(pending, struct drbd_request, tl_requests))) {
|
||||||
req->rq_state |= RQ_IN_ACT_LOG;
|
req->rq_state |= RQ_IN_ACT_LOG;
|
||||||
req->in_actlog_jif = jiffies;
|
req->in_actlog_jif = jiffies;
|
||||||
atomic_dec(&device->ap_actlog_cnt);
|
atomic_dec(&device->ap_actlog_cnt);
|
||||||
list_del_init(&req->tl_requests);
|
list_del_init(&req->tl_requests);
|
||||||
drbd_send_and_submit(device, req);
|
drbd_send_and_submit(device, req);
|
||||||
}
|
}
|
||||||
|
blk_finish_plug(&plug);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_submit(struct work_struct *ws)
|
void do_submit(struct work_struct *ws)
|
||||||
|
|
|
@ -212,6 +212,11 @@ enum drbd_req_state_bits {
|
||||||
/* Should call drbd_al_complete_io() for this request... */
|
/* Should call drbd_al_complete_io() for this request... */
|
||||||
__RQ_IN_ACT_LOG,
|
__RQ_IN_ACT_LOG,
|
||||||
|
|
||||||
|
/* This was the most recent request during some blk_finish_plug()
|
||||||
|
* or its implicit from-schedule equivalent.
|
||||||
|
* We may use it as hint to send a P_UNPLUG_REMOTE */
|
||||||
|
__RQ_UNPLUG,
|
||||||
|
|
||||||
/* The peer has sent a retry ACK */
|
/* The peer has sent a retry ACK */
|
||||||
__RQ_POSTPONED,
|
__RQ_POSTPONED,
|
||||||
|
|
||||||
|
@ -249,6 +254,7 @@ enum drbd_req_state_bits {
|
||||||
#define RQ_WSAME (1UL << __RQ_WSAME)
|
#define RQ_WSAME (1UL << __RQ_WSAME)
|
||||||
#define RQ_UNMAP (1UL << __RQ_UNMAP)
|
#define RQ_UNMAP (1UL << __RQ_UNMAP)
|
||||||
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
|
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
|
||||||
|
#define RQ_UNPLUG (1UL << __RQ_UNPLUG)
|
||||||
#define RQ_POSTPONED (1UL << __RQ_POSTPONED)
|
#define RQ_POSTPONED (1UL << __RQ_POSTPONED)
|
||||||
#define RQ_COMPLETION_SUSP (1UL << __RQ_COMPLETION_SUSP)
|
#define RQ_COMPLETION_SUSP (1UL << __RQ_COMPLETION_SUSP)
|
||||||
#define RQ_EXP_RECEIVE_ACK (1UL << __RQ_EXP_RECEIVE_ACK)
|
#define RQ_EXP_RECEIVE_ACK (1UL << __RQ_EXP_RECEIVE_ACK)
|
||||||
|
|
|
@ -346,7 +346,7 @@ static enum drbd_role min_role(enum drbd_role role1, enum drbd_role role2)
|
||||||
|
|
||||||
enum drbd_role conn_highest_role(struct drbd_connection *connection)
|
enum drbd_role conn_highest_role(struct drbd_connection *connection)
|
||||||
{
|
{
|
||||||
enum drbd_role role = R_UNKNOWN;
|
enum drbd_role role = R_SECONDARY;
|
||||||
struct drbd_peer_device *peer_device;
|
struct drbd_peer_device *peer_device;
|
||||||
int vnr;
|
int vnr;
|
||||||
|
|
||||||
|
@ -579,11 +579,14 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
union drbd_state os, ns;
|
union drbd_state os, ns;
|
||||||
enum drbd_state_rv rv;
|
enum drbd_state_rv rv;
|
||||||
|
void *buffer = NULL;
|
||||||
|
|
||||||
init_completion(&done);
|
init_completion(&done);
|
||||||
|
|
||||||
if (f & CS_SERIALIZE)
|
if (f & CS_SERIALIZE)
|
||||||
mutex_lock(device->state_mutex);
|
mutex_lock(device->state_mutex);
|
||||||
|
if (f & CS_INHIBIT_MD_IO)
|
||||||
|
buffer = drbd_md_get_buffer(device, __func__);
|
||||||
|
|
||||||
spin_lock_irqsave(&device->resource->req_lock, flags);
|
spin_lock_irqsave(&device->resource->req_lock, flags);
|
||||||
os = drbd_read_state(device);
|
os = drbd_read_state(device);
|
||||||
|
@ -636,6 +639,8 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
|
||||||
}
|
}
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
|
if (buffer)
|
||||||
|
drbd_md_put_buffer(device);
|
||||||
if (f & CS_SERIALIZE)
|
if (f & CS_SERIALIZE)
|
||||||
mutex_unlock(device->state_mutex);
|
mutex_unlock(device->state_mutex);
|
||||||
|
|
||||||
|
@ -664,6 +669,47 @@ _drbd_request_state(struct drbd_device *device, union drbd_state mask,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We grab drbd_md_get_buffer(), because we don't want to "fail" the disk while
|
||||||
|
* there is IO in-flight: the transition into D_FAILED for detach purposes
|
||||||
|
* may get misinterpreted as actual IO error in a confused endio function.
|
||||||
|
*
|
||||||
|
* We wrap it all into wait_event(), to retry in case the drbd_req_state()
|
||||||
|
* returns SS_IN_TRANSIENT_STATE.
|
||||||
|
*
|
||||||
|
* To avoid potential deadlock with e.g. the receiver thread trying to grab
|
||||||
|
* drbd_md_get_buffer() while trying to get out of the "transient state", we
|
||||||
|
* need to grab and release the meta data buffer inside of that wait_event loop.
|
||||||
|
*/
|
||||||
|
static enum drbd_state_rv
|
||||||
|
request_detach(struct drbd_device *device)
|
||||||
|
{
|
||||||
|
return drbd_req_state(device, NS(disk, D_FAILED),
|
||||||
|
CS_VERBOSE | CS_ORDERED | CS_INHIBIT_MD_IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum drbd_state_rv
|
||||||
|
drbd_request_detach_interruptible(struct drbd_device *device)
|
||||||
|
{
|
||||||
|
enum drbd_state_rv rv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */
|
||||||
|
wait_event_interruptible(device->state_wait,
|
||||||
|
(rv = request_detach(device)) != SS_IN_TRANSIENT_STATE);
|
||||||
|
drbd_resume_io(device);
|
||||||
|
|
||||||
|
ret = wait_event_interruptible(device->misc_wait,
|
||||||
|
device->state.disk != D_FAILED);
|
||||||
|
|
||||||
|
if (rv == SS_IS_DISKLESS)
|
||||||
|
rv = SS_NOTHING_TO_DO;
|
||||||
|
if (ret)
|
||||||
|
rv = ERR_INTR;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
enum drbd_state_rv
|
enum drbd_state_rv
|
||||||
_drbd_request_state_holding_state_mutex(struct drbd_device *device, union drbd_state mask,
|
_drbd_request_state_holding_state_mutex(struct drbd_device *device, union drbd_state mask,
|
||||||
union drbd_state val, enum chg_state_flags f)
|
union drbd_state val, enum chg_state_flags f)
|
||||||
|
|
|
@ -71,6 +71,10 @@ enum chg_state_flags {
|
||||||
CS_DC_SUSP = 1 << 10,
|
CS_DC_SUSP = 1 << 10,
|
||||||
CS_DC_MASK = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK,
|
CS_DC_MASK = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK,
|
||||||
CS_IGN_OUTD_FAIL = 1 << 11,
|
CS_IGN_OUTD_FAIL = 1 << 11,
|
||||||
|
|
||||||
|
/* Make sure no meta data IO is in flight, by calling
|
||||||
|
* drbd_md_get_buffer(). Used for graceful detach. */
|
||||||
|
CS_INHIBIT_MD_IO = 1 << 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* drbd_dev_state and drbd_state are different types. This is to stress the
|
/* drbd_dev_state and drbd_state are different types. This is to stress the
|
||||||
|
@ -156,6 +160,10 @@ static inline int drbd_request_state(struct drbd_device *device,
|
||||||
return _drbd_request_state(device, mask, val, CS_VERBOSE + CS_ORDERED);
|
return _drbd_request_state(device, mask, val, CS_VERBOSE + CS_ORDERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for use in adm_detach() (drbd_adm_detach(), drbd_adm_down()) */
|
||||||
|
enum drbd_state_rv
|
||||||
|
drbd_request_detach_interruptible(struct drbd_device *device);
|
||||||
|
|
||||||
enum drbd_role conn_highest_role(struct drbd_connection *connection);
|
enum drbd_role conn_highest_role(struct drbd_connection *connection);
|
||||||
enum drbd_role conn_highest_peer(struct drbd_connection *connection);
|
enum drbd_role conn_highest_peer(struct drbd_connection *connection);
|
||||||
enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection);
|
enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection);
|
||||||
|
|
|
@ -65,6 +65,11 @@ void drbd_md_endio(struct bio *bio)
|
||||||
device = bio->bi_private;
|
device = bio->bi_private;
|
||||||
device->md_io.error = blk_status_to_errno(bio->bi_status);
|
device->md_io.error = blk_status_to_errno(bio->bi_status);
|
||||||
|
|
||||||
|
/* special case: drbd_md_read() during drbd_adm_attach() */
|
||||||
|
if (device->ldev)
|
||||||
|
put_ldev(device);
|
||||||
|
bio_put(bio);
|
||||||
|
|
||||||
/* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
|
/* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
|
||||||
* to timeout on the lower level device, and eventually detach from it.
|
* to timeout on the lower level device, and eventually detach from it.
|
||||||
* If this io completion runs after that timeout expired, this
|
* If this io completion runs after that timeout expired, this
|
||||||
|
@ -79,9 +84,6 @@ void drbd_md_endio(struct bio *bio)
|
||||||
drbd_md_put_buffer(device);
|
drbd_md_put_buffer(device);
|
||||||
device->md_io.done = 1;
|
device->md_io.done = 1;
|
||||||
wake_up(&device->misc_wait);
|
wake_up(&device->misc_wait);
|
||||||
bio_put(bio);
|
|
||||||
if (device->ldev) /* special case: drbd_md_read() during drbd_adm_attach() */
|
|
||||||
put_ldev(device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reads on behalf of the partner,
|
/* reads on behalf of the partner,
|
||||||
|
@ -128,6 +130,14 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
|
||||||
block_id = peer_req->block_id;
|
block_id = peer_req->block_id;
|
||||||
peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO;
|
peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO;
|
||||||
|
|
||||||
|
if (peer_req->flags & EE_WAS_ERROR) {
|
||||||
|
/* In protocol != C, we usually do not send write acks.
|
||||||
|
* In case of a write error, send the neg ack anyways. */
|
||||||
|
if (!__test_and_set_bit(__EE_SEND_WRITE_ACK, &peer_req->flags))
|
||||||
|
inc_unacked(device);
|
||||||
|
drbd_set_out_of_sync(device, peer_req->i.sector, peer_req->i.size);
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&device->resource->req_lock, flags);
|
spin_lock_irqsave(&device->resource->req_lock, flags);
|
||||||
device->writ_cnt += peer_req->i.size >> 9;
|
device->writ_cnt += peer_req->i.size >> 9;
|
||||||
list_move_tail(&peer_req->w.list, &device->done_ee);
|
list_move_tail(&peer_req->w.list, &device->done_ee);
|
||||||
|
@ -195,7 +205,8 @@ void drbd_peer_request_endio(struct bio *bio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *device)
|
static void
|
||||||
|
drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *device)
|
||||||
{
|
{
|
||||||
panic("drbd%u %s/%u potential random memory corruption caused by delayed completion of aborted local request\n",
|
panic("drbd%u %s/%u potential random memory corruption caused by delayed completion of aborted local request\n",
|
||||||
device->minor, device->resource->name, device->vnr);
|
device->minor, device->resource->name, device->vnr);
|
||||||
|
@ -1382,18 +1393,22 @@ static int drbd_send_barrier(struct drbd_connection *connection)
|
||||||
return conn_send_command(connection, sock, P_BARRIER, sizeof(*p), NULL, 0);
|
return conn_send_command(connection, sock, P_BARRIER, sizeof(*p), NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pd_send_unplug_remote(struct drbd_peer_device *pd)
|
||||||
|
{
|
||||||
|
struct drbd_socket *sock = &pd->connection->data;
|
||||||
|
if (!drbd_prepare_command(pd, sock))
|
||||||
|
return -EIO;
|
||||||
|
return drbd_send_command(pd, sock, P_UNPLUG_REMOTE, 0, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int w_send_write_hint(struct drbd_work *w, int cancel)
|
int w_send_write_hint(struct drbd_work *w, int cancel)
|
||||||
{
|
{
|
||||||
struct drbd_device *device =
|
struct drbd_device *device =
|
||||||
container_of(w, struct drbd_device, unplug_work);
|
container_of(w, struct drbd_device, unplug_work);
|
||||||
struct drbd_socket *sock;
|
|
||||||
|
|
||||||
if (cancel)
|
if (cancel)
|
||||||
return 0;
|
return 0;
|
||||||
sock = &first_peer_device(device)->connection->data;
|
return pd_send_unplug_remote(first_peer_device(device));
|
||||||
if (!drbd_prepare_command(first_peer_device(device), sock))
|
|
||||||
return -EIO;
|
|
||||||
return drbd_send_command(first_peer_device(device), sock, P_UNPLUG_REMOTE, 0, NULL, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch)
|
static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch)
|
||||||
|
@ -1455,6 +1470,7 @@ int w_send_dblock(struct drbd_work *w, int cancel)
|
||||||
struct drbd_device *device = req->device;
|
struct drbd_device *device = req->device;
|
||||||
struct drbd_peer_device *const peer_device = first_peer_device(device);
|
struct drbd_peer_device *const peer_device = first_peer_device(device);
|
||||||
struct drbd_connection *connection = peer_device->connection;
|
struct drbd_connection *connection = peer_device->connection;
|
||||||
|
bool do_send_unplug = req->rq_state & RQ_UNPLUG;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (unlikely(cancel)) {
|
if (unlikely(cancel)) {
|
||||||
|
@ -1470,6 +1486,9 @@ int w_send_dblock(struct drbd_work *w, int cancel)
|
||||||
err = drbd_send_dblock(peer_device, req);
|
err = drbd_send_dblock(peer_device, req);
|
||||||
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
|
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
|
||||||
|
|
||||||
|
if (do_send_unplug && !err)
|
||||||
|
pd_send_unplug_remote(peer_device);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1484,6 +1503,7 @@ int w_send_read_req(struct drbd_work *w, int cancel)
|
||||||
struct drbd_device *device = req->device;
|
struct drbd_device *device = req->device;
|
||||||
struct drbd_peer_device *const peer_device = first_peer_device(device);
|
struct drbd_peer_device *const peer_device = first_peer_device(device);
|
||||||
struct drbd_connection *connection = peer_device->connection;
|
struct drbd_connection *connection = peer_device->connection;
|
||||||
|
bool do_send_unplug = req->rq_state & RQ_UNPLUG;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (unlikely(cancel)) {
|
if (unlikely(cancel)) {
|
||||||
|
@ -1501,6 +1521,9 @@ int w_send_read_req(struct drbd_work *w, int cancel)
|
||||||
|
|
||||||
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
|
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
|
||||||
|
|
||||||
|
if (do_send_unplug && !err)
|
||||||
|
pd_send_unplug_remote(peer_device);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1513,7 +1536,7 @@ int w_restart_disk_io(struct drbd_work *w, int cancel)
|
||||||
drbd_al_begin_io(device, &req->i);
|
drbd_al_begin_io(device, &req->i);
|
||||||
|
|
||||||
drbd_req_make_private_bio(req, req->master_bio);
|
drbd_req_make_private_bio(req, req->master_bio);
|
||||||
req->private_bio->bi_bdev = device->ldev->backing_bdev;
|
bio_set_dev(req->private_bio, device->ldev->backing_bdev);
|
||||||
generic_make_request(req->private_bio);
|
generic_make_request(req->private_bio);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1733,6 +1756,11 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!connection) {
|
||||||
|
drbd_err(device, "No connection to peer, aborting!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!test_bit(B_RS_H_DONE, &device->flags)) {
|
if (!test_bit(B_RS_H_DONE, &device->flags)) {
|
||||||
if (side == C_SYNC_TARGET) {
|
if (side == C_SYNC_TARGET) {
|
||||||
/* Since application IO was locked out during C_WF_BITMAP_T and
|
/* Since application IO was locked out during C_WF_BITMAP_T and
|
||||||
|
|
|
@ -4134,7 +4134,7 @@ static int __floppy_read_block_0(struct block_device *bdev, int drive)
|
||||||
cbdata.drive = drive;
|
cbdata.drive = drive;
|
||||||
|
|
||||||
bio_init(&bio, &bio_vec, 1);
|
bio_init(&bio, &bio_vec, 1);
|
||||||
bio.bi_bdev = bdev;
|
bio_set_dev(&bio, bdev);
|
||||||
bio_add_page(&bio, page, size, 0);
|
bio_add_page(&bio, page, size, 0);
|
||||||
|
|
||||||
bio.bi_iter.bi_sector = 0;
|
bio.bi_iter.bi_sector = 0;
|
||||||
|
|
|
@ -1966,10 +1966,6 @@ static int __init loop_init(void)
|
||||||
struct loop_device *lo;
|
struct loop_device *lo;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = misc_register(&loop_misc);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
part_shift = 0;
|
part_shift = 0;
|
||||||
if (max_part > 0) {
|
if (max_part > 0) {
|
||||||
part_shift = fls(max_part);
|
part_shift = fls(max_part);
|
||||||
|
@ -1987,12 +1983,12 @@ static int __init loop_init(void)
|
||||||
|
|
||||||
if ((1UL << part_shift) > DISK_MAX_PARTS) {
|
if ((1UL << part_shift) > DISK_MAX_PARTS) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto misc_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_loop > 1UL << (MINORBITS - part_shift)) {
|
if (max_loop > 1UL << (MINORBITS - part_shift)) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto misc_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2011,6 +2007,11 @@ static int __init loop_init(void)
|
||||||
range = 1UL << MINORBITS;
|
range = 1UL << MINORBITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = misc_register(&loop_misc);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_out;
|
||||||
|
|
||||||
|
|
||||||
if (register_blkdev(LOOP_MAJOR, "loop")) {
|
if (register_blkdev(LOOP_MAJOR, "loop")) {
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
goto misc_out;
|
goto misc_out;
|
||||||
|
@ -2030,6 +2031,7 @@ static int __init loop_init(void)
|
||||||
|
|
||||||
misc_out:
|
misc_out:
|
||||||
misc_deregister(&loop_misc);
|
misc_deregister(&loop_misc);
|
||||||
|
err_out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ static struct dentry *nbd_dbg_dir;
|
||||||
#define NBD_MAGIC 0x68797548
|
#define NBD_MAGIC 0x68797548
|
||||||
|
|
||||||
static unsigned int nbds_max = 16;
|
static unsigned int nbds_max = 16;
|
||||||
static int max_part;
|
static int max_part = 16;
|
||||||
static struct workqueue_struct *recv_workqueue;
|
static struct workqueue_struct *recv_workqueue;
|
||||||
static int part_shift;
|
static int part_shift;
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ static ssize_t pid_show(struct device *dev,
|
||||||
return sprintf(buf, "%d\n", task_pid_nr(nbd->task_recv));
|
return sprintf(buf, "%d\n", task_pid_nr(nbd->task_recv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_attribute pid_attr = {
|
static const struct device_attribute pid_attr = {
|
||||||
.attr = { .name = "pid", .mode = S_IRUGO},
|
.attr = { .name = "pid", .mode = S_IRUGO},
|
||||||
.show = pid_show,
|
.show = pid_show,
|
||||||
};
|
};
|
||||||
|
@ -1584,6 +1584,15 @@ again:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nbd = idr_find(&nbd_index_idr, index);
|
nbd = idr_find(&nbd_index_idr, index);
|
||||||
|
if (!nbd) {
|
||||||
|
ret = nbd_dev_add(index);
|
||||||
|
if (ret < 0) {
|
||||||
|
mutex_unlock(&nbd_index_mutex);
|
||||||
|
printk(KERN_ERR "nbd: failed to add new device\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
nbd = idr_find(&nbd_index_idr, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!nbd) {
|
if (!nbd) {
|
||||||
printk(KERN_ERR "nbd: couldn't find device at index %d\n",
|
printk(KERN_ERR "nbd: couldn't find device at index %d\n",
|
||||||
|
@ -2137,4 +2146,4 @@ MODULE_LICENSE("GPL");
|
||||||
module_param(nbds_max, int, 0444);
|
module_param(nbds_max, int, 0444);
|
||||||
MODULE_PARM_DESC(nbds_max, "number of network block devices to initialize (default: 16)");
|
MODULE_PARM_DESC(nbds_max, "number of network block devices to initialize (default: 16)");
|
||||||
module_param(max_part, int, 0444);
|
module_param(max_part, int, 0444);
|
||||||
MODULE_PARM_DESC(max_part, "number of partitions per device (default: 0)");
|
MODULE_PARM_DESC(max_part, "number of partitions per device (default: 16)");
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1028,7 +1028,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
|
||||||
bio = pkt->r_bios[f];
|
bio = pkt->r_bios[f];
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
|
bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
|
||||||
bio->bi_bdev = pd->bdev;
|
bio_set_dev(bio, pd->bdev);
|
||||||
bio->bi_end_io = pkt_end_io_read;
|
bio->bi_end_io = pkt_end_io_read;
|
||||||
bio->bi_private = pkt;
|
bio->bi_private = pkt;
|
||||||
|
|
||||||
|
@ -1122,7 +1122,7 @@ static int pkt_start_recovery(struct packet_data *pkt)
|
||||||
pkt->sector = new_sector;
|
pkt->sector = new_sector;
|
||||||
|
|
||||||
bio_reset(pkt->bio);
|
bio_reset(pkt->bio);
|
||||||
pkt->bio->bi_bdev = pd->bdev;
|
bio_set_set(pkt->bio, pd->bdev);
|
||||||
bio_set_op_attrs(pkt->bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(pkt->bio, REQ_OP_WRITE, 0);
|
||||||
pkt->bio->bi_iter.bi_sector = new_sector;
|
pkt->bio->bi_iter.bi_sector = new_sector;
|
||||||
pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE;
|
pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE;
|
||||||
|
@ -1267,7 +1267,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
|
||||||
|
|
||||||
bio_reset(pkt->w_bio);
|
bio_reset(pkt->w_bio);
|
||||||
pkt->w_bio->bi_iter.bi_sector = pkt->sector;
|
pkt->w_bio->bi_iter.bi_sector = pkt->sector;
|
||||||
pkt->w_bio->bi_bdev = pd->bdev;
|
bio_set_dev(pkt->w_bio, pd->bdev);
|
||||||
pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
|
pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
|
||||||
pkt->w_bio->bi_private = pkt;
|
pkt->w_bio->bi_private = pkt;
|
||||||
|
|
||||||
|
@ -2314,7 +2314,7 @@ static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio)
|
||||||
|
|
||||||
psd->pd = pd;
|
psd->pd = pd;
|
||||||
psd->bio = bio;
|
psd->bio = bio;
|
||||||
cloned_bio->bi_bdev = pd->bdev;
|
bio_set_dev(cloned_bio, pd->bdev);
|
||||||
cloned_bio->bi_private = psd;
|
cloned_bio->bi_private = psd;
|
||||||
cloned_bio->bi_end_io = pkt_end_io_read_cloned;
|
cloned_bio->bi_end_io = pkt_end_io_read_cloned;
|
||||||
pd->stats.secs_r += bio_sectors(bio);
|
pd->stats.secs_r += bio_sectors(bio);
|
||||||
|
@ -2415,8 +2415,7 @@ static blk_qc_t pkt_make_request(struct request_queue *q, struct bio *bio)
|
||||||
|
|
||||||
pd = q->queuedata;
|
pd = q->queuedata;
|
||||||
if (!pd) {
|
if (!pd) {
|
||||||
pr_err("%s incorrect request queue\n",
|
pr_err("%s incorrect request queue\n", bio_devname(bio, b));
|
||||||
bdevname(bio->bi_bdev, b));
|
|
||||||
goto end_io;
|
goto end_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ static const struct block_device_operations rsxx_fops = {
|
||||||
|
|
||||||
static void disk_stats_start(struct rsxx_cardinfo *card, struct bio *bio)
|
static void disk_stats_start(struct rsxx_cardinfo *card, struct bio *bio)
|
||||||
{
|
{
|
||||||
generic_start_io_acct(bio_data_dir(bio), bio_sectors(bio),
|
generic_start_io_acct(card->queue, bio_data_dir(bio), bio_sectors(bio),
|
||||||
&card->gendisk->part0);
|
&card->gendisk->part0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +120,8 @@ static void disk_stats_complete(struct rsxx_cardinfo *card,
|
||||||
struct bio *bio,
|
struct bio *bio,
|
||||||
unsigned long start_time)
|
unsigned long start_time)
|
||||||
{
|
{
|
||||||
generic_end_io_acct(bio_data_dir(bio), &card->gendisk->part0,
|
generic_end_io_acct(card->queue, bio_data_dir(bio),
|
||||||
start_time);
|
&card->gendisk->part0, start_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bio_dma_done_cb(struct rsxx_cardinfo *card,
|
static void bio_dma_done_cb(struct rsxx_cardinfo *card,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,15 @@
|
||||||
/* Copyright 2012 STEC, Inc.
|
/*
|
||||||
|
* Copyright 2012 STEC, Inc.
|
||||||
|
* Copyright (c) 2017 Western Digital Corporation or its affiliates.
|
||||||
*
|
*
|
||||||
* This file is licensed under the terms of the 3-clause
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* BSD License (http://opensource.org/licenses/BSD-3-Clause)
|
* the terms of the GNU General Public License version 2.
|
||||||
* or the GNU GPL-2.0 (http://www.gnu.org/licenses/gpl-2.0.html),
|
|
||||||
* at your option. Both licenses are also available in the LICENSE file
|
|
||||||
* distributed with this project. This file may not be copied, modified,
|
|
||||||
* or distributed except in accordance with those terms.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef SKD_S1120_H
|
#ifndef SKD_S1120_H
|
||||||
#define SKD_S1120_H
|
#define SKD_S1120_H
|
||||||
|
|
||||||
#pragma pack(push, s1120_h, 1)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Q-channel, 64-bit r/w
|
* Q-channel, 64-bit r/w
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +26,7 @@
|
||||||
#define FIT_QCMD_MSGSIZE_128 (0x1 << 4)
|
#define FIT_QCMD_MSGSIZE_128 (0x1 << 4)
|
||||||
#define FIT_QCMD_MSGSIZE_256 (0x2 << 4)
|
#define FIT_QCMD_MSGSIZE_256 (0x2 << 4)
|
||||||
#define FIT_QCMD_MSGSIZE_512 (0x3 << 4)
|
#define FIT_QCMD_MSGSIZE_512 (0x3 << 4)
|
||||||
#define FIT_QCMD_BASE_ADDRESS_MASK (0xFFFFFFFFFFFFFFC0ull)
|
#define FIT_QCMD_ALIGN L1_CACHE_BYTES
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control, 32-bit r/w
|
* Control, 32-bit r/w
|
||||||
|
@ -250,7 +246,7 @@ struct fit_msg_hdr {
|
||||||
* 20-23 of the FIT_MTD_FITFW_INIT response.
|
* 20-23 of the FIT_MTD_FITFW_INIT response.
|
||||||
*/
|
*/
|
||||||
struct fit_completion_entry_v1 {
|
struct fit_completion_entry_v1 {
|
||||||
uint32_t num_returned_bytes;
|
__be32 num_returned_bytes;
|
||||||
uint16_t tag;
|
uint16_t tag;
|
||||||
uint8_t status; /* SCSI status */
|
uint8_t status; /* SCSI status */
|
||||||
uint8_t cycle;
|
uint8_t cycle;
|
||||||
|
@ -278,7 +274,7 @@ struct fit_comp_error_info {
|
||||||
uint16_t sks_low; /* 10: Sense Key Specific (LSW) */
|
uint16_t sks_low; /* 10: Sense Key Specific (LSW) */
|
||||||
uint16_t reserved3; /* 12: Part of additional sense bytes (unused) */
|
uint16_t reserved3; /* 12: Part of additional sense bytes (unused) */
|
||||||
uint16_t uec; /* 14: Additional Sense Bytes */
|
uint16_t uec; /* 14: Additional Sense Bytes */
|
||||||
uint64_t per; /* 16: Additional Sense Bytes */
|
uint64_t per __packed; /* 16: Additional Sense Bytes */
|
||||||
uint8_t reserved4[2]; /* 1E: Additional Sense Bytes (unused) */
|
uint8_t reserved4[2]; /* 1E: Additional Sense Bytes (unused) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -292,11 +288,11 @@ struct fit_comp_error_info {
|
||||||
* Version one has the last 32 bits sg_list_len_bytes;
|
* Version one has the last 32 bits sg_list_len_bytes;
|
||||||
*/
|
*/
|
||||||
struct skd_command_header {
|
struct skd_command_header {
|
||||||
uint64_t sg_list_dma_address;
|
__be64 sg_list_dma_address;
|
||||||
uint16_t tag;
|
uint16_t tag;
|
||||||
uint8_t attribute;
|
uint8_t attribute;
|
||||||
uint8_t add_cdb_len; /* In 32 bit words */
|
uint8_t add_cdb_len; /* In 32 bit words */
|
||||||
uint32_t sg_list_len_bytes;
|
__be32 sg_list_len_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct skd_scsi_request {
|
struct skd_scsi_request {
|
||||||
|
@ -309,22 +305,20 @@ struct driver_inquiry_data {
|
||||||
uint8_t peripheral_device_type:5;
|
uint8_t peripheral_device_type:5;
|
||||||
uint8_t qualifier:3;
|
uint8_t qualifier:3;
|
||||||
uint8_t page_code;
|
uint8_t page_code;
|
||||||
uint16_t page_length;
|
__be16 page_length;
|
||||||
uint16_t pcie_bus_number;
|
__be16 pcie_bus_number;
|
||||||
uint8_t pcie_device_number;
|
uint8_t pcie_device_number;
|
||||||
uint8_t pcie_function_number;
|
uint8_t pcie_function_number;
|
||||||
uint8_t pcie_link_speed;
|
uint8_t pcie_link_speed;
|
||||||
uint8_t pcie_link_lanes;
|
uint8_t pcie_link_lanes;
|
||||||
uint16_t pcie_vendor_id;
|
__be16 pcie_vendor_id;
|
||||||
uint16_t pcie_device_id;
|
__be16 pcie_device_id;
|
||||||
uint16_t pcie_subsystem_vendor_id;
|
__be16 pcie_subsystem_vendor_id;
|
||||||
uint16_t pcie_subsystem_device_id;
|
__be16 pcie_subsystem_device_id;
|
||||||
uint8_t reserved1[2];
|
uint8_t reserved1[2];
|
||||||
uint8_t reserved2[3];
|
uint8_t reserved2[3];
|
||||||
uint8_t driver_version_length;
|
uint8_t driver_version_length;
|
||||||
uint8_t driver_version[0x14];
|
uint8_t driver_version[0x14];
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop, s1120_h)
|
|
||||||
|
|
||||||
#endif /* SKD_S1120_H */
|
#endif /* SKD_S1120_H */
|
||||||
|
|
|
@ -265,7 +265,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
|
spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
|
||||||
if (req_op(req) == REQ_OP_SCSI_IN || req_op(req) == REQ_OP_SCSI_OUT)
|
if (blk_rq_is_scsi(req))
|
||||||
err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num);
|
err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num);
|
||||||
else
|
else
|
||||||
err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
|
err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
|
||||||
|
|
|
@ -705,9 +705,9 @@ static unsigned int xen_blkbk_unmap_prepare(
|
||||||
GNTMAP_host_map, pages[i]->handle);
|
GNTMAP_host_map, pages[i]->handle);
|
||||||
pages[i]->handle = BLKBACK_INVALID_HANDLE;
|
pages[i]->handle = BLKBACK_INVALID_HANDLE;
|
||||||
invcount++;
|
invcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return invcount;
|
return invcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_queue_data *data)
|
static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_queue_data *data)
|
||||||
|
@ -1251,6 +1251,7 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
|
||||||
break;
|
break;
|
||||||
case BLKIF_OP_WRITE_BARRIER:
|
case BLKIF_OP_WRITE_BARRIER:
|
||||||
drain = true;
|
drain = true;
|
||||||
|
/* fall through */
|
||||||
case BLKIF_OP_FLUSH_DISKCACHE:
|
case BLKIF_OP_FLUSH_DISKCACHE:
|
||||||
ring->st_f_req++;
|
ring->st_f_req++;
|
||||||
operation = REQ_OP_WRITE;
|
operation = REQ_OP_WRITE;
|
||||||
|
@ -1362,7 +1363,7 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
|
||||||
goto fail_put_bio;
|
goto fail_put_bio;
|
||||||
|
|
||||||
biolist[nbio++] = bio;
|
biolist[nbio++] = bio;
|
||||||
bio->bi_bdev = preq.bdev;
|
bio_set_dev(bio, preq.bdev);
|
||||||
bio->bi_private = pending_req;
|
bio->bi_private = pending_req;
|
||||||
bio->bi_end_io = end_block_io_op;
|
bio->bi_end_io = end_block_io_op;
|
||||||
bio->bi_iter.bi_sector = preq.sector_number;
|
bio->bi_iter.bi_sector = preq.sector_number;
|
||||||
|
@ -1381,7 +1382,7 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
|
||||||
goto fail_put_bio;
|
goto fail_put_bio;
|
||||||
|
|
||||||
biolist[nbio++] = bio;
|
biolist[nbio++] = bio;
|
||||||
bio->bi_bdev = preq.bdev;
|
bio_set_dev(bio, preq.bdev);
|
||||||
bio->bi_private = pending_req;
|
bio->bi_private = pending_req;
|
||||||
bio->bi_end_io = end_block_io_op;
|
bio->bi_end_io = end_block_io_op;
|
||||||
bio_set_op_attrs(bio, operation, operation_flags);
|
bio_set_op_attrs(bio, operation, operation_flags);
|
||||||
|
|
|
@ -816,7 +816,8 @@ static void frontend_changed(struct xenbus_device *dev,
|
||||||
xenbus_switch_state(dev, XenbusStateClosed);
|
xenbus_switch_state(dev, XenbusStateClosed);
|
||||||
if (xenbus_dev_is_online(dev))
|
if (xenbus_dev_is_online(dev))
|
||||||
break;
|
break;
|
||||||
/* fall through if not online */
|
/* fall through */
|
||||||
|
/* if not online */
|
||||||
case XenbusStateUnknown:
|
case XenbusStateUnknown:
|
||||||
/* implies xen_blkif_disconnect() via xen_blkbk_remove() */
|
/* implies xen_blkif_disconnect() via xen_blkbk_remove() */
|
||||||
device_unregister(&dev->dev);
|
device_unregister(&dev->dev);
|
||||||
|
|
|
@ -2456,7 +2456,7 @@ static void blkback_changed(struct xenbus_device *dev,
|
||||||
case XenbusStateClosed:
|
case XenbusStateClosed:
|
||||||
if (dev->state == XenbusStateClosed)
|
if (dev->state == XenbusStateClosed)
|
||||||
break;
|
break;
|
||||||
/* Missed the backend's Closing state -- fallthrough */
|
/* fall through */
|
||||||
case XenbusStateClosing:
|
case XenbusStateClosing:
|
||||||
if (info)
|
if (info)
|
||||||
blkfront_closing(info);
|
blkfront_closing(info);
|
||||||
|
|
|
@ -467,7 +467,7 @@ static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
|
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
|
||||||
bio->bi_bdev = zram->bdev;
|
bio_set_dev(bio, zram->bdev);
|
||||||
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, bvec->bv_offset)) {
|
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, bvec->bv_offset)) {
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -561,7 +561,7 @@ static int write_to_bdev(struct zram *zram, struct bio_vec *bvec,
|
||||||
}
|
}
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
|
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
|
||||||
bio->bi_bdev = zram->bdev;
|
bio_set_dev(bio, zram->bdev);
|
||||||
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len,
|
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len,
|
||||||
bvec->bv_offset)) {
|
bvec->bv_offset)) {
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
@ -1171,9 +1171,10 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
|
||||||
{
|
{
|
||||||
unsigned long start_time = jiffies;
|
unsigned long start_time = jiffies;
|
||||||
int rw_acct = is_write ? REQ_OP_WRITE : REQ_OP_READ;
|
int rw_acct = is_write ? REQ_OP_WRITE : REQ_OP_READ;
|
||||||
|
struct request_queue *q = zram->disk->queue;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
generic_start_io_acct(rw_acct, bvec->bv_len >> SECTOR_SHIFT,
|
generic_start_io_acct(q, rw_acct, bvec->bv_len >> SECTOR_SHIFT,
|
||||||
&zram->disk->part0);
|
&zram->disk->part0);
|
||||||
|
|
||||||
if (!is_write) {
|
if (!is_write) {
|
||||||
|
@ -1185,7 +1186,7 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
|
||||||
ret = zram_bvec_write(zram, bvec, index, offset, bio);
|
ret = zram_bvec_write(zram, bvec, index, offset, bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_end_io_acct(rw_acct, &zram->disk->part0, start_time);
|
generic_end_io_acct(q, rw_acct, &zram->disk->part0, start_time);
|
||||||
|
|
||||||
if (unlikely(ret < 0)) {
|
if (unlikely(ret < 0)) {
|
||||||
if (!is_write)
|
if (!is_write)
|
||||||
|
|
|
@ -72,7 +72,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
|
||||||
drive->failed_pc = NULL;
|
drive->failed_pc = NULL;
|
||||||
|
|
||||||
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
|
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
|
||||||
(req_op(rq) == REQ_OP_SCSI_IN || req_op(rq) == REQ_OP_SCSI_OUT))
|
blk_rq_is_scsi(rq))
|
||||||
uptodate = 1; /* FIXME */
|
uptodate = 1; /* FIXME */
|
||||||
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
|
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ void bch_btree_verify(struct btree *b)
|
||||||
v->keys.ops = b->keys.ops;
|
v->keys.ops = b->keys.ops;
|
||||||
|
|
||||||
bio = bch_bbio_alloc(b->c);
|
bio = bch_bbio_alloc(b->c);
|
||||||
bio->bi_bdev = PTR_CACHE(b->c, &b->key, 0)->bdev;
|
bio_set_dev(bio, PTR_CACHE(b->c, &b->key, 0)->bdev);
|
||||||
bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0);
|
bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0);
|
||||||
bio->bi_iter.bi_size = KEY_SIZE(&v->key) << 9;
|
bio->bi_iter.bi_size = KEY_SIZE(&v->key) << 9;
|
||||||
bio->bi_opf = REQ_OP_READ | REQ_META;
|
bio->bi_opf = REQ_OP_READ | REQ_META;
|
||||||
|
|
|
@ -34,7 +34,7 @@ void __bch_submit_bbio(struct bio *bio, struct cache_set *c)
|
||||||
struct bbio *b = container_of(bio, struct bbio, bio);
|
struct bbio *b = container_of(bio, struct bbio, bio);
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0);
|
bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0);
|
||||||
bio->bi_bdev = PTR_CACHE(c, &b->key, 0)->bdev;
|
bio_set_dev(bio, PTR_CACHE(c, &b->key, 0)->bdev);
|
||||||
|
|
||||||
b->submit_time_us = local_clock_us();
|
b->submit_time_us = local_clock_us();
|
||||||
closure_bio_submit(bio, bio->bi_private);
|
closure_bio_submit(bio, bio->bi_private);
|
||||||
|
|
|
@ -53,7 +53,7 @@ reread: left = ca->sb.bucket_size - offset;
|
||||||
|
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
bio->bi_iter.bi_sector = bucket + offset;
|
bio->bi_iter.bi_sector = bucket + offset;
|
||||||
bio->bi_bdev = ca->bdev;
|
bio_set_dev(bio, ca->bdev);
|
||||||
bio->bi_iter.bi_size = len << 9;
|
bio->bi_iter.bi_size = len << 9;
|
||||||
|
|
||||||
bio->bi_end_io = journal_read_endio;
|
bio->bi_end_io = journal_read_endio;
|
||||||
|
@ -452,7 +452,7 @@ static void do_journal_discard(struct cache *ca)
|
||||||
bio_set_op_attrs(bio, REQ_OP_DISCARD, 0);
|
bio_set_op_attrs(bio, REQ_OP_DISCARD, 0);
|
||||||
bio->bi_iter.bi_sector = bucket_to_sector(ca->set,
|
bio->bi_iter.bi_sector = bucket_to_sector(ca->set,
|
||||||
ca->sb.d[ja->discard_idx]);
|
ca->sb.d[ja->discard_idx]);
|
||||||
bio->bi_bdev = ca->bdev;
|
bio_set_dev(bio, ca->bdev);
|
||||||
bio->bi_iter.bi_size = bucket_bytes(ca);
|
bio->bi_iter.bi_size = bucket_bytes(ca);
|
||||||
bio->bi_end_io = journal_discard_endio;
|
bio->bi_end_io = journal_discard_endio;
|
||||||
|
|
||||||
|
@ -623,7 +623,7 @@ static void journal_write_unlocked(struct closure *cl)
|
||||||
|
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
bio->bi_iter.bi_sector = PTR_OFFSET(k, i);
|
bio->bi_iter.bi_sector = PTR_OFFSET(k, i);
|
||||||
bio->bi_bdev = ca->bdev;
|
bio_set_dev(bio, ca->bdev);
|
||||||
bio->bi_iter.bi_size = sectors << 9;
|
bio->bi_iter.bi_size = sectors << 9;
|
||||||
|
|
||||||
bio->bi_end_io = journal_write_endio;
|
bio->bi_end_io = journal_write_endio;
|
||||||
|
|
|
@ -607,7 +607,8 @@ static void request_endio(struct bio *bio)
|
||||||
static void bio_complete(struct search *s)
|
static void bio_complete(struct search *s)
|
||||||
{
|
{
|
||||||
if (s->orig_bio) {
|
if (s->orig_bio) {
|
||||||
generic_end_io_acct(bio_data_dir(s->orig_bio),
|
struct request_queue *q = s->orig_bio->bi_disk->queue;
|
||||||
|
generic_end_io_acct(q, bio_data_dir(s->orig_bio),
|
||||||
&s->d->disk->part0, s->start_time);
|
&s->d->disk->part0, s->start_time);
|
||||||
|
|
||||||
trace_bcache_request_end(s->d, s->orig_bio);
|
trace_bcache_request_end(s->d, s->orig_bio);
|
||||||
|
@ -734,7 +735,7 @@ static void cached_dev_read_done(struct closure *cl)
|
||||||
if (s->iop.bio) {
|
if (s->iop.bio) {
|
||||||
bio_reset(s->iop.bio);
|
bio_reset(s->iop.bio);
|
||||||
s->iop.bio->bi_iter.bi_sector = s->cache_miss->bi_iter.bi_sector;
|
s->iop.bio->bi_iter.bi_sector = s->cache_miss->bi_iter.bi_sector;
|
||||||
s->iop.bio->bi_bdev = s->cache_miss->bi_bdev;
|
bio_copy_dev(s->iop.bio, s->cache_miss);
|
||||||
s->iop.bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
|
s->iop.bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
|
||||||
bch_bio_map(s->iop.bio, NULL);
|
bch_bio_map(s->iop.bio, NULL);
|
||||||
|
|
||||||
|
@ -793,7 +794,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
|
||||||
!(bio->bi_opf & REQ_META) &&
|
!(bio->bi_opf & REQ_META) &&
|
||||||
s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA)
|
s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA)
|
||||||
reada = min_t(sector_t, dc->readahead >> 9,
|
reada = min_t(sector_t, dc->readahead >> 9,
|
||||||
bdev_sectors(bio->bi_bdev) - bio_end_sector(bio));
|
get_capacity(bio->bi_disk) - bio_end_sector(bio));
|
||||||
|
|
||||||
s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada);
|
s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada);
|
||||||
|
|
||||||
|
@ -819,7 +820,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
|
||||||
goto out_submit;
|
goto out_submit;
|
||||||
|
|
||||||
cache_bio->bi_iter.bi_sector = miss->bi_iter.bi_sector;
|
cache_bio->bi_iter.bi_sector = miss->bi_iter.bi_sector;
|
||||||
cache_bio->bi_bdev = miss->bi_bdev;
|
bio_copy_dev(cache_bio, miss);
|
||||||
cache_bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
|
cache_bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
|
||||||
|
|
||||||
cache_bio->bi_end_io = request_endio;
|
cache_bio->bi_end_io = request_endio;
|
||||||
|
@ -918,7 +919,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
|
||||||
struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0,
|
struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0,
|
||||||
dc->disk.bio_split);
|
dc->disk.bio_split);
|
||||||
|
|
||||||
flush->bi_bdev = bio->bi_bdev;
|
bio_copy_dev(flush, bio);
|
||||||
flush->bi_end_io = request_endio;
|
flush->bi_end_io = request_endio;
|
||||||
flush->bi_private = cl;
|
flush->bi_private = cl;
|
||||||
flush->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
flush->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||||
|
@ -955,13 +956,13 @@ static blk_qc_t cached_dev_make_request(struct request_queue *q,
|
||||||
struct bio *bio)
|
struct bio *bio)
|
||||||
{
|
{
|
||||||
struct search *s;
|
struct search *s;
|
||||||
struct bcache_device *d = bio->bi_bdev->bd_disk->private_data;
|
struct bcache_device *d = bio->bi_disk->private_data;
|
||||||
struct cached_dev *dc = container_of(d, struct cached_dev, disk);
|
struct cached_dev *dc = container_of(d, struct cached_dev, disk);
|
||||||
int rw = bio_data_dir(bio);
|
int rw = bio_data_dir(bio);
|
||||||
|
|
||||||
generic_start_io_acct(rw, bio_sectors(bio), &d->disk->part0);
|
generic_start_io_acct(q, rw, bio_sectors(bio), &d->disk->part0);
|
||||||
|
|
||||||
bio->bi_bdev = dc->bdev;
|
bio_set_dev(bio, dc->bdev);
|
||||||
bio->bi_iter.bi_sector += dc->sb.data_offset;
|
bio->bi_iter.bi_sector += dc->sb.data_offset;
|
||||||
|
|
||||||
if (cached_dev_get(dc)) {
|
if (cached_dev_get(dc)) {
|
||||||
|
@ -1071,10 +1072,10 @@ static blk_qc_t flash_dev_make_request(struct request_queue *q,
|
||||||
{
|
{
|
||||||
struct search *s;
|
struct search *s;
|
||||||
struct closure *cl;
|
struct closure *cl;
|
||||||
struct bcache_device *d = bio->bi_bdev->bd_disk->private_data;
|
struct bcache_device *d = bio->bi_disk->private_data;
|
||||||
int rw = bio_data_dir(bio);
|
int rw = bio_data_dir(bio);
|
||||||
|
|
||||||
generic_start_io_acct(rw, bio_sectors(bio), &d->disk->part0);
|
generic_start_io_acct(q, rw, bio_sectors(bio), &d->disk->part0);
|
||||||
|
|
||||||
s = search_alloc(bio, d);
|
s = search_alloc(bio, d);
|
||||||
cl = &s->cl;
|
cl = &s->cl;
|
||||||
|
|
|
@ -257,7 +257,7 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
|
||||||
closure_init(cl, parent);
|
closure_init(cl, parent);
|
||||||
|
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
bio->bi_bdev = dc->bdev;
|
bio_set_dev(bio, dc->bdev);
|
||||||
bio->bi_end_io = write_bdev_super_endio;
|
bio->bi_end_io = write_bdev_super_endio;
|
||||||
bio->bi_private = dc;
|
bio->bi_private = dc;
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ void bcache_write_super(struct cache_set *c)
|
||||||
SET_CACHE_SYNC(&ca->sb, CACHE_SYNC(&c->sb));
|
SET_CACHE_SYNC(&ca->sb, CACHE_SYNC(&c->sb));
|
||||||
|
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
bio->bi_bdev = ca->bdev;
|
bio_set_dev(bio, ca->bdev);
|
||||||
bio->bi_end_io = write_super_endio;
|
bio->bi_end_io = write_super_endio;
|
||||||
bio->bi_private = ca;
|
bio->bi_private = ca;
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ static void prio_io(struct cache *ca, uint64_t bucket, int op,
|
||||||
closure_init_stack(cl);
|
closure_init_stack(cl);
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = bucket * ca->sb.bucket_size;
|
bio->bi_iter.bi_sector = bucket * ca->sb.bucket_size;
|
||||||
bio->bi_bdev = ca->bdev;
|
bio_set_dev(bio, ca->bdev);
|
||||||
bio->bi_iter.bi_size = bucket_bytes(ca);
|
bio->bi_iter.bi_size = bucket_bytes(ca);
|
||||||
|
|
||||||
bio->bi_end_io = prio_endio;
|
bio->bi_end_io = prio_endio;
|
||||||
|
|
|
@ -181,7 +181,7 @@ static void write_dirty(struct closure *cl)
|
||||||
dirty_init(w);
|
dirty_init(w);
|
||||||
bio_set_op_attrs(&io->bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(&io->bio, REQ_OP_WRITE, 0);
|
||||||
io->bio.bi_iter.bi_sector = KEY_START(&w->key);
|
io->bio.bi_iter.bi_sector = KEY_START(&w->key);
|
||||||
io->bio.bi_bdev = io->dc->bdev;
|
bio_set_dev(&io->bio, io->dc->bdev);
|
||||||
io->bio.bi_end_io = dirty_endio;
|
io->bio.bi_end_io = dirty_endio;
|
||||||
|
|
||||||
closure_bio_submit(&io->bio, cl);
|
closure_bio_submit(&io->bio, cl);
|
||||||
|
@ -250,8 +250,7 @@ static void read_dirty(struct cached_dev *dc)
|
||||||
dirty_init(w);
|
dirty_init(w);
|
||||||
bio_set_op_attrs(&io->bio, REQ_OP_READ, 0);
|
bio_set_op_attrs(&io->bio, REQ_OP_READ, 0);
|
||||||
io->bio.bi_iter.bi_sector = PTR_OFFSET(&w->key, 0);
|
io->bio.bi_iter.bi_sector = PTR_OFFSET(&w->key, 0);
|
||||||
io->bio.bi_bdev = PTR_CACHE(dc->disk.c,
|
bio_set_dev(&io->bio, PTR_CACHE(dc->disk.c, &w->key, 0)->bdev);
|
||||||
&w->key, 0)->bdev;
|
|
||||||
io->bio.bi_end_io = read_dirty_endio;
|
io->bio.bi_end_io = read_dirty_endio;
|
||||||
|
|
||||||
if (bio_alloc_pages(&io->bio, GFP_KERNEL))
|
if (bio_alloc_pages(&io->bio, GFP_KERNEL))
|
||||||
|
|
|
@ -18,21 +18,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct dm_bio_details {
|
struct dm_bio_details {
|
||||||
struct block_device *bi_bdev;
|
struct gendisk *bi_disk;
|
||||||
|
u8 bi_partno;
|
||||||
unsigned long bi_flags;
|
unsigned long bi_flags;
|
||||||
struct bvec_iter bi_iter;
|
struct bvec_iter bi_iter;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
|
static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
|
||||||
{
|
{
|
||||||
bd->bi_bdev = bio->bi_bdev;
|
bd->bi_disk = bio->bi_disk;
|
||||||
|
bd->bi_partno = bio->bi_partno;
|
||||||
bd->bi_flags = bio->bi_flags;
|
bd->bi_flags = bio->bi_flags;
|
||||||
bd->bi_iter = bio->bi_iter;
|
bd->bi_iter = bio->bi_iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
|
static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio->bi_bdev = bd->bi_bdev;
|
bio->bi_disk = bd->bi_disk;
|
||||||
|
bio->bi_partno = bd->bi_partno;
|
||||||
bio->bi_flags = bd->bi_flags;
|
bio->bi_flags = bd->bi_flags;
|
||||||
bio->bi_iter = bd->bi_iter;
|
bio->bi_iter = bd->bi_iter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -616,7 +616,7 @@ static void use_inline_bio(struct dm_buffer *b, int rw, sector_t sector,
|
||||||
|
|
||||||
bio_init(&b->bio, b->bio_vec, DM_BUFIO_INLINE_VECS);
|
bio_init(&b->bio, b->bio_vec, DM_BUFIO_INLINE_VECS);
|
||||||
b->bio.bi_iter.bi_sector = sector;
|
b->bio.bi_iter.bi_sector = sector;
|
||||||
b->bio.bi_bdev = b->c->bdev;
|
bio_set_dev(&b->bio, b->c->bdev);
|
||||||
b->bio.bi_end_io = inline_endio;
|
b->bio.bi_end_io = inline_endio;
|
||||||
/*
|
/*
|
||||||
* Use of .bi_private isn't a problem here because
|
* Use of .bi_private isn't a problem here because
|
||||||
|
|
|
@ -833,7 +833,7 @@ static bool is_discarded_oblock(struct cache *cache, dm_oblock_t b)
|
||||||
*--------------------------------------------------------------*/
|
*--------------------------------------------------------------*/
|
||||||
static void remap_to_origin(struct cache *cache, struct bio *bio)
|
static void remap_to_origin(struct cache *cache, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio->bi_bdev = cache->origin_dev->bdev;
|
bio_set_dev(bio, cache->origin_dev->bdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remap_to_cache(struct cache *cache, struct bio *bio,
|
static void remap_to_cache(struct cache *cache, struct bio *bio,
|
||||||
|
@ -842,7 +842,7 @@ static void remap_to_cache(struct cache *cache, struct bio *bio,
|
||||||
sector_t bi_sector = bio->bi_iter.bi_sector;
|
sector_t bi_sector = bio->bi_iter.bi_sector;
|
||||||
sector_t block = from_cblock(cblock);
|
sector_t block = from_cblock(cblock);
|
||||||
|
|
||||||
bio->bi_bdev = cache->cache_dev->bdev;
|
bio_set_dev(bio, cache->cache_dev->bdev);
|
||||||
if (!block_size_is_power_of_two(cache))
|
if (!block_size_is_power_of_two(cache))
|
||||||
bio->bi_iter.bi_sector =
|
bio->bi_iter.bi_sector =
|
||||||
(block * cache->sectors_per_block) +
|
(block * cache->sectors_per_block) +
|
||||||
|
|
|
@ -932,9 +932,6 @@ static int dm_crypt_integrity_io_alloc(struct dm_crypt_io *io, struct bio *bio)
|
||||||
bip->bip_iter.bi_size = tag_len;
|
bip->bip_iter.bi_size = tag_len;
|
||||||
bip->bip_iter.bi_sector = io->cc->start + io->sector;
|
bip->bip_iter.bi_sector = io->cc->start + io->sector;
|
||||||
|
|
||||||
/* We own the metadata, do not let bio_free to release it */
|
|
||||||
bip->bip_flags &= ~BIP_BLOCK_INTEGRITY;
|
|
||||||
|
|
||||||
ret = bio_integrity_add_page(bio, virt_to_page(io->integrity_metadata),
|
ret = bio_integrity_add_page(bio, virt_to_page(io->integrity_metadata),
|
||||||
tag_len, offset_in_page(io->integrity_metadata));
|
tag_len, offset_in_page(io->integrity_metadata));
|
||||||
if (unlikely(ret != tag_len))
|
if (unlikely(ret != tag_len))
|
||||||
|
@ -1546,7 +1543,7 @@ static void clone_init(struct dm_crypt_io *io, struct bio *clone)
|
||||||
|
|
||||||
clone->bi_private = io;
|
clone->bi_private = io;
|
||||||
clone->bi_end_io = crypt_endio;
|
clone->bi_end_io = crypt_endio;
|
||||||
clone->bi_bdev = cc->dev->bdev;
|
bio_set_dev(clone, cc->dev->bdev);
|
||||||
clone->bi_opf = io->base_bio->bi_opf;
|
clone->bi_opf = io->base_bio->bi_opf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2795,7 +2792,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
|
||||||
*/
|
*/
|
||||||
if (unlikely(bio->bi_opf & REQ_PREFLUSH ||
|
if (unlikely(bio->bi_opf & REQ_PREFLUSH ||
|
||||||
bio_op(bio) == REQ_OP_DISCARD)) {
|
bio_op(bio) == REQ_OP_DISCARD)) {
|
||||||
bio->bi_bdev = cc->dev->bdev;
|
bio_set_dev(bio, cc->dev->bdev);
|
||||||
if (bio_sectors(bio))
|
if (bio_sectors(bio))
|
||||||
bio->bi_iter.bi_sector = cc->start +
|
bio->bi_iter.bi_sector = cc->start +
|
||||||
dm_target_offset(ti, bio->bi_iter.bi_sector);
|
dm_target_offset(ti, bio->bi_iter.bi_sector);
|
||||||
|
|
|
@ -282,7 +282,7 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
|
||||||
struct delay_c *dc = ti->private;
|
struct delay_c *dc = ti->private;
|
||||||
|
|
||||||
if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) {
|
if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) {
|
||||||
bio->bi_bdev = dc->dev_write->bdev;
|
bio_set_dev(bio, dc->dev_write->bdev);
|
||||||
if (bio_sectors(bio))
|
if (bio_sectors(bio))
|
||||||
bio->bi_iter.bi_sector = dc->start_write +
|
bio->bi_iter.bi_sector = dc->start_write +
|
||||||
dm_target_offset(ti, bio->bi_iter.bi_sector);
|
dm_target_offset(ti, bio->bi_iter.bi_sector);
|
||||||
|
@ -290,7 +290,7 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
|
||||||
return delay_bio(dc, dc->write_delay, bio);
|
return delay_bio(dc, dc->write_delay, bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
bio->bi_bdev = dc->dev_read->bdev;
|
bio_set_dev(bio, dc->dev_read->bdev);
|
||||||
bio->bi_iter.bi_sector = dc->start_read +
|
bio->bi_iter.bi_sector = dc->start_read +
|
||||||
dm_target_offset(ti, bio->bi_iter.bi_sector);
|
dm_target_offset(ti, bio->bi_iter.bi_sector);
|
||||||
|
|
||||||
|
|
|
@ -1192,7 +1192,7 @@ static dm_block_t get_block(struct era *era, struct bio *bio)
|
||||||
|
|
||||||
static void remap_to_origin(struct era *era, struct bio *bio)
|
static void remap_to_origin(struct era *era, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio->bi_bdev = era->origin_dev->bdev;
|
bio_set_dev(bio, era->origin_dev->bdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------
|
/*----------------------------------------------------------------
|
||||||
|
|
|
@ -274,7 +274,7 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct flakey_c *fc = ti->private;
|
struct flakey_c *fc = ti->private;
|
||||||
|
|
||||||
bio->bi_bdev = fc->dev->bdev;
|
bio_set_dev(bio, fc->dev->bdev);
|
||||||
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
|
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
|
||||||
bio->bi_iter.bi_sector =
|
bio->bi_iter.bi_sector =
|
||||||
flakey_map_sector(ti, bio->bi_iter.bi_sector);
|
flakey_map_sector(ti, bio->bi_iter.bi_sector);
|
||||||
|
|
|
@ -250,7 +250,8 @@ struct dm_integrity_io {
|
||||||
|
|
||||||
struct completion *completion;
|
struct completion *completion;
|
||||||
|
|
||||||
struct block_device *orig_bi_bdev;
|
struct gendisk *orig_bi_disk;
|
||||||
|
u8 orig_bi_partno;
|
||||||
bio_end_io_t *orig_bi_end_io;
|
bio_end_io_t *orig_bi_end_io;
|
||||||
struct bio_integrity_payload *orig_bi_integrity;
|
struct bio_integrity_payload *orig_bi_integrity;
|
||||||
struct bvec_iter orig_bi_iter;
|
struct bvec_iter orig_bi_iter;
|
||||||
|
@ -1164,7 +1165,8 @@ static void integrity_end_io(struct bio *bio)
|
||||||
struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io));
|
struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io));
|
||||||
|
|
||||||
bio->bi_iter = dio->orig_bi_iter;
|
bio->bi_iter = dio->orig_bi_iter;
|
||||||
bio->bi_bdev = dio->orig_bi_bdev;
|
bio->bi_disk = dio->orig_bi_disk;
|
||||||
|
bio->bi_partno = dio->orig_bi_partno;
|
||||||
if (dio->orig_bi_integrity) {
|
if (dio->orig_bi_integrity) {
|
||||||
bio->bi_integrity = dio->orig_bi_integrity;
|
bio->bi_integrity = dio->orig_bi_integrity;
|
||||||
bio->bi_opf |= REQ_INTEGRITY;
|
bio->bi_opf |= REQ_INTEGRITY;
|
||||||
|
@ -1681,8 +1683,9 @@ sleep:
|
||||||
|
|
||||||
dio->orig_bi_iter = bio->bi_iter;
|
dio->orig_bi_iter = bio->bi_iter;
|
||||||
|
|
||||||
dio->orig_bi_bdev = bio->bi_bdev;
|
dio->orig_bi_disk = bio->bi_disk;
|
||||||
bio->bi_bdev = ic->dev->bdev;
|
dio->orig_bi_partno = bio->bi_partno;
|
||||||
|
bio_set_dev(bio, ic->dev->bdev);
|
||||||
|
|
||||||
dio->orig_bi_integrity = bio_integrity(bio);
|
dio->orig_bi_integrity = bio_integrity(bio);
|
||||||
bio->bi_integrity = NULL;
|
bio->bi_integrity = NULL;
|
||||||
|
|
|
@ -347,7 +347,7 @@ static void do_region(int op, int op_flags, unsigned region,
|
||||||
|
|
||||||
bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
|
bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
|
||||||
bio->bi_iter.bi_sector = where->sector + (where->count - remaining);
|
bio->bi_iter.bi_sector = where->sector + (where->count - remaining);
|
||||||
bio->bi_bdev = where->bdev;
|
bio_set_dev(bio, where->bdev);
|
||||||
bio->bi_end_io = endio;
|
bio->bi_end_io = endio;
|
||||||
bio_set_op_attrs(bio, op, op_flags);
|
bio_set_op_attrs(bio, op, op_flags);
|
||||||
store_io_and_region_in_bio(bio, io, region);
|
store_io_and_region_in_bio(bio, io, region);
|
||||||
|
|
|
@ -88,7 +88,7 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct linear_c *lc = ti->private;
|
struct linear_c *lc = ti->private;
|
||||||
|
|
||||||
bio->bi_bdev = lc->dev->bdev;
|
bio_set_dev(bio, lc->dev->bdev);
|
||||||
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
|
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
|
||||||
bio->bi_iter.bi_sector =
|
bio->bi_iter.bi_sector =
|
||||||
linear_map_sector(ti, bio->bi_iter.bi_sector);
|
linear_map_sector(ti, bio->bi_iter.bi_sector);
|
||||||
|
|
|
@ -198,7 +198,7 @@ static int write_metadata(struct log_writes_c *lc, void *entry,
|
||||||
}
|
}
|
||||||
bio->bi_iter.bi_size = 0;
|
bio->bi_iter.bi_size = 0;
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = lc->logdev->bdev;
|
bio_set_dev(bio, lc->logdev->bdev);
|
||||||
bio->bi_end_io = log_end_io;
|
bio->bi_end_io = log_end_io;
|
||||||
bio->bi_private = lc;
|
bio->bi_private = lc;
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||||
|
@ -263,7 +263,7 @@ static int log_one_block(struct log_writes_c *lc,
|
||||||
}
|
}
|
||||||
bio->bi_iter.bi_size = 0;
|
bio->bi_iter.bi_size = 0;
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = lc->logdev->bdev;
|
bio_set_dev(bio, lc->logdev->bdev);
|
||||||
bio->bi_end_io = log_end_io;
|
bio->bi_end_io = log_end_io;
|
||||||
bio->bi_private = lc;
|
bio->bi_private = lc;
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||||
|
@ -285,7 +285,7 @@ static int log_one_block(struct log_writes_c *lc,
|
||||||
}
|
}
|
||||||
bio->bi_iter.bi_size = 0;
|
bio->bi_iter.bi_size = 0;
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio->bi_bdev = lc->logdev->bdev;
|
bio_set_dev(bio, lc->logdev->bdev);
|
||||||
bio->bi_end_io = log_end_io;
|
bio->bi_end_io = log_end_io;
|
||||||
bio->bi_private = lc;
|
bio->bi_private = lc;
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||||
|
@ -539,7 +539,7 @@ static void normal_map_bio(struct dm_target *ti, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct log_writes_c *lc = ti->private;
|
struct log_writes_c *lc = ti->private;
|
||||||
|
|
||||||
bio->bi_bdev = lc->dev->bdev;
|
bio_set_dev(bio, lc->dev->bdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int log_writes_map(struct dm_target *ti, struct bio *bio)
|
static int log_writes_map(struct dm_target *ti, struct bio *bio)
|
||||||
|
|
|
@ -565,7 +565,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m
|
||||||
mpio->nr_bytes = nr_bytes;
|
mpio->nr_bytes = nr_bytes;
|
||||||
|
|
||||||
bio->bi_status = 0;
|
bio->bi_status = 0;
|
||||||
bio->bi_bdev = pgpath->path.dev->bdev;
|
bio_set_dev(bio, pgpath->path.dev->bdev);
|
||||||
bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
|
bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
|
||||||
|
|
||||||
if (pgpath->pg->ps.type->start_io)
|
if (pgpath->pg->ps.type->start_io)
|
||||||
|
|
|
@ -145,7 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list)
|
||||||
|
|
||||||
struct dm_raid1_bio_record {
|
struct dm_raid1_bio_record {
|
||||||
struct mirror *m;
|
struct mirror *m;
|
||||||
/* if details->bi_bdev == NULL, details were not saved */
|
/* if details->bi_disk == NULL, details were not saved */
|
||||||
struct dm_bio_details details;
|
struct dm_bio_details details;
|
||||||
region_t write_region;
|
region_t write_region;
|
||||||
};
|
};
|
||||||
|
@ -464,7 +464,7 @@ static sector_t map_sector(struct mirror *m, struct bio *bio)
|
||||||
|
|
||||||
static void map_bio(struct mirror *m, struct bio *bio)
|
static void map_bio(struct mirror *m, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio->bi_bdev = m->dev->bdev;
|
bio_set_dev(bio, m->dev->bdev);
|
||||||
bio->bi_iter.bi_sector = map_sector(m, bio);
|
bio->bi_iter.bi_sector = map_sector(m, bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1199,7 +1199,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
|
||||||
struct dm_raid1_bio_record *bio_record =
|
struct dm_raid1_bio_record *bio_record =
|
||||||
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
|
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
|
||||||
|
|
||||||
bio_record->details.bi_bdev = NULL;
|
bio_record->details.bi_disk = NULL;
|
||||||
|
|
||||||
if (rw == WRITE) {
|
if (rw == WRITE) {
|
||||||
/* Save region for mirror_end_io() handler */
|
/* Save region for mirror_end_io() handler */
|
||||||
|
@ -1266,7 +1266,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (unlikely(*error)) {
|
if (unlikely(*error)) {
|
||||||
if (!bio_record->details.bi_bdev) {
|
if (!bio_record->details.bi_disk) {
|
||||||
/*
|
/*
|
||||||
* There wasn't enough memory to record necessary
|
* There wasn't enough memory to record necessary
|
||||||
* information for a retry or there was no other
|
* information for a retry or there was no other
|
||||||
|
@ -1291,7 +1291,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
|
||||||
bd = &bio_record->details;
|
bd = &bio_record->details;
|
||||||
|
|
||||||
dm_bio_restore(bd, bio);
|
dm_bio_restore(bd, bio);
|
||||||
bio_record->details.bi_bdev = NULL;
|
bio_record->details.bi_disk = NULL;
|
||||||
bio->bi_status = 0;
|
bio->bi_status = 0;
|
||||||
|
|
||||||
queue_bio(ms, bio, rw);
|
queue_bio(ms, bio, rw);
|
||||||
|
@ -1301,7 +1301,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
bio_record->details.bi_bdev = NULL;
|
bio_record->details.bi_disk = NULL;
|
||||||
|
|
||||||
return DM_ENDIO_DONE;
|
return DM_ENDIO_DONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1663,7 +1663,7 @@ __find_pending_exception(struct dm_snapshot *s,
|
||||||
static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
|
static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
|
||||||
struct bio *bio, chunk_t chunk)
|
struct bio *bio, chunk_t chunk)
|
||||||
{
|
{
|
||||||
bio->bi_bdev = s->cow->bdev;
|
bio_set_dev(bio, s->cow->bdev);
|
||||||
bio->bi_iter.bi_sector =
|
bio->bi_iter.bi_sector =
|
||||||
chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) +
|
chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) +
|
||||||
(chunk - e->old_chunk)) +
|
(chunk - e->old_chunk)) +
|
||||||
|
@ -1681,7 +1681,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
|
||||||
init_tracked_chunk(bio);
|
init_tracked_chunk(bio);
|
||||||
|
|
||||||
if (bio->bi_opf & REQ_PREFLUSH) {
|
if (bio->bi_opf & REQ_PREFLUSH) {
|
||||||
bio->bi_bdev = s->cow->bdev;
|
bio_set_dev(bio, s->cow->bdev);
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1769,7 +1769,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bio->bi_bdev = s->origin->bdev;
|
bio_set_dev(bio, s->origin->bdev);
|
||||||
track_chunk(s, bio, chunk);
|
track_chunk(s, bio, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1802,9 +1802,9 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
|
||||||
|
|
||||||
if (bio->bi_opf & REQ_PREFLUSH) {
|
if (bio->bi_opf & REQ_PREFLUSH) {
|
||||||
if (!dm_bio_get_target_bio_nr(bio))
|
if (!dm_bio_get_target_bio_nr(bio))
|
||||||
bio->bi_bdev = s->origin->bdev;
|
bio_set_dev(bio, s->origin->bdev);
|
||||||
else
|
else
|
||||||
bio->bi_bdev = s->cow->bdev;
|
bio_set_dev(bio, s->cow->bdev);
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1824,7 +1824,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
|
||||||
chunk >= s->first_merging_chunk &&
|
chunk >= s->first_merging_chunk &&
|
||||||
chunk < (s->first_merging_chunk +
|
chunk < (s->first_merging_chunk +
|
||||||
s->num_merging_chunks)) {
|
s->num_merging_chunks)) {
|
||||||
bio->bi_bdev = s->origin->bdev;
|
bio_set_dev(bio, s->origin->bdev);
|
||||||
bio_list_add(&s->bios_queued_during_merge, bio);
|
bio_list_add(&s->bios_queued_during_merge, bio);
|
||||||
r = DM_MAPIO_SUBMITTED;
|
r = DM_MAPIO_SUBMITTED;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
@ -1838,7 +1838,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect_to_origin:
|
redirect_to_origin:
|
||||||
bio->bi_bdev = s->origin->bdev;
|
bio_set_dev(bio, s->origin->bdev);
|
||||||
|
|
||||||
if (bio_data_dir(bio) == WRITE) {
|
if (bio_data_dir(bio) == WRITE) {
|
||||||
up_write(&s->lock);
|
up_write(&s->lock);
|
||||||
|
@ -2285,7 +2285,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio)
|
||||||
struct dm_origin *o = ti->private;
|
struct dm_origin *o = ti->private;
|
||||||
unsigned available_sectors;
|
unsigned available_sectors;
|
||||||
|
|
||||||
bio->bi_bdev = o->dev->bdev;
|
bio_set_dev(bio, o->dev->bdev);
|
||||||
|
|
||||||
if (unlikely(bio->bi_opf & REQ_PREFLUSH))
|
if (unlikely(bio->bi_opf & REQ_PREFLUSH))
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
|
|
|
@ -270,7 +270,7 @@ static int stripe_map_range(struct stripe_c *sc, struct bio *bio,
|
||||||
stripe_map_range_sector(sc, bio_end_sector(bio),
|
stripe_map_range_sector(sc, bio_end_sector(bio),
|
||||||
target_stripe, &end);
|
target_stripe, &end);
|
||||||
if (begin < end) {
|
if (begin < end) {
|
||||||
bio->bi_bdev = sc->stripe[target_stripe].dev->bdev;
|
bio_set_dev(bio, sc->stripe[target_stripe].dev->bdev);
|
||||||
bio->bi_iter.bi_sector = begin +
|
bio->bi_iter.bi_sector = begin +
|
||||||
sc->stripe[target_stripe].physical_start;
|
sc->stripe[target_stripe].physical_start;
|
||||||
bio->bi_iter.bi_size = to_bytes(end - begin);
|
bio->bi_iter.bi_size = to_bytes(end - begin);
|
||||||
|
@ -291,7 +291,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
|
||||||
if (bio->bi_opf & REQ_PREFLUSH) {
|
if (bio->bi_opf & REQ_PREFLUSH) {
|
||||||
target_bio_nr = dm_bio_get_target_bio_nr(bio);
|
target_bio_nr = dm_bio_get_target_bio_nr(bio);
|
||||||
BUG_ON(target_bio_nr >= sc->stripes);
|
BUG_ON(target_bio_nr >= sc->stripes);
|
||||||
bio->bi_bdev = sc->stripe[target_bio_nr].dev->bdev;
|
bio_set_dev(bio, sc->stripe[target_bio_nr].dev->bdev);
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
}
|
}
|
||||||
if (unlikely(bio_op(bio) == REQ_OP_DISCARD) ||
|
if (unlikely(bio_op(bio) == REQ_OP_DISCARD) ||
|
||||||
|
@ -306,7 +306,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
|
||||||
&stripe, &bio->bi_iter.bi_sector);
|
&stripe, &bio->bi_iter.bi_sector);
|
||||||
|
|
||||||
bio->bi_iter.bi_sector += sc->stripe[stripe].physical_start;
|
bio->bi_iter.bi_sector += sc->stripe[stripe].physical_start;
|
||||||
bio->bi_bdev = sc->stripe[stripe].dev->bdev;
|
bio_set_dev(bio, sc->stripe[stripe].dev->bdev);
|
||||||
|
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
}
|
}
|
||||||
|
@ -430,9 +430,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
|
||||||
return DM_ENDIO_DONE;
|
return DM_ENDIO_DONE;
|
||||||
|
|
||||||
memset(major_minor, 0, sizeof(major_minor));
|
memset(major_minor, 0, sizeof(major_minor));
|
||||||
sprintf(major_minor, "%d:%d",
|
sprintf(major_minor, "%d:%d", MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)));
|
||||||
MAJOR(disk_devt(bio->bi_bdev->bd_disk)),
|
|
||||||
MINOR(disk_devt(bio->bi_bdev->bd_disk)));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test to see which stripe drive triggered the event
|
* Test to see which stripe drive triggered the event
|
||||||
|
|
|
@ -322,7 +322,7 @@ static int switch_map(struct dm_target *ti, struct bio *bio)
|
||||||
sector_t offset = dm_target_offset(ti, bio->bi_iter.bi_sector);
|
sector_t offset = dm_target_offset(ti, bio->bi_iter.bi_sector);
|
||||||
unsigned path_nr = switch_get_path_nr(sctx, offset);
|
unsigned path_nr = switch_get_path_nr(sctx, offset);
|
||||||
|
|
||||||
bio->bi_bdev = sctx->path_list[path_nr].dmdev->bdev;
|
bio_set_dev(bio, sctx->path_list[path_nr].dmdev->bdev);
|
||||||
bio->bi_iter.bi_sector = sctx->path_list[path_nr].start + offset;
|
bio->bi_iter.bi_sector = sctx->path_list[path_nr].start + offset;
|
||||||
|
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
|
|
|
@ -679,7 +679,7 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
|
||||||
struct pool *pool = tc->pool;
|
struct pool *pool = tc->pool;
|
||||||
sector_t bi_sector = bio->bi_iter.bi_sector;
|
sector_t bi_sector = bio->bi_iter.bi_sector;
|
||||||
|
|
||||||
bio->bi_bdev = tc->pool_dev->bdev;
|
bio_set_dev(bio, tc->pool_dev->bdev);
|
||||||
if (block_size_is_power_of_two(pool))
|
if (block_size_is_power_of_two(pool))
|
||||||
bio->bi_iter.bi_sector =
|
bio->bi_iter.bi_sector =
|
||||||
(block << pool->sectors_per_block_shift) |
|
(block << pool->sectors_per_block_shift) |
|
||||||
|
@ -691,7 +691,7 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
|
||||||
|
|
||||||
static void remap_to_origin(struct thin_c *tc, struct bio *bio)
|
static void remap_to_origin(struct thin_c *tc, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio->bi_bdev = tc->origin_dev->bdev;
|
bio_set_dev(bio, tc->origin_dev->bdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bio_triggers_commit(struct thin_c *tc, struct bio *bio)
|
static int bio_triggers_commit(struct thin_c *tc, struct bio *bio)
|
||||||
|
@ -3313,7 +3313,7 @@ static int pool_map(struct dm_target *ti, struct bio *bio)
|
||||||
* As this is a singleton target, ti->begin is always zero.
|
* As this is a singleton target, ti->begin is always zero.
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&pool->lock, flags);
|
spin_lock_irqsave(&pool->lock, flags);
|
||||||
bio->bi_bdev = pt->data_dev->bdev;
|
bio_set_dev(bio, pt->data_dev->bdev);
|
||||||
r = DM_MAPIO_REMAPPED;
|
r = DM_MAPIO_REMAPPED;
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
spin_unlock_irqrestore(&pool->lock, flags);
|
||||||
|
|
||||||
|
|
|
@ -637,7 +637,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
|
||||||
struct dm_verity *v = ti->private;
|
struct dm_verity *v = ti->private;
|
||||||
struct dm_verity_io *io;
|
struct dm_verity_io *io;
|
||||||
|
|
||||||
bio->bi_bdev = v->data_dev->bdev;
|
bio_set_dev(bio, v->data_dev->bdev);
|
||||||
bio->bi_iter.bi_sector = verity_map_sector(v, bio->bi_iter.bi_sector);
|
bio->bi_iter.bi_sector = verity_map_sector(v, bio->bi_iter.bi_sector);
|
||||||
|
|
||||||
if (((unsigned)bio->bi_iter.bi_sector | bio_sectors(bio)) &
|
if (((unsigned)bio->bi_iter.bi_sector | bio_sectors(bio)) &
|
||||||
|
|
|
@ -409,7 +409,7 @@ static struct dmz_mblock *dmz_fetch_mblock(struct dmz_metadata *zmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = dmz_blk2sect(block);
|
bio->bi_iter.bi_sector = dmz_blk2sect(block);
|
||||||
bio->bi_bdev = zmd->dev->bdev;
|
bio_set_dev(bio, zmd->dev->bdev);
|
||||||
bio->bi_private = mblk;
|
bio->bi_private = mblk;
|
||||||
bio->bi_end_io = dmz_mblock_bio_end_io;
|
bio->bi_end_io = dmz_mblock_bio_end_io;
|
||||||
bio_set_op_attrs(bio, REQ_OP_READ, REQ_META | REQ_PRIO);
|
bio_set_op_attrs(bio, REQ_OP_READ, REQ_META | REQ_PRIO);
|
||||||
|
@ -564,7 +564,7 @@ static void dmz_write_mblock(struct dmz_metadata *zmd, struct dmz_mblock *mblk,
|
||||||
set_bit(DMZ_META_WRITING, &mblk->state);
|
set_bit(DMZ_META_WRITING, &mblk->state);
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = dmz_blk2sect(block);
|
bio->bi_iter.bi_sector = dmz_blk2sect(block);
|
||||||
bio->bi_bdev = zmd->dev->bdev;
|
bio_set_dev(bio, zmd->dev->bdev);
|
||||||
bio->bi_private = mblk;
|
bio->bi_private = mblk;
|
||||||
bio->bi_end_io = dmz_mblock_bio_end_io;
|
bio->bi_end_io = dmz_mblock_bio_end_io;
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_META | REQ_PRIO);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_META | REQ_PRIO);
|
||||||
|
@ -586,7 +586,7 @@ static int dmz_rdwr_block(struct dmz_metadata *zmd, int op, sector_t block,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = dmz_blk2sect(block);
|
bio->bi_iter.bi_sector = dmz_blk2sect(block);
|
||||||
bio->bi_bdev = zmd->dev->bdev;
|
bio_set_dev(bio, zmd->dev->bdev);
|
||||||
bio_set_op_attrs(bio, op, REQ_SYNC | REQ_META | REQ_PRIO);
|
bio_set_op_attrs(bio, op, REQ_SYNC | REQ_META | REQ_PRIO);
|
||||||
bio_add_page(bio, page, DMZ_BLOCK_SIZE, 0);
|
bio_add_page(bio, page, DMZ_BLOCK_SIZE, 0);
|
||||||
ret = submit_bio_wait(bio);
|
ret = submit_bio_wait(bio);
|
||||||
|
|
|
@ -238,7 +238,7 @@ static void dmz_submit_write_bio(struct dmz_target *dmz, struct dm_zone *zone,
|
||||||
struct dmz_bioctx *bioctx = dm_per_bio_data(bio, sizeof(struct dmz_bioctx));
|
struct dmz_bioctx *bioctx = dm_per_bio_data(bio, sizeof(struct dmz_bioctx));
|
||||||
|
|
||||||
/* Setup and submit the BIO */
|
/* Setup and submit the BIO */
|
||||||
bio->bi_bdev = dmz->dev->bdev;
|
bio_set_dev(bio, dmz->dev->bdev);
|
||||||
bio->bi_iter.bi_sector = dmz_start_sect(dmz->metadata, zone) + dmz_blk2sect(chunk_block);
|
bio->bi_iter.bi_sector = dmz_start_sect(dmz->metadata, zone) + dmz_blk2sect(chunk_block);
|
||||||
atomic_inc(&bioctx->ref);
|
atomic_inc(&bioctx->ref);
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
|
@ -586,7 +586,7 @@ static int dmz_map(struct dm_target *ti, struct bio *bio)
|
||||||
(unsigned long long)dmz_chunk_block(dmz->dev, dmz_bio_block(bio)),
|
(unsigned long long)dmz_chunk_block(dmz->dev, dmz_bio_block(bio)),
|
||||||
(unsigned int)dmz_bio_blocks(bio));
|
(unsigned int)dmz_bio_blocks(bio));
|
||||||
|
|
||||||
bio->bi_bdev = dev->bdev;
|
bio_set_dev(bio, dev->bdev);
|
||||||
|
|
||||||
if (!nr_sectors && bio_op(bio) != REQ_OP_WRITE)
|
if (!nr_sectors && bio_op(bio) != REQ_OP_WRITE)
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
|
|
|
@ -510,7 +510,7 @@ static void start_io_acct(struct dm_io *io)
|
||||||
io->start_time = jiffies;
|
io->start_time = jiffies;
|
||||||
|
|
||||||
cpu = part_stat_lock();
|
cpu = part_stat_lock();
|
||||||
part_round_stats(cpu, &dm_disk(md)->part0);
|
part_round_stats(md->queue, cpu, &dm_disk(md)->part0);
|
||||||
part_stat_unlock();
|
part_stat_unlock();
|
||||||
atomic_set(&dm_disk(md)->part0.in_flight[rw],
|
atomic_set(&dm_disk(md)->part0.in_flight[rw],
|
||||||
atomic_inc_return(&md->pending[rw]));
|
atomic_inc_return(&md->pending[rw]));
|
||||||
|
@ -529,7 +529,7 @@ static void end_io_acct(struct dm_io *io)
|
||||||
int pending;
|
int pending;
|
||||||
int rw = bio_data_dir(bio);
|
int rw = bio_data_dir(bio);
|
||||||
|
|
||||||
generic_end_io_acct(rw, &dm_disk(md)->part0, io->start_time);
|
generic_end_io_acct(md->queue, rw, &dm_disk(md)->part0, io->start_time);
|
||||||
|
|
||||||
if (unlikely(dm_stats_used(&md->stats)))
|
if (unlikely(dm_stats_used(&md->stats)))
|
||||||
dm_stats_account_io(&md->stats, bio_data_dir(bio),
|
dm_stats_account_io(&md->stats, bio_data_dir(bio),
|
||||||
|
@ -841,10 +841,10 @@ static void clone_endio(struct bio *bio)
|
||||||
|
|
||||||
if (unlikely(error == BLK_STS_TARGET)) {
|
if (unlikely(error == BLK_STS_TARGET)) {
|
||||||
if (bio_op(bio) == REQ_OP_WRITE_SAME &&
|
if (bio_op(bio) == REQ_OP_WRITE_SAME &&
|
||||||
!bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors)
|
!bio->bi_disk->queue->limits.max_write_same_sectors)
|
||||||
disable_write_same(md);
|
disable_write_same(md);
|
||||||
if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
|
if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
|
||||||
!bdev_get_queue(bio->bi_bdev)->limits.max_write_zeroes_sectors)
|
!bio->bi_disk->queue->limits.max_write_zeroes_sectors)
|
||||||
disable_write_zeroes(md);
|
disable_write_zeroes(md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,8 +1205,8 @@ static void __map_bio(struct dm_target_io *tio)
|
||||||
break;
|
break;
|
||||||
case DM_MAPIO_REMAPPED:
|
case DM_MAPIO_REMAPPED:
|
||||||
/* the bio has been remapped so dispatch it */
|
/* the bio has been remapped so dispatch it */
|
||||||
trace_block_bio_remap(bdev_get_queue(clone->bi_bdev), clone,
|
trace_block_bio_remap(clone->bi_disk->queue, clone,
|
||||||
tio->io->bio->bi_bdev->bd_dev, sector);
|
bio_dev(tio->io->bio), sector);
|
||||||
generic_make_request(clone);
|
generic_make_request(clone);
|
||||||
break;
|
break;
|
||||||
case DM_MAPIO_KILL:
|
case DM_MAPIO_KILL:
|
||||||
|
@ -1532,7 +1532,7 @@ static blk_qc_t dm_make_request(struct request_queue *q, struct bio *bio)
|
||||||
|
|
||||||
map = dm_get_live_table(md, &srcu_idx);
|
map = dm_get_live_table(md, &srcu_idx);
|
||||||
|
|
||||||
generic_start_io_acct(rw, bio_sectors(bio), &dm_disk(md)->part0);
|
generic_start_io_acct(q, rw, bio_sectors(bio), &dm_disk(md)->part0);
|
||||||
|
|
||||||
/* if we're suspended, we have to queue this io for later */
|
/* if we're suspended, we have to queue this io for later */
|
||||||
if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
|
if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
|
||||||
|
@ -1786,7 +1786,7 @@ static struct mapped_device *alloc_dev(int minor)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
bio_init(&md->flush_bio, NULL, 0);
|
bio_init(&md->flush_bio, NULL, 0);
|
||||||
md->flush_bio.bi_bdev = md->bdev;
|
bio_set_dev(&md->flush_bio, md->bdev);
|
||||||
md->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC;
|
md->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC;
|
||||||
|
|
||||||
dm_stats_init(&md->stats);
|
dm_stats_init(&md->stats);
|
||||||
|
|
|
@ -216,12 +216,12 @@ static bool faulty_make_request(struct mddev *mddev, struct bio *bio)
|
||||||
if (failit) {
|
if (failit) {
|
||||||
struct bio *b = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
|
struct bio *b = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
|
||||||
|
|
||||||
b->bi_bdev = conf->rdev->bdev;
|
bio_set_dev(b, conf->rdev->bdev);
|
||||||
b->bi_private = bio;
|
b->bi_private = bio;
|
||||||
b->bi_end_io = faulty_fail;
|
b->bi_end_io = faulty_fail;
|
||||||
bio = b;
|
bio = b;
|
||||||
} else
|
} else
|
||||||
bio->bi_bdev = conf->rdev->bdev;
|
bio_set_dev(bio, conf->rdev->bdev);
|
||||||
|
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -275,17 +275,17 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio)
|
||||||
bio = split;
|
bio = split;
|
||||||
}
|
}
|
||||||
|
|
||||||
bio->bi_bdev = tmp_dev->rdev->bdev;
|
bio_set_dev(bio, tmp_dev->rdev->bdev);
|
||||||
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector -
|
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector -
|
||||||
start_sector + data_offset;
|
start_sector + data_offset;
|
||||||
|
|
||||||
if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
|
!blk_queue_discard(bio->bi_disk->queue))) {
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio);
|
bio_endio(bio);
|
||||||
} else {
|
} else {
|
||||||
if (mddev->gendisk)
|
if (mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(bio->bi_bdev),
|
trace_block_bio_remap(bio->bi_disk->queue,
|
||||||
bio, disk_devt(mddev->gendisk),
|
bio, disk_devt(mddev->gendisk),
|
||||||
bio_sector);
|
bio_sector);
|
||||||
mddev_check_writesame(mddev, bio);
|
mddev_check_writesame(mddev, bio);
|
||||||
|
|
|
@ -422,7 +422,7 @@ static void submit_flushes(struct work_struct *ws)
|
||||||
bi = bio_alloc_mddev(GFP_NOIO, 0, mddev);
|
bi = bio_alloc_mddev(GFP_NOIO, 0, mddev);
|
||||||
bi->bi_end_io = md_end_flush;
|
bi->bi_end_io = md_end_flush;
|
||||||
bi->bi_private = rdev;
|
bi->bi_private = rdev;
|
||||||
bi->bi_bdev = rdev->bdev;
|
bio_set_dev(bi, rdev->bdev);
|
||||||
bi->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
bi->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||||
atomic_inc(&mddev->flush_pending);
|
atomic_inc(&mddev->flush_pending);
|
||||||
submit_bio(bi);
|
submit_bio(bi);
|
||||||
|
@ -772,7 +772,7 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
|
||||||
|
|
||||||
atomic_inc(&rdev->nr_pending);
|
atomic_inc(&rdev->nr_pending);
|
||||||
|
|
||||||
bio->bi_bdev = rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev;
|
bio_set_dev(bio, rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev);
|
||||||
bio->bi_iter.bi_sector = sector;
|
bio->bi_iter.bi_sector = sector;
|
||||||
bio_add_page(bio, page, size, 0);
|
bio_add_page(bio, page, size, 0);
|
||||||
bio->bi_private = rdev;
|
bio->bi_private = rdev;
|
||||||
|
@ -803,8 +803,10 @@ int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
|
||||||
struct bio *bio = md_bio_alloc_sync(rdev->mddev);
|
struct bio *bio = md_bio_alloc_sync(rdev->mddev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
bio->bi_bdev = (metadata_op && rdev->meta_bdev) ?
|
if (metadata_op && rdev->meta_bdev)
|
||||||
rdev->meta_bdev : rdev->bdev;
|
bio_set_dev(bio, rdev->meta_bdev);
|
||||||
|
else
|
||||||
|
bio_set_dev(bio, rdev->bdev);
|
||||||
bio_set_op_attrs(bio, op, op_flags);
|
bio_set_op_attrs(bio, op, op_flags);
|
||||||
if (metadata_op)
|
if (metadata_op)
|
||||||
bio->bi_iter.bi_sector = sector + rdev->sb_start;
|
bio->bi_iter.bi_sector = sector + rdev->sb_start;
|
||||||
|
|
|
@ -509,6 +509,11 @@ static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sect
|
||||||
atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
|
atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void md_sync_acct_bio(struct bio *bio, unsigned long nr_sectors)
|
||||||
|
{
|
||||||
|
atomic_add(nr_sectors, &bio->bi_disk->sync_io);
|
||||||
|
}
|
||||||
|
|
||||||
struct md_personality
|
struct md_personality
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -721,14 +726,14 @@ static inline void mddev_clear_unsupported_flags(struct mddev *mddev,
|
||||||
static inline void mddev_check_writesame(struct mddev *mddev, struct bio *bio)
|
static inline void mddev_check_writesame(struct mddev *mddev, struct bio *bio)
|
||||||
{
|
{
|
||||||
if (bio_op(bio) == REQ_OP_WRITE_SAME &&
|
if (bio_op(bio) == REQ_OP_WRITE_SAME &&
|
||||||
!bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors)
|
!bio->bi_disk->queue->limits.max_write_same_sectors)
|
||||||
mddev->queue->limits.max_write_same_sectors = 0;
|
mddev->queue->limits.max_write_same_sectors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio)
|
static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio)
|
||||||
{
|
{
|
||||||
if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
|
if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
|
||||||
!bdev_get_queue(bio->bi_bdev)->limits.max_write_zeroes_sectors)
|
!bio->bi_disk->queue->limits.max_write_zeroes_sectors)
|
||||||
mddev->queue->limits.max_write_zeroes_sectors = 0;
|
mddev->queue->limits.max_write_zeroes_sectors = 0;
|
||||||
}
|
}
|
||||||
#endif /* _MD_MD_H */
|
#endif /* _MD_MD_H */
|
||||||
|
|
|
@ -134,7 +134,7 @@ static bool multipath_make_request(struct mddev *mddev, struct bio * bio)
|
||||||
__bio_clone_fast(&mp_bh->bio, bio);
|
__bio_clone_fast(&mp_bh->bio, bio);
|
||||||
|
|
||||||
mp_bh->bio.bi_iter.bi_sector += multipath->rdev->data_offset;
|
mp_bh->bio.bi_iter.bi_sector += multipath->rdev->data_offset;
|
||||||
mp_bh->bio.bi_bdev = multipath->rdev->bdev;
|
bio_set_dev(&mp_bh->bio, multipath->rdev->bdev);
|
||||||
mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT;
|
mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT;
|
||||||
mp_bh->bio.bi_end_io = multipath_end_request;
|
mp_bh->bio.bi_end_io = multipath_end_request;
|
||||||
mp_bh->bio.bi_private = mp_bh;
|
mp_bh->bio.bi_private = mp_bh;
|
||||||
|
@ -345,17 +345,17 @@ static void multipathd(struct md_thread *thread)
|
||||||
|
|
||||||
if ((mp_bh->path = multipath_map (conf))<0) {
|
if ((mp_bh->path = multipath_map (conf))<0) {
|
||||||
pr_err("multipath: %s: unrecoverable IO read error for block %llu\n",
|
pr_err("multipath: %s: unrecoverable IO read error for block %llu\n",
|
||||||
bdevname(bio->bi_bdev,b),
|
bio_devname(bio, b),
|
||||||
(unsigned long long)bio->bi_iter.bi_sector);
|
(unsigned long long)bio->bi_iter.bi_sector);
|
||||||
multipath_end_bh_io(mp_bh, BLK_STS_IOERR);
|
multipath_end_bh_io(mp_bh, BLK_STS_IOERR);
|
||||||
} else {
|
} else {
|
||||||
pr_err("multipath: %s: redirecting sector %llu to another IO path\n",
|
pr_err("multipath: %s: redirecting sector %llu to another IO path\n",
|
||||||
bdevname(bio->bi_bdev,b),
|
bio_devname(bio, b),
|
||||||
(unsigned long long)bio->bi_iter.bi_sector);
|
(unsigned long long)bio->bi_iter.bi_sector);
|
||||||
*bio = *(mp_bh->master_bio);
|
*bio = *(mp_bh->master_bio);
|
||||||
bio->bi_iter.bi_sector +=
|
bio->bi_iter.bi_sector +=
|
||||||
conf->multipaths[mp_bh->path].rdev->data_offset;
|
conf->multipaths[mp_bh->path].rdev->data_offset;
|
||||||
bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev;
|
bio_set_dev(bio, conf->multipaths[mp_bh->path].rdev->bdev);
|
||||||
bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
|
bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
|
||||||
bio->bi_end_io = multipath_end_request;
|
bio->bi_end_io = multipath_end_request;
|
||||||
bio->bi_private = mp_bh;
|
bio->bi_private = mp_bh;
|
||||||
|
|
|
@ -588,14 +588,13 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
|
||||||
|
|
||||||
zone = find_zone(mddev->private, §or);
|
zone = find_zone(mddev->private, §or);
|
||||||
tmp_dev = map_sector(mddev, zone, sector, §or);
|
tmp_dev = map_sector(mddev, zone, sector, §or);
|
||||||
bio->bi_bdev = tmp_dev->bdev;
|
bio_set_dev(bio, tmp_dev->bdev);
|
||||||
bio->bi_iter.bi_sector = sector + zone->dev_start +
|
bio->bi_iter.bi_sector = sector + zone->dev_start +
|
||||||
tmp_dev->data_offset;
|
tmp_dev->data_offset;
|
||||||
|
|
||||||
if (mddev->gendisk)
|
if (mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(bio->bi_bdev),
|
trace_block_bio_remap(bio->bi_disk->queue, bio,
|
||||||
bio, disk_devt(mddev->gendisk),
|
disk_devt(mddev->gendisk), bio_sector);
|
||||||
bio_sector);
|
|
||||||
mddev_check_writesame(mddev, bio);
|
mddev_check_writesame(mddev, bio);
|
||||||
mddev_check_write_zeroes(mddev, bio);
|
mddev_check_write_zeroes(mddev, bio);
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
|
|
|
@ -786,13 +786,13 @@ static void flush_bio_list(struct r1conf *conf, struct bio *bio)
|
||||||
|
|
||||||
while (bio) { /* submit pending writes */
|
while (bio) { /* submit pending writes */
|
||||||
struct bio *next = bio->bi_next;
|
struct bio *next = bio->bi_next;
|
||||||
struct md_rdev *rdev = (void*)bio->bi_bdev;
|
struct md_rdev *rdev = (void *)bio->bi_disk;
|
||||||
bio->bi_next = NULL;
|
bio->bi_next = NULL;
|
||||||
bio->bi_bdev = rdev->bdev;
|
bio_set_dev(bio, rdev->bdev);
|
||||||
if (test_bit(Faulty, &rdev->flags)) {
|
if (test_bit(Faulty, &rdev->flags)) {
|
||||||
bio_io_error(bio);
|
bio_io_error(bio);
|
||||||
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
!blk_queue_discard(bio->bi_disk->queue)))
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
|
@ -1273,7 +1273,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
|
||||||
|
|
||||||
read_bio->bi_iter.bi_sector = r1_bio->sector +
|
read_bio->bi_iter.bi_sector = r1_bio->sector +
|
||||||
mirror->rdev->data_offset;
|
mirror->rdev->data_offset;
|
||||||
read_bio->bi_bdev = mirror->rdev->bdev;
|
bio_set_dev(read_bio, mirror->rdev->bdev);
|
||||||
read_bio->bi_end_io = raid1_end_read_request;
|
read_bio->bi_end_io = raid1_end_read_request;
|
||||||
bio_set_op_attrs(read_bio, op, do_sync);
|
bio_set_op_attrs(read_bio, op, do_sync);
|
||||||
if (test_bit(FailFast, &mirror->rdev->flags) &&
|
if (test_bit(FailFast, &mirror->rdev->flags) &&
|
||||||
|
@ -1282,9 +1282,8 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
|
||||||
read_bio->bi_private = r1_bio;
|
read_bio->bi_private = r1_bio;
|
||||||
|
|
||||||
if (mddev->gendisk)
|
if (mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(read_bio->bi_bdev),
|
trace_block_bio_remap(read_bio->bi_disk->queue, read_bio,
|
||||||
read_bio, disk_devt(mddev->gendisk),
|
disk_devt(mddev->gendisk), r1_bio->sector);
|
||||||
r1_bio->sector);
|
|
||||||
|
|
||||||
generic_make_request(read_bio);
|
generic_make_request(read_bio);
|
||||||
}
|
}
|
||||||
|
@ -1496,7 +1495,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
|
||||||
|
|
||||||
mbio->bi_iter.bi_sector = (r1_bio->sector +
|
mbio->bi_iter.bi_sector = (r1_bio->sector +
|
||||||
conf->mirrors[i].rdev->data_offset);
|
conf->mirrors[i].rdev->data_offset);
|
||||||
mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
|
bio_set_dev(mbio, conf->mirrors[i].rdev->bdev);
|
||||||
mbio->bi_end_io = raid1_end_write_request;
|
mbio->bi_end_io = raid1_end_write_request;
|
||||||
mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
|
mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
|
||||||
if (test_bit(FailFast, &conf->mirrors[i].rdev->flags) &&
|
if (test_bit(FailFast, &conf->mirrors[i].rdev->flags) &&
|
||||||
|
@ -1508,11 +1507,11 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
|
||||||
atomic_inc(&r1_bio->remaining);
|
atomic_inc(&r1_bio->remaining);
|
||||||
|
|
||||||
if (mddev->gendisk)
|
if (mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(mbio->bi_bdev),
|
trace_block_bio_remap(mbio->bi_disk->queue,
|
||||||
mbio, disk_devt(mddev->gendisk),
|
mbio, disk_devt(mddev->gendisk),
|
||||||
r1_bio->sector);
|
r1_bio->sector);
|
||||||
/* flush_pending_writes() needs access to the rdev so...*/
|
/* flush_pending_writes() needs access to the rdev so...*/
|
||||||
mbio->bi_bdev = (void*)conf->mirrors[i].rdev;
|
mbio->bi_disk = (void *)conf->mirrors[i].rdev;
|
||||||
|
|
||||||
cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug));
|
cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug));
|
||||||
if (cb)
|
if (cb)
|
||||||
|
@ -1990,8 +1989,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
|
||||||
* Don't fail devices as that won't really help.
|
* Don't fail devices as that won't really help.
|
||||||
*/
|
*/
|
||||||
pr_crit_ratelimited("md/raid1:%s: %s: unrecoverable I/O read error for block %llu\n",
|
pr_crit_ratelimited("md/raid1:%s: %s: unrecoverable I/O read error for block %llu\n",
|
||||||
mdname(mddev),
|
mdname(mddev), bio_devname(bio, b),
|
||||||
bdevname(bio->bi_bdev, b),
|
|
||||||
(unsigned long long)r1_bio->sector);
|
(unsigned long long)r1_bio->sector);
|
||||||
for (d = 0; d < conf->raid_disks * 2; d++) {
|
for (d = 0; d < conf->raid_disks * 2; d++) {
|
||||||
rdev = conf->mirrors[d].rdev;
|
rdev = conf->mirrors[d].rdev;
|
||||||
|
@ -2082,7 +2080,7 @@ static void process_checks(struct r1bio *r1_bio)
|
||||||
b->bi_status = status;
|
b->bi_status = status;
|
||||||
b->bi_iter.bi_sector = r1_bio->sector +
|
b->bi_iter.bi_sector = r1_bio->sector +
|
||||||
conf->mirrors[i].rdev->data_offset;
|
conf->mirrors[i].rdev->data_offset;
|
||||||
b->bi_bdev = conf->mirrors[i].rdev->bdev;
|
bio_set_dev(b, conf->mirrors[i].rdev->bdev);
|
||||||
b->bi_end_io = end_sync_read;
|
b->bi_end_io = end_sync_read;
|
||||||
rp->raid_bio = r1_bio;
|
rp->raid_bio = r1_bio;
|
||||||
b->bi_private = rp;
|
b->bi_private = rp;
|
||||||
|
@ -2350,7 +2348,7 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
|
||||||
|
|
||||||
bio_trim(wbio, sector - r1_bio->sector, sectors);
|
bio_trim(wbio, sector - r1_bio->sector, sectors);
|
||||||
wbio->bi_iter.bi_sector += rdev->data_offset;
|
wbio->bi_iter.bi_sector += rdev->data_offset;
|
||||||
wbio->bi_bdev = rdev->bdev;
|
bio_set_dev(wbio, rdev->bdev);
|
||||||
|
|
||||||
if (submit_bio_wait(wbio) < 0)
|
if (submit_bio_wait(wbio) < 0)
|
||||||
/* failure! */
|
/* failure! */
|
||||||
|
@ -2440,7 +2438,6 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
|
||||||
struct mddev *mddev = conf->mddev;
|
struct mddev *mddev = conf->mddev;
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
struct md_rdev *rdev;
|
struct md_rdev *rdev;
|
||||||
dev_t bio_dev;
|
|
||||||
sector_t bio_sector;
|
sector_t bio_sector;
|
||||||
|
|
||||||
clear_bit(R1BIO_ReadError, &r1_bio->state);
|
clear_bit(R1BIO_ReadError, &r1_bio->state);
|
||||||
|
@ -2454,7 +2451,6 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bio = r1_bio->bios[r1_bio->read_disk];
|
bio = r1_bio->bios[r1_bio->read_disk];
|
||||||
bio_dev = bio->bi_bdev->bd_dev;
|
|
||||||
bio_sector = conf->mirrors[r1_bio->read_disk].rdev->data_offset + r1_bio->sector;
|
bio_sector = conf->mirrors[r1_bio->read_disk].rdev->data_offset + r1_bio->sector;
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
r1_bio->bios[r1_bio->read_disk] = NULL;
|
r1_bio->bios[r1_bio->read_disk] = NULL;
|
||||||
|
@ -2727,7 +2723,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
if (bio->bi_end_io) {
|
if (bio->bi_end_io) {
|
||||||
atomic_inc(&rdev->nr_pending);
|
atomic_inc(&rdev->nr_pending);
|
||||||
bio->bi_iter.bi_sector = sector_nr + rdev->data_offset;
|
bio->bi_iter.bi_sector = sector_nr + rdev->data_offset;
|
||||||
bio->bi_bdev = rdev->bdev;
|
bio_set_dev(bio, rdev->bdev);
|
||||||
if (test_bit(FailFast, &rdev->flags))
|
if (test_bit(FailFast, &rdev->flags))
|
||||||
bio->bi_opf |= MD_FAILFAST;
|
bio->bi_opf |= MD_FAILFAST;
|
||||||
}
|
}
|
||||||
|
@ -2853,7 +2849,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
bio = r1_bio->bios[i];
|
bio = r1_bio->bios[i];
|
||||||
if (bio->bi_end_io == end_sync_read) {
|
if (bio->bi_end_io == end_sync_read) {
|
||||||
read_targets--;
|
read_targets--;
|
||||||
md_sync_acct(bio->bi_bdev, nr_sectors);
|
md_sync_acct_bio(bio, nr_sectors);
|
||||||
if (read_targets == 1)
|
if (read_targets == 1)
|
||||||
bio->bi_opf &= ~MD_FAILFAST;
|
bio->bi_opf &= ~MD_FAILFAST;
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
|
@ -2862,7 +2858,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
} else {
|
} else {
|
||||||
atomic_set(&r1_bio->remaining, 1);
|
atomic_set(&r1_bio->remaining, 1);
|
||||||
bio = r1_bio->bios[r1_bio->read_disk];
|
bio = r1_bio->bios[r1_bio->read_disk];
|
||||||
md_sync_acct(bio->bi_bdev, nr_sectors);
|
md_sync_acct_bio(bio, nr_sectors);
|
||||||
if (read_targets == 1)
|
if (read_targets == 1)
|
||||||
bio->bi_opf &= ~MD_FAILFAST;
|
bio->bi_opf &= ~MD_FAILFAST;
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
|
|
|
@ -901,13 +901,13 @@ static void flush_pending_writes(struct r10conf *conf)
|
||||||
|
|
||||||
while (bio) { /* submit pending writes */
|
while (bio) { /* submit pending writes */
|
||||||
struct bio *next = bio->bi_next;
|
struct bio *next = bio->bi_next;
|
||||||
struct md_rdev *rdev = (void*)bio->bi_bdev;
|
struct md_rdev *rdev = (void*)bio->bi_disk;
|
||||||
bio->bi_next = NULL;
|
bio->bi_next = NULL;
|
||||||
bio->bi_bdev = rdev->bdev;
|
bio_set_dev(bio, rdev->bdev);
|
||||||
if (test_bit(Faulty, &rdev->flags)) {
|
if (test_bit(Faulty, &rdev->flags)) {
|
||||||
bio_io_error(bio);
|
bio_io_error(bio);
|
||||||
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
!blk_queue_discard(bio->bi_disk->queue)))
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
|
@ -1085,13 +1085,13 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
|
||||||
|
|
||||||
while (bio) { /* submit pending writes */
|
while (bio) { /* submit pending writes */
|
||||||
struct bio *next = bio->bi_next;
|
struct bio *next = bio->bi_next;
|
||||||
struct md_rdev *rdev = (void*)bio->bi_bdev;
|
struct md_rdev *rdev = (void*)bio->bi_disk;
|
||||||
bio->bi_next = NULL;
|
bio->bi_next = NULL;
|
||||||
bio->bi_bdev = rdev->bdev;
|
bio_set_dev(bio, rdev->bdev);
|
||||||
if (test_bit(Faulty, &rdev->flags)) {
|
if (test_bit(Faulty, &rdev->flags)) {
|
||||||
bio_io_error(bio);
|
bio_io_error(bio);
|
||||||
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
!blk_queue_discard(bio->bi_disk->queue)))
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
|
@ -1200,7 +1200,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
|
||||||
|
|
||||||
read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr +
|
read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr +
|
||||||
choose_data_offset(r10_bio, rdev);
|
choose_data_offset(r10_bio, rdev);
|
||||||
read_bio->bi_bdev = rdev->bdev;
|
bio_set_dev(read_bio, rdev->bdev);
|
||||||
read_bio->bi_end_io = raid10_end_read_request;
|
read_bio->bi_end_io = raid10_end_read_request;
|
||||||
bio_set_op_attrs(read_bio, op, do_sync);
|
bio_set_op_attrs(read_bio, op, do_sync);
|
||||||
if (test_bit(FailFast, &rdev->flags) &&
|
if (test_bit(FailFast, &rdev->flags) &&
|
||||||
|
@ -1209,7 +1209,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
|
||||||
read_bio->bi_private = r10_bio;
|
read_bio->bi_private = r10_bio;
|
||||||
|
|
||||||
if (mddev->gendisk)
|
if (mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(read_bio->bi_bdev),
|
trace_block_bio_remap(read_bio->bi_disk->queue,
|
||||||
read_bio, disk_devt(mddev->gendisk),
|
read_bio, disk_devt(mddev->gendisk),
|
||||||
r10_bio->sector);
|
r10_bio->sector);
|
||||||
generic_make_request(read_bio);
|
generic_make_request(read_bio);
|
||||||
|
@ -1249,7 +1249,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
|
||||||
|
|
||||||
mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
|
mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
|
||||||
choose_data_offset(r10_bio, rdev));
|
choose_data_offset(r10_bio, rdev));
|
||||||
mbio->bi_bdev = rdev->bdev;
|
bio_set_dev(mbio, rdev->bdev);
|
||||||
mbio->bi_end_io = raid10_end_write_request;
|
mbio->bi_end_io = raid10_end_write_request;
|
||||||
bio_set_op_attrs(mbio, op, do_sync | do_fua);
|
bio_set_op_attrs(mbio, op, do_sync | do_fua);
|
||||||
if (!replacement && test_bit(FailFast,
|
if (!replacement && test_bit(FailFast,
|
||||||
|
@ -1259,11 +1259,11 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
|
||||||
mbio->bi_private = r10_bio;
|
mbio->bi_private = r10_bio;
|
||||||
|
|
||||||
if (conf->mddev->gendisk)
|
if (conf->mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(mbio->bi_bdev),
|
trace_block_bio_remap(mbio->bi_disk->queue,
|
||||||
mbio, disk_devt(conf->mddev->gendisk),
|
mbio, disk_devt(conf->mddev->gendisk),
|
||||||
r10_bio->sector);
|
r10_bio->sector);
|
||||||
/* flush_pending_writes() needs access to the rdev so...*/
|
/* flush_pending_writes() needs access to the rdev so...*/
|
||||||
mbio->bi_bdev = (void *)rdev;
|
mbio->bi_disk = (void *)rdev;
|
||||||
|
|
||||||
atomic_inc(&r10_bio->remaining);
|
atomic_inc(&r10_bio->remaining);
|
||||||
|
|
||||||
|
@ -2094,7 +2094,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
|
||||||
if (test_bit(FailFast, &conf->mirrors[d].rdev->flags))
|
if (test_bit(FailFast, &conf->mirrors[d].rdev->flags))
|
||||||
tbio->bi_opf |= MD_FAILFAST;
|
tbio->bi_opf |= MD_FAILFAST;
|
||||||
tbio->bi_iter.bi_sector += conf->mirrors[d].rdev->data_offset;
|
tbio->bi_iter.bi_sector += conf->mirrors[d].rdev->data_offset;
|
||||||
tbio->bi_bdev = conf->mirrors[d].rdev->bdev;
|
bio_set_dev(tbio, conf->mirrors[d].rdev->bdev);
|
||||||
generic_make_request(tbio);
|
generic_make_request(tbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2552,7 +2552,7 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
|
||||||
wsector = r10_bio->devs[i].addr + (sector - r10_bio->sector);
|
wsector = r10_bio->devs[i].addr + (sector - r10_bio->sector);
|
||||||
wbio->bi_iter.bi_sector = wsector +
|
wbio->bi_iter.bi_sector = wsector +
|
||||||
choose_data_offset(r10_bio, rdev);
|
choose_data_offset(r10_bio, rdev);
|
||||||
wbio->bi_bdev = rdev->bdev;
|
bio_set_dev(wbio, rdev->bdev);
|
||||||
bio_set_op_attrs(wbio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(wbio, REQ_OP_WRITE, 0);
|
||||||
|
|
||||||
if (submit_bio_wait(wbio) < 0)
|
if (submit_bio_wait(wbio) < 0)
|
||||||
|
@ -2575,7 +2575,6 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
struct r10conf *conf = mddev->private;
|
struct r10conf *conf = mddev->private;
|
||||||
struct md_rdev *rdev = r10_bio->devs[slot].rdev;
|
struct md_rdev *rdev = r10_bio->devs[slot].rdev;
|
||||||
dev_t bio_dev;
|
|
||||||
sector_t bio_last_sector;
|
sector_t bio_last_sector;
|
||||||
|
|
||||||
/* we got a read error. Maybe the drive is bad. Maybe just
|
/* we got a read error. Maybe the drive is bad. Maybe just
|
||||||
|
@ -2587,7 +2586,6 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
|
||||||
* frozen.
|
* frozen.
|
||||||
*/
|
*/
|
||||||
bio = r10_bio->devs[slot].bio;
|
bio = r10_bio->devs[slot].bio;
|
||||||
bio_dev = bio->bi_bdev->bd_dev;
|
|
||||||
bio_last_sector = r10_bio->devs[slot].addr + rdev->data_offset + r10_bio->sectors;
|
bio_last_sector = r10_bio->devs[slot].addr + rdev->data_offset + r10_bio->sectors;
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
r10_bio->devs[slot].bio = NULL;
|
r10_bio->devs[slot].bio = NULL;
|
||||||
|
@ -2950,7 +2948,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
|
|
||||||
/* Again, very different code for resync and recovery.
|
/* Again, very different code for resync and recovery.
|
||||||
* Both must result in an r10bio with a list of bios that
|
* Both must result in an r10bio with a list of bios that
|
||||||
* have bi_end_io, bi_sector, bi_bdev set,
|
* have bi_end_io, bi_sector, bi_disk set,
|
||||||
* and bi_private set to the r10bio.
|
* and bi_private set to the r10bio.
|
||||||
* For recovery, we may actually create several r10bios
|
* For recovery, we may actually create several r10bios
|
||||||
* with 2 bios in each, that correspond to the bios in the main one.
|
* with 2 bios in each, that correspond to the bios in the main one.
|
||||||
|
@ -3095,7 +3093,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
from_addr = r10_bio->devs[j].addr;
|
from_addr = r10_bio->devs[j].addr;
|
||||||
bio->bi_iter.bi_sector = from_addr +
|
bio->bi_iter.bi_sector = from_addr +
|
||||||
rdev->data_offset;
|
rdev->data_offset;
|
||||||
bio->bi_bdev = rdev->bdev;
|
bio_set_dev(bio, rdev->bdev);
|
||||||
atomic_inc(&rdev->nr_pending);
|
atomic_inc(&rdev->nr_pending);
|
||||||
/* and we write to 'i' (if not in_sync) */
|
/* and we write to 'i' (if not in_sync) */
|
||||||
|
|
||||||
|
@ -3117,7 +3115,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||||
bio->bi_iter.bi_sector = to_addr
|
bio->bi_iter.bi_sector = to_addr
|
||||||
+ mrdev->data_offset;
|
+ mrdev->data_offset;
|
||||||
bio->bi_bdev = mrdev->bdev;
|
bio_set_dev(bio, mrdev->bdev);
|
||||||
atomic_inc(&r10_bio->remaining);
|
atomic_inc(&r10_bio->remaining);
|
||||||
} else
|
} else
|
||||||
r10_bio->devs[1].bio->bi_end_io = NULL;
|
r10_bio->devs[1].bio->bi_end_io = NULL;
|
||||||
|
@ -3143,7 +3141,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||||
bio->bi_iter.bi_sector = to_addr +
|
bio->bi_iter.bi_sector = to_addr +
|
||||||
mreplace->data_offset;
|
mreplace->data_offset;
|
||||||
bio->bi_bdev = mreplace->bdev;
|
bio_set_dev(bio, mreplace->bdev);
|
||||||
atomic_inc(&r10_bio->remaining);
|
atomic_inc(&r10_bio->remaining);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3289,7 +3287,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
if (test_bit(FailFast, &rdev->flags))
|
if (test_bit(FailFast, &rdev->flags))
|
||||||
bio->bi_opf |= MD_FAILFAST;
|
bio->bi_opf |= MD_FAILFAST;
|
||||||
bio->bi_iter.bi_sector = sector + rdev->data_offset;
|
bio->bi_iter.bi_sector = sector + rdev->data_offset;
|
||||||
bio->bi_bdev = rdev->bdev;
|
bio_set_dev(bio, rdev->bdev);
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
rdev = rcu_dereference(conf->mirrors[d].replacement);
|
rdev = rcu_dereference(conf->mirrors[d].replacement);
|
||||||
|
@ -3311,7 +3309,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
if (test_bit(FailFast, &rdev->flags))
|
if (test_bit(FailFast, &rdev->flags))
|
||||||
bio->bi_opf |= MD_FAILFAST;
|
bio->bi_opf |= MD_FAILFAST;
|
||||||
bio->bi_iter.bi_sector = sector + rdev->data_offset;
|
bio->bi_iter.bi_sector = sector + rdev->data_offset;
|
||||||
bio->bi_bdev = rdev->bdev;
|
bio_set_dev(bio, rdev->bdev);
|
||||||
count++;
|
count++;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
@ -3367,7 +3365,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
r10_bio->sectors = nr_sectors;
|
r10_bio->sectors = nr_sectors;
|
||||||
|
|
||||||
if (bio->bi_end_io == end_sync_read) {
|
if (bio->bi_end_io == end_sync_read) {
|
||||||
md_sync_acct(bio->bi_bdev, nr_sectors);
|
md_sync_acct_bio(bio, nr_sectors);
|
||||||
bio->bi_status = 0;
|
bio->bi_status = 0;
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
}
|
}
|
||||||
|
@ -4383,7 +4381,7 @@ read_more:
|
||||||
|
|
||||||
read_bio = bio_alloc_mddev(GFP_KERNEL, RESYNC_PAGES, mddev);
|
read_bio = bio_alloc_mddev(GFP_KERNEL, RESYNC_PAGES, mddev);
|
||||||
|
|
||||||
read_bio->bi_bdev = rdev->bdev;
|
bio_set_dev(read_bio, rdev->bdev);
|
||||||
read_bio->bi_iter.bi_sector = (r10_bio->devs[r10_bio->read_slot].addr
|
read_bio->bi_iter.bi_sector = (r10_bio->devs[r10_bio->read_slot].addr
|
||||||
+ rdev->data_offset);
|
+ rdev->data_offset);
|
||||||
read_bio->bi_private = r10_bio;
|
read_bio->bi_private = r10_bio;
|
||||||
|
@ -4417,7 +4415,7 @@ read_more:
|
||||||
if (!rdev2 || test_bit(Faulty, &rdev2->flags))
|
if (!rdev2 || test_bit(Faulty, &rdev2->flags))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
b->bi_bdev = rdev2->bdev;
|
bio_set_dev(b, rdev2->bdev);
|
||||||
b->bi_iter.bi_sector = r10_bio->devs[s/2].addr +
|
b->bi_iter.bi_sector = r10_bio->devs[s/2].addr +
|
||||||
rdev2->new_data_offset;
|
rdev2->new_data_offset;
|
||||||
b->bi_end_io = end_reshape_write;
|
b->bi_end_io = end_reshape_write;
|
||||||
|
@ -4449,7 +4447,7 @@ read_more:
|
||||||
r10_bio->sectors = nr_sectors;
|
r10_bio->sectors = nr_sectors;
|
||||||
|
|
||||||
/* Now submit the read */
|
/* Now submit the read */
|
||||||
md_sync_acct(read_bio->bi_bdev, r10_bio->sectors);
|
md_sync_acct_bio(read_bio, r10_bio->sectors);
|
||||||
atomic_inc(&r10_bio->remaining);
|
atomic_inc(&r10_bio->remaining);
|
||||||
read_bio->bi_next = NULL;
|
read_bio->bi_next = NULL;
|
||||||
generic_make_request(read_bio);
|
generic_make_request(read_bio);
|
||||||
|
@ -4511,7 +4509,7 @@ static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio)
|
||||||
}
|
}
|
||||||
atomic_inc(&rdev->nr_pending);
|
atomic_inc(&rdev->nr_pending);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
md_sync_acct(b->bi_bdev, r10_bio->sectors);
|
md_sync_acct_bio(b, r10_bio->sectors);
|
||||||
atomic_inc(&r10_bio->remaining);
|
atomic_inc(&r10_bio->remaining);
|
||||||
b->bi_next = NULL;
|
b->bi_next = NULL;
|
||||||
generic_make_request(b);
|
generic_make_request(b);
|
||||||
|
|
|
@ -745,7 +745,7 @@ static struct bio *r5l_bio_alloc(struct r5l_log *log)
|
||||||
struct bio *bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, log->bs);
|
struct bio *bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, log->bs);
|
||||||
|
|
||||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||||
bio->bi_bdev = log->rdev->bdev;
|
bio_set_dev(bio, log->rdev->bdev);
|
||||||
bio->bi_iter.bi_sector = log->rdev->data_offset + log->log_start;
|
bio->bi_iter.bi_sector = log->rdev->data_offset + log->log_start;
|
||||||
|
|
||||||
return bio;
|
return bio;
|
||||||
|
@ -1313,7 +1313,7 @@ void r5l_flush_stripe_to_raid(struct r5l_log *log)
|
||||||
if (!do_flush)
|
if (!do_flush)
|
||||||
return;
|
return;
|
||||||
bio_reset(&log->flush_bio);
|
bio_reset(&log->flush_bio);
|
||||||
log->flush_bio.bi_bdev = log->rdev->bdev;
|
bio_set_dev(&log->flush_bio, log->rdev->bdev);
|
||||||
log->flush_bio.bi_end_io = r5l_log_flush_endio;
|
log->flush_bio.bi_end_io = r5l_log_flush_endio;
|
||||||
log->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
log->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||||
submit_bio(&log->flush_bio);
|
submit_bio(&log->flush_bio);
|
||||||
|
@ -1691,7 +1691,7 @@ static int r5l_recovery_fetch_ra_pool(struct r5l_log *log,
|
||||||
sector_t offset)
|
sector_t offset)
|
||||||
{
|
{
|
||||||
bio_reset(ctx->ra_bio);
|
bio_reset(ctx->ra_bio);
|
||||||
ctx->ra_bio->bi_bdev = log->rdev->bdev;
|
bio_set_dev(ctx->ra_bio, log->rdev->bdev);
|
||||||
bio_set_op_attrs(ctx->ra_bio, REQ_OP_READ, 0);
|
bio_set_op_attrs(ctx->ra_bio, REQ_OP_READ, 0);
|
||||||
ctx->ra_bio->bi_iter.bi_sector = log->rdev->data_offset + offset;
|
ctx->ra_bio->bi_iter.bi_sector = log->rdev->data_offset + offset;
|
||||||
|
|
||||||
|
|
|
@ -415,7 +415,7 @@ static void ppl_submit_iounit_bio(struct ppl_io_unit *io, struct bio *bio)
|
||||||
pr_debug("%s: seq: %llu size: %u sector: %llu dev: %s\n",
|
pr_debug("%s: seq: %llu size: %u sector: %llu dev: %s\n",
|
||||||
__func__, io->seq, bio->bi_iter.bi_size,
|
__func__, io->seq, bio->bi_iter.bi_size,
|
||||||
(unsigned long long)bio->bi_iter.bi_sector,
|
(unsigned long long)bio->bi_iter.bi_sector,
|
||||||
bdevname(bio->bi_bdev, b));
|
bio_devname(bio, b));
|
||||||
|
|
||||||
submit_bio(bio);
|
submit_bio(bio);
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
|
||||||
|
|
||||||
bio->bi_end_io = ppl_log_endio;
|
bio->bi_end_io = ppl_log_endio;
|
||||||
bio->bi_opf = REQ_OP_WRITE | REQ_FUA;
|
bio->bi_opf = REQ_OP_WRITE | REQ_FUA;
|
||||||
bio->bi_bdev = log->rdev->bdev;
|
bio_set_dev(bio, log->rdev->bdev);
|
||||||
bio->bi_iter.bi_sector = log->rdev->ppl.sector;
|
bio->bi_iter.bi_sector = log->rdev->ppl.sector;
|
||||||
bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
|
bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
|
||||||
bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES,
|
bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES,
|
||||||
ppl_conf->bs);
|
ppl_conf->bs);
|
||||||
bio->bi_opf = prev->bi_opf;
|
bio->bi_opf = prev->bi_opf;
|
||||||
bio->bi_bdev = prev->bi_bdev;
|
bio_copy_dev(bio, prev);
|
||||||
bio->bi_iter.bi_sector = bio_end_sector(prev);
|
bio->bi_iter.bi_sector = bio_end_sector(prev);
|
||||||
bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0);
|
bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0);
|
||||||
|
|
||||||
|
|
|
@ -1096,7 +1096,7 @@ again:
|
||||||
|
|
||||||
set_bit(STRIPE_IO_STARTED, &sh->state);
|
set_bit(STRIPE_IO_STARTED, &sh->state);
|
||||||
|
|
||||||
bi->bi_bdev = rdev->bdev;
|
bio_set_dev(bi, rdev->bdev);
|
||||||
bio_set_op_attrs(bi, op, op_flags);
|
bio_set_op_attrs(bi, op, op_flags);
|
||||||
bi->bi_end_io = op_is_write(op)
|
bi->bi_end_io = op_is_write(op)
|
||||||
? raid5_end_write_request
|
? raid5_end_write_request
|
||||||
|
@ -1145,7 +1145,7 @@ again:
|
||||||
set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
|
set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
|
||||||
|
|
||||||
if (conf->mddev->gendisk)
|
if (conf->mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
|
trace_block_bio_remap(bi->bi_disk->queue,
|
||||||
bi, disk_devt(conf->mddev->gendisk),
|
bi, disk_devt(conf->mddev->gendisk),
|
||||||
sh->dev[i].sector);
|
sh->dev[i].sector);
|
||||||
if (should_defer && op_is_write(op))
|
if (should_defer && op_is_write(op))
|
||||||
|
@ -1160,7 +1160,7 @@ again:
|
||||||
|
|
||||||
set_bit(STRIPE_IO_STARTED, &sh->state);
|
set_bit(STRIPE_IO_STARTED, &sh->state);
|
||||||
|
|
||||||
rbi->bi_bdev = rrdev->bdev;
|
bio_set_dev(rbi, rrdev->bdev);
|
||||||
bio_set_op_attrs(rbi, op, op_flags);
|
bio_set_op_attrs(rbi, op, op_flags);
|
||||||
BUG_ON(!op_is_write(op));
|
BUG_ON(!op_is_write(op));
|
||||||
rbi->bi_end_io = raid5_end_write_request;
|
rbi->bi_end_io = raid5_end_write_request;
|
||||||
|
@ -1193,7 +1193,7 @@ again:
|
||||||
if (op == REQ_OP_DISCARD)
|
if (op == REQ_OP_DISCARD)
|
||||||
rbi->bi_vcnt = 0;
|
rbi->bi_vcnt = 0;
|
||||||
if (conf->mddev->gendisk)
|
if (conf->mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
|
trace_block_bio_remap(rbi->bi_disk->queue,
|
||||||
rbi, disk_devt(conf->mddev->gendisk),
|
rbi, disk_devt(conf->mddev->gendisk),
|
||||||
sh->dev[i].sector);
|
sh->dev[i].sector);
|
||||||
if (should_defer && op_is_write(op))
|
if (should_defer && op_is_write(op))
|
||||||
|
@ -5092,10 +5092,12 @@ static int raid5_congested(struct mddev *mddev, int bits)
|
||||||
static int in_chunk_boundary(struct mddev *mddev, struct bio *bio)
|
static int in_chunk_boundary(struct mddev *mddev, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct r5conf *conf = mddev->private;
|
struct r5conf *conf = mddev->private;
|
||||||
sector_t sector = bio->bi_iter.bi_sector + get_start_sect(bio->bi_bdev);
|
sector_t sector = bio->bi_iter.bi_sector;
|
||||||
unsigned int chunk_sectors;
|
unsigned int chunk_sectors;
|
||||||
unsigned int bio_sectors = bio_sectors(bio);
|
unsigned int bio_sectors = bio_sectors(bio);
|
||||||
|
|
||||||
|
WARN_ON_ONCE(bio->bi_partno);
|
||||||
|
|
||||||
chunk_sectors = min(conf->chunk_sectors, conf->prev_chunk_sectors);
|
chunk_sectors = min(conf->chunk_sectors, conf->prev_chunk_sectors);
|
||||||
return chunk_sectors >=
|
return chunk_sectors >=
|
||||||
((sector & (chunk_sectors - 1)) + bio_sectors);
|
((sector & (chunk_sectors - 1)) + bio_sectors);
|
||||||
|
@ -5231,7 +5233,7 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio)
|
||||||
atomic_inc(&rdev->nr_pending);
|
atomic_inc(&rdev->nr_pending);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
raid_bio->bi_next = (void*)rdev;
|
raid_bio->bi_next = (void*)rdev;
|
||||||
align_bi->bi_bdev = rdev->bdev;
|
bio_set_dev(align_bi, rdev->bdev);
|
||||||
bio_clear_flag(align_bi, BIO_SEG_VALID);
|
bio_clear_flag(align_bi, BIO_SEG_VALID);
|
||||||
|
|
||||||
if (is_badblock(rdev, align_bi->bi_iter.bi_sector,
|
if (is_badblock(rdev, align_bi->bi_iter.bi_sector,
|
||||||
|
@ -5253,7 +5255,7 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio)
|
||||||
spin_unlock_irq(&conf->device_lock);
|
spin_unlock_irq(&conf->device_lock);
|
||||||
|
|
||||||
if (mddev->gendisk)
|
if (mddev->gendisk)
|
||||||
trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
|
trace_block_bio_remap(align_bi->bi_disk->queue,
|
||||||
align_bi, disk_devt(mddev->gendisk),
|
align_bi, disk_devt(mddev->gendisk),
|
||||||
raid_bio->bi_iter.bi_sector);
|
raid_bio->bi_iter.bi_sector);
|
||||||
generic_make_request(align_bi);
|
generic_make_request(align_bi);
|
||||||
|
|
|
@ -390,21 +390,22 @@ int nd_region_activate(struct nd_region *nd_region);
|
||||||
void __nd_iostat_start(struct bio *bio, unsigned long *start);
|
void __nd_iostat_start(struct bio *bio, unsigned long *start);
|
||||||
static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
|
static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
|
||||||
{
|
{
|
||||||
struct gendisk *disk = bio->bi_bdev->bd_disk;
|
struct gendisk *disk = bio->bi_disk;
|
||||||
|
|
||||||
if (!blk_queue_io_stat(disk->queue))
|
if (!blk_queue_io_stat(disk->queue))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*start = jiffies;
|
*start = jiffies;
|
||||||
generic_start_io_acct(bio_data_dir(bio),
|
generic_start_io_acct(disk->queue, bio_data_dir(bio),
|
||||||
bio_sectors(bio), &disk->part0);
|
bio_sectors(bio), &disk->part0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static inline void nd_iostat_end(struct bio *bio, unsigned long start)
|
static inline void nd_iostat_end(struct bio *bio, unsigned long start)
|
||||||
{
|
{
|
||||||
struct gendisk *disk = bio->bi_bdev->bd_disk;
|
struct gendisk *disk = bio->bi_disk;
|
||||||
|
|
||||||
generic_end_io_acct(bio_data_dir(bio), &disk->part0, start);
|
generic_end_io_acct(disk->queue, bio_data_dir(bio), &disk->part0,
|
||||||
|
start);
|
||||||
}
|
}
|
||||||
static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
|
static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
|
||||||
unsigned int len)
|
unsigned int len)
|
||||||
|
|
|
@ -613,11 +613,7 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
|
||||||
|
|
||||||
if (!disk)
|
if (!disk)
|
||||||
goto submit;
|
goto submit;
|
||||||
bio->bi_bdev = bdget_disk(disk, 0);
|
bio->bi_disk = disk;
|
||||||
if (!bio->bi_bdev) {
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto out_unmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta_buffer && meta_len) {
|
if (meta_buffer && meta_len) {
|
||||||
struct bio_integrity_payload *bip;
|
struct bio_integrity_payload *bip;
|
||||||
|
@ -668,11 +664,8 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
|
||||||
out_free_meta:
|
out_free_meta:
|
||||||
kfree(meta);
|
kfree(meta);
|
||||||
out_unmap:
|
out_unmap:
|
||||||
if (bio) {
|
if (bio)
|
||||||
if (disk && bio->bi_bdev)
|
|
||||||
bdput(bio->bi_bdev);
|
|
||||||
blk_rq_unmap_user(bio);
|
blk_rq_unmap_user(bio);
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
blk_mq_free_request(req);
|
blk_mq_free_request(req);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -2168,7 +2168,6 @@ static const struct blk_mq_ops nvme_fc_mq_ops = {
|
||||||
.complete = nvme_fc_complete_rq,
|
.complete = nvme_fc_complete_rq,
|
||||||
.init_request = nvme_fc_init_request,
|
.init_request = nvme_fc_init_request,
|
||||||
.exit_request = nvme_fc_exit_request,
|
.exit_request = nvme_fc_exit_request,
|
||||||
.reinit_request = nvme_fc_reinit_request,
|
|
||||||
.init_hctx = nvme_fc_init_hctx,
|
.init_hctx = nvme_fc_init_hctx,
|
||||||
.poll = nvme_fc_poll,
|
.poll = nvme_fc_poll,
|
||||||
.timeout = nvme_fc_timeout,
|
.timeout = nvme_fc_timeout,
|
||||||
|
@ -2269,7 +2268,7 @@ nvme_fc_reinit_io_queues(struct nvme_fc_ctrl *ctrl)
|
||||||
|
|
||||||
nvme_fc_init_io_queues(ctrl);
|
nvme_fc_init_io_queues(ctrl);
|
||||||
|
|
||||||
ret = blk_mq_reinit_tagset(&ctrl->tag_set);
|
ret = blk_mq_reinit_tagset(&ctrl->tag_set, nvme_fc_reinit_request);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_free_io_queues;
|
goto out_free_io_queues;
|
||||||
|
|
||||||
|
@ -2655,7 +2654,6 @@ static const struct blk_mq_ops nvme_fc_admin_mq_ops = {
|
||||||
.complete = nvme_fc_complete_rq,
|
.complete = nvme_fc_complete_rq,
|
||||||
.init_request = nvme_fc_init_request,
|
.init_request = nvme_fc_init_request,
|
||||||
.exit_request = nvme_fc_exit_request,
|
.exit_request = nvme_fc_exit_request,
|
||||||
.reinit_request = nvme_fc_reinit_request,
|
|
||||||
.init_hctx = nvme_fc_init_admin_hctx,
|
.init_hctx = nvme_fc_init_admin_hctx,
|
||||||
.timeout = nvme_fc_timeout,
|
.timeout = nvme_fc_timeout,
|
||||||
};
|
};
|
||||||
|
|
|
@ -643,17 +643,9 @@ static int nvme_nvm_submit_user_cmd(struct request_queue *q,
|
||||||
vcmd->ph_rw.metadata = cpu_to_le64(metadata_dma);
|
vcmd->ph_rw.metadata = cpu_to_le64(metadata_dma);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!disk)
|
bio->bi_disk = disk;
|
||||||
goto submit;
|
|
||||||
|
|
||||||
bio->bi_bdev = bdget_disk(disk, 0);
|
|
||||||
if (!bio->bi_bdev) {
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err_meta;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
submit:
|
|
||||||
blk_execute_rq(q, NULL, rq, 0);
|
blk_execute_rq(q, NULL, rq, 0);
|
||||||
|
|
||||||
if (nvme_req(rq)->flags & NVME_REQ_CANCELLED)
|
if (nvme_req(rq)->flags & NVME_REQ_CANCELLED)
|
||||||
|
@ -673,11 +665,8 @@ err_meta:
|
||||||
if (meta_buf && meta_len)
|
if (meta_buf && meta_len)
|
||||||
dma_pool_free(dev->dma_pool, metadata, metadata_dma);
|
dma_pool_free(dev->dma_pool, metadata, metadata_dma);
|
||||||
err_map:
|
err_map:
|
||||||
if (bio) {
|
if (bio)
|
||||||
if (disk && bio->bi_bdev)
|
|
||||||
bdput(bio->bi_bdev);
|
|
||||||
blk_rq_unmap_user(bio);
|
blk_rq_unmap_user(bio);
|
||||||
}
|
|
||||||
err_ppa:
|
err_ppa:
|
||||||
if (ppa_buf && ppa_len)
|
if (ppa_buf && ppa_len)
|
||||||
dma_pool_free(dev->dma_pool, ppa_list, ppa_dma);
|
dma_pool_free(dev->dma_pool, ppa_list, ppa_dma);
|
||||||
|
|
|
@ -711,14 +711,16 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
|
||||||
if (ctrl->ctrl.queue_count > 1) {
|
if (ctrl->ctrl.queue_count > 1) {
|
||||||
nvme_rdma_free_io_queues(ctrl);
|
nvme_rdma_free_io_queues(ctrl);
|
||||||
|
|
||||||
ret = blk_mq_reinit_tagset(&ctrl->tag_set);
|
ret = blk_mq_reinit_tagset(&ctrl->tag_set,
|
||||||
|
nvme_rdma_reinit_request);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto requeue;
|
goto requeue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvme_rdma_stop_and_free_queue(&ctrl->queues[0]);
|
nvme_rdma_stop_and_free_queue(&ctrl->queues[0]);
|
||||||
|
|
||||||
ret = blk_mq_reinit_tagset(&ctrl->admin_tag_set);
|
ret = blk_mq_reinit_tagset(&ctrl->admin_tag_set,
|
||||||
|
nvme_rdma_reinit_request);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto requeue;
|
goto requeue;
|
||||||
|
|
||||||
|
@ -1521,7 +1523,6 @@ static const struct blk_mq_ops nvme_rdma_mq_ops = {
|
||||||
.complete = nvme_rdma_complete_rq,
|
.complete = nvme_rdma_complete_rq,
|
||||||
.init_request = nvme_rdma_init_request,
|
.init_request = nvme_rdma_init_request,
|
||||||
.exit_request = nvme_rdma_exit_request,
|
.exit_request = nvme_rdma_exit_request,
|
||||||
.reinit_request = nvme_rdma_reinit_request,
|
|
||||||
.init_hctx = nvme_rdma_init_hctx,
|
.init_hctx = nvme_rdma_init_hctx,
|
||||||
.poll = nvme_rdma_poll,
|
.poll = nvme_rdma_poll,
|
||||||
.timeout = nvme_rdma_timeout,
|
.timeout = nvme_rdma_timeout,
|
||||||
|
@ -1533,7 +1534,6 @@ static const struct blk_mq_ops nvme_rdma_admin_mq_ops = {
|
||||||
.complete = nvme_rdma_complete_rq,
|
.complete = nvme_rdma_complete_rq,
|
||||||
.init_request = nvme_rdma_init_request,
|
.init_request = nvme_rdma_init_request,
|
||||||
.exit_request = nvme_rdma_exit_request,
|
.exit_request = nvme_rdma_exit_request,
|
||||||
.reinit_request = nvme_rdma_reinit_request,
|
|
||||||
.init_hctx = nvme_rdma_init_admin_hctx,
|
.init_hctx = nvme_rdma_init_admin_hctx,
|
||||||
.timeout = nvme_rdma_timeout,
|
.timeout = nvme_rdma_timeout,
|
||||||
};
|
};
|
||||||
|
@ -1731,7 +1731,8 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctrl->ctrl.queue_count > 1) {
|
if (ctrl->ctrl.queue_count > 1) {
|
||||||
ret = blk_mq_reinit_tagset(&ctrl->tag_set);
|
ret = blk_mq_reinit_tagset(&ctrl->tag_set,
|
||||||
|
nvme_rdma_reinit_request);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto del_dead_ctrl;
|
goto del_dead_ctrl;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue