mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
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
|
||||
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
|
||||
M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
|
||||
S: Maintained
|
||||
|
@ -110,7 +110,7 @@ axon_ram_irq_handler(int irq, void *dev)
|
||||
static blk_qc_t
|
||||
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;
|
||||
void *user_mem;
|
||||
struct bio_vec vec;
|
||||
|
@ -128,7 +128,7 @@ BFQ_BFQQ_FNS(busy);
|
||||
BFQ_BFQQ_FNS(wait_request);
|
||||
BFQ_BFQQ_FNS(non_blocking_wait_rq);
|
||||
BFQ_BFQQ_FNS(fifo_expire);
|
||||
BFQ_BFQQ_FNS(idle_window);
|
||||
BFQ_BFQQ_FNS(has_short_ttime);
|
||||
BFQ_BFQQ_FNS(sync);
|
||||
BFQ_BFQQ_FNS(IO_bound);
|
||||
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;
|
||||
bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq);
|
||||
|
||||
if (bic->saved_idle_window)
|
||||
bfq_mark_bfqq_idle_window(bfqq);
|
||||
if (bic->saved_has_short_ttime)
|
||||
bfq_mark_bfqq_has_short_ttime(bfqq);
|
||||
else
|
||||
bfq_clear_bfqq_idle_window(bfqq);
|
||||
bfq_clear_bfqq_has_short_ttime(bfqq);
|
||||
|
||||
if (bic->saved_IO_bound)
|
||||
bfq_mark_bfqq_IO_bound(bfqq);
|
||||
@ -2012,7 +2012,7 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
|
||||
return;
|
||||
|
||||
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_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
|
||||
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,
|
||||
"expire (%d, slow %d, num_disp %d, idle_win %d)", reason,
|
||||
slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq));
|
||||
"expire (%d, slow %d, num_disp %d, short_ttime %d)", reason,
|
||||
slow, bfqq->dispatched, bfq_bfqq_has_short_ttime(bfqq));
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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,
|
||||
asymmetric_scenario;
|
||||
|
||||
if (bfqd->strict_guarantees)
|
||||
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
|
||||
* boosts the throughput.
|
||||
*
|
||||
* The value of the variable is computed considering, first, that
|
||||
* idling is virtually always beneficial for the throughput if:
|
||||
* (a) the device is not NCQ-capable, or
|
||||
* (b) regardless of the presence of NCQ, the device is rotational
|
||||
* and the request pattern for bfqq is I/O-bound and sequential.
|
||||
* (a) the device is not NCQ-capable and rotational, or
|
||||
* (b) regardless of the presence of NCQ, the device is rotational and
|
||||
* 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
|
||||
* NCQ-capable flash-based device would not boost the
|
||||
* throughput even with sequential I/O; rather it would lower
|
||||
* the throughput in proportion to how fast the device
|
||||
* is. Accordingly, the next variable is true if any of the
|
||||
* above conditions (a) and (b) is true, and, in particular,
|
||||
* happens to be false if bfqd is an NCQ-capable flash-based
|
||||
* device.
|
||||
* above conditions (a), (b) or (c) is true, and, in
|
||||
* particular, happens to be false if bfqd is an NCQ-capable
|
||||
* flash-based device.
|
||||
*/
|
||||
idling_boosts_thr = !bfqd->hw_tag ||
|
||||
(!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) &&
|
||||
bfq_bfqq_idle_window(bfqq));
|
||||
idling_boosts_thr = rot_without_queueing ||
|
||||
((!blk_queue_nonrot(bfqd->queue) || !bfqd->hw_tag) &&
|
||||
bfqq_sequential_and_IO_bound);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* We have now all the components we need to compute the return
|
||||
* value of the function, which is true only if both the following
|
||||
* conditions hold:
|
||||
* 1) bfqq is sync, because idling make sense only for sync queues;
|
||||
* 2) idling either boosts the throughput (without issues), or
|
||||
* is necessary to preserve service guarantees.
|
||||
* We have now all the components we need to compute the
|
||||
* return value of the function, which is true only if idling
|
||||
* either boosts the throughput (without issues), or is
|
||||
* necessary to preserve service guarantees.
|
||||
*/
|
||||
return bfq_bfqq_sync(bfqq) &&
|
||||
(idling_boosts_thr_without_issues ||
|
||||
idling_needed_for_service_guarantees);
|
||||
return idling_boosts_thr_without_issues ||
|
||||
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)
|
||||
{
|
||||
struct bfq_data *bfqd = bfqq->bfqd;
|
||||
|
||||
return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 &&
|
||||
bfq_bfqq_may_idle(bfqq);
|
||||
return RB_EMPTY_ROOT(&bfqq->sort_list) && 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:
|
||||
bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE;
|
||||
bfqq->new_ioprio = 7;
|
||||
bfq_clear_bfqq_idle_window(bfqq);
|
||||
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);
|
||||
|
||||
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))
|
||||
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_just_created(bfqq);
|
||||
} 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable idle window if the process thinks too long or seeks so much that
|
||||
* it doesn't matter.
|
||||
*/
|
||||
static void bfq_update_idle_window(struct bfq_data *bfqd,
|
||||
struct bfq_queue *bfqq,
|
||||
struct bfq_io_cq *bic)
|
||||
static void bfq_update_has_short_ttime(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;
|
||||
|
||||
/* 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))
|
||||
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 ||
|
||||
bfqd->bfq_slice_idle == 0 ||
|
||||
(bfqd->hw_tag && BFQQ_SEEKY(bfqq) &&
|
||||
bfqq->wr_coeff == 1))
|
||||
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);
|
||||
(bfq_sample_valid(bfqq->ttime.ttime_samples) &&
|
||||
bfqq->ttime.ttime_mean > bfqd->bfq_slice_idle))
|
||||
has_short_ttime = false;
|
||||
|
||||
if (enable_idle)
|
||||
bfq_mark_bfqq_idle_window(bfqq);
|
||||
bfq_log_bfqq(bfqd, bfqq, "update_has_short_ttime: has_short_ttime %d",
|
||||
has_short_ttime);
|
||||
|
||||
if (has_short_ttime)
|
||||
bfq_mark_bfqq_has_short_ttime(bfqq);
|
||||
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++;
|
||||
|
||||
bfq_update_io_thinktime(bfqd, bfqq);
|
||||
bfq_update_has_short_ttime(bfqd, bfqq, bic);
|
||||
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,
|
||||
"rq_enqueued: idle_window=%d (seeky %d)",
|
||||
bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq));
|
||||
"rq_enqueued: has_short_ttime=%d (seeky %d)",
|
||||
bfq_bfqq_has_short_ttime(bfqq), BFQQ_SEEKY(bfqq));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static ssize_t bfq_var_store(unsigned long *var, const char *page,
|
||||
size_t count)
|
||||
static void bfq_var_store(unsigned long *var, const char *page)
|
||||
{
|
||||
unsigned long new_val;
|
||||
int ret = kstrtoul(page, 10, &new_val);
|
||||
|
||||
if (ret == 0)
|
||||
*var = new_val;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#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; \
|
||||
unsigned long uninitialized_var(__data); \
|
||||
int ret = bfq_var_store(&__data, (page), count); \
|
||||
bfq_var_store(&__data, (page)); \
|
||||
if (__data < (MIN)) \
|
||||
__data = (MIN); \
|
||||
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; \
|
||||
else \
|
||||
*(__PTR) = __data; \
|
||||
return ret; \
|
||||
return count; \
|
||||
}
|
||||
STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
|
||||
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; \
|
||||
unsigned long uninitialized_var(__data); \
|
||||
int ret = bfq_var_store(&__data, (page), count); \
|
||||
bfq_var_store(&__data, (page)); \
|
||||
if (__data < (MIN)) \
|
||||
__data = (MIN); \
|
||||
else if (__data > (MAX)) \
|
||||
__data = (MAX); \
|
||||
*(__PTR) = (u64)__data * NSEC_PER_USEC; \
|
||||
return ret; \
|
||||
return count; \
|
||||
}
|
||||
USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0,
|
||||
UINT_MAX);
|
||||
@ -4883,7 +4894,8 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
|
||||
{
|
||||
struct bfq_data *bfqd = e->elevator_data;
|
||||
unsigned long uninitialized_var(__data);
|
||||
int ret = bfq_var_store(&__data, (page), count);
|
||||
|
||||
bfq_var_store(&__data, (page));
|
||||
|
||||
if (__data == 0)
|
||||
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;
|
||||
|
||||
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;
|
||||
unsigned long uninitialized_var(__data);
|
||||
int ret = bfq_var_store(&__data, (page), count);
|
||||
|
||||
bfq_var_store(&__data, (page));
|
||||
|
||||
if (__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)
|
||||
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
|
||||
|
||||
return ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned long uninitialized_var(__data);
|
||||
int ret = bfq_var_store(&__data, (page), count);
|
||||
|
||||
bfq_var_store(&__data, (page));
|
||||
|
||||
if (__data > 1)
|
||||
__data = 1;
|
||||
@ -4936,7 +4950,7 @@ static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
|
||||
|
||||
bfqd->strict_guarantees = __data;
|
||||
|
||||
return ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned long uninitialized_var(__data);
|
||||
int ret = bfq_var_store(&__data, (page), count);
|
||||
|
||||
bfq_var_store(&__data, (page));
|
||||
|
||||
if (__data > 1)
|
||||
__data = 1;
|
||||
@ -4952,7 +4967,7 @@ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
|
||||
bfq_end_wr(bfqd);
|
||||
bfqd->low_latency = __data;
|
||||
|
||||
return ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
#define BFQ_ATTR(name) \
|
||||
@ -4998,6 +5013,7 @@ static struct elevator_type iosched_bfq_mq = {
|
||||
.elevator_name = "bfq",
|
||||
.elevator_owner = THIS_MODULE,
|
||||
};
|
||||
MODULE_ALIAS("bfq-iosched");
|
||||
|
||||
static int __init bfq_init(void)
|
||||
{
|
||||
@ -5048,10 +5064,12 @@ static int __init bfq_init(void)
|
||||
|
||||
ret = elv_register(&iosched_bfq_mq);
|
||||
if (ret)
|
||||
goto err_pol_unreg;
|
||||
goto slab_kill;
|
||||
|
||||
return 0;
|
||||
|
||||
slab_kill:
|
||||
bfq_slab_kill();
|
||||
err_pol_unreg:
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
blkcg_policy_unregister(&blkcg_policy_bfq);
|
||||
|
@ -360,11 +360,11 @@ struct bfq_io_cq {
|
||||
uint64_t blkcg_serial_nr; /* the current blkcg serial */
|
||||
#endif
|
||||
/*
|
||||
* Snapshot of the idle window before merging; taken to
|
||||
* remember this value while the queue is merged, so as to be
|
||||
* able to restore it in case of split.
|
||||
* Snapshot of the has_short_time flag before merging; taken
|
||||
* to remember its value while the queue is merged, so as to
|
||||
* 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
|
||||
* classification of a queue.
|
||||
@ -638,7 +638,7 @@ enum bfqq_state_flags {
|
||||
* without idling the device
|
||||
*/
|
||||
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_IO_bound, /*
|
||||
* bfqq has timed-out at least once
|
||||
@ -667,7 +667,7 @@ BFQ_BFQQ_FNS(busy);
|
||||
BFQ_BFQQ_FNS(wait_request);
|
||||
BFQ_BFQQ_FNS(non_blocking_wait_rq);
|
||||
BFQ_BFQQ_FNS(fifo_expire);
|
||||
BFQ_BFQQ_FNS(idle_window);
|
||||
BFQ_BFQQ_FNS(has_short_ttime);
|
||||
BFQ_BFQQ_FNS(sync);
|
||||
BFQ_BFQQ_FNS(IO_bound);
|
||||
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);
|
||||
|
||||
#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \
|
||||
blk_add_trace_msg((bfqd)->queue, "bfq%d%c %s " fmt, (bfqq)->pid,\
|
||||
bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \
|
||||
bfqq_group(bfqq)->blkg_path, ##args); \
|
||||
blk_add_cgroup_trace_msg((bfqd)->queue, \
|
||||
bfqg_to_blkg(bfqq_group(bfqq))->blkcg, \
|
||||
"bfq%d%c " fmt, (bfqq)->pid, \
|
||||
bfq_bfqq_sync((bfqq)) ? 'S' : 'A', ##args); \
|
||||
} while (0)
|
||||
|
||||
#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) \
|
||||
blk_add_trace_msg((bfqd)->queue, "%s " fmt, (bfqg)->blkg_path, ##args)
|
||||
#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do { \
|
||||
blk_add_cgroup_trace_msg((bfqd)->queue, \
|
||||
bfqg_to_blkg(bfqg)->blkcg, fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
#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;
|
||||
|
||||
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))
|
||||
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,
|
||||
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 bvec_iter bviter;
|
||||
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) +
|
||||
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.seed = proc_iter->bi_sector;
|
||||
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)
|
||||
{
|
||||
struct bio_integrity_payload *bip;
|
||||
struct blk_integrity *bi;
|
||||
struct request_queue *q;
|
||||
struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
|
||||
struct request_queue *q = bio->bi_disk->queue;
|
||||
void *buf;
|
||||
unsigned long start, end;
|
||||
unsigned int len, nr_pages;
|
||||
@ -245,8 +245,9 @@ bool bio_integrity_prep(struct bio *bio)
|
||||
unsigned int intervals;
|
||||
blk_status_t status;
|
||||
|
||||
bi = bdev_get_integrity(bio->bi_bdev);
|
||||
q = bdev_get_queue(bio->bi_bdev);
|
||||
if (!bi)
|
||||
return true;
|
||||
|
||||
if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE)
|
||||
return true;
|
||||
|
||||
@ -257,9 +258,6 @@ bool bio_integrity_prep(struct bio *bio)
|
||||
if (bio_integrity(bio))
|
||||
return true;
|
||||
|
||||
if (bi == NULL)
|
||||
return true;
|
||||
|
||||
if (bio_data_dir(bio) == READ) {
|
||||
if (!bi->profile->verify_fn ||
|
||||
!(bi->flags & BLK_INTEGRITY_VERIFY))
|
||||
@ -354,7 +352,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
|
||||
struct bio_integrity_payload *bip =
|
||||
container_of(work, struct bio_integrity_payload, bip_work);
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -387,7 +385,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
|
||||
*/
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
bip->bip_iter.bi_sector += bytes_done >> 9;
|
||||
@ -430,7 +428,7 @@ EXPORT_SYMBOL(bio_integrity_advance);
|
||||
void bio_integrity_trim(struct bio *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));
|
||||
}
|
||||
|
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));
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
bio->bi_bdev = bio_src->bi_bdev;
|
||||
bio->bi_disk = bio_src->bi_disk;
|
||||
bio_set_flag(bio, BIO_CLONED);
|
||||
bio->bi_opf = bio_src->bi_opf;
|
||||
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);
|
||||
if (!bio)
|
||||
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_write_hint = bio_src->bi_write_hint;
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
@ -1732,29 +1736,29 @@ void bio_check_pages_dirty(struct bio *bio)
|
||||
}
|
||||
}
|
||||
|
||||
void generic_start_io_acct(int rw, unsigned long sectors,
|
||||
struct hd_struct *part)
|
||||
void generic_start_io_acct(struct request_queue *q, int rw,
|
||||
unsigned long sectors, struct hd_struct *part)
|
||||
{
|
||||
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_add(cpu, part, sectors[rw], sectors);
|
||||
part_inc_in_flight(part, rw);
|
||||
part_inc_in_flight(q, part, rw);
|
||||
|
||||
part_stat_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(generic_start_io_acct);
|
||||
|
||||
void generic_end_io_acct(int rw, struct hd_struct *part,
|
||||
unsigned long start_time)
|
||||
void generic_end_io_acct(struct request_queue *q, int rw,
|
||||
struct hd_struct *part, unsigned long start_time)
|
||||
{
|
||||
unsigned long duration = jiffies - start_time;
|
||||
int cpu = part_stat_lock();
|
||||
|
||||
part_stat_add(cpu, part, ticks[rw], duration);
|
||||
part_round_stats(cpu, part);
|
||||
part_dec_in_flight(part, rw);
|
||||
part_round_stats(q, cpu, part);
|
||||
part_dec_in_flight(q, part, rw);
|
||||
|
||||
part_stat_unlock();
|
||||
}
|
||||
@ -1826,8 +1830,8 @@ again:
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
|
||||
trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), bio,
|
||||
if (bio->bi_disk && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
|
||||
trace_block_bio_complete(bio->bi_disk->queue, bio,
|
||||
blk_status_to_errno(bio->bi_status));
|
||||
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);
|
||||
if (!blkcg) {
|
||||
ret = ERR_PTR(-ENOMEM);
|
||||
goto free_blkcg;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,8 +1111,10 @@ free_pd_blkcg:
|
||||
for (i--; i >= 0; i--)
|
||||
if (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);
|
||||
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)
|
||||
{
|
||||
lockdep_assert_held(q->queue_lock);
|
||||
WARN_ON(!irqs_disabled());
|
||||
WARN_ON(!in_interrupt() && !irqs_disabled());
|
||||
WARN_ON_ONCE(q->mq_ops);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void part_round_stats_single(int cpu, struct hd_struct *part,
|
||||
unsigned long now)
|
||||
static void part_round_stats_single(struct request_queue *q, int cpu,
|
||||
struct hd_struct *part, unsigned long now,
|
||||
unsigned int inflight)
|
||||
{
|
||||
int inflight;
|
||||
|
||||
if (now == part->stamp)
|
||||
return;
|
||||
|
||||
inflight = part_in_flight(part);
|
||||
if (inflight) {
|
||||
__part_stat_add(cpu, part, time_in_queue,
|
||||
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.
|
||||
* @q: target block queue
|
||||
* @cpu: cpu number for stats access
|
||||
* @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
|
||||
* 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 int inflight[2];
|
||||
int stats = 0;
|
||||
|
||||
if (part->partno)
|
||||
part_round_stats_single(cpu, &part_to_disk(part)->part0, now);
|
||||
part_round_stats_single(cpu, part, now);
|
||||
if (part->stamp != now)
|
||||
stats |= 1;
|
||||
|
||||
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);
|
||||
|
||||
@ -1896,40 +1910,15 @@ out_unlock:
|
||||
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)
|
||||
{
|
||||
char b[BDEVNAME_SIZE];
|
||||
|
||||
printk(KERN_INFO "attempt to access beyond end of device\n");
|
||||
printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n",
|
||||
bdevname(bio->bi_bdev, b),
|
||||
bio->bi_opf,
|
||||
bio_devname(bio, b), bio->bi_opf,
|
||||
(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
|
||||
@ -1967,6 +1956,38 @@ static inline bool should_fail_request(struct hd_struct *part,
|
||||
|
||||
#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.
|
||||
*/
|
||||
@ -1978,7 +1999,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
|
||||
return 0;
|
||||
|
||||
/* 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) {
|
||||
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);
|
||||
blk_status_t status = BLK_STS_IOERR;
|
||||
char b[BDEVNAME_SIZE];
|
||||
struct hd_struct *part;
|
||||
|
||||
might_sleep();
|
||||
|
||||
if (bio_check_eod(bio, nr_sectors))
|
||||
goto end_io;
|
||||
|
||||
q = bdev_get_queue(bio->bi_bdev);
|
||||
q = bio->bi_disk->queue;
|
||||
if (unlikely(!q)) {
|
||||
printk(KERN_ERR
|
||||
"generic_make_request: Trying to access "
|
||||
"nonexistent block-device %s (%Lu)\n",
|
||||
bdevname(bio->bi_bdev, b),
|
||||
(long long) bio->bi_iter.bi_sector);
|
||||
bio_devname(bio, b), (long long)bio->bi_iter.bi_sector);
|
||||
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))
|
||||
goto not_supported;
|
||||
|
||||
part = bio->bi_bdev->bd_part;
|
||||
if (should_fail_request(part, bio->bi_iter.bi_size) ||
|
||||
should_fail_request(&part_to_disk(part)->part0,
|
||||
bio->bi_iter.bi_size))
|
||||
if (should_fail_request(&bio->bi_disk->part0, bio->bi_iter.bi_size))
|
||||
goto end_io;
|
||||
|
||||
/*
|
||||
* If this device has partitions, remap block n
|
||||
* of partition p to block n+start(p) of the disk.
|
||||
*/
|
||||
blk_partition_remap(bio);
|
||||
if (blk_partition_remap(bio))
|
||||
goto end_io;
|
||||
|
||||
if (bio_check_eod(bio, nr_sectors))
|
||||
goto end_io;
|
||||
@ -2067,16 +2080,16 @@ generic_make_request_checks(struct bio *bio)
|
||||
goto not_supported;
|
||||
break;
|
||||
case REQ_OP_WRITE_SAME:
|
||||
if (!bdev_write_same(bio->bi_bdev))
|
||||
if (!q->limits.max_write_same_sectors)
|
||||
goto not_supported;
|
||||
break;
|
||||
case REQ_OP_ZONE_REPORT:
|
||||
case REQ_OP_ZONE_RESET:
|
||||
if (!bdev_is_zoned(bio->bi_bdev))
|
||||
if (!blk_queue_is_zoned(q))
|
||||
goto not_supported;
|
||||
break;
|
||||
case REQ_OP_WRITE_ZEROES:
|
||||
if (!bdev_write_zeroes_sectors(bio->bi_bdev))
|
||||
if (!q->limits.max_write_zeroes_sectors)
|
||||
goto not_supported;
|
||||
break;
|
||||
default:
|
||||
@ -2183,7 +2196,7 @@ blk_qc_t generic_make_request(struct bio *bio)
|
||||
bio_list_init(&bio_list_on_stack[0]);
|
||||
current->bio_list = bio_list_on_stack;
|
||||
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)) {
|
||||
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(&same);
|
||||
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);
|
||||
else
|
||||
bio_list_add(&lower, bio);
|
||||
@ -2244,7 +2257,7 @@ blk_qc_t submit_bio(struct bio *bio)
|
||||
unsigned int count;
|
||||
|
||||
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
|
||||
count = bio_sectors(bio);
|
||||
|
||||
@ -2261,8 +2274,7 @@ blk_qc_t submit_bio(struct bio *bio)
|
||||
current->comm, task_pid_nr(current),
|
||||
op_is_write(bio_op(bio)) ? "WRITE" : "READ",
|
||||
(unsigned long long)bio->bi_iter.bi_sector,
|
||||
bdevname(bio->bi_bdev, b),
|
||||
count);
|
||||
bio_devname(bio, b), count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2431,8 +2443,8 @@ void blk_account_io_done(struct request *req)
|
||||
|
||||
part_stat_inc(cpu, part, ios[rw]);
|
||||
part_stat_add(cpu, part, ticks[rw], duration);
|
||||
part_round_stats(cpu, part);
|
||||
part_dec_in_flight(part, rw);
|
||||
part_round_stats(req->q, cpu, part);
|
||||
part_dec_in_flight(req->q, part, rw);
|
||||
|
||||
hd_struct_put(part);
|
||||
part_stat_unlock();
|
||||
@ -2489,8 +2501,8 @@ void blk_account_io_start(struct request *rq, bool new_io)
|
||||
part = &rq->rq_disk->part0;
|
||||
hd_struct_get(part);
|
||||
}
|
||||
part_round_stats(cpu, part);
|
||||
part_inc_in_flight(part, rw);
|
||||
part_round_stats(rq->q, cpu, part);
|
||||
part_inc_in_flight(rq->q, part, rw);
|
||||
rq->part = part;
|
||||
}
|
||||
|
||||
@ -2603,7 +2615,7 @@ struct request *blk_peek_request(struct request_queue *q)
|
||||
}
|
||||
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;
|
||||
|
||||
@ -2630,9 +2642,6 @@ void blk_dequeue_request(struct request *rq)
|
||||
* Description:
|
||||
* Dequeue @req and start timeout timer on it. This hands off the
|
||||
* 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)
|
||||
{
|
||||
@ -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->bio = rq->biotail = bio;
|
||||
|
||||
if (bio->bi_bdev)
|
||||
rq->rq_disk = bio->bi_bdev->bd_disk;
|
||||
if (bio->bi_disk)
|
||||
rq->rq_disk = bio->bi_disk;
|
||||
}
|
||||
|
||||
#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 Tejun Heo <tj@kernel.org>
|
||||
*
|
||||
* 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
|
||||
* properties and hardware capability.
|
||||
*
|
||||
@ -16,9 +16,9 @@
|
||||
* REQ_FUA means that the data must be on non-volatile media on request
|
||||
* completion.
|
||||
*
|
||||
* If the device doesn't have writeback cache, FLUSH and FUA don't make any
|
||||
* difference. The requests are either completed immediately if there's no
|
||||
* data or executed as normal requests otherwise.
|
||||
* 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 data
|
||||
* or executed as normal requests otherwise.
|
||||
*
|
||||
* If the device has writeback cache and supports FUA, REQ_PREFLUSH is
|
||||
* 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
|
||||
* 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
|
||||
* step. This allows arbitrary merging of different types of FLUSH/FUA
|
||||
* step. This allows arbitrary merging of different types of PREFLUSH/FUA
|
||||
* requests.
|
||||
*
|
||||
* 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
|
||||
* waited longer than FLUSH_PENDING_TIMEOUT. This is to avoid
|
||||
* 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)
|
||||
* 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
|
||||
* complete. The first completion updates the contained bio but doesn't
|
||||
* 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
|
||||
* 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
|
||||
* merged in the usual way.
|
||||
*/
|
||||
@ -76,7 +76,7 @@
|
||||
#include "blk-mq-tag.h"
|
||||
#include "blk-mq-sched.h"
|
||||
|
||||
/* FLUSH/FUA sequences */
|
||||
/* PREFLUSH/FUA sequences */
|
||||
enum {
|
||||
REQ_FSEQ_PREFLUSH = (1 << 0), /* pre-flushing 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
|
||||
* @rq: FLUSH/FUA request being sequenced
|
||||
* @rq: PREFLUSH/FUA request being sequenced
|
||||
* @fq: flush queue
|
||||
* @seq: sequences to complete (mask of %REQ_FSEQ_*, can be zero)
|
||||
* @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
|
||||
*
|
||||
* 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;
|
||||
|
||||
bio = bio_alloc(gfp_mask, 0);
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||
|
||||
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->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio_set_op_attrs(bio, op, 0);
|
||||
|
||||
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) {
|
||||
bio = next_bio(bio, 1, gfp_mask);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio->bi_vcnt = 1;
|
||||
bio->bi_io_vec->bv_page = page;
|
||||
bio->bi_io_vec->bv_offset = 0;
|
||||
@ -241,7 +241,7 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
|
||||
while (nr_sects) {
|
||||
bio = next_bio(bio, 0, gfp_mask);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio->bi_opf = REQ_OP_WRITE_ZEROES;
|
||||
if (flags & BLKDEV_ZERO_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),
|
||||
gfp_mask);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
|
||||
while (nr_sects != 0) {
|
||||
|
@ -633,8 +633,8 @@ static void blk_account_io_merge(struct request *req)
|
||||
cpu = part_stat_lock();
|
||||
part = req->part;
|
||||
|
||||
part_round_stats(cpu, part);
|
||||
part_dec_in_flight(part, rq_data_dir(req));
|
||||
part_round_stats(req->q, cpu, part);
|
||||
part_dec_in_flight(req->q, part, rq_data_dir(req));
|
||||
|
||||
hd_struct_put(part);
|
||||
part_stat_unlock();
|
||||
@ -786,7 +786,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
|
||||
return false;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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[] = {
|
||||
QUEUE_FLAG_NAME(QUEUED),
|
||||
QUEUE_FLAG_NAME(STOPPED),
|
||||
QUEUE_FLAG_NAME(SYNCFULL),
|
||||
QUEUE_FLAG_NAME(ASYNCFULL),
|
||||
QUEUE_FLAG_NAME(DYING),
|
||||
QUEUE_FLAG_NAME(BYPASS),
|
||||
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);
|
||||
}
|
||||
|
||||
const struct file_operations blk_mq_debugfs_fops = {
|
||||
static const struct file_operations blk_mq_debugfs_fops = {
|
||||
.open = blk_mq_debugfs_open,
|
||||
.read = seq_read,
|
||||
.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;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
@ -248,9 +252,15 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
|
||||
|
||||
if (!reserved)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -288,11 +298,12 @@ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
|
||||
}
|
||||
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;
|
||||
|
||||
if (!set->ops->reinit_request)
|
||||
if (WARN_ON_ONCE(!reinit_request))
|
||||
goto out;
|
||||
|
||||
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])
|
||||
continue;
|
||||
|
||||
ret = set->ops->reinit_request(set->driver_data,
|
||||
tags->static_rqs[j]);
|
||||
ret = reinit_request(set->driver_data,
|
||||
tags->static_rqs[j]);
|
||||
if (ret)
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
LIST_HEAD(rq_list);
|
||||
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);
|
||||
spin_unlock_irqrestore(&q->requeue_lock, flags);
|
||||
spin_unlock_irq(&q->requeue_lock);
|
||||
|
||||
list_for_each_entry_safe(rq, next, &rq_list, queuelist) {
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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) &&
|
||||
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)) {
|
||||
rcu_read_lock();
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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;
|
||||
}
|
||||
|
||||
void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
|
||||
unsigned int inflight[2]);
|
||||
|
||||
#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)
|
||||
{
|
||||
WARN_ON_ONCE(q->mq_ops);
|
||||
q->rq_timed_out_fn = fn;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_queue_rq_timed_out);
|
||||
|
@ -931,7 +931,9 @@ void blk_unregister_queue(struct gendisk *disk)
|
||||
if (WARN_ON(!q))
|
||||
return;
|
||||
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
queue_flag_clear_unlocked(QUEUE_FLAG_REGISTERED, q);
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_end_tag);
|
||||
|
||||
/**
|
||||
* 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))) \
|
||||
break; \
|
||||
if ((__tg)) { \
|
||||
char __pbuf[128]; \
|
||||
\
|
||||
blkg_path(tg_to_blkg(__tg), __pbuf, sizeof(__pbuf)); \
|
||||
blk_add_trace_msg(__td->queue, "throtl %s " fmt, __pbuf, ##args); \
|
||||
blk_add_cgroup_trace_msg(__td->queue, \
|
||||
tg_to_blkg(__tg)->blkcg, "throtl " fmt, ##args);\
|
||||
} else { \
|
||||
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)
|
||||
{
|
||||
#ifdef CONFIG_BLK_DEV_THROTTLING_LOW
|
||||
int ret;
|
||||
|
||||
ret = bio_associate_current(bio);
|
||||
if (ret == 0 || ret == -EBUSY)
|
||||
if (bio->bi_css)
|
||||
bio->bi_cg_private = tg;
|
||||
blk_stat_set_issue(&bio->bi_issue_stat, bio_sectors(bio));
|
||||
#else
|
||||
bio_associate_current(bio);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ int blkdev_report_zones(struct block_device *bdev,
|
||||
if (!bio)
|
||||
return -ENOMEM;
|
||||
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio->bi_iter.bi_sector = blk_zone_start(q, sector);
|
||||
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->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio_set_op_attrs(bio, REQ_OP_ZONE_RESET, 0);
|
||||
|
||||
ret = submit_bio_wait(bio);
|
||||
|
@ -64,7 +64,6 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
|
||||
struct bio *bio);
|
||||
void blk_queue_bypass_start(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_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);
|
||||
}
|
||||
|
||||
struct hd_struct *__disk_get_part(struct gendisk *disk, int partno);
|
||||
|
||||
#ifdef CONFIG_FAIL_IO_TIMEOUT
|
||||
int blk_should_fake_timeout(struct request_queue *);
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* block device ioctls
|
||||
*/
|
||||
default:
|
||||
#if 0
|
||||
return ioctl_by_bdev(bd->bdev, cmd, arg);
|
||||
#else
|
||||
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 { \
|
||||
char __pbuf[128]; \
|
||||
\
|
||||
blkg_path(cfqg_to_blkg((cfqq)->cfqg), __pbuf, sizeof(__pbuf)); \
|
||||
blk_add_trace_msg((cfqd)->queue, "cfq%d%c%c %s " fmt, (cfqq)->pid, \
|
||||
blk_add_cgroup_trace_msg((cfqd)->queue, \
|
||||
cfqg_to_blkg((cfqq)->cfqg)->blkcg, \
|
||||
"cfq%d%c%c " fmt, (cfqq)->pid, \
|
||||
cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \
|
||||
cfqq_type((cfqq)) == SYNC_NOIDLE_WORKLOAD ? 'N' : ' ',\
|
||||
__pbuf, ##args); \
|
||||
##args); \
|
||||
} while (0)
|
||||
|
||||
#define cfq_log_cfqg(cfqd, cfqg, fmt, args...) do { \
|
||||
char __pbuf[128]; \
|
||||
\
|
||||
blkg_path(cfqg_to_blkg(cfqg), __pbuf, sizeof(__pbuf)); \
|
||||
blk_add_trace_msg((cfqd)->queue, "%s " fmt, __pbuf, ##args); \
|
||||
blk_add_cgroup_trace_msg((cfqd)->queue, \
|
||||
cfqg_to_blkg(cfqg)->blkcg, fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
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
|
||||
* 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
cfq_var_store(unsigned int *var, const char *page, size_t count)
|
||||
static void
|
||||
cfq_var_store(unsigned int *var, const char *page)
|
||||
{
|
||||
char *p = (char *) page;
|
||||
|
||||
*var = simple_strtoul(p, &p, 10);
|
||||
return count;
|
||||
}
|
||||
|
||||
#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; \
|
||||
unsigned int __data; \
|
||||
int ret = cfq_var_store(&__data, (page), count); \
|
||||
cfq_var_store(&__data, (page)); \
|
||||
if (__data < (MIN)) \
|
||||
__data = (MIN); \
|
||||
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; \
|
||||
else \
|
||||
*(__PTR) = __data; \
|
||||
return ret; \
|
||||
return count; \
|
||||
}
|
||||
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,
|
||||
@ -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; \
|
||||
unsigned int __data; \
|
||||
int ret = cfq_var_store(&__data, (page), count); \
|
||||
cfq_var_store(&__data, (page)); \
|
||||
if (__data < (MIN)) \
|
||||
__data = (MIN); \
|
||||
else if (__data > (MAX)) \
|
||||
__data = (MAX); \
|
||||
*(__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_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);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
deadline_var_store(int *var, const char *page, size_t count)
|
||||
static void
|
||||
deadline_var_store(int *var, const char *page)
|
||||
{
|
||||
char *p = (char *) page;
|
||||
|
||||
*var = simple_strtol(p, &p, 10);
|
||||
return count;
|
||||
}
|
||||
|
||||
#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; \
|
||||
int __data; \
|
||||
int ret = deadline_var_store(&__data, (page), count); \
|
||||
deadline_var_store(&__data, (page)); \
|
||||
if (__data < (MIN)) \
|
||||
__data = (MIN); \
|
||||
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); \
|
||||
else \
|
||||
*(__PTR) = __data; \
|
||||
return ret; \
|
||||
return count; \
|
||||
}
|
||||
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);
|
||||
|
@ -1055,6 +1055,10 @@ static int __elevator_change(struct request_queue *q, const char *name)
|
||||
char elevator_name[ELV_NAME_MAX];
|
||||
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
|
||||
*/
|
||||
|
@ -45,6 +45,52 @@ static void disk_add_events(struct gendisk *disk);
|
||||
static void disk_del_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: 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 *part = NULL;
|
||||
struct disk_part_tbl *ptbl;
|
||||
|
||||
if (unlikely(partno < 0))
|
||||
return NULL;
|
||||
struct hd_struct *part;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
ptbl = rcu_dereference(disk->part_tbl);
|
||||
if (likely(partno < ptbl->len)) {
|
||||
part = rcu_dereference(ptbl->part[partno]);
|
||||
if (part)
|
||||
get_device(part_to_dev(part));
|
||||
}
|
||||
|
||||
part = __disk_get_part(disk, partno);
|
||||
if (part)
|
||||
get_device(part_to_dev(part));
|
||||
rcu_read_unlock();
|
||||
|
||||
return part;
|
||||
@ -1098,12 +1135,13 @@ static const struct attribute_group *disk_attr_groups[] = {
|
||||
* original ptbl is freed using RCU callback.
|
||||
*
|
||||
* 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,
|
||||
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);
|
||||
|
||||
@ -1122,14 +1160,16 @@ static void disk_replace_part_tbl(struct gendisk *disk,
|
||||
* uses RCU to allow unlocked dereferencing for stats and other stuff.
|
||||
*
|
||||
* LOCKING:
|
||||
* Matching bd_mutex locked, might sleep.
|
||||
* Matching bd_mutex locked or the caller is the only user of @disk.
|
||||
* Might sleep.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno on failure.
|
||||
*/
|
||||
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;
|
||||
int len = old_ptbl ? old_ptbl->len : 0;
|
||||
int i, target;
|
||||
@ -1212,6 +1252,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
|
||||
struct disk_part_iter piter;
|
||||
struct hd_struct *hd;
|
||||
char buf[BDEVNAME_SIZE];
|
||||
unsigned int inflight[2];
|
||||
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);
|
||||
while ((hd = disk_part_iter_next(&piter))) {
|
||||
cpu = part_stat_lock();
|
||||
part_round_stats(cpu, hd);
|
||||
part_round_stats(gp->queue, cpu, hd);
|
||||
part_stat_unlock();
|
||||
part_in_flight(gp->queue, hd, inflight);
|
||||
seq_printf(seqf, "%4d %7d %s %lu %lu %lu "
|
||||
"%u %lu %lu %lu %u %u %u %u\n",
|
||||
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, sectors[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, time_in_queue))
|
||||
);
|
||||
@ -1321,6 +1363,14 @@ EXPORT_SYMBOL(alloc_disk);
|
||||
struct gendisk *alloc_disk_node(int minors, int node_id)
|
||||
{
|
||||
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);
|
||||
if (disk) {
|
||||
@ -1334,7 +1384,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
|
||||
kfree(disk);
|
||||
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
|
||||
|
@ -457,13 +457,12 @@ deadline_var_show(int var, char *page)
|
||||
return sprintf(page, "%d\n", var);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
deadline_var_store(int *var, const char *page, size_t count)
|
||||
static void
|
||||
deadline_var_store(int *var, const char *page)
|
||||
{
|
||||
char *p = (char *) page;
|
||||
|
||||
*var = simple_strtol(p, &p, 10);
|
||||
return count;
|
||||
}
|
||||
|
||||
#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; \
|
||||
int __data; \
|
||||
int ret = deadline_var_store(&__data, (page), count); \
|
||||
deadline_var_store(&__data, (page)); \
|
||||
if (__data < (MIN)) \
|
||||
__data = (MIN); \
|
||||
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); \
|
||||
else \
|
||||
*(__PTR) = __data; \
|
||||
return ret; \
|
||||
return count; \
|
||||
}
|
||||
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);
|
||||
@ -660,6 +659,7 @@ static struct elevator_type mq_deadline = {
|
||||
.elevator_name = "mq-deadline",
|
||||
.elevator_owner = THIS_MODULE,
|
||||
};
|
||||
MODULE_ALIAS("mq-deadline-iosched");
|
||||
|
||||
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 hd_struct *p = dev_to_part(dev);
|
||||
struct request_queue *q = dev_to_disk(dev)->queue;
|
||||
unsigned int inflight[2];
|
||||
int cpu;
|
||||
|
||||
cpu = part_stat_lock();
|
||||
part_round_stats(cpu, p);
|
||||
part_round_stats(q, cpu, p);
|
||||
part_stat_unlock();
|
||||
part_in_flight(q, p, inflight);
|
||||
return sprintf(buf,
|
||||
"%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]),
|
||||
(unsigned long long)part_stat_read(p, sectors[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, time_in_queue)));
|
||||
}
|
||||
@ -249,15 +252,20 @@ void __delete_partition(struct percpu_ref *ref)
|
||||
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)
|
||||
{
|
||||
struct disk_part_tbl *ptbl = disk->part_tbl;
|
||||
struct disk_part_tbl *ptbl =
|
||||
rcu_dereference_protected(disk->part_tbl, 1);
|
||||
struct hd_struct *part;
|
||||
|
||||
if (partno >= ptbl->len)
|
||||
return;
|
||||
|
||||
part = ptbl->part[partno];
|
||||
part = rcu_dereference_protected(ptbl->part[partno], 1);
|
||||
if (!part)
|
||||
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,
|
||||
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,
|
||||
sector_t start, sector_t len, int flags,
|
||||
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);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
ptbl = disk->part_tbl;
|
||||
ptbl = rcu_dereference_protected(disk->part_tbl, 1);
|
||||
|
||||
if (ptbl->part[partno])
|
||||
return ERR_PTR(-EBUSY);
|
||||
@ -391,7 +403,6 @@ out_del:
|
||||
device_del(pdev);
|
||||
out_put:
|
||||
put_device(pdev);
|
||||
blk_free_devt(devt);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
|
@ -1678,9 +1678,12 @@ static bool DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
|
||||
Enquiry2->FirmwareID.FirmwareType = '0';
|
||||
Enquiry2->FirmwareID.TurnID = 0;
|
||||
}
|
||||
sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
|
||||
Enquiry2->FirmwareID.MajorVersion, Enquiry2->FirmwareID.MinorVersion,
|
||||
Enquiry2->FirmwareID.FirmwareType, Enquiry2->FirmwareID.TurnID);
|
||||
snprintf(Controller->FirmwareVersion, sizeof(Controller->FirmwareVersion),
|
||||
"%d.%02d-%c-%02d",
|
||||
Enquiry2->FirmwareID.MajorVersion,
|
||||
Enquiry2->FirmwareID.MinorVersion,
|
||||
Enquiry2->FirmwareID.FirmwareType,
|
||||
Enquiry2->FirmwareID.TurnID);
|
||||
if (!((Controller->FirmwareVersion[0] == '5' &&
|
||||
strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
|
||||
(Controller->FirmwareVersion[0] == '4' &&
|
||||
@ -6588,7 +6591,8 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
|
||||
&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,
|
||||
DAC960_ProcDirectoryEntry);
|
||||
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
|
||||
tristate "Null test block driver"
|
||||
depends on CONFIGFS_FS
|
||||
|
||||
config BLK_DEV_FD
|
||||
tristate "Normal floppy disk support"
|
||||
|
@ -294,14 +294,13 @@ out:
|
||||
|
||||
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 = bdev->bd_disk->private_data;
|
||||
struct brd_device *brd = bio->bi_disk->private_data;
|
||||
struct bio_vec bvec;
|
||||
sector_t sector;
|
||||
struct bvec_iter iter;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
err = -EIO;
|
||||
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);
|
||||
} else
|
||||
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_add_page of a single page to an empty bio will always succeed,
|
||||
* according to api. Do we want to assert that? */
|
||||
|
@ -63,19 +63,15 @@
|
||||
# define __must_hold(x)
|
||||
#endif
|
||||
|
||||
/* module parameter, 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);
|
||||
|
||||
/* shared module parameters, defined in drbd_main.c */
|
||||
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
||||
extern int enable_faults;
|
||||
extern int fault_rate;
|
||||
extern int fault_devs;
|
||||
extern int drbd_enable_faults;
|
||||
extern int drbd_fault_rate;
|
||||
#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.
|
||||
@ -181,8 +177,8 @@ _drbd_insert_fault(struct drbd_device *device, unsigned int type);
|
||||
static inline int
|
||||
drbd_insert_fault(struct drbd_device *device, unsigned int type) {
|
||||
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
||||
return fault_rate &&
|
||||
(enable_faults & (1<<type)) &&
|
||||
return drbd_fault_rate &&
|
||||
(drbd_enable_faults & (1<<type)) &&
|
||||
_drbd_insert_fault(device, type);
|
||||
#else
|
||||
return 0;
|
||||
@ -745,6 +741,8 @@ struct drbd_connection {
|
||||
unsigned current_tle_writes; /* writes seen within this tl epoch */
|
||||
|
||||
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 worker;
|
||||
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 void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev);
|
||||
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 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 conn_free_crypto(struct drbd_connection *connection);
|
||||
|
||||
extern int proc_details;
|
||||
|
||||
/* drbd_req */
|
||||
extern void do_submit(struct work_struct *ws);
|
||||
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)
|
||||
{
|
||||
__release(local);
|
||||
if (!bio->bi_bdev) {
|
||||
drbd_err(device, "drbd_generic_make_request: bio->bi_bdev == NULL\n");
|
||||
if (!bio->bi_disk) {
|
||||
drbd_err(device, "drbd_generic_make_request: bio->bi_disk == NULL\n");
|
||||
bio->bi_status = BLK_STS_IOERR;
|
||||
bio_endio(bio);
|
||||
return;
|
||||
|
@ -77,41 +77,41 @@ MODULE_PARM_DESC(minor_count, "Approximate number of drbd devices ("
|
||||
MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR);
|
||||
|
||||
#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),
|
||||
* this becomes the boot parameter 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);
|
||||
* these become boot parameters (e.g., drbd.minor_count) */
|
||||
|
||||
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
||||
int enable_faults;
|
||||
int fault_rate;
|
||||
static int fault_count;
|
||||
int fault_devs;
|
||||
int drbd_enable_faults;
|
||||
int drbd_fault_rate;
|
||||
static int drbd_fault_count;
|
||||
static int drbd_fault_devs;
|
||||
/* 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 */
|
||||
module_param(fault_rate, int, 0664);
|
||||
module_param_named(fault_rate, drbd_fault_rate, int, 0664);
|
||||
/* 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 */
|
||||
module_param(fault_devs, int, 0644);
|
||||
module_param_named(fault_devs, drbd_fault_devs, int, 0644);
|
||||
#endif
|
||||
|
||||
/* module parameter, defined */
|
||||
unsigned int minor_count = DRBD_MINOR_COUNT_DEF;
|
||||
bool disable_sendpage;
|
||||
bool allow_oos;
|
||||
int proc_details; /* Detail level in proc drbd*/
|
||||
/* module parameters we can keep static */
|
||||
static bool drbd_allow_oos; /* allow_open_on_secondary */
|
||||
static bool drbd_disable_sendpage;
|
||||
MODULE_PARM_DESC(allow_oos, "DONT USE!");
|
||||
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
|
||||
* to run. Default is /sbin/drbdadm */
|
||||
char usermode_helper[80] = "/sbin/drbdadm";
|
||||
|
||||
module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644);
|
||||
char drbd_usermode_helper[80] = "/sbin/drbdadm";
|
||||
module_param_named(minor_count, drbd_minor_count, uint, 0444);
|
||||
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
|
||||
* 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) */
|
||||
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) {
|
||||
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
|
||||
* __page_cache_release a page that would actually still be referenced
|
||||
* 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);
|
||||
|
||||
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 (mode & FMODE_WRITE)
|
||||
rv = -EROFS;
|
||||
else if (!allow_oos)
|
||||
else if (!drbd_allow_oos)
|
||||
rv = -EMEDIUMTYPE;
|
||||
}
|
||||
|
||||
@ -1952,6 +1954,19 @@ static void drbd_release(struct gendisk *gd, fmode_t mode)
|
||||
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)
|
||||
{
|
||||
/* 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->bm_io_work.w.cb = w_bitmap_io;
|
||||
|
||||
init_timer(&device->resync_timer);
|
||||
init_timer(&device->md_sync_timer);
|
||||
init_timer(&device->start_resync_timer);
|
||||
init_timer(&device->request_timer);
|
||||
device->resync_timer.function = resync_timer_fn;
|
||||
device->resync_timer.data = (unsigned long) device;
|
||||
device->md_sync_timer.function = md_sync_timer_fn;
|
||||
device->md_sync_timer.data = (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;
|
||||
setup_timer(&device->resync_timer, resync_timer_fn,
|
||||
(unsigned long)device);
|
||||
setup_timer(&device->md_sync_timer, md_sync_timer_fn,
|
||||
(unsigned long)device);
|
||||
setup_timer(&device->start_resync_timer, start_resync_timer_fn,
|
||||
(unsigned long)device);
|
||||
setup_timer(&device->request_timer, request_timer_fn,
|
||||
(unsigned long)device);
|
||||
|
||||
init_waitqueue_head(&device->misc_wait);
|
||||
init_waitqueue_head(&device->state_wait);
|
||||
@ -2131,7 +2142,7 @@ static void drbd_destroy_mempools(void)
|
||||
static int drbd_create_mempools(void)
|
||||
{
|
||||
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;
|
||||
|
||||
/* prepare our caches and mempools */
|
||||
@ -2167,13 +2178,12 @@ static int drbd_create_mempools(void)
|
||||
goto Enomem;
|
||||
|
||||
/* 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)
|
||||
goto Enomem;
|
||||
|
||||
drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0,
|
||||
BIOSET_NEED_BVECS |
|
||||
BIOSET_NEED_RESCUER);
|
||||
BIOSET_NEED_BVECS);
|
||||
if (drbd_md_io_bio_set == NULL)
|
||||
goto Enomem;
|
||||
|
||||
@ -2409,7 +2419,6 @@ static void drbd_cleanup(void)
|
||||
destroy_workqueue(retry.wq);
|
||||
|
||||
drbd_genl_unregister();
|
||||
drbd_debugfs_cleanup();
|
||||
|
||||
idr_for_each_entry(&drbd_devices, device, i)
|
||||
drbd_delete_device(device);
|
||||
@ -2420,6 +2429,8 @@ static void drbd_cleanup(void)
|
||||
drbd_free_resource(resource);
|
||||
}
|
||||
|
||||
drbd_debugfs_cleanup();
|
||||
|
||||
drbd_destroy_mempools();
|
||||
unregister_blkdev(DRBD_MAJOR, "drbd");
|
||||
|
||||
@ -2972,12 +2983,12 @@ static int __init drbd_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
|
||||
pr_err("invalid minor_count (%d)\n", minor_count);
|
||||
if (drbd_minor_count < DRBD_MINOR_COUNT_MIN || drbd_minor_count > DRBD_MINOR_COUNT_MAX) {
|
||||
pr_err("invalid minor_count (%d)\n", drbd_minor_count);
|
||||
#ifdef MODULE
|
||||
return -EINVAL;
|
||||
#else
|
||||
minor_count = DRBD_MINOR_COUNT_DEF;
|
||||
drbd_minor_count = DRBD_MINOR_COUNT_DEF;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -3900,12 +3911,12 @@ _drbd_insert_fault(struct drbd_device *device, unsigned int type)
|
||||
static struct fault_random_state rrs = {0, 0};
|
||||
|
||||
unsigned int ret = (
|
||||
(fault_devs == 0 ||
|
||||
((1 << device_to_minor(device)) & fault_devs) != 0) &&
|
||||
(((_drbd_fault_random(&rrs) % 100) + 1) <= fault_rate));
|
||||
(drbd_fault_devs == 0 ||
|
||||
((1 << device_to_minor(device)) & drbd_fault_devs) != 0) &&
|
||||
(((_drbd_fault_random(&rrs) % 100) + 1) <= drbd_fault_rate));
|
||||
|
||||
if (ret) {
|
||||
fault_count++;
|
||||
drbd_fault_count++;
|
||||
|
||||
if (__ratelimit(&drbd_ratelimit_state))
|
||||
drbd_warn(device, "***Simulating %s failure\n",
|
||||
|
@ -344,7 +344,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
|
||||
(char[60]) { }, /* address */
|
||||
NULL };
|
||||
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 sib_info sib;
|
||||
int ret;
|
||||
@ -359,19 +359,19 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
|
||||
* write out any unsynced meta data changes now */
|
||||
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.helper_name = cmd;
|
||||
drbd_bcast_event(device, &sib);
|
||||
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)
|
||||
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);
|
||||
else
|
||||
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);
|
||||
sib.sib_reason = SIB_HELPER_POST;
|
||||
sib.helper_exit_code = ret;
|
||||
@ -396,24 +396,24 @@ enum drbd_peer_state conn_khelper(struct drbd_connection *connection, char *cmd)
|
||||
(char[60]) { }, /* address */
|
||||
NULL };
|
||||
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;
|
||||
|
||||
setup_khelper_env(connection, envp);
|
||||
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() ?? */
|
||||
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)
|
||||
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);
|
||||
else
|
||||
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);
|
||||
/* TODO: conn_bcast_event() ?? */
|
||||
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,
|
||||
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_connection *connection = peer_device->connection;
|
||||
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)) {
|
||||
can_do = false;
|
||||
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 disk_conf *dc;
|
||||
bool discard_zeroes_if_aligned = true;
|
||||
bool disable_write_same = false;
|
||||
|
||||
if (bdev) {
|
||||
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);
|
||||
max_segments = dc->max_bio_bvecs;
|
||||
discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned;
|
||||
disable_write_same = dc->disable_write_same;
|
||||
rcu_read_unlock();
|
||||
|
||||
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_segment_boundary(q, PAGE_SIZE-1);
|
||||
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) {
|
||||
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))
|
||||
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_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)
|
||||
{
|
||||
enum drbd_state_rv retcode;
|
||||
void *buffer;
|
||||
int ret;
|
||||
|
||||
if (force) {
|
||||
set_bit(FORCE_DETACH, &device->flags);
|
||||
drbd_force_state(device, NS(disk, D_FAILED));
|
||||
retcode = SS_SUCCESS;
|
||||
goto out;
|
||||
return SS_SUCCESS;
|
||||
}
|
||||
|
||||
drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */
|
||||
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;
|
||||
return drbd_request_detach_interruptible(device);
|
||||
}
|
||||
|
||||
/* 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, '>');
|
||||
for (i = 0; i < y; i++)
|
||||
seq_printf(seq, ".");
|
||||
seq_putc(seq, '.');
|
||||
seq_puts(seq, "] ");
|
||||
|
||||
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_puts(seq, " (");
|
||||
/* ------------------------- ~3s average ------------------------ */
|
||||
if (proc_details >= 1) {
|
||||
if (drbd_proc_details >= 1) {
|
||||
/* this is what drbd_rs_should_slow_down() uses */
|
||||
i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
|
||||
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)" : "");
|
||||
|
||||
if (proc_details >= 1) {
|
||||
if (drbd_proc_details >= 1) {
|
||||
/* 64 bit:
|
||||
* we convert to sectors in the display below. */
|
||||
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)
|
||||
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->act_log);
|
||||
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));
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
@ -332,7 +332,7 @@ static void drbd_free_pages(struct drbd_device *device, struct page *page, int i
|
||||
if (page == NULL)
|
||||
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);
|
||||
else {
|
||||
struct page *tmp;
|
||||
@ -1100,7 +1100,10 @@ randomize:
|
||||
idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
|
||||
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);
|
||||
spin_unlock_irq(&connection->resource->req_lock);
|
||||
|
||||
idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
|
||||
mutex_unlock(peer_device->device->state_mutex);
|
||||
@ -1194,6 +1197,14 @@ static int decode_header(struct drbd_connection *connection, void *header, struc
|
||||
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)
|
||||
{
|
||||
void *buffer = connection->data.rbuf;
|
||||
@ -1209,6 +1220,36 @@ static int drbd_recv_header(struct drbd_connection *connection, struct packet_in
|
||||
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.
|
||||
* We want to submit to all component volumes in parallel,
|
||||
* then wait for all completions.
|
||||
@ -1223,7 +1264,7 @@ struct one_flush_context {
|
||||
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 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->ctx = ctx;
|
||||
bio->bi_bdev = device->ldev->backing_bdev;
|
||||
bio_set_dev(bio, device->ldev->backing_bdev);
|
||||
bio->bi_private = octx;
|
||||
bio->bi_end_io = one_flush_endio;
|
||||
bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
|
||||
@ -1548,7 +1589,7 @@ next_bio:
|
||||
}
|
||||
/* > peer_req->i.sector, unless this is the first bio */
|
||||
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->bi_private = peer_req;
|
||||
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);
|
||||
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) {
|
||||
drbd_err(device, "kmalloc of p_uuid failed\n");
|
||||
return false;
|
||||
@ -4882,8 +4923,8 @@ static void drbdd(struct drbd_connection *connection)
|
||||
struct data_cmd const *cmd;
|
||||
|
||||
drbd_thread_current_set_cpu(&connection->receiver);
|
||||
update_receiver_timing_details(connection, drbd_recv_header);
|
||||
if (drbd_recv_header(connection, &pi))
|
||||
update_receiver_timing_details(connection, drbd_recv_header_maybe_unplug);
|
||||
if (drbd_recv_header_maybe_unplug(connection, &pi))
|
||||
goto err_out;
|
||||
|
||||
cmd = &drbd_cmd_handler[pi.cmd];
|
||||
@ -5375,8 +5416,11 @@ int drbd_receiver(struct drbd_thread *thi)
|
||||
}
|
||||
} while (h == 0);
|
||||
|
||||
if (h > 0)
|
||||
if (h > 0) {
|
||||
blk_start_plug(&connection->receiver_plug);
|
||||
drbdd(connection);
|
||||
blk_finish_plug(&connection->receiver_plug);
|
||||
}
|
||||
|
||||
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 */
|
||||
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,
|
||||
&device->vdisk->part0);
|
||||
struct request_queue *q = device->rq_queue;
|
||||
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1175,7 +1179,7 @@ drbd_submit_req_private_bio(struct drbd_request *req)
|
||||
else
|
||||
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
|
||||
* ->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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
* The slow path has added it already. */
|
||||
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)
|
||||
{
|
||||
struct blk_plug plug;
|
||||
struct drbd_request *req, *tmp;
|
||||
|
||||
blk_start_plug(&plug);
|
||||
list_for_each_entry_safe(req, tmp, incoming, tl_requests) {
|
||||
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);
|
||||
drbd_send_and_submit(device, req);
|
||||
}
|
||||
blk_finish_plug(&plug);
|
||||
}
|
||||
|
||||
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 *later)
|
||||
{
|
||||
struct drbd_request *req, *tmp;
|
||||
struct drbd_request *req;
|
||||
int wake = 0;
|
||||
int err;
|
||||
|
||||
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);
|
||||
if (err == -ENOBUFS)
|
||||
break;
|
||||
@ -1442,17 +1507,20 @@ static bool prepare_al_transaction_nonblock(struct drbd_device *device,
|
||||
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->in_actlog_jif = jiffies;
|
||||
atomic_dec(&device->ap_actlog_cnt);
|
||||
list_del_init(&req->tl_requests);
|
||||
drbd_send_and_submit(device, req);
|
||||
}
|
||||
blk_finish_plug(&plug);
|
||||
}
|
||||
|
||||
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... */
|
||||
__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 */
|
||||
__RQ_POSTPONED,
|
||||
|
||||
@ -249,6 +254,7 @@ enum drbd_req_state_bits {
|
||||
#define RQ_WSAME (1UL << __RQ_WSAME)
|
||||
#define RQ_UNMAP (1UL << __RQ_UNMAP)
|
||||
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
|
||||
#define RQ_UNPLUG (1UL << __RQ_UNPLUG)
|
||||
#define RQ_POSTPONED (1UL << __RQ_POSTPONED)
|
||||
#define RQ_COMPLETION_SUSP (1UL << __RQ_COMPLETION_SUSP)
|
||||
#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 role = R_UNKNOWN;
|
||||
enum drbd_role role = R_SECONDARY;
|
||||
struct drbd_peer_device *peer_device;
|
||||
int vnr;
|
||||
|
||||
@ -579,11 +579,14 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
|
||||
unsigned long flags;
|
||||
union drbd_state os, ns;
|
||||
enum drbd_state_rv rv;
|
||||
void *buffer = NULL;
|
||||
|
||||
init_completion(&done);
|
||||
|
||||
if (f & CS_SERIALIZE)
|
||||
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);
|
||||
os = drbd_read_state(device);
|
||||
@ -636,6 +639,8 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
|
||||
}
|
||||
|
||||
abort:
|
||||
if (buffer)
|
||||
drbd_md_put_buffer(device);
|
||||
if (f & CS_SERIALIZE)
|
||||
mutex_unlock(device->state_mutex);
|
||||
|
||||
@ -664,6 +669,47 @@ _drbd_request_state(struct drbd_device *device, union drbd_state mask,
|
||||
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
|
||||
_drbd_request_state_holding_state_mutex(struct drbd_device *device, union drbd_state mask,
|
||||
union drbd_state val, enum chg_state_flags f)
|
||||
|
@ -71,6 +71,10 @@ enum chg_state_flags {
|
||||
CS_DC_SUSP = 1 << 10,
|
||||
CS_DC_MASK = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK,
|
||||
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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/* 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_peer(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->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
|
||||
* to timeout on the lower level device, and eventually detach from it.
|
||||
* 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);
|
||||
device->md_io.done = 1;
|
||||
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,
|
||||
@ -128,6 +130,14 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
|
||||
block_id = peer_req->block_id;
|
||||
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);
|
||||
device->writ_cnt += peer_req->i.size >> 9;
|
||||
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",
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct drbd_device *device =
|
||||
container_of(w, struct drbd_device, unplug_work);
|
||||
struct drbd_socket *sock;
|
||||
|
||||
if (cancel)
|
||||
return 0;
|
||||
sock = &first_peer_device(device)->connection->data;
|
||||
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);
|
||||
return pd_send_unplug_remote(first_peer_device(device));
|
||||
}
|
||||
|
||||
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_peer_device *const peer_device = first_peer_device(device);
|
||||
struct drbd_connection *connection = peer_device->connection;
|
||||
bool do_send_unplug = req->rq_state & RQ_UNPLUG;
|
||||
int err;
|
||||
|
||||
if (unlikely(cancel)) {
|
||||
@ -1470,6 +1486,9 @@ int w_send_dblock(struct drbd_work *w, int cancel)
|
||||
err = drbd_send_dblock(peer_device, req);
|
||||
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
|
||||
|
||||
if (do_send_unplug && !err)
|
||||
pd_send_unplug_remote(peer_device);
|
||||
|
||||
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_peer_device *const peer_device = first_peer_device(device);
|
||||
struct drbd_connection *connection = peer_device->connection;
|
||||
bool do_send_unplug = req->rq_state & RQ_UNPLUG;
|
||||
int err;
|
||||
|
||||
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);
|
||||
|
||||
if (do_send_unplug && !err)
|
||||
pd_send_unplug_remote(peer_device);
|
||||
|
||||
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_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);
|
||||
|
||||
return 0;
|
||||
@ -1733,6 +1756,11 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connection) {
|
||||
drbd_err(device, "No connection to peer, aborting!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!test_bit(B_RS_H_DONE, &device->flags)) {
|
||||
if (side == C_SYNC_TARGET) {
|
||||
/* 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;
|
||||
|
||||
bio_init(&bio, &bio_vec, 1);
|
||||
bio.bi_bdev = bdev;
|
||||
bio_set_dev(&bio, bdev);
|
||||
bio_add_page(&bio, page, size, 0);
|
||||
|
||||
bio.bi_iter.bi_sector = 0;
|
||||
|
@ -1966,10 +1966,6 @@ static int __init loop_init(void)
|
||||
struct loop_device *lo;
|
||||
int err;
|
||||
|
||||
err = misc_register(&loop_misc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
part_shift = 0;
|
||||
if (max_part > 0) {
|
||||
part_shift = fls(max_part);
|
||||
@ -1987,12 +1983,12 @@ static int __init loop_init(void)
|
||||
|
||||
if ((1UL << part_shift) > DISK_MAX_PARTS) {
|
||||
err = -EINVAL;
|
||||
goto misc_out;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (max_loop > 1UL << (MINORBITS - part_shift)) {
|
||||
err = -EINVAL;
|
||||
goto misc_out;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2011,6 +2007,11 @@ static int __init loop_init(void)
|
||||
range = 1UL << MINORBITS;
|
||||
}
|
||||
|
||||
err = misc_register(&loop_misc);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
|
||||
|
||||
if (register_blkdev(LOOP_MAJOR, "loop")) {
|
||||
err = -EIO;
|
||||
goto misc_out;
|
||||
@ -2030,6 +2031,7 @@ static int __init loop_init(void)
|
||||
|
||||
misc_out:
|
||||
misc_deregister(&loop_misc);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ static struct dentry *nbd_dbg_dir;
|
||||
#define NBD_MAGIC 0x68797548
|
||||
|
||||
static unsigned int nbds_max = 16;
|
||||
static int max_part;
|
||||
static int max_part = 16;
|
||||
static struct workqueue_struct *recv_workqueue;
|
||||
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));
|
||||
}
|
||||
|
||||
static struct device_attribute pid_attr = {
|
||||
static const struct device_attribute pid_attr = {
|
||||
.attr = { .name = "pid", .mode = S_IRUGO},
|
||||
.show = pid_show,
|
||||
};
|
||||
@ -1584,6 +1584,15 @@ again:
|
||||
}
|
||||
} else {
|
||||
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) {
|
||||
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_PARM_DESC(nbds_max, "number of network block devices to initialize (default: 16)");
|
||||
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_reset(bio);
|
||||
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_private = pkt;
|
||||
|
||||
@ -1122,7 +1122,7 @@ static int pkt_start_recovery(struct packet_data *pkt)
|
||||
pkt->sector = new_sector;
|
||||
|
||||
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);
|
||||
pkt->bio->bi_iter.bi_sector = new_sector;
|
||||
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);
|
||||
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_private = pkt;
|
||||
|
||||
@ -2314,7 +2314,7 @@ static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio)
|
||||
|
||||
psd->pd = pd;
|
||||
psd->bio = bio;
|
||||
cloned_bio->bi_bdev = pd->bdev;
|
||||
bio_set_dev(cloned_bio, pd->bdev);
|
||||
cloned_bio->bi_private = psd;
|
||||
cloned_bio->bi_end_io = pkt_end_io_read_cloned;
|
||||
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;
|
||||
if (!pd) {
|
||||
pr_err("%s incorrect request queue\n",
|
||||
bdevname(bio->bi_bdev, b));
|
||||
pr_err("%s incorrect request queue\n", bio_devname(bio, b));
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -120,8 +120,8 @@ static void disk_stats_complete(struct rsxx_cardinfo *card,
|
||||
struct bio *bio,
|
||||
unsigned long start_time)
|
||||
{
|
||||
generic_end_io_acct(bio_data_dir(bio), &card->gendisk->part0,
|
||||
start_time);
|
||||
generic_end_io_acct(card->queue, bio_data_dir(bio),
|
||||
&card->gendisk->part0, start_time);
|
||||
}
|
||||
|
||||
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
|
||||
* BSD License (http://opensource.org/licenses/BSD-3-Clause)
|
||||
* 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.
|
||||
* This file is part of the Linux kernel, and is made available under
|
||||
* the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SKD_S1120_H
|
||||
#define SKD_S1120_H
|
||||
|
||||
#pragma pack(push, s1120_h, 1)
|
||||
|
||||
/*
|
||||
* Q-channel, 64-bit r/w
|
||||
*/
|
||||
@ -30,7 +26,7 @@
|
||||
#define FIT_QCMD_MSGSIZE_128 (0x1 << 4)
|
||||
#define FIT_QCMD_MSGSIZE_256 (0x2 << 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
|
||||
@ -250,7 +246,7 @@ struct fit_msg_hdr {
|
||||
* 20-23 of the FIT_MTD_FITFW_INIT response.
|
||||
*/
|
||||
struct fit_completion_entry_v1 {
|
||||
uint32_t num_returned_bytes;
|
||||
__be32 num_returned_bytes;
|
||||
uint16_t tag;
|
||||
uint8_t status; /* SCSI status */
|
||||
uint8_t cycle;
|
||||
@ -278,7 +274,7 @@ struct fit_comp_error_info {
|
||||
uint16_t sks_low; /* 10: Sense Key Specific (LSW) */
|
||||
uint16_t reserved3; /* 12: Part of additional sense bytes (unused) */
|
||||
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) */
|
||||
};
|
||||
|
||||
@ -292,11 +288,11 @@ struct fit_comp_error_info {
|
||||
* Version one has the last 32 bits sg_list_len_bytes;
|
||||
*/
|
||||
struct skd_command_header {
|
||||
uint64_t sg_list_dma_address;
|
||||
__be64 sg_list_dma_address;
|
||||
uint16_t tag;
|
||||
uint8_t attribute;
|
||||
uint8_t add_cdb_len; /* In 32 bit words */
|
||||
uint32_t sg_list_len_bytes;
|
||||
__be32 sg_list_len_bytes;
|
||||
};
|
||||
|
||||
struct skd_scsi_request {
|
||||
@ -309,22 +305,20 @@ struct driver_inquiry_data {
|
||||
uint8_t peripheral_device_type:5;
|
||||
uint8_t qualifier:3;
|
||||
uint8_t page_code;
|
||||
uint16_t page_length;
|
||||
uint16_t pcie_bus_number;
|
||||
__be16 page_length;
|
||||
__be16 pcie_bus_number;
|
||||
uint8_t pcie_device_number;
|
||||
uint8_t pcie_function_number;
|
||||
uint8_t pcie_link_speed;
|
||||
uint8_t pcie_link_lanes;
|
||||
uint16_t pcie_vendor_id;
|
||||
uint16_t pcie_device_id;
|
||||
uint16_t pcie_subsystem_vendor_id;
|
||||
uint16_t pcie_subsystem_device_id;
|
||||
__be16 pcie_vendor_id;
|
||||
__be16 pcie_device_id;
|
||||
__be16 pcie_subsystem_vendor_id;
|
||||
__be16 pcie_subsystem_device_id;
|
||||
uint8_t reserved1[2];
|
||||
uint8_t reserved2[3];
|
||||
uint8_t driver_version_length;
|
||||
uint8_t driver_version[0x14];
|
||||
};
|
||||
|
||||
#pragma pack(pop, 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);
|
||||
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);
|
||||
else
|
||||
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);
|
||||
pages[i]->handle = BLKBACK_INVALID_HANDLE;
|
||||
invcount++;
|
||||
}
|
||||
}
|
||||
|
||||
return invcount;
|
||||
return invcount;
|
||||
}
|
||||
|
||||
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;
|
||||
case BLKIF_OP_WRITE_BARRIER:
|
||||
drain = true;
|
||||
/* fall through */
|
||||
case BLKIF_OP_FLUSH_DISKCACHE:
|
||||
ring->st_f_req++;
|
||||
operation = REQ_OP_WRITE;
|
||||
@ -1362,7 +1363,7 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
|
||||
goto fail_put_bio;
|
||||
|
||||
biolist[nbio++] = bio;
|
||||
bio->bi_bdev = preq.bdev;
|
||||
bio_set_dev(bio, preq.bdev);
|
||||
bio->bi_private = pending_req;
|
||||
bio->bi_end_io = end_block_io_op;
|
||||
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;
|
||||
|
||||
biolist[nbio++] = bio;
|
||||
bio->bi_bdev = preq.bdev;
|
||||
bio_set_dev(bio, preq.bdev);
|
||||
bio->bi_private = pending_req;
|
||||
bio->bi_end_io = end_block_io_op;
|
||||
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);
|
||||
if (xenbus_dev_is_online(dev))
|
||||
break;
|
||||
/* fall through if not online */
|
||||
/* fall through */
|
||||
/* if not online */
|
||||
case XenbusStateUnknown:
|
||||
/* implies xen_blkif_disconnect() via xen_blkbk_remove() */
|
||||
device_unregister(&dev->dev);
|
||||
|
@ -2456,7 +2456,7 @@ static void blkback_changed(struct xenbus_device *dev,
|
||||
case XenbusStateClosed:
|
||||
if (dev->state == XenbusStateClosed)
|
||||
break;
|
||||
/* Missed the backend's Closing state -- fallthrough */
|
||||
/* fall through */
|
||||
case XenbusStateClosing:
|
||||
if (info)
|
||||
blkfront_closing(info);
|
||||
|
@ -467,7 +467,7 @@ static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec,
|
||||
return -ENOMEM;
|
||||
|
||||
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)) {
|
||||
bio_put(bio);
|
||||
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_bdev = zram->bdev;
|
||||
bio_set_dev(bio, zram->bdev);
|
||||
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len,
|
||||
bvec->bv_offset)) {
|
||||
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;
|
||||
int rw_acct = is_write ? REQ_OP_WRITE : REQ_OP_READ;
|
||||
struct request_queue *q = zram->disk->queue;
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 (!is_write)
|
||||
|
@ -72,7 +72,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
|
||||
drive->failed_pc = NULL;
|
||||
|
||||
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 */
|
||||
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;
|
||||
|
||||
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_size = KEY_SIZE(&v->key) << 9;
|
||||
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);
|
||||
|
||||
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();
|
||||
closure_bio_submit(bio, bio->bi_private);
|
||||
|
@ -53,7 +53,7 @@ reread: left = ca->sb.bucket_size - offset;
|
||||
|
||||
bio_reset(bio);
|
||||
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_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->bi_iter.bi_sector = bucket_to_sector(ca->set,
|
||||
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_end_io = journal_discard_endio;
|
||||
|
||||
@ -623,7 +623,7 @@ static void journal_write_unlocked(struct closure *cl)
|
||||
|
||||
bio_reset(bio);
|
||||
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_end_io = journal_write_endio;
|
||||
|
@ -607,7 +607,8 @@ static void request_endio(struct bio *bio)
|
||||
static void bio_complete(struct search *s)
|
||||
{
|
||||
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);
|
||||
|
||||
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) {
|
||||
bio_reset(s->iop.bio);
|
||||
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;
|
||||
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) &&
|
||||
s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA)
|
||||
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);
|
||||
|
||||
@ -819,7 +820,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
|
||||
goto out_submit;
|
||||
|
||||
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_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,
|
||||
dc->disk.bio_split);
|
||||
|
||||
flush->bi_bdev = bio->bi_bdev;
|
||||
bio_copy_dev(flush, bio);
|
||||
flush->bi_end_io = request_endio;
|
||||
flush->bi_private = cl;
|
||||
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 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);
|
||||
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;
|
||||
|
||||
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 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);
|
||||
|
||||
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);
|
||||
cl = &s->cl;
|
||||
|
@ -257,7 +257,7 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
|
||||
closure_init(cl, parent);
|
||||
|
||||
bio_reset(bio);
|
||||
bio->bi_bdev = dc->bdev;
|
||||
bio_set_dev(bio, dc->bdev);
|
||||
bio->bi_end_io = write_bdev_super_endio;
|
||||
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));
|
||||
|
||||
bio_reset(bio);
|
||||
bio->bi_bdev = ca->bdev;
|
||||
bio_set_dev(bio, ca->bdev);
|
||||
bio->bi_end_io = write_super_endio;
|
||||
bio->bi_private = ca;
|
||||
|
||||
@ -508,7 +508,7 @@ static void prio_io(struct cache *ca, uint64_t bucket, int op,
|
||||
closure_init_stack(cl);
|
||||
|
||||
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_end_io = prio_endio;
|
||||
|
@ -181,7 +181,7 @@ static void write_dirty(struct closure *cl)
|
||||
dirty_init(w);
|
||||
bio_set_op_attrs(&io->bio, REQ_OP_WRITE, 0);
|
||||
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;
|
||||
|
||||
closure_bio_submit(&io->bio, cl);
|
||||
@ -250,8 +250,7 @@ static void read_dirty(struct cached_dev *dc)
|
||||
dirty_init(w);
|
||||
bio_set_op_attrs(&io->bio, REQ_OP_READ, 0);
|
||||
io->bio.bi_iter.bi_sector = PTR_OFFSET(&w->key, 0);
|
||||
io->bio.bi_bdev = PTR_CACHE(dc->disk.c,
|
||||
&w->key, 0)->bdev;
|
||||
bio_set_dev(&io->bio, PTR_CACHE(dc->disk.c, &w->key, 0)->bdev);
|
||||
io->bio.bi_end_io = read_dirty_endio;
|
||||
|
||||
if (bio_alloc_pages(&io->bio, GFP_KERNEL))
|
||||
|
@ -18,21 +18,24 @@
|
||||
*/
|
||||
|
||||
struct dm_bio_details {
|
||||
struct block_device *bi_bdev;
|
||||
struct gendisk *bi_disk;
|
||||
u8 bi_partno;
|
||||
unsigned long bi_flags;
|
||||
struct bvec_iter bi_iter;
|
||||
};
|
||||
|
||||
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_iter = bio->bi_iter;
|
||||
}
|
||||
|
||||
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_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);
|
||||
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;
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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,
|
||||
@ -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 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))
|
||||
bio->bi_iter.bi_sector =
|
||||
(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_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),
|
||||
tag_len, offset_in_page(io->integrity_metadata));
|
||||
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_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;
|
||||
}
|
||||
|
||||
@ -2795,7 +2792,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
|
||||
*/
|
||||
if (unlikely(bio->bi_opf & REQ_PREFLUSH ||
|
||||
bio_op(bio) == REQ_OP_DISCARD)) {
|
||||
bio->bi_bdev = cc->dev->bdev;
|
||||
bio_set_dev(bio, cc->dev->bdev);
|
||||
if (bio_sectors(bio))
|
||||
bio->bi_iter.bi_sector = cc->start +
|
||||
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;
|
||||
|
||||
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))
|
||||
bio->bi_iter.bi_sector = dc->start_write +
|
||||
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);
|
||||
}
|
||||
|
||||
bio->bi_bdev = dc->dev_read->bdev;
|
||||
bio_set_dev(bio, dc->dev_read->bdev);
|
||||
bio->bi_iter.bi_sector = dc->start_read +
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
bio->bi_bdev = fc->dev->bdev;
|
||||
bio_set_dev(bio, fc->dev->bdev);
|
||||
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
|
||||
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 block_device *orig_bi_bdev;
|
||||
struct gendisk *orig_bi_disk;
|
||||
u8 orig_bi_partno;
|
||||
bio_end_io_t *orig_bi_end_io;
|
||||
struct bio_integrity_payload *orig_bi_integrity;
|
||||
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));
|
||||
|
||||
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) {
|
||||
bio->bi_integrity = dio->orig_bi_integrity;
|
||||
bio->bi_opf |= REQ_INTEGRITY;
|
||||
@ -1681,8 +1683,9 @@ sleep:
|
||||
|
||||
dio->orig_bi_iter = bio->bi_iter;
|
||||
|
||||
dio->orig_bi_bdev = bio->bi_bdev;
|
||||
bio->bi_bdev = ic->dev->bdev;
|
||||
dio->orig_bi_disk = bio->bi_disk;
|
||||
dio->orig_bi_partno = bio->bi_partno;
|
||||
bio_set_dev(bio, ic->dev->bdev);
|
||||
|
||||
dio->orig_bi_integrity = bio_integrity(bio);
|
||||
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->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_set_op_attrs(bio, op, op_flags);
|
||||
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;
|
||||
|
||||
bio->bi_bdev = lc->dev->bdev;
|
||||
bio_set_dev(bio, lc->dev->bdev);
|
||||
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
|
||||
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_sector = sector;
|
||||
bio->bi_bdev = lc->logdev->bdev;
|
||||
bio_set_dev(bio, lc->logdev->bdev);
|
||||
bio->bi_end_io = log_end_io;
|
||||
bio->bi_private = lc;
|
||||
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_sector = sector;
|
||||
bio->bi_bdev = lc->logdev->bdev;
|
||||
bio_set_dev(bio, lc->logdev->bdev);
|
||||
bio->bi_end_io = log_end_io;
|
||||
bio->bi_private = lc;
|
||||
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_sector = sector;
|
||||
bio->bi_bdev = lc->logdev->bdev;
|
||||
bio_set_dev(bio, lc->logdev->bdev);
|
||||
bio->bi_end_io = log_end_io;
|
||||
bio->bi_private = lc;
|
||||
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;
|
||||
|
||||
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)
|
||||
|
@ -565,7 +565,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m
|
||||
mpio->nr_bytes = nr_bytes;
|
||||
|
||||
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;
|
||||
|
||||
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 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;
|
||||
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)
|
||||
{
|
||||
bio->bi_bdev = m->dev->bdev;
|
||||
bio_set_dev(bio, m->dev->bdev);
|
||||
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 =
|
||||
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) {
|
||||
/* 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;
|
||||
|
||||
if (unlikely(*error)) {
|
||||
if (!bio_record->details.bi_bdev) {
|
||||
if (!bio_record->details.bi_disk) {
|
||||
/*
|
||||
* There wasn't enough memory to record necessary
|
||||
* 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;
|
||||
|
||||
dm_bio_restore(bd, bio);
|
||||
bio_record->details.bi_bdev = NULL;
|
||||
bio_record->details.bi_disk = NULL;
|
||||
bio->bi_status = 0;
|
||||
|
||||
queue_bio(ms, bio, rw);
|
||||
@ -1301,7 +1301,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
|
||||
}
|
||||
|
||||
out:
|
||||
bio_record->details.bi_bdev = NULL;
|
||||
bio_record->details.bi_disk = NULL;
|
||||
|
||||
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,
|
||||
struct bio *bio, chunk_t chunk)
|
||||
{
|
||||
bio->bi_bdev = s->cow->bdev;
|
||||
bio_set_dev(bio, s->cow->bdev);
|
||||
bio->bi_iter.bi_sector =
|
||||
chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) +
|
||||
(chunk - e->old_chunk)) +
|
||||
@ -1681,7 +1681,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
|
||||
init_tracked_chunk(bio);
|
||||
|
||||
if (bio->bi_opf & REQ_PREFLUSH) {
|
||||
bio->bi_bdev = s->cow->bdev;
|
||||
bio_set_dev(bio, s->cow->bdev);
|
||||
return DM_MAPIO_REMAPPED;
|
||||
}
|
||||
|
||||
@ -1769,7 +1769,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
bio->bi_bdev = s->origin->bdev;
|
||||
bio_set_dev(bio, s->origin->bdev);
|
||||
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 (!dm_bio_get_target_bio_nr(bio))
|
||||
bio->bi_bdev = s->origin->bdev;
|
||||
bio_set_dev(bio, s->origin->bdev);
|
||||
else
|
||||
bio->bi_bdev = s->cow->bdev;
|
||||
bio_set_dev(bio, s->cow->bdev);
|
||||
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 +
|
||||
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);
|
||||
r = DM_MAPIO_SUBMITTED;
|
||||
goto out_unlock;
|
||||
@ -1838,7 +1838,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
|
||||
}
|
||||
|
||||
redirect_to_origin:
|
||||
bio->bi_bdev = s->origin->bdev;
|
||||
bio_set_dev(bio, s->origin->bdev);
|
||||
|
||||
if (bio_data_dir(bio) == WRITE) {
|
||||
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;
|
||||
unsigned available_sectors;
|
||||
|
||||
bio->bi_bdev = o->dev->bdev;
|
||||
bio_set_dev(bio, o->dev->bdev);
|
||||
|
||||
if (unlikely(bio->bi_opf & REQ_PREFLUSH))
|
||||
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),
|
||||
target_stripe, &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 +
|
||||
sc->stripe[target_stripe].physical_start;
|
||||
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) {
|
||||
target_bio_nr = dm_bio_get_target_bio_nr(bio);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
@ -430,9 +430,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
|
||||
return DM_ENDIO_DONE;
|
||||
|
||||
memset(major_minor, 0, sizeof(major_minor));
|
||||
sprintf(major_minor, "%d:%d",
|
||||
MAJOR(disk_devt(bio->bi_bdev->bd_disk)),
|
||||
MINOR(disk_devt(bio->bi_bdev->bd_disk)));
|
||||
sprintf(major_minor, "%d:%d", MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)));
|
||||
|
||||
/*
|
||||
* 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);
|
||||
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;
|
||||
|
||||
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;
|
||||
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))
|
||||
bio->bi_iter.bi_sector =
|
||||
(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)
|
||||
{
|
||||
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)
|
||||
@ -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.
|
||||
*/
|
||||
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;
|
||||
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_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);
|
||||
|
||||
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_bdev = zmd->dev->bdev;
|
||||
bio_set_dev(bio, zmd->dev->bdev);
|
||||
bio->bi_private = mblk;
|
||||
bio->bi_end_io = dmz_mblock_bio_end_io;
|
||||
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);
|
||||
|
||||
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_end_io = dmz_mblock_bio_end_io;
|
||||
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;
|
||||
|
||||
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_add_page(bio, page, DMZ_BLOCK_SIZE, 0);
|
||||
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));
|
||||
|
||||
/* 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);
|
||||
atomic_inc(&bioctx->ref);
|
||||
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 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)
|
||||
return DM_MAPIO_REMAPPED;
|
||||
|
@ -510,7 +510,7 @@ static void start_io_acct(struct dm_io *io)
|
||||
io->start_time = jiffies;
|
||||
|
||||
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();
|
||||
atomic_set(&dm_disk(md)->part0.in_flight[rw],
|
||||
atomic_inc_return(&md->pending[rw]));
|
||||
@ -529,7 +529,7 @@ static void end_io_acct(struct dm_io *io)
|
||||
int pending;
|
||||
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)))
|
||||
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 (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);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1205,8 +1205,8 @@ static void __map_bio(struct dm_target_io *tio)
|
||||
break;
|
||||
case DM_MAPIO_REMAPPED:
|
||||
/* the bio has been remapped so dispatch it */
|
||||
trace_block_bio_remap(bdev_get_queue(clone->bi_bdev), clone,
|
||||
tio->io->bio->bi_bdev->bd_dev, sector);
|
||||
trace_block_bio_remap(clone->bi_disk->queue, clone,
|
||||
bio_dev(tio->io->bio), sector);
|
||||
generic_make_request(clone);
|
||||
break;
|
||||
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);
|
||||
|
||||
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 (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
|
||||
@ -1786,7 +1786,7 @@ static struct mapped_device *alloc_dev(int minor)
|
||||
goto bad;
|
||||
|
||||
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;
|
||||
|
||||
dm_stats_init(&md->stats);
|
||||
|
@ -216,12 +216,12 @@ static bool faulty_make_request(struct mddev *mddev, struct bio *bio)
|
||||
if (failit) {
|
||||
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_end_io = faulty_fail;
|
||||
bio = b;
|
||||
} else
|
||||
bio->bi_bdev = conf->rdev->bdev;
|
||||
bio_set_dev(bio, conf->rdev->bdev);
|
||||
|
||||
generic_make_request(bio);
|
||||
return true;
|
||||
|
@ -275,17 +275,17 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio)
|
||||
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 -
|
||||
start_sector + data_offset;
|
||||
|
||||
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 */
|
||||
bio_endio(bio);
|
||||
} else {
|
||||
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_sector);
|
||||
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->bi_end_io = md_end_flush;
|
||||
bi->bi_private = rdev;
|
||||
bi->bi_bdev = rdev->bdev;
|
||||
bio_set_dev(bi, rdev->bdev);
|
||||
bi->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||
atomic_inc(&mddev->flush_pending);
|
||||
submit_bio(bi);
|
||||
@ -772,7 +772,7 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
|
||||
|
||||
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_add_page(bio, page, size, 0);
|
||||
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);
|
||||
int ret;
|
||||
|
||||
bio->bi_bdev = (metadata_op && rdev->meta_bdev) ?
|
||||
rdev->meta_bdev : rdev->bdev;
|
||||
if (metadata_op && rdev->meta_bdev)
|
||||
bio_set_dev(bio, rdev->meta_bdev);
|
||||
else
|
||||
bio_set_dev(bio, rdev->bdev);
|
||||
bio_set_op_attrs(bio, op, op_flags);
|
||||
if (metadata_op)
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#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);
|
||||
|
||||
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_end_io = multipath_end_request;
|
||||
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) {
|
||||
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);
|
||||
multipath_end_bh_io(mp_bh, BLK_STS_IOERR);
|
||||
} else {
|
||||
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);
|
||||
*bio = *(mp_bh->master_bio);
|
||||
bio->bi_iter.bi_sector +=
|
||||
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_end_io = multipath_end_request;
|
||||
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);
|
||||
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 +
|
||||
tmp_dev->data_offset;
|
||||
|
||||
if (mddev->gendisk)
|
||||
trace_block_bio_remap(bdev_get_queue(bio->bi_bdev),
|
||||
bio, disk_devt(mddev->gendisk),
|
||||
bio_sector);
|
||||
trace_block_bio_remap(bio->bi_disk->queue, bio,
|
||||
disk_devt(mddev->gendisk), bio_sector);
|
||||
mddev_check_writesame(mddev, bio);
|
||||
mddev_check_write_zeroes(mddev, 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 */
|
||||
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_bdev = rdev->bdev;
|
||||
bio_set_dev(bio, rdev->bdev);
|
||||
if (test_bit(Faulty, &rdev->flags)) {
|
||||
bio_io_error(bio);
|
||||
} 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 */
|
||||
bio_endio(bio);
|
||||
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 +
|
||||
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;
|
||||
bio_set_op_attrs(read_bio, op, do_sync);
|
||||
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;
|
||||
|
||||
if (mddev->gendisk)
|
||||
trace_block_bio_remap(bdev_get_queue(read_bio->bi_bdev),
|
||||
read_bio, disk_devt(mddev->gendisk),
|
||||
r1_bio->sector);
|
||||
trace_block_bio_remap(read_bio->bi_disk->queue, read_bio,
|
||||
disk_devt(mddev->gendisk), r1_bio->sector);
|
||||
|
||||
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 +
|
||||
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_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
|
||||
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);
|
||||
|
||||
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),
|
||||
r1_bio->sector);
|
||||
/* 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));
|
||||
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.
|
||||
*/
|
||||
pr_crit_ratelimited("md/raid1:%s: %s: unrecoverable I/O read error for block %llu\n",
|
||||
mdname(mddev),
|
||||
bdevname(bio->bi_bdev, b),
|
||||
mdname(mddev), bio_devname(bio, b),
|
||||
(unsigned long long)r1_bio->sector);
|
||||
for (d = 0; d < conf->raid_disks * 2; d++) {
|
||||
rdev = conf->mirrors[d].rdev;
|
||||
@ -2082,7 +2080,7 @@ static void process_checks(struct r1bio *r1_bio)
|
||||
b->bi_status = status;
|
||||
b->bi_iter.bi_sector = r1_bio->sector +
|
||||
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;
|
||||
rp->raid_bio = r1_bio;
|
||||
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);
|
||||
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)
|
||||
/* failure! */
|
||||
@ -2440,7 +2438,6 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
|
||||
struct mddev *mddev = conf->mddev;
|
||||
struct bio *bio;
|
||||
struct md_rdev *rdev;
|
||||
dev_t bio_dev;
|
||||
sector_t bio_sector;
|
||||
|
||||
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_dev = bio->bi_bdev->bd_dev;
|
||||
bio_sector = conf->mirrors[r1_bio->read_disk].rdev->data_offset + r1_bio->sector;
|
||||
bio_put(bio);
|
||||
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) {
|
||||
atomic_inc(&rdev->nr_pending);
|
||||
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))
|
||||
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];
|
||||
if (bio->bi_end_io == end_sync_read) {
|
||||
read_targets--;
|
||||
md_sync_acct(bio->bi_bdev, nr_sectors);
|
||||
md_sync_acct_bio(bio, nr_sectors);
|
||||
if (read_targets == 1)
|
||||
bio->bi_opf &= ~MD_FAILFAST;
|
||||
generic_make_request(bio);
|
||||
@ -2862,7 +2858,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
} else {
|
||||
atomic_set(&r1_bio->remaining, 1);
|
||||
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)
|
||||
bio->bi_opf &= ~MD_FAILFAST;
|
||||
generic_make_request(bio);
|
||||
|
@ -901,13 +901,13 @@ static void flush_pending_writes(struct r10conf *conf)
|
||||
|
||||
while (bio) { /* submit pending writes */
|
||||
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_bdev = rdev->bdev;
|
||||
bio_set_dev(bio, rdev->bdev);
|
||||
if (test_bit(Faulty, &rdev->flags)) {
|
||||
bio_io_error(bio);
|
||||
} 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 */
|
||||
bio_endio(bio);
|
||||
else
|
||||
@ -1085,13 +1085,13 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
|
||||
|
||||
while (bio) { /* submit pending writes */
|
||||
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_bdev = rdev->bdev;
|
||||
bio_set_dev(bio, rdev->bdev);
|
||||
if (test_bit(Faulty, &rdev->flags)) {
|
||||
bio_io_error(bio);
|
||||
} 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 */
|
||||
bio_endio(bio);
|
||||
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 +
|
||||
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;
|
||||
bio_set_op_attrs(read_bio, op, do_sync);
|
||||
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;
|
||||
|
||||
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),
|
||||
r10_bio->sector);
|
||||
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 +
|
||||
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;
|
||||
bio_set_op_attrs(mbio, op, do_sync | do_fua);
|
||||
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;
|
||||
|
||||
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),
|
||||
r10_bio->sector);
|
||||
/* flush_pending_writes() needs access to the rdev so...*/
|
||||
mbio->bi_bdev = (void *)rdev;
|
||||
mbio->bi_disk = (void *)rdev;
|
||||
|
||||
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))
|
||||
tbio->bi_opf |= MD_FAILFAST;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
wbio->bi_iter.bi_sector = wsector +
|
||||
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);
|
||||
|
||||
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 r10conf *conf = mddev->private;
|
||||
struct md_rdev *rdev = r10_bio->devs[slot].rdev;
|
||||
dev_t bio_dev;
|
||||
sector_t bio_last_sector;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
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_put(bio);
|
||||
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.
|
||||
* 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.
|
||||
* For recovery, we may actually create several r10bios
|
||||
* 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;
|
||||
bio->bi_iter.bi_sector = from_addr +
|
||||
rdev->data_offset;
|
||||
bio->bi_bdev = rdev->bdev;
|
||||
bio_set_dev(bio, rdev->bdev);
|
||||
atomic_inc(&rdev->nr_pending);
|
||||
/* 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->bi_iter.bi_sector = to_addr
|
||||
+ mrdev->data_offset;
|
||||
bio->bi_bdev = mrdev->bdev;
|
||||
bio_set_dev(bio, mrdev->bdev);
|
||||
atomic_inc(&r10_bio->remaining);
|
||||
} else
|
||||
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->bi_iter.bi_sector = to_addr +
|
||||
mreplace->data_offset;
|
||||
bio->bi_bdev = mreplace->bdev;
|
||||
bio_set_dev(bio, mreplace->bdev);
|
||||
atomic_inc(&r10_bio->remaining);
|
||||
break;
|
||||
}
|
||||
@ -3289,7 +3287,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||
if (test_bit(FailFast, &rdev->flags))
|
||||
bio->bi_opf |= MD_FAILFAST;
|
||||
bio->bi_iter.bi_sector = sector + rdev->data_offset;
|
||||
bio->bi_bdev = rdev->bdev;
|
||||
bio_set_dev(bio, rdev->bdev);
|
||||
count++;
|
||||
|
||||
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))
|
||||
bio->bi_opf |= MD_FAILFAST;
|
||||
bio->bi_iter.bi_sector = sector + rdev->data_offset;
|
||||
bio->bi_bdev = rdev->bdev;
|
||||
bio_set_dev(bio, rdev->bdev);
|
||||
count++;
|
||||
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;
|
||||
|
||||
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;
|
||||
generic_make_request(bio);
|
||||
}
|
||||
@ -4383,7 +4381,7 @@ read_more:
|
||||
|
||||
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
|
||||
+ rdev->data_offset);
|
||||
read_bio->bi_private = r10_bio;
|
||||
@ -4417,7 +4415,7 @@ read_more:
|
||||
if (!rdev2 || test_bit(Faulty, &rdev2->flags))
|
||||
continue;
|
||||
|
||||
b->bi_bdev = rdev2->bdev;
|
||||
bio_set_dev(b, rdev2->bdev);
|
||||
b->bi_iter.bi_sector = r10_bio->devs[s/2].addr +
|
||||
rdev2->new_data_offset;
|
||||
b->bi_end_io = end_reshape_write;
|
||||
@ -4449,7 +4447,7 @@ read_more:
|
||||
r10_bio->sectors = nr_sectors;
|
||||
|
||||
/* 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);
|
||||
read_bio->bi_next = NULL;
|
||||
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);
|
||||
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);
|
||||
b->bi_next = NULL;
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
return bio;
|
||||
@ -1313,7 +1313,7 @@ void r5l_flush_stripe_to_raid(struct r5l_log *log)
|
||||
if (!do_flush)
|
||||
return;
|
||||
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_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||
submit_bio(&log->flush_bio);
|
||||
@ -1691,7 +1691,7 @@ static int r5l_recovery_fetch_ra_pool(struct r5l_log *log,
|
||||
sector_t offset)
|
||||
{
|
||||
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);
|
||||
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",
|
||||
__func__, io->seq, bio->bi_iter.bi_size,
|
||||
(unsigned long long)bio->bi_iter.bi_sector,
|
||||
bdevname(bio->bi_bdev, b));
|
||||
bio_devname(bio, b));
|
||||
|
||||
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_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_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,
|
||||
ppl_conf->bs);
|
||||
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_add_page(bio, sh->ppl_page, PAGE_SIZE, 0);
|
||||
|
||||
|
@ -1096,7 +1096,7 @@ again:
|
||||
|
||||
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);
|
||||
bi->bi_end_io = op_is_write(op)
|
||||
? raid5_end_write_request
|
||||
@ -1145,7 +1145,7 @@ again:
|
||||
set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
|
||||
|
||||
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),
|
||||
sh->dev[i].sector);
|
||||
if (should_defer && op_is_write(op))
|
||||
@ -1160,7 +1160,7 @@ again:
|
||||
|
||||
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);
|
||||
BUG_ON(!op_is_write(op));
|
||||
rbi->bi_end_io = raid5_end_write_request;
|
||||
@ -1193,7 +1193,7 @@ again:
|
||||
if (op == REQ_OP_DISCARD)
|
||||
rbi->bi_vcnt = 0;
|
||||
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),
|
||||
sh->dev[i].sector);
|
||||
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)
|
||||
{
|
||||
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 bio_sectors = bio_sectors(bio);
|
||||
|
||||
WARN_ON_ONCE(bio->bi_partno);
|
||||
|
||||
chunk_sectors = min(conf->chunk_sectors, conf->prev_chunk_sectors);
|
||||
return chunk_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);
|
||||
rcu_read_unlock();
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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),
|
||||
raid_bio->bi_iter.bi_sector);
|
||||
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);
|
||||
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))
|
||||
return false;
|
||||
|
||||
*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);
|
||||
return true;
|
||||
}
|
||||
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,
|
||||
unsigned int len)
|
||||
|
@ -613,11 +613,7 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
|
||||
|
||||
if (!disk)
|
||||
goto submit;
|
||||
bio->bi_bdev = bdget_disk(disk, 0);
|
||||
if (!bio->bi_bdev) {
|
||||
ret = -ENODEV;
|
||||
goto out_unmap;
|
||||
}
|
||||
bio->bi_disk = disk;
|
||||
|
||||
if (meta_buffer && meta_len) {
|
||||
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:
|
||||
kfree(meta);
|
||||
out_unmap:
|
||||
if (bio) {
|
||||
if (disk && bio->bi_bdev)
|
||||
bdput(bio->bi_bdev);
|
||||
if (bio)
|
||||
blk_rq_unmap_user(bio);
|
||||
}
|
||||
out:
|
||||
blk_mq_free_request(req);
|
||||
return ret;
|
||||
|
@ -2168,7 +2168,6 @@ static const struct blk_mq_ops nvme_fc_mq_ops = {
|
||||
.complete = nvme_fc_complete_rq,
|
||||
.init_request = nvme_fc_init_request,
|
||||
.exit_request = nvme_fc_exit_request,
|
||||
.reinit_request = nvme_fc_reinit_request,
|
||||
.init_hctx = nvme_fc_init_hctx,
|
||||
.poll = nvme_fc_poll,
|
||||
.timeout = nvme_fc_timeout,
|
||||
@ -2269,7 +2268,7 @@ nvme_fc_reinit_io_queues(struct nvme_fc_ctrl *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)
|
||||
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,
|
||||
.init_request = nvme_fc_init_request,
|
||||
.exit_request = nvme_fc_exit_request,
|
||||
.reinit_request = nvme_fc_reinit_request,
|
||||
.init_hctx = nvme_fc_init_admin_hctx,
|
||||
.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);
|
||||
}
|
||||
|
||||
if (!disk)
|
||||
goto submit;
|
||||
|
||||
bio->bi_bdev = bdget_disk(disk, 0);
|
||||
if (!bio->bi_bdev) {
|
||||
ret = -ENODEV;
|
||||
goto err_meta;
|
||||
}
|
||||
bio->bi_disk = disk;
|
||||
}
|
||||
|
||||
submit:
|
||||
blk_execute_rq(q, NULL, rq, 0);
|
||||
|
||||
if (nvme_req(rq)->flags & NVME_REQ_CANCELLED)
|
||||
@ -673,11 +665,8 @@ err_meta:
|
||||
if (meta_buf && meta_len)
|
||||
dma_pool_free(dev->dma_pool, metadata, metadata_dma);
|
||||
err_map:
|
||||
if (bio) {
|
||||
if (disk && bio->bi_bdev)
|
||||
bdput(bio->bi_bdev);
|
||||
if (bio)
|
||||
blk_rq_unmap_user(bio);
|
||||
}
|
||||
err_ppa:
|
||||
if (ppa_buf && ppa_len)
|
||||
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) {
|
||||
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)
|
||||
goto requeue;
|
||||
}
|
||||
|
||||
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)
|
||||
goto requeue;
|
||||
|
||||
@ -1521,7 +1523,6 @@ static const struct blk_mq_ops nvme_rdma_mq_ops = {
|
||||
.complete = nvme_rdma_complete_rq,
|
||||
.init_request = nvme_rdma_init_request,
|
||||
.exit_request = nvme_rdma_exit_request,
|
||||
.reinit_request = nvme_rdma_reinit_request,
|
||||
.init_hctx = nvme_rdma_init_hctx,
|
||||
.poll = nvme_rdma_poll,
|
||||
.timeout = nvme_rdma_timeout,
|
||||
@ -1533,7 +1534,6 @@ static const struct blk_mq_ops nvme_rdma_admin_mq_ops = {
|
||||
.complete = nvme_rdma_complete_rq,
|
||||
.init_request = nvme_rdma_init_request,
|
||||
.exit_request = nvme_rdma_exit_request,
|
||||
.reinit_request = nvme_rdma_reinit_request,
|
||||
.init_hctx = nvme_rdma_init_admin_hctx,
|
||||
.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) {
|
||||
ret = blk_mq_reinit_tagset(&ctrl->tag_set);
|
||||
ret = blk_mq_reinit_tagset(&ctrl->tag_set,
|
||||
nvme_rdma_reinit_request);
|
||||
if (ret)
|
||||
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
Block a user