1
0
Fork 0

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
  ...
hifive-unleashed-5.1
Linus Torvalds 2017-09-07 11:59:42 -07:00
commit a0725ab0c7
160 changed files with 3721 additions and 3523 deletions

View File

@ -12561,6 +12561,12 @@ M: Ion Badulescu <ionut@badula.org>
S: Odd Fixes S: Odd Fixes
F: drivers/net/ethernet/adaptec/starfire* F: drivers/net/ethernet/adaptec/starfire*
STEC S1220 SKD DRIVER
M: Bart Van Assche <bart.vanassche@wdc.com>
L: linux-block@vger.kernel.org
S: Maintained
F: drivers/block/skd*[ch]
STI CEC DRIVER STI CEC DRIVER
M: Benjamin Gaignard <benjamin.gaignard@linaro.org> M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
S: Maintained S: Maintained

View File

@ -110,7 +110,7 @@ axon_ram_irq_handler(int irq, void *dev)
static blk_qc_t static blk_qc_t
axon_ram_make_request(struct request_queue *queue, struct bio *bio) axon_ram_make_request(struct request_queue *queue, struct bio *bio)
{ {
struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data; struct axon_ram_bank *bank = bio->bi_disk->private_data;
unsigned long phys_mem, phys_end; unsigned long phys_mem, phys_end;
void *user_mem; void *user_mem;
struct bio_vec vec; struct bio_vec vec;

View File

@ -128,7 +128,7 @@ BFQ_BFQQ_FNS(busy);
BFQ_BFQQ_FNS(wait_request); BFQ_BFQQ_FNS(wait_request);
BFQ_BFQQ_FNS(non_blocking_wait_rq); BFQ_BFQQ_FNS(non_blocking_wait_rq);
BFQ_BFQQ_FNS(fifo_expire); BFQ_BFQQ_FNS(fifo_expire);
BFQ_BFQQ_FNS(idle_window); BFQ_BFQQ_FNS(has_short_ttime);
BFQ_BFQQ_FNS(sync); BFQ_BFQQ_FNS(sync);
BFQ_BFQQ_FNS(IO_bound); BFQ_BFQQ_FNS(IO_bound);
BFQ_BFQQ_FNS(in_large_burst); BFQ_BFQQ_FNS(in_large_burst);
@ -731,10 +731,10 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
unsigned int old_wr_coeff = bfqq->wr_coeff; unsigned int old_wr_coeff = bfqq->wr_coeff;
bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq); bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq);
if (bic->saved_idle_window) if (bic->saved_has_short_ttime)
bfq_mark_bfqq_idle_window(bfqq); bfq_mark_bfqq_has_short_ttime(bfqq);
else else
bfq_clear_bfqq_idle_window(bfqq); bfq_clear_bfqq_has_short_ttime(bfqq);
if (bic->saved_IO_bound) if (bic->saved_IO_bound)
bfq_mark_bfqq_IO_bound(bfqq); bfq_mark_bfqq_IO_bound(bfqq);
@ -2012,7 +2012,7 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
return; return;
bic->saved_ttime = bfqq->ttime; bic->saved_ttime = bfqq->ttime;
bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); bic->saved_has_short_ttime = bfq_bfqq_has_short_ttime(bfqq);
bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
@ -3038,8 +3038,8 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
} }
bfq_log_bfqq(bfqd, bfqq, bfq_log_bfqq(bfqd, bfqq,
"expire (%d, slow %d, num_disp %d, idle_win %d)", reason, "expire (%d, slow %d, num_disp %d, short_ttime %d)", reason,
slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq)); slow, bfqq->dispatched, bfq_bfqq_has_short_ttime(bfqq));
/* /*
* Increase, decrease or leave budget unchanged according to * Increase, decrease or leave budget unchanged according to
@ -3114,35 +3114,56 @@ static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
{ {
struct bfq_data *bfqd = bfqq->bfqd; struct bfq_data *bfqd = bfqq->bfqd;
bool idling_boosts_thr, idling_boosts_thr_without_issues, bool rot_without_queueing =
!blk_queue_nonrot(bfqd->queue) && !bfqd->hw_tag,
bfqq_sequential_and_IO_bound,
idling_boosts_thr, idling_boosts_thr_without_issues,
idling_needed_for_service_guarantees, idling_needed_for_service_guarantees,
asymmetric_scenario; asymmetric_scenario;
if (bfqd->strict_guarantees) if (bfqd->strict_guarantees)
return true; return true;
/*
* Idling is performed only if slice_idle > 0. In addition, we
* do not idle if
* (a) bfqq is async
* (b) bfqq is in the idle io prio class: in this case we do
* not idle because we want to minimize the bandwidth that
* queues in this class can steal to higher-priority queues
*/
if (bfqd->bfq_slice_idle == 0 || !bfq_bfqq_sync(bfqq) ||
bfq_class_idle(bfqq))
return false;
bfqq_sequential_and_IO_bound = !BFQQ_SEEKY(bfqq) &&
bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_has_short_ttime(bfqq);
/* /*
* The next variable takes into account the cases where idling * The next variable takes into account the cases where idling
* boosts the throughput. * boosts the throughput.
* *
* The value of the variable is computed considering, first, that * The value of the variable is computed considering, first, that
* idling is virtually always beneficial for the throughput if: * idling is virtually always beneficial for the throughput if:
* (a) the device is not NCQ-capable, or * (a) the device is not NCQ-capable and rotational, or
* (b) regardless of the presence of NCQ, the device is rotational * (b) regardless of the presence of NCQ, the device is rotational and
* and the request pattern for bfqq is I/O-bound and sequential. * the request pattern for bfqq is I/O-bound and sequential, or
* (c) regardless of whether it is rotational, the device is
* not NCQ-capable and the request pattern for bfqq is
* I/O-bound and sequential.
* *
* Secondly, and in contrast to the above item (b), idling an * Secondly, and in contrast to the above item (b), idling an
* NCQ-capable flash-based device would not boost the * NCQ-capable flash-based device would not boost the
* throughput even with sequential I/O; rather it would lower * throughput even with sequential I/O; rather it would lower
* the throughput in proportion to how fast the device * the throughput in proportion to how fast the device
* is. Accordingly, the next variable is true if any of the * is. Accordingly, the next variable is true if any of the
* above conditions (a) and (b) is true, and, in particular, * above conditions (a), (b) or (c) is true, and, in
* happens to be false if bfqd is an NCQ-capable flash-based * particular, happens to be false if bfqd is an NCQ-capable
* device. * flash-based device.
*/ */
idling_boosts_thr = !bfqd->hw_tag || idling_boosts_thr = rot_without_queueing ||
(!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) && ((!blk_queue_nonrot(bfqd->queue) || !bfqd->hw_tag) &&
bfq_bfqq_idle_window(bfqq)); bfqq_sequential_and_IO_bound);
/* /*
* The value of the next variable, * The value of the next variable,
@ -3313,16 +3334,13 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq); asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq);
/* /*
* We have now all the components we need to compute the return * We have now all the components we need to compute the
* value of the function, which is true only if both the following * return value of the function, which is true only if idling
* conditions hold: * either boosts the throughput (without issues), or is
* 1) bfqq is sync, because idling make sense only for sync queues; * necessary to preserve service guarantees.
* 2) idling either boosts the throughput (without issues), or
* is necessary to preserve service guarantees.
*/ */
return bfq_bfqq_sync(bfqq) && return idling_boosts_thr_without_issues ||
(idling_boosts_thr_without_issues || idling_needed_for_service_guarantees;
idling_needed_for_service_guarantees);
} }
/* /*
@ -3338,10 +3356,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
*/ */
static bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) static bool bfq_bfqq_must_idle(struct bfq_queue *bfqq)
{ {
struct bfq_data *bfqd = bfqq->bfqd; return RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_may_idle(bfqq);
return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 &&
bfq_bfqq_may_idle(bfqq);
} }
/* /*
@ -3783,7 +3798,6 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
case IOPRIO_CLASS_IDLE: case IOPRIO_CLASS_IDLE:
bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE; bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE;
bfqq->new_ioprio = 7; bfqq->new_ioprio = 7;
bfq_clear_bfqq_idle_window(bfqq);
break; break;
} }
@ -3843,8 +3857,14 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
bfq_set_next_ioprio_data(bfqq, bic); bfq_set_next_ioprio_data(bfqq, bic);
if (is_sync) { if (is_sync) {
/*
* No need to mark as has_short_ttime if in
* idle_class, because no device idling is performed
* for queues in idle class
*/
if (!bfq_class_idle(bfqq)) if (!bfq_class_idle(bfqq))
bfq_mark_bfqq_idle_window(bfqq); /* tentatively mark as has_short_ttime */
bfq_mark_bfqq_has_short_ttime(bfqq);
bfq_mark_bfqq_sync(bfqq); bfq_mark_bfqq_sync(bfqq);
bfq_mark_bfqq_just_created(bfqq); bfq_mark_bfqq_just_created(bfqq);
} else } else
@ -3985,18 +4005,19 @@ bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq,
blk_rq_sectors(rq) < BFQQ_SECT_THR_NONROT); blk_rq_sectors(rq) < BFQQ_SECT_THR_NONROT);
} }
/* static void bfq_update_has_short_ttime(struct bfq_data *bfqd,
* Disable idle window if the process thinks too long or seeks so much that struct bfq_queue *bfqq,
* it doesn't matter. struct bfq_io_cq *bic)
*/
static void bfq_update_idle_window(struct bfq_data *bfqd,
struct bfq_queue *bfqq,
struct bfq_io_cq *bic)
{ {
int enable_idle; bool has_short_ttime = true;
/* Don't idle for async or idle io prio class. */ /*
if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) * No need to update has_short_ttime if bfqq is async or in
* idle io prio class, or if bfq_slice_idle is zero, because
* no device idling is performed for bfqq in this case.
*/
if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq) ||
bfqd->bfq_slice_idle == 0)
return; return;
/* Idle window just restored, statistics are meaningless. */ /* Idle window just restored, statistics are meaningless. */
@ -4004,27 +4025,22 @@ static void bfq_update_idle_window(struct bfq_data *bfqd,
bfqd->bfq_wr_min_idle_time)) bfqd->bfq_wr_min_idle_time))
return; return;
enable_idle = bfq_bfqq_idle_window(bfqq); /* Think time is infinite if no process is linked to
* bfqq. Otherwise check average think time to
* decide whether to mark as has_short_ttime
*/
if (atomic_read(&bic->icq.ioc->active_ref) == 0 || if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
bfqd->bfq_slice_idle == 0 || (bfq_sample_valid(bfqq->ttime.ttime_samples) &&
(bfqd->hw_tag && BFQQ_SEEKY(bfqq) && bfqq->ttime.ttime_mean > bfqd->bfq_slice_idle))
bfqq->wr_coeff == 1)) has_short_ttime = false;
enable_idle = 0;
else if (bfq_sample_valid(bfqq->ttime.ttime_samples)) {
if (bfqq->ttime.ttime_mean > bfqd->bfq_slice_idle &&
bfqq->wr_coeff == 1)
enable_idle = 0;
else
enable_idle = 1;
}
bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d",
enable_idle);
if (enable_idle) bfq_log_bfqq(bfqd, bfqq, "update_has_short_ttime: has_short_ttime %d",
bfq_mark_bfqq_idle_window(bfqq); has_short_ttime);
if (has_short_ttime)
bfq_mark_bfqq_has_short_ttime(bfqq);
else else
bfq_clear_bfqq_idle_window(bfqq); bfq_clear_bfqq_has_short_ttime(bfqq);
} }
/* /*
@ -4040,14 +4056,12 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
bfqq->meta_pending++; bfqq->meta_pending++;
bfq_update_io_thinktime(bfqd, bfqq); bfq_update_io_thinktime(bfqd, bfqq);
bfq_update_has_short_ttime(bfqd, bfqq, bic);
bfq_update_io_seektime(bfqd, bfqq, rq); bfq_update_io_seektime(bfqd, bfqq, rq);
if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
!BFQQ_SEEKY(bfqq))
bfq_update_idle_window(bfqd, bfqq, bic);
bfq_log_bfqq(bfqd, bfqq, bfq_log_bfqq(bfqd, bfqq,
"rq_enqueued: idle_window=%d (seeky %d)", "rq_enqueued: has_short_ttime=%d (seeky %d)",
bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq)); bfq_bfqq_has_short_ttime(bfqq), BFQQ_SEEKY(bfqq));
bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
@ -4787,16 +4801,13 @@ static ssize_t bfq_var_show(unsigned int var, char *page)
return sprintf(page, "%u\n", var); return sprintf(page, "%u\n", var);
} }
static ssize_t bfq_var_store(unsigned long *var, const char *page, static void bfq_var_store(unsigned long *var, const char *page)
size_t count)
{ {
unsigned long new_val; unsigned long new_val;
int ret = kstrtoul(page, 10, &new_val); int ret = kstrtoul(page, 10, &new_val);
if (ret == 0) if (ret == 0)
*var = new_val; *var = new_val;
return count;
} }
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ #define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
@ -4838,7 +4849,7 @@ __FUNC(struct elevator_queue *e, const char *page, size_t count) \
{ \ { \
struct bfq_data *bfqd = e->elevator_data; \ struct bfq_data *bfqd = e->elevator_data; \
unsigned long uninitialized_var(__data); \ unsigned long uninitialized_var(__data); \
int ret = bfq_var_store(&__data, (page), count); \ bfq_var_store(&__data, (page)); \
if (__data < (MIN)) \ if (__data < (MIN)) \
__data = (MIN); \ __data = (MIN); \
else if (__data > (MAX)) \ else if (__data > (MAX)) \
@ -4849,7 +4860,7 @@ __FUNC(struct elevator_queue *e, const char *page, size_t count) \
*(__PTR) = (u64)__data * NSEC_PER_MSEC; \ *(__PTR) = (u64)__data * NSEC_PER_MSEC; \
else \ else \
*(__PTR) = __data; \ *(__PTR) = __data; \
return ret; \ return count; \
} }
STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
INT_MAX, 2); INT_MAX, 2);
@ -4866,13 +4877,13 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)\
{ \ { \
struct bfq_data *bfqd = e->elevator_data; \ struct bfq_data *bfqd = e->elevator_data; \
unsigned long uninitialized_var(__data); \ unsigned long uninitialized_var(__data); \
int ret = bfq_var_store(&__data, (page), count); \ bfq_var_store(&__data, (page)); \
if (__data < (MIN)) \ if (__data < (MIN)) \
__data = (MIN); \ __data = (MIN); \
else if (__data > (MAX)) \ else if (__data > (MAX)) \
__data = (MAX); \ __data = (MAX); \
*(__PTR) = (u64)__data * NSEC_PER_USEC; \ *(__PTR) = (u64)__data * NSEC_PER_USEC; \
return ret; \ return count; \
} }
USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0, USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0,
UINT_MAX); UINT_MAX);
@ -4883,7 +4894,8 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
{ {
struct bfq_data *bfqd = e->elevator_data; struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data); unsigned long uninitialized_var(__data);
int ret = bfq_var_store(&__data, (page), count);
bfq_var_store(&__data, (page));
if (__data == 0) if (__data == 0)
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd); bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
@ -4895,7 +4907,7 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
bfqd->bfq_user_max_budget = __data; bfqd->bfq_user_max_budget = __data;
return ret; return count;
} }
/* /*
@ -4907,7 +4919,8 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
{ {
struct bfq_data *bfqd = e->elevator_data; struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data); unsigned long uninitialized_var(__data);
int ret = bfq_var_store(&__data, (page), count);
bfq_var_store(&__data, (page));
if (__data < 1) if (__data < 1)
__data = 1; __data = 1;
@ -4918,7 +4931,7 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
if (bfqd->bfq_user_max_budget == 0) if (bfqd->bfq_user_max_budget == 0)
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd); bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
return ret; return count;
} }
static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e, static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
@ -4926,7 +4939,8 @@ static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
{ {
struct bfq_data *bfqd = e->elevator_data; struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data); unsigned long uninitialized_var(__data);
int ret = bfq_var_store(&__data, (page), count);
bfq_var_store(&__data, (page));
if (__data > 1) if (__data > 1)
__data = 1; __data = 1;
@ -4936,7 +4950,7 @@ static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
bfqd->strict_guarantees = __data; bfqd->strict_guarantees = __data;
return ret; return count;
} }
static ssize_t bfq_low_latency_store(struct elevator_queue *e, static ssize_t bfq_low_latency_store(struct elevator_queue *e,
@ -4944,7 +4958,8 @@ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
{ {
struct bfq_data *bfqd = e->elevator_data; struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data); unsigned long uninitialized_var(__data);
int ret = bfq_var_store(&__data, (page), count);
bfq_var_store(&__data, (page));
if (__data > 1) if (__data > 1)
__data = 1; __data = 1;
@ -4952,7 +4967,7 @@ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
bfq_end_wr(bfqd); bfq_end_wr(bfqd);
bfqd->low_latency = __data; bfqd->low_latency = __data;
return ret; return count;
} }
#define BFQ_ATTR(name) \ #define BFQ_ATTR(name) \
@ -4998,6 +5013,7 @@ static struct elevator_type iosched_bfq_mq = {
.elevator_name = "bfq", .elevator_name = "bfq",
.elevator_owner = THIS_MODULE, .elevator_owner = THIS_MODULE,
}; };
MODULE_ALIAS("bfq-iosched");
static int __init bfq_init(void) static int __init bfq_init(void)
{ {
@ -5048,10 +5064,12 @@ static int __init bfq_init(void)
ret = elv_register(&iosched_bfq_mq); ret = elv_register(&iosched_bfq_mq);
if (ret) if (ret)
goto err_pol_unreg; goto slab_kill;
return 0; return 0;
slab_kill:
bfq_slab_kill();
err_pol_unreg: err_pol_unreg:
#ifdef CONFIG_BFQ_GROUP_IOSCHED #ifdef CONFIG_BFQ_GROUP_IOSCHED
blkcg_policy_unregister(&blkcg_policy_bfq); blkcg_policy_unregister(&blkcg_policy_bfq);

View File

@ -360,11 +360,11 @@ struct bfq_io_cq {
uint64_t blkcg_serial_nr; /* the current blkcg serial */ uint64_t blkcg_serial_nr; /* the current blkcg serial */
#endif #endif
/* /*
* Snapshot of the idle window before merging; taken to * Snapshot of the has_short_time flag before merging; taken
* remember this value while the queue is merged, so as to be * to remember its value while the queue is merged, so as to
* able to restore it in case of split. * be able to restore it in case of split.
*/ */
bool saved_idle_window; bool saved_has_short_ttime;
/* /*
* Same purpose as the previous two fields for the I/O bound * Same purpose as the previous two fields for the I/O bound
* classification of a queue. * classification of a queue.
@ -638,7 +638,7 @@ enum bfqq_state_flags {
* without idling the device * without idling the device
*/ */
BFQQF_fifo_expire, /* FIFO checked in this slice */ BFQQF_fifo_expire, /* FIFO checked in this slice */
BFQQF_idle_window, /* slice idling enabled */ BFQQF_has_short_ttime, /* queue has a short think time */
BFQQF_sync, /* synchronous queue */ BFQQF_sync, /* synchronous queue */
BFQQF_IO_bound, /* BFQQF_IO_bound, /*
* bfqq has timed-out at least once * bfqq has timed-out at least once
@ -667,7 +667,7 @@ BFQ_BFQQ_FNS(busy);
BFQ_BFQQ_FNS(wait_request); BFQ_BFQQ_FNS(wait_request);
BFQ_BFQQ_FNS(non_blocking_wait_rq); BFQ_BFQQ_FNS(non_blocking_wait_rq);
BFQ_BFQQ_FNS(fifo_expire); BFQ_BFQQ_FNS(fifo_expire);
BFQ_BFQQ_FNS(idle_window); BFQ_BFQQ_FNS(has_short_ttime);
BFQ_BFQQ_FNS(sync); BFQ_BFQQ_FNS(sync);
BFQ_BFQQ_FNS(IO_bound); BFQ_BFQQ_FNS(IO_bound);
BFQ_BFQQ_FNS(in_large_burst); BFQ_BFQQ_FNS(in_large_burst);
@ -929,13 +929,16 @@ void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq);
struct bfq_group *bfqq_group(struct bfq_queue *bfqq); struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \ #define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \
blk_add_trace_msg((bfqd)->queue, "bfq%d%c %s " fmt, (bfqq)->pid,\ blk_add_cgroup_trace_msg((bfqd)->queue, \
bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \ bfqg_to_blkg(bfqq_group(bfqq))->blkcg, \
bfqq_group(bfqq)->blkg_path, ##args); \ "bfq%d%c " fmt, (bfqq)->pid, \
bfq_bfqq_sync((bfqq)) ? 'S' : 'A', ##args); \
} while (0) } while (0)
#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) \ #define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do { \
blk_add_trace_msg((bfqd)->queue, "%s " fmt, (bfqg)->blkg_path, ##args) blk_add_cgroup_trace_msg((bfqd)->queue, \
bfqg_to_blkg(bfqg)->blkcg, fmt, ##args); \
} while (0)
#else /* CONFIG_BFQ_GROUP_IOSCHED */ #else /* CONFIG_BFQ_GROUP_IOSCHED */

View File

@ -146,7 +146,7 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
iv = bip->bip_vec + bip->bip_vcnt; iv = bip->bip_vec + bip->bip_vcnt;
if (bip->bip_vcnt && if (bip->bip_vcnt &&
bvec_gap_to_prev(bdev_get_queue(bio->bi_bdev), bvec_gap_to_prev(bio->bi_disk->queue,
&bip->bip_vec[bip->bip_vcnt - 1], offset)) &bip->bip_vec[bip->bip_vcnt - 1], offset))
return 0; return 0;
@ -190,7 +190,7 @@ static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
static blk_status_t bio_integrity_process(struct bio *bio, static blk_status_t bio_integrity_process(struct bio *bio,
struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn) struct bvec_iter *proc_iter, integrity_processing_fn *proc_fn)
{ {
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
struct blk_integrity_iter iter; struct blk_integrity_iter iter;
struct bvec_iter bviter; struct bvec_iter bviter;
struct bio_vec bv; struct bio_vec bv;
@ -199,7 +199,7 @@ static blk_status_t bio_integrity_process(struct bio *bio,
void *prot_buf = page_address(bip->bip_vec->bv_page) + void *prot_buf = page_address(bip->bip_vec->bv_page) +
bip->bip_vec->bv_offset; bip->bip_vec->bv_offset;
iter.disk_name = bio->bi_bdev->bd_disk->disk_name; iter.disk_name = bio->bi_disk->disk_name;
iter.interval = 1 << bi->interval_exp; iter.interval = 1 << bi->interval_exp;
iter.seed = proc_iter->bi_sector; iter.seed = proc_iter->bi_sector;
iter.prot_buf = prot_buf; iter.prot_buf = prot_buf;
@ -236,8 +236,8 @@ static blk_status_t bio_integrity_process(struct bio *bio,
bool bio_integrity_prep(struct bio *bio) bool bio_integrity_prep(struct bio *bio)
{ {
struct bio_integrity_payload *bip; struct bio_integrity_payload *bip;
struct blk_integrity *bi; struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
struct request_queue *q; struct request_queue *q = bio->bi_disk->queue;
void *buf; void *buf;
unsigned long start, end; unsigned long start, end;
unsigned int len, nr_pages; unsigned int len, nr_pages;
@ -245,8 +245,9 @@ bool bio_integrity_prep(struct bio *bio)
unsigned int intervals; unsigned int intervals;
blk_status_t status; blk_status_t status;
bi = bdev_get_integrity(bio->bi_bdev); if (!bi)
q = bdev_get_queue(bio->bi_bdev); return true;
if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE) if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE)
return true; return true;
@ -257,9 +258,6 @@ bool bio_integrity_prep(struct bio *bio)
if (bio_integrity(bio)) if (bio_integrity(bio))
return true; return true;
if (bi == NULL)
return true;
if (bio_data_dir(bio) == READ) { if (bio_data_dir(bio) == READ) {
if (!bi->profile->verify_fn || if (!bi->profile->verify_fn ||
!(bi->flags & BLK_INTEGRITY_VERIFY)) !(bi->flags & BLK_INTEGRITY_VERIFY))
@ -354,7 +352,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
struct bio_integrity_payload *bip = struct bio_integrity_payload *bip =
container_of(work, struct bio_integrity_payload, bip_work); container_of(work, struct bio_integrity_payload, bip_work);
struct bio *bio = bip->bip_bio; struct bio *bio = bip->bip_bio;
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
struct bvec_iter iter = bio->bi_iter; struct bvec_iter iter = bio->bi_iter;
/* /*
@ -387,7 +385,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
*/ */
bool __bio_integrity_endio(struct bio *bio) bool __bio_integrity_endio(struct bio *bio)
{ {
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
struct bio_integrity_payload *bip = bio_integrity(bio); struct bio_integrity_payload *bip = bio_integrity(bio);
if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
@ -413,7 +411,7 @@ bool __bio_integrity_endio(struct bio *bio)
void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
{ {
struct bio_integrity_payload *bip = bio_integrity(bio); struct bio_integrity_payload *bip = bio_integrity(bio);
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9); unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
bip->bip_iter.bi_sector += bytes_done >> 9; bip->bip_iter.bi_sector += bytes_done >> 9;
@ -430,7 +428,7 @@ EXPORT_SYMBOL(bio_integrity_advance);
void bio_integrity_trim(struct bio *bio) void bio_integrity_trim(struct bio *bio)
{ {
struct bio_integrity_payload *bip = bio_integrity(bio); struct bio_integrity_payload *bip = bio_integrity(bio);
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio)); bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio));
} }

View File

@ -593,10 +593,10 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
BUG_ON(bio->bi_pool && BVEC_POOL_IDX(bio)); BUG_ON(bio->bi_pool && BVEC_POOL_IDX(bio));
/* /*
* most users will be overriding ->bi_bdev with a new target, * most users will be overriding ->bi_disk with a new target,
* so we don't set nor calculate new physical/hw segment counts here * so we don't set nor calculate new physical/hw segment counts here
*/ */
bio->bi_bdev = bio_src->bi_bdev; bio->bi_disk = bio_src->bi_disk;
bio_set_flag(bio, BIO_CLONED); bio_set_flag(bio, BIO_CLONED);
bio->bi_opf = bio_src->bi_opf; bio->bi_opf = bio_src->bi_opf;
bio->bi_write_hint = bio_src->bi_write_hint; bio->bi_write_hint = bio_src->bi_write_hint;
@ -681,7 +681,7 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs); bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
if (!bio) if (!bio)
return NULL; return NULL;
bio->bi_bdev = bio_src->bi_bdev; bio->bi_disk = bio_src->bi_disk;
bio->bi_opf = bio_src->bi_opf; bio->bi_opf = bio_src->bi_opf;
bio->bi_write_hint = bio_src->bi_write_hint; bio->bi_write_hint = bio_src->bi_write_hint;
bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
@ -936,6 +936,10 @@ static void submit_bio_wait_endio(struct bio *bio)
* *
* Simple wrapper around submit_bio(). Returns 0 on success, or the error from * Simple wrapper around submit_bio(). Returns 0 on success, or the error from
* bio_endio() on failure. * bio_endio() on failure.
*
* WARNING: Unlike to how submit_bio() is usually used, this function does not
* result in bio reference to be consumed. The caller must drop the reference
* on his own.
*/ */
int submit_bio_wait(struct bio *bio) int submit_bio_wait(struct bio *bio)
{ {
@ -1732,29 +1736,29 @@ void bio_check_pages_dirty(struct bio *bio)
} }
} }
void generic_start_io_acct(int rw, unsigned long sectors, void generic_start_io_acct(struct request_queue *q, int rw,
struct hd_struct *part) unsigned long sectors, struct hd_struct *part)
{ {
int cpu = part_stat_lock(); int cpu = part_stat_lock();
part_round_stats(cpu, part); part_round_stats(q, cpu, part);
part_stat_inc(cpu, part, ios[rw]); part_stat_inc(cpu, part, ios[rw]);
part_stat_add(cpu, part, sectors[rw], sectors); part_stat_add(cpu, part, sectors[rw], sectors);
part_inc_in_flight(part, rw); part_inc_in_flight(q, part, rw);
part_stat_unlock(); part_stat_unlock();
} }
EXPORT_SYMBOL(generic_start_io_acct); EXPORT_SYMBOL(generic_start_io_acct);
void generic_end_io_acct(int rw, struct hd_struct *part, void generic_end_io_acct(struct request_queue *q, int rw,
unsigned long start_time) struct hd_struct *part, unsigned long start_time)
{ {
unsigned long duration = jiffies - start_time; unsigned long duration = jiffies - start_time;
int cpu = part_stat_lock(); int cpu = part_stat_lock();
part_stat_add(cpu, part, ticks[rw], duration); part_stat_add(cpu, part, ticks[rw], duration);
part_round_stats(cpu, part); part_round_stats(q, cpu, part);
part_dec_in_flight(part, rw); part_dec_in_flight(q, part, rw);
part_stat_unlock(); part_stat_unlock();
} }
@ -1826,8 +1830,8 @@ again:
goto again; goto again;
} }
if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) { if (bio->bi_disk && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), bio, trace_block_bio_complete(bio->bi_disk->queue, bio,
blk_status_to_errno(bio->bi_status)); blk_status_to_errno(bio->bi_status));
bio_clear_flag(bio, BIO_TRACE_COMPLETION); bio_clear_flag(bio, BIO_TRACE_COMPLETION);
} }

View File

@ -1067,7 +1067,7 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL); blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
if (!blkcg) { if (!blkcg) {
ret = ERR_PTR(-ENOMEM); ret = ERR_PTR(-ENOMEM);
goto free_blkcg; goto unlock;
} }
} }
@ -1111,8 +1111,10 @@ free_pd_blkcg:
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
if (blkcg->cpd[i]) if (blkcg->cpd[i])
blkcg_policy[i]->cpd_free_fn(blkcg->cpd[i]); blkcg_policy[i]->cpd_free_fn(blkcg->cpd[i]);
free_blkcg:
kfree(blkcg); if (blkcg != &blkcg_root)
kfree(blkcg);
unlock:
mutex_unlock(&blkcg_pol_mutex); mutex_unlock(&blkcg_pol_mutex);
return ret; return ret;
} }

View File

@ -280,7 +280,7 @@ EXPORT_SYMBOL(blk_start_queue_async);
void blk_start_queue(struct request_queue *q) void blk_start_queue(struct request_queue *q)
{ {
lockdep_assert_held(q->queue_lock); lockdep_assert_held(q->queue_lock);
WARN_ON(!irqs_disabled()); WARN_ON(!in_interrupt() && !irqs_disabled());
WARN_ON_ONCE(q->mq_ops); WARN_ON_ONCE(q->mq_ops);
queue_flag_clear(QUEUE_FLAG_STOPPED, q); queue_flag_clear(QUEUE_FLAG_STOPPED, q);
@ -1469,15 +1469,10 @@ static void add_acct_request(struct request_queue *q, struct request *rq,
__elv_add_request(q, rq, where); __elv_add_request(q, rq, where);
} }
static void part_round_stats_single(int cpu, struct hd_struct *part, static void part_round_stats_single(struct request_queue *q, int cpu,
unsigned long now) struct hd_struct *part, unsigned long now,
unsigned int inflight)
{ {
int inflight;
if (now == part->stamp)
return;
inflight = part_in_flight(part);
if (inflight) { if (inflight) {
__part_stat_add(cpu, part, time_in_queue, __part_stat_add(cpu, part, time_in_queue,
inflight * (now - part->stamp)); inflight * (now - part->stamp));
@ -1488,6 +1483,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
/** /**
* part_round_stats() - Round off the performance stats on a struct disk_stats. * part_round_stats() - Round off the performance stats on a struct disk_stats.
* @q: target block queue
* @cpu: cpu number for stats access * @cpu: cpu number for stats access
* @part: target partition * @part: target partition
* *
@ -1502,13 +1498,31 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
* /proc/diskstats. This accounts immediately for all queue usage up to * /proc/diskstats. This accounts immediately for all queue usage up to
* the current jiffies and restarts the counters again. * the current jiffies and restarts the counters again.
*/ */
void part_round_stats(int cpu, struct hd_struct *part) void part_round_stats(struct request_queue *q, int cpu, struct hd_struct *part)
{ {
struct hd_struct *part2 = NULL;
unsigned long now = jiffies; unsigned long now = jiffies;
unsigned int inflight[2];
int stats = 0;
if (part->partno) if (part->stamp != now)
part_round_stats_single(cpu, &part_to_disk(part)->part0, now); stats |= 1;
part_round_stats_single(cpu, part, now);
if (part->partno) {
part2 = &part_to_disk(part)->part0;
if (part2->stamp != now)
stats |= 2;
}
if (!stats)
return;
part_in_flight(q, part, inflight);
if (stats & 2)
part_round_stats_single(q, cpu, part2, now, inflight[1]);
if (stats & 1)
part_round_stats_single(q, cpu, part, now, inflight[0]);
} }
EXPORT_SYMBOL_GPL(part_round_stats); EXPORT_SYMBOL_GPL(part_round_stats);
@ -1896,40 +1910,15 @@ out_unlock:
return BLK_QC_T_NONE; return BLK_QC_T_NONE;
} }
/*
* If bio->bi_dev is a partition, remap the location
*/
static inline void blk_partition_remap(struct bio *bio)
{
struct block_device *bdev = bio->bi_bdev;
/*
* Zone reset does not include bi_size so bio_sectors() is always 0.
* Include a test for the reset op code and perform the remap if needed.
*/
if (bdev != bdev->bd_contains &&
(bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)) {
struct hd_struct *p = bdev->bd_part;
bio->bi_iter.bi_sector += p->start_sect;
bio->bi_bdev = bdev->bd_contains;
trace_block_bio_remap(bdev_get_queue(bio->bi_bdev), bio,
bdev->bd_dev,
bio->bi_iter.bi_sector - p->start_sect);
}
}
static void handle_bad_sector(struct bio *bio) static void handle_bad_sector(struct bio *bio)
{ {
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
printk(KERN_INFO "attempt to access beyond end of device\n"); printk(KERN_INFO "attempt to access beyond end of device\n");
printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n", printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n",
bdevname(bio->bi_bdev, b), bio_devname(bio, b), bio->bi_opf,
bio->bi_opf,
(unsigned long long)bio_end_sector(bio), (unsigned long long)bio_end_sector(bio),
(long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9)); (long long)get_capacity(bio->bi_disk));
} }
#ifdef CONFIG_FAIL_MAKE_REQUEST #ifdef CONFIG_FAIL_MAKE_REQUEST
@ -1967,6 +1956,38 @@ static inline bool should_fail_request(struct hd_struct *part,
#endif /* CONFIG_FAIL_MAKE_REQUEST */ #endif /* CONFIG_FAIL_MAKE_REQUEST */
/*
* Remap block n of partition p to block n+start(p) of the disk.
*/
static inline int blk_partition_remap(struct bio *bio)
{
struct hd_struct *p;
int ret = 0;
/*
* Zone reset does not include bi_size so bio_sectors() is always 0.
* Include a test for the reset op code and perform the remap if needed.
*/
if (!bio->bi_partno ||
(!bio_sectors(bio) && bio_op(bio) != REQ_OP_ZONE_RESET))
return 0;
rcu_read_lock();
p = __disk_get_part(bio->bi_disk, bio->bi_partno);
if (likely(p && !should_fail_request(p, bio->bi_iter.bi_size))) {
bio->bi_iter.bi_sector += p->start_sect;
bio->bi_partno = 0;
trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
bio->bi_iter.bi_sector - p->start_sect);
} else {
printk("%s: fail for partition %d\n", __func__, bio->bi_partno);
ret = -EIO;
}
rcu_read_unlock();
return ret;
}
/* /*
* Check whether this bio extends beyond the end of the device. * Check whether this bio extends beyond the end of the device.
*/ */
@ -1978,7 +1999,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
return 0; return 0;
/* Test device or partition size, when known. */ /* Test device or partition size, when known. */
maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9; maxsector = get_capacity(bio->bi_disk);
if (maxsector) { if (maxsector) {
sector_t sector = bio->bi_iter.bi_sector; sector_t sector = bio->bi_iter.bi_sector;
@ -2003,20 +2024,18 @@ generic_make_request_checks(struct bio *bio)
int nr_sectors = bio_sectors(bio); int nr_sectors = bio_sectors(bio);
blk_status_t status = BLK_STS_IOERR; blk_status_t status = BLK_STS_IOERR;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
struct hd_struct *part;
might_sleep(); might_sleep();
if (bio_check_eod(bio, nr_sectors)) if (bio_check_eod(bio, nr_sectors))
goto end_io; goto end_io;
q = bdev_get_queue(bio->bi_bdev); q = bio->bi_disk->queue;
if (unlikely(!q)) { if (unlikely(!q)) {
printk(KERN_ERR printk(KERN_ERR
"generic_make_request: Trying to access " "generic_make_request: Trying to access "
"nonexistent block-device %s (%Lu)\n", "nonexistent block-device %s (%Lu)\n",
bdevname(bio->bi_bdev, b), bio_devname(bio, b), (long long)bio->bi_iter.bi_sector);
(long long) bio->bi_iter.bi_sector);
goto end_io; goto end_io;
} }
@ -2028,17 +2047,11 @@ generic_make_request_checks(struct bio *bio)
if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_rq_based(q)) if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_rq_based(q))
goto not_supported; goto not_supported;
part = bio->bi_bdev->bd_part; if (should_fail_request(&bio->bi_disk->part0, bio->bi_iter.bi_size))
if (should_fail_request(part, bio->bi_iter.bi_size) ||
should_fail_request(&part_to_disk(part)->part0,
bio->bi_iter.bi_size))
goto end_io; goto end_io;
/* if (blk_partition_remap(bio))
* If this device has partitions, remap block n goto end_io;
* of partition p to block n+start(p) of the disk.
*/
blk_partition_remap(bio);
if (bio_check_eod(bio, nr_sectors)) if (bio_check_eod(bio, nr_sectors))
goto end_io; goto end_io;
@ -2067,16 +2080,16 @@ generic_make_request_checks(struct bio *bio)
goto not_supported; goto not_supported;
break; break;
case REQ_OP_WRITE_SAME: case REQ_OP_WRITE_SAME:
if (!bdev_write_same(bio->bi_bdev)) if (!q->limits.max_write_same_sectors)
goto not_supported; goto not_supported;
break; break;
case REQ_OP_ZONE_REPORT: case REQ_OP_ZONE_REPORT:
case REQ_OP_ZONE_RESET: case REQ_OP_ZONE_RESET:
if (!bdev_is_zoned(bio->bi_bdev)) if (!blk_queue_is_zoned(q))
goto not_supported; goto not_supported;
break; break;
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
if (!bdev_write_zeroes_sectors(bio->bi_bdev)) if (!q->limits.max_write_zeroes_sectors)
goto not_supported; goto not_supported;
break; break;
default: default:
@ -2183,7 +2196,7 @@ blk_qc_t generic_make_request(struct bio *bio)
bio_list_init(&bio_list_on_stack[0]); bio_list_init(&bio_list_on_stack[0]);
current->bio_list = bio_list_on_stack; current->bio_list = bio_list_on_stack;
do { do {
struct request_queue *q = bdev_get_queue(bio->bi_bdev); struct request_queue *q = bio->bi_disk->queue;
if (likely(blk_queue_enter(q, bio->bi_opf & REQ_NOWAIT) == 0)) { if (likely(blk_queue_enter(q, bio->bi_opf & REQ_NOWAIT) == 0)) {
struct bio_list lower, same; struct bio_list lower, same;
@ -2201,7 +2214,7 @@ blk_qc_t generic_make_request(struct bio *bio)
bio_list_init(&lower); bio_list_init(&lower);
bio_list_init(&same); bio_list_init(&same);
while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL) while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL)
if (q == bdev_get_queue(bio->bi_bdev)) if (q == bio->bi_disk->queue)
bio_list_add(&same, bio); bio_list_add(&same, bio);
else else
bio_list_add(&lower, bio); bio_list_add(&lower, bio);
@ -2244,7 +2257,7 @@ blk_qc_t submit_bio(struct bio *bio)
unsigned int count; unsigned int count;
if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME)) if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
count = bdev_logical_block_size(bio->bi_bdev) >> 9; count = queue_logical_block_size(bio->bi_disk->queue);
else else
count = bio_sectors(bio); count = bio_sectors(bio);
@ -2261,8 +2274,7 @@ blk_qc_t submit_bio(struct bio *bio)
current->comm, task_pid_nr(current), current->comm, task_pid_nr(current),
op_is_write(bio_op(bio)) ? "WRITE" : "READ", op_is_write(bio_op(bio)) ? "WRITE" : "READ",
(unsigned long long)bio->bi_iter.bi_sector, (unsigned long long)bio->bi_iter.bi_sector,
bdevname(bio->bi_bdev, b), bio_devname(bio, b), count);
count);
} }
} }
@ -2431,8 +2443,8 @@ void blk_account_io_done(struct request *req)
part_stat_inc(cpu, part, ios[rw]); part_stat_inc(cpu, part, ios[rw]);
part_stat_add(cpu, part, ticks[rw], duration); part_stat_add(cpu, part, ticks[rw], duration);
part_round_stats(cpu, part); part_round_stats(req->q, cpu, part);
part_dec_in_flight(part, rw); part_dec_in_flight(req->q, part, rw);
hd_struct_put(part); hd_struct_put(part);
part_stat_unlock(); part_stat_unlock();
@ -2489,8 +2501,8 @@ void blk_account_io_start(struct request *rq, bool new_io)
part = &rq->rq_disk->part0; part = &rq->rq_disk->part0;
hd_struct_get(part); hd_struct_get(part);
} }
part_round_stats(cpu, part); part_round_stats(rq->q, cpu, part);
part_inc_in_flight(part, rw); part_inc_in_flight(rq->q, part, rw);
rq->part = part; rq->part = part;
} }
@ -2603,7 +2615,7 @@ struct request *blk_peek_request(struct request_queue *q)
} }
EXPORT_SYMBOL(blk_peek_request); EXPORT_SYMBOL(blk_peek_request);
void blk_dequeue_request(struct request *rq) static void blk_dequeue_request(struct request *rq)
{ {
struct request_queue *q = rq->q; struct request_queue *q = rq->q;
@ -2630,9 +2642,6 @@ void blk_dequeue_request(struct request *rq)
* Description: * Description:
* Dequeue @req and start timeout timer on it. This hands off the * Dequeue @req and start timeout timer on it. This hands off the
* request to the driver. * request to the driver.
*
* Block internal functions which don't want to start timer should
* call blk_dequeue_request().
*/ */
void blk_start_request(struct request *req) void blk_start_request(struct request *req)
{ {
@ -3035,8 +3044,8 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
rq->__data_len = bio->bi_iter.bi_size; rq->__data_len = bio->bi_iter.bi_size;
rq->bio = rq->biotail = bio; rq->bio = rq->biotail = bio;
if (bio->bi_bdev) if (bio->bi_disk)
rq->rq_disk = bio->bi_bdev->bd_disk; rq->rq_disk = bio->bi_disk;
} }
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE

View File

@ -1,12 +1,12 @@
/* /*
* Functions to sequence FLUSH and FUA writes. * Functions to sequence PREFLUSH and FUA writes.
* *
* Copyright (C) 2011 Max Planck Institute for Gravitational Physics * Copyright (C) 2011 Max Planck Institute for Gravitational Physics
* Copyright (C) 2011 Tejun Heo <tj@kernel.org> * Copyright (C) 2011 Tejun Heo <tj@kernel.org>
* *
* This file is released under the GPLv2. * This file is released under the GPLv2.
* *
* REQ_{FLUSH|FUA} requests are decomposed to sequences consisted of three * REQ_{PREFLUSH|FUA} requests are decomposed to sequences consisted of three
* optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request * optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request
* properties and hardware capability. * properties and hardware capability.
* *
@ -16,9 +16,9 @@
* REQ_FUA means that the data must be on non-volatile media on request * REQ_FUA means that the data must be on non-volatile media on request
* completion. * completion.
* *
* If the device doesn't have writeback cache, FLUSH and FUA don't make any * If the device doesn't have writeback cache, PREFLUSH and FUA don't make any
* difference. The requests are either completed immediately if there's no * difference. The requests are either completed immediately if there's no data
* data or executed as normal requests otherwise. * or executed as normal requests otherwise.
* *
* If the device has writeback cache and supports FUA, REQ_PREFLUSH is * If the device has writeback cache and supports FUA, REQ_PREFLUSH is
* translated to PREFLUSH but REQ_FUA is passed down directly with DATA. * translated to PREFLUSH but REQ_FUA is passed down directly with DATA.
@ -31,7 +31,7 @@
* fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a * fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a
* REQ_OP_FLUSH is issued and the pending_idx is toggled. When the flush * REQ_OP_FLUSH is issued and the pending_idx is toggled. When the flush
* completes, all the requests which were pending are proceeded to the next * completes, all the requests which were pending are proceeded to the next
* step. This allows arbitrary merging of different types of FLUSH/FUA * step. This allows arbitrary merging of different types of PREFLUSH/FUA
* requests. * requests.
* *
* Currently, the following conditions are used to determine when to issue * Currently, the following conditions are used to determine when to issue
@ -47,19 +47,19 @@
* C3. The second condition is ignored if there is a request which has * C3. The second condition is ignored if there is a request which has
* waited longer than FLUSH_PENDING_TIMEOUT. This is to avoid * waited longer than FLUSH_PENDING_TIMEOUT. This is to avoid
* starvation in the unlikely case where there are continuous stream of * starvation in the unlikely case where there are continuous stream of
* FUA (without FLUSH) requests. * FUA (without PREFLUSH) requests.
* *
* For devices which support FUA, it isn't clear whether C2 (and thus C3) * For devices which support FUA, it isn't clear whether C2 (and thus C3)
* is beneficial. * is beneficial.
* *
* Note that a sequenced FLUSH/FUA request with DATA is completed twice. * Note that a sequenced PREFLUSH/FUA request with DATA is completed twice.
* Once while executing DATA and again after the whole sequence is * Once while executing DATA and again after the whole sequence is
* complete. The first completion updates the contained bio but doesn't * complete. The first completion updates the contained bio but doesn't
* finish it so that the bio submitter is notified only after the whole * finish it so that the bio submitter is notified only after the whole
* sequence is complete. This is implemented by testing RQF_FLUSH_SEQ in * sequence is complete. This is implemented by testing RQF_FLUSH_SEQ in
* req_bio_endio(). * req_bio_endio().
* *
* The above peculiarity requires that each FLUSH/FUA request has only one * The above peculiarity requires that each PREFLUSH/FUA request has only one
* bio attached to it, which is guaranteed as they aren't allowed to be * bio attached to it, which is guaranteed as they aren't allowed to be
* merged in the usual way. * merged in the usual way.
*/ */
@ -76,7 +76,7 @@
#include "blk-mq-tag.h" #include "blk-mq-tag.h"
#include "blk-mq-sched.h" #include "blk-mq-sched.h"
/* FLUSH/FUA sequences */ /* PREFLUSH/FUA sequences */
enum { enum {
REQ_FSEQ_PREFLUSH = (1 << 0), /* pre-flushing in progress */ REQ_FSEQ_PREFLUSH = (1 << 0), /* pre-flushing in progress */
REQ_FSEQ_DATA = (1 << 1), /* data write in progress */ REQ_FSEQ_DATA = (1 << 1), /* data write in progress */
@ -148,7 +148,7 @@ static bool blk_flush_queue_rq(struct request *rq, bool add_front)
/** /**
* blk_flush_complete_seq - complete flush sequence * blk_flush_complete_seq - complete flush sequence
* @rq: FLUSH/FUA request being sequenced * @rq: PREFLUSH/FUA request being sequenced
* @fq: flush queue * @fq: flush queue
* @seq: sequences to complete (mask of %REQ_FSEQ_*, can be zero) * @seq: sequences to complete (mask of %REQ_FSEQ_*, can be zero)
* @error: whether an error occurred * @error: whether an error occurred
@ -406,7 +406,7 @@ static void mq_flush_data_end_io(struct request *rq, blk_status_t error)
} }
/** /**
* blk_insert_flush - insert a new FLUSH/FUA request * blk_insert_flush - insert a new PREFLUSH/FUA request
* @rq: request to insert * @rq: request to insert
* *
* To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions. * To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions.
@ -525,7 +525,7 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
return -ENXIO; return -ENXIO;
bio = bio_alloc(gfp_mask, 0); bio = bio_alloc(gfp_mask, 0);
bio->bi_bdev = bdev; bio_set_dev(bio, bdev);
bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
ret = submit_bio_wait(bio); ret = submit_bio_wait(bio);

View File

@ -77,7 +77,7 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
bio = next_bio(bio, 0, gfp_mask); bio = next_bio(bio, 0, gfp_mask);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = bdev; bio_set_dev(bio, bdev);
bio_set_op_attrs(bio, op, 0); bio_set_op_attrs(bio, op, 0);
bio->bi_iter.bi_size = req_sects << 9; bio->bi_iter.bi_size = req_sects << 9;
@ -168,7 +168,7 @@ static int __blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
while (nr_sects) { while (nr_sects) {
bio = next_bio(bio, 1, gfp_mask); bio = next_bio(bio, 1, gfp_mask);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = bdev; bio_set_dev(bio, bdev);
bio->bi_vcnt = 1; bio->bi_vcnt = 1;
bio->bi_io_vec->bv_page = page; bio->bi_io_vec->bv_page = page;
bio->bi_io_vec->bv_offset = 0; bio->bi_io_vec->bv_offset = 0;
@ -241,7 +241,7 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
while (nr_sects) { while (nr_sects) {
bio = next_bio(bio, 0, gfp_mask); bio = next_bio(bio, 0, gfp_mask);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = bdev; bio_set_dev(bio, bdev);
bio->bi_opf = REQ_OP_WRITE_ZEROES; bio->bi_opf = REQ_OP_WRITE_ZEROES;
if (flags & BLKDEV_ZERO_NOUNMAP) if (flags & BLKDEV_ZERO_NOUNMAP)
bio->bi_opf |= REQ_NOUNMAP; bio->bi_opf |= REQ_NOUNMAP;
@ -323,7 +323,7 @@ int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
bio = next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects), bio = next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects),
gfp_mask); gfp_mask);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = bdev; bio_set_dev(bio, bdev);
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
while (nr_sects != 0) { while (nr_sects != 0) {

View File

@ -633,8 +633,8 @@ static void blk_account_io_merge(struct request *req)
cpu = part_stat_lock(); cpu = part_stat_lock();
part = req->part; part = req->part;
part_round_stats(cpu, part); part_round_stats(req->q, cpu, part);
part_dec_in_flight(part, rq_data_dir(req)); part_dec_in_flight(req->q, part, rq_data_dir(req));
hd_struct_put(part); hd_struct_put(part);
part_stat_unlock(); part_stat_unlock();
@ -786,7 +786,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
return false; return false;
/* must be same device and not a special request */ /* must be same device and not a special request */
if (rq->rq_disk != bio->bi_bdev->bd_disk || req_no_special_merge(rq)) if (rq->rq_disk != bio->bi_disk || req_no_special_merge(rq))
return false; return false;
/* only merge integrity protected bio into ditto rq */ /* only merge integrity protected bio into ditto rq */

View File

@ -48,8 +48,6 @@ static int blk_flags_show(struct seq_file *m, const unsigned long flags,
static const char *const blk_queue_flag_name[] = { static const char *const blk_queue_flag_name[] = {
QUEUE_FLAG_NAME(QUEUED), QUEUE_FLAG_NAME(QUEUED),
QUEUE_FLAG_NAME(STOPPED), QUEUE_FLAG_NAME(STOPPED),
QUEUE_FLAG_NAME(SYNCFULL),
QUEUE_FLAG_NAME(ASYNCFULL),
QUEUE_FLAG_NAME(DYING), QUEUE_FLAG_NAME(DYING),
QUEUE_FLAG_NAME(BYPASS), QUEUE_FLAG_NAME(BYPASS),
QUEUE_FLAG_NAME(BIDI), QUEUE_FLAG_NAME(BIDI),
@ -744,7 +742,7 @@ static int blk_mq_debugfs_release(struct inode *inode, struct file *file)
return seq_release(inode, file); return seq_release(inode, file);
} }
const struct file_operations blk_mq_debugfs_fops = { static const struct file_operations blk_mq_debugfs_fops = {
.open = blk_mq_debugfs_open, .open = blk_mq_debugfs_open,
.read = seq_read, .read = seq_read,
.write = blk_mq_debugfs_write, .write = blk_mq_debugfs_write,

View File

@ -214,7 +214,11 @@ static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
bitnr += tags->nr_reserved_tags; bitnr += tags->nr_reserved_tags;
rq = tags->rqs[bitnr]; rq = tags->rqs[bitnr];
if (rq->q == hctx->queue) /*
* We can hit rq == NULL here, because the tagging functions
* test and set the bit before assining ->rqs[].
*/
if (rq && rq->q == hctx->queue)
iter_data->fn(hctx, rq, iter_data->data, reserved); iter_data->fn(hctx, rq, iter_data->data, reserved);
return true; return true;
} }
@ -248,9 +252,15 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
if (!reserved) if (!reserved)
bitnr += tags->nr_reserved_tags; bitnr += tags->nr_reserved_tags;
rq = tags->rqs[bitnr];
iter_data->fn(rq, iter_data->data, reserved); /*
* We can hit rq == NULL here, because the tagging functions
* test and set the bit before assining ->rqs[].
*/
rq = tags->rqs[bitnr];
if (rq)
iter_data->fn(rq, iter_data->data, reserved);
return true; return true;
} }
@ -288,11 +298,12 @@ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
} }
EXPORT_SYMBOL(blk_mq_tagset_busy_iter); EXPORT_SYMBOL(blk_mq_tagset_busy_iter);
int blk_mq_reinit_tagset(struct blk_mq_tag_set *set) int blk_mq_reinit_tagset(struct blk_mq_tag_set *set,
int (reinit_request)(void *, struct request *))
{ {
int i, j, ret = 0; int i, j, ret = 0;
if (!set->ops->reinit_request) if (WARN_ON_ONCE(!reinit_request))
goto out; goto out;
for (i = 0; i < set->nr_hw_queues; i++) { for (i = 0; i < set->nr_hw_queues; i++) {
@ -305,8 +316,8 @@ int blk_mq_reinit_tagset(struct blk_mq_tag_set *set)
if (!tags->static_rqs[j]) if (!tags->static_rqs[j])
continue; continue;
ret = set->ops->reinit_request(set->driver_data, ret = reinit_request(set->driver_data,
tags->static_rqs[j]); tags->static_rqs[j]);
if (ret) if (ret)
goto out; goto out;
} }

View File

@ -83,6 +83,41 @@ static void blk_mq_hctx_clear_pending(struct blk_mq_hw_ctx *hctx,
sbitmap_clear_bit(&hctx->ctx_map, ctx->index_hw); sbitmap_clear_bit(&hctx->ctx_map, ctx->index_hw);
} }
struct mq_inflight {
struct hd_struct *part;
unsigned int *inflight;
};
static void blk_mq_check_inflight(struct blk_mq_hw_ctx *hctx,
struct request *rq, void *priv,
bool reserved)
{
struct mq_inflight *mi = priv;
if (test_bit(REQ_ATOM_STARTED, &rq->atomic_flags) &&
!test_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags)) {
/*
* index[0] counts the specific partition that was asked
* for. index[1] counts the ones that are active on the
* whole device, so increment that if mi->part is indeed
* a partition, and not a whole device.
*/
if (rq->part == mi->part)
mi->inflight[0]++;
if (mi->part->partno)
mi->inflight[1]++;
}
}
void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
unsigned int inflight[2])
{
struct mq_inflight mi = { .part = part, .inflight = inflight, };
inflight[0] = inflight[1] = 0;
blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi);
}
void blk_freeze_queue_start(struct request_queue *q) void blk_freeze_queue_start(struct request_queue *q)
{ {
int freeze_depth; int freeze_depth;
@ -624,11 +659,10 @@ static void blk_mq_requeue_work(struct work_struct *work)
container_of(work, struct request_queue, requeue_work.work); container_of(work, struct request_queue, requeue_work.work);
LIST_HEAD(rq_list); LIST_HEAD(rq_list);
struct request *rq, *next; struct request *rq, *next;
unsigned long flags;
spin_lock_irqsave(&q->requeue_lock, flags); spin_lock_irq(&q->requeue_lock);
list_splice_init(&q->requeue_list, &rq_list); list_splice_init(&q->requeue_list, &rq_list);
spin_unlock_irqrestore(&q->requeue_lock, flags); spin_unlock_irq(&q->requeue_lock);
list_for_each_entry_safe(rq, next, &rq_list, queuelist) { list_for_each_entry_safe(rq, next, &rq_list, queuelist) {
if (!(rq->rq_flags & RQF_SOFTBARRIER)) if (!(rq->rq_flags & RQF_SOFTBARRIER))
@ -1102,9 +1136,19 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
{ {
int srcu_idx; int srcu_idx;
/*
* We should be running this queue from one of the CPUs that
* are mapped to it.
*/
WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) && WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) &&
cpu_online(hctx->next_cpu)); cpu_online(hctx->next_cpu));
/*
* We can't run the queue inline with ints disabled. Ensure that
* we catch bad users of this early.
*/
WARN_ON_ONCE(in_interrupt());
if (!(hctx->flags & BLK_MQ_F_BLOCKING)) { if (!(hctx->flags & BLK_MQ_F_BLOCKING)) {
rcu_read_lock(); rcu_read_lock();
blk_mq_sched_dispatch_requests(hctx); blk_mq_sched_dispatch_requests(hctx);
@ -1218,7 +1262,7 @@ EXPORT_SYMBOL(blk_mq_queue_stopped);
/* /*
* This function is often used for pausing .queue_rq() by driver when * This function is often used for pausing .queue_rq() by driver when
* there isn't enough resource or some conditions aren't satisfied, and * there isn't enough resource or some conditions aren't satisfied, and
* BLK_MQ_RQ_QUEUE_BUSY is usually returned. * BLK_STS_RESOURCE is usually returned.
* *
* We do not guarantee that dispatch can be drained or blocked * We do not guarantee that dispatch can be drained or blocked
* after blk_mq_stop_hw_queue() returns. Please use * after blk_mq_stop_hw_queue() returns. Please use
@ -1235,7 +1279,7 @@ EXPORT_SYMBOL(blk_mq_stop_hw_queue);
/* /*
* This function is often used for pausing .queue_rq() by driver when * This function is often used for pausing .queue_rq() by driver when
* there isn't enough resource or some conditions aren't satisfied, and * there isn't enough resource or some conditions aren't satisfied, and
* BLK_MQ_RQ_QUEUE_BUSY is usually returned. * BLK_STS_RESOURCE is usually returned.
* *
* We do not guarantee that dispatch can be drained or blocked * We do not guarantee that dispatch can be drained or blocked
* after blk_mq_stop_hw_queues() returns. Please use * after blk_mq_stop_hw_queues() returns. Please use

View File

@ -133,4 +133,7 @@ static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx)
return hctx->nr_ctx && hctx->tags; return hctx->nr_ctx && hctx->tags;
} }
void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
unsigned int inflight[2]);
#endif #endif

View File

@ -68,6 +68,7 @@ EXPORT_SYMBOL_GPL(blk_queue_rq_timeout);
void blk_queue_rq_timed_out(struct request_queue *q, rq_timed_out_fn *fn) void blk_queue_rq_timed_out(struct request_queue *q, rq_timed_out_fn *fn)
{ {
WARN_ON_ONCE(q->mq_ops);
q->rq_timed_out_fn = fn; q->rq_timed_out_fn = fn;
} }
EXPORT_SYMBOL_GPL(blk_queue_rq_timed_out); EXPORT_SYMBOL_GPL(blk_queue_rq_timed_out);

View File

@ -931,7 +931,9 @@ void blk_unregister_queue(struct gendisk *disk)
if (WARN_ON(!q)) if (WARN_ON(!q))
return; return;
mutex_lock(&q->sysfs_lock);
queue_flag_clear_unlocked(QUEUE_FLAG_REGISTERED, q); queue_flag_clear_unlocked(QUEUE_FLAG_REGISTERED, q);
mutex_unlock(&q->sysfs_lock);
wbt_exit(q); wbt_exit(q);

View File

@ -290,7 +290,6 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
*/ */
clear_bit_unlock(tag, bqt->tag_map); clear_bit_unlock(tag, bqt->tag_map);
} }
EXPORT_SYMBOL(blk_queue_end_tag);
/** /**
* blk_queue_start_tag - find a free tag and assign it * blk_queue_start_tag - find a free tag and assign it

View File

@ -373,10 +373,8 @@ static unsigned int tg_iops_limit(struct throtl_grp *tg, int rw)
if (likely(!blk_trace_note_message_enabled(__td->queue))) \ if (likely(!blk_trace_note_message_enabled(__td->queue))) \
break; \ break; \
if ((__tg)) { \ if ((__tg)) { \
char __pbuf[128]; \ blk_add_cgroup_trace_msg(__td->queue, \
\ tg_to_blkg(__tg)->blkcg, "throtl " fmt, ##args);\
blkg_path(tg_to_blkg(__tg), __pbuf, sizeof(__pbuf)); \
blk_add_trace_msg(__td->queue, "throtl %s " fmt, __pbuf, ##args); \
} else { \ } else { \
blk_add_trace_msg(__td->queue, "throtl " fmt, ##args); \ blk_add_trace_msg(__td->queue, "throtl " fmt, ##args); \
} \ } \
@ -2114,14 +2112,9 @@ static inline void throtl_update_latency_buckets(struct throtl_data *td)
static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio) static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio)
{ {
#ifdef CONFIG_BLK_DEV_THROTTLING_LOW #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
int ret; if (bio->bi_css)
ret = bio_associate_current(bio);
if (ret == 0 || ret == -EBUSY)
bio->bi_cg_private = tg; bio->bi_cg_private = tg;
blk_stat_set_issue(&bio->bi_issue_stat, bio_sectors(bio)); blk_stat_set_issue(&bio->bi_issue_stat, bio_sectors(bio));
#else
bio_associate_current(bio);
#endif #endif
} }

View File

@ -116,7 +116,7 @@ int blkdev_report_zones(struct block_device *bdev,
if (!bio) if (!bio)
return -ENOMEM; return -ENOMEM;
bio->bi_bdev = bdev; bio_set_dev(bio, bdev);
bio->bi_iter.bi_sector = blk_zone_start(q, sector); bio->bi_iter.bi_sector = blk_zone_start(q, sector);
bio_set_op_attrs(bio, REQ_OP_ZONE_REPORT, 0); bio_set_op_attrs(bio, REQ_OP_ZONE_REPORT, 0);
@ -234,7 +234,7 @@ int blkdev_reset_zones(struct block_device *bdev,
bio = bio_alloc(gfp_mask, 0); bio = bio_alloc(gfp_mask, 0);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = bdev; bio_set_dev(bio, bdev);
bio_set_op_attrs(bio, REQ_OP_ZONE_RESET, 0); bio_set_op_attrs(bio, REQ_OP_ZONE_RESET, 0);
ret = submit_bio_wait(bio); ret = submit_bio_wait(bio);

View File

@ -64,7 +64,6 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
struct bio *bio); struct bio *bio);
void blk_queue_bypass_start(struct request_queue *q); void blk_queue_bypass_start(struct request_queue *q);
void blk_queue_bypass_end(struct request_queue *q); void blk_queue_bypass_end(struct request_queue *q);
void blk_dequeue_request(struct request *rq);
void __blk_queue_free_tags(struct request_queue *q); void __blk_queue_free_tags(struct request_queue *q);
void blk_freeze_queue(struct request_queue *q); void blk_freeze_queue(struct request_queue *q);
@ -204,6 +203,8 @@ static inline void elv_deactivate_rq(struct request_queue *q, struct request *rq
e->type->ops.sq.elevator_deactivate_req_fn(q, rq); e->type->ops.sq.elevator_deactivate_req_fn(q, rq);
} }
struct hd_struct *__disk_get_part(struct gendisk *disk, int partno);
#ifdef CONFIG_FAIL_IO_TIMEOUT #ifdef CONFIG_FAIL_IO_TIMEOUT
int blk_should_fake_timeout(struct request_queue *); int blk_should_fake_timeout(struct request_queue *);
ssize_t part_timeout_show(struct device *, struct device_attribute *, char *); ssize_t part_timeout_show(struct device *, struct device_attribute *, char *);

View File

@ -932,15 +932,8 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret; return ret;
} }
/*
* block device ioctls
*/
default: default:
#if 0
return ioctl_by_bdev(bd->bdev, cmd, arg);
#else
return -ENOTTY; return -ENOTTY;
#endif
} }
} }

View File

@ -656,20 +656,17 @@ static inline void cfqg_put(struct cfq_group *cfqg)
} }
#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) do { \ #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) do { \
char __pbuf[128]; \ blk_add_cgroup_trace_msg((cfqd)->queue, \
\ cfqg_to_blkg((cfqq)->cfqg)->blkcg, \
blkg_path(cfqg_to_blkg((cfqq)->cfqg), __pbuf, sizeof(__pbuf)); \ "cfq%d%c%c " fmt, (cfqq)->pid, \
blk_add_trace_msg((cfqd)->queue, "cfq%d%c%c %s " fmt, (cfqq)->pid, \
cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \ cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \
cfqq_type((cfqq)) == SYNC_NOIDLE_WORKLOAD ? 'N' : ' ',\ cfqq_type((cfqq)) == SYNC_NOIDLE_WORKLOAD ? 'N' : ' ',\
__pbuf, ##args); \ ##args); \
} while (0) } while (0)
#define cfq_log_cfqg(cfqd, cfqg, fmt, args...) do { \ #define cfq_log_cfqg(cfqd, cfqg, fmt, args...) do { \
char __pbuf[128]; \ blk_add_cgroup_trace_msg((cfqd)->queue, \
\ cfqg_to_blkg(cfqg)->blkcg, fmt, ##args); \
blkg_path(cfqg_to_blkg(cfqg), __pbuf, sizeof(__pbuf)); \
blk_add_trace_msg((cfqd)->queue, "%s " fmt, __pbuf, ##args); \
} while (0) } while (0)
static inline void cfqg_stats_update_io_add(struct cfq_group *cfqg, static inline void cfqg_stats_update_io_add(struct cfq_group *cfqg,
@ -2937,7 +2934,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
* for devices that support queuing, otherwise we still have a problem * for devices that support queuing, otherwise we still have a problem
* with sync vs async workloads. * with sync vs async workloads.
*/ */
if (blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag) if (blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag &&
!cfqd->cfq_group_idle)
return; return;
WARN_ON(!RB_EMPTY_ROOT(&cfqq->sort_list)); WARN_ON(!RB_EMPTY_ROOT(&cfqq->sort_list));
@ -4714,13 +4712,12 @@ cfq_var_show(unsigned int var, char *page)
return sprintf(page, "%u\n", var); return sprintf(page, "%u\n", var);
} }
static ssize_t static void
cfq_var_store(unsigned int *var, const char *page, size_t count) cfq_var_store(unsigned int *var, const char *page)
{ {
char *p = (char *) page; char *p = (char *) page;
*var = simple_strtoul(p, &p, 10); *var = simple_strtoul(p, &p, 10);
return count;
} }
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ #define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
@ -4766,7 +4763,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
{ \ { \
struct cfq_data *cfqd = e->elevator_data; \ struct cfq_data *cfqd = e->elevator_data; \
unsigned int __data; \ unsigned int __data; \
int ret = cfq_var_store(&__data, (page), count); \ cfq_var_store(&__data, (page)); \
if (__data < (MIN)) \ if (__data < (MIN)) \
__data = (MIN); \ __data = (MIN); \
else if (__data > (MAX)) \ else if (__data > (MAX)) \
@ -4775,7 +4772,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
*(__PTR) = (u64)__data * NSEC_PER_MSEC; \ *(__PTR) = (u64)__data * NSEC_PER_MSEC; \
else \ else \
*(__PTR) = __data; \ *(__PTR) = __data; \
return ret; \ return count; \
} }
STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0); STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0);
STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1, STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1,
@ -4800,13 +4797,13 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
{ \ { \
struct cfq_data *cfqd = e->elevator_data; \ struct cfq_data *cfqd = e->elevator_data; \
unsigned int __data; \ unsigned int __data; \
int ret = cfq_var_store(&__data, (page), count); \ cfq_var_store(&__data, (page)); \
if (__data < (MIN)) \ if (__data < (MIN)) \
__data = (MIN); \ __data = (MIN); \
else if (__data > (MAX)) \ else if (__data > (MAX)) \
__data = (MAX); \ __data = (MAX); \
*(__PTR) = (u64)__data * NSEC_PER_USEC; \ *(__PTR) = (u64)__data * NSEC_PER_USEC; \
return ret; \ return count; \
} }
USEC_STORE_FUNCTION(cfq_slice_idle_us_store, &cfqd->cfq_slice_idle, 0, UINT_MAX); USEC_STORE_FUNCTION(cfq_slice_idle_us_store, &cfqd->cfq_slice_idle, 0, UINT_MAX);
USEC_STORE_FUNCTION(cfq_group_idle_us_store, &cfqd->cfq_group_idle, 0, UINT_MAX); USEC_STORE_FUNCTION(cfq_group_idle_us_store, &cfqd->cfq_group_idle, 0, UINT_MAX);

View File

@ -373,13 +373,12 @@ deadline_var_show(int var, char *page)
return sprintf(page, "%d\n", var); return sprintf(page, "%d\n", var);
} }
static ssize_t static void
deadline_var_store(int *var, const char *page, size_t count) deadline_var_store(int *var, const char *page)
{ {
char *p = (char *) page; char *p = (char *) page;
*var = simple_strtol(p, &p, 10); *var = simple_strtol(p, &p, 10);
return count;
} }
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ #define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
@ -403,7 +402,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
{ \ { \
struct deadline_data *dd = e->elevator_data; \ struct deadline_data *dd = e->elevator_data; \
int __data; \ int __data; \
int ret = deadline_var_store(&__data, (page), count); \ deadline_var_store(&__data, (page)); \
if (__data < (MIN)) \ if (__data < (MIN)) \
__data = (MIN); \ __data = (MIN); \
else if (__data > (MAX)) \ else if (__data > (MAX)) \
@ -412,7 +411,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
*(__PTR) = msecs_to_jiffies(__data); \ *(__PTR) = msecs_to_jiffies(__data); \
else \ else \
*(__PTR) = __data; \ *(__PTR) = __data; \
return ret; \ return count; \
} }
STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1); STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1); STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);

View File

@ -1055,6 +1055,10 @@ static int __elevator_change(struct request_queue *q, const char *name)
char elevator_name[ELV_NAME_MAX]; char elevator_name[ELV_NAME_MAX];
struct elevator_type *e; struct elevator_type *e;
/* Make sure queue is not in the middle of being removed */
if (!test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags))
return -ENOENT;
/* /*
* Special case for mq, turn off scheduling * Special case for mq, turn off scheduling
*/ */

View File

@ -45,6 +45,52 @@ static void disk_add_events(struct gendisk *disk);
static void disk_del_events(struct gendisk *disk); static void disk_del_events(struct gendisk *disk);
static void disk_release_events(struct gendisk *disk); static void disk_release_events(struct gendisk *disk);
void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
{
if (q->mq_ops)
return;
atomic_inc(&part->in_flight[rw]);
if (part->partno)
atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
}
void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
{
if (q->mq_ops)
return;
atomic_dec(&part->in_flight[rw]);
if (part->partno)
atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
}
void part_in_flight(struct request_queue *q, struct hd_struct *part,
unsigned int inflight[2])
{
if (q->mq_ops) {
blk_mq_in_flight(q, part, inflight);
return;
}
inflight[0] = atomic_read(&part->in_flight[0]) +
atomic_read(&part->in_flight[1]);
if (part->partno) {
part = &part_to_disk(part)->part0;
inflight[1] = atomic_read(&part->in_flight[0]) +
atomic_read(&part->in_flight[1]);
}
}
struct hd_struct *__disk_get_part(struct gendisk *disk, int partno)
{
struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl);
if (unlikely(partno < 0 || partno >= ptbl->len))
return NULL;
return rcu_dereference(ptbl->part[partno]);
}
/** /**
* disk_get_part - get partition * disk_get_part - get partition
* @disk: disk to look partition from * @disk: disk to look partition from
@ -61,21 +107,12 @@ static void disk_release_events(struct gendisk *disk);
*/ */
struct hd_struct *disk_get_part(struct gendisk *disk, int partno) struct hd_struct *disk_get_part(struct gendisk *disk, int partno)
{ {
struct hd_struct *part = NULL; struct hd_struct *part;
struct disk_part_tbl *ptbl;
if (unlikely(partno < 0))
return NULL;
rcu_read_lock(); rcu_read_lock();
part = __disk_get_part(disk, partno);
ptbl = rcu_dereference(disk->part_tbl); if (part)
if (likely(partno < ptbl->len)) { get_device(part_to_dev(part));
part = rcu_dereference(ptbl->part[partno]);
if (part)
get_device(part_to_dev(part));
}
rcu_read_unlock(); rcu_read_unlock();
return part; return part;
@ -1098,12 +1135,13 @@ static const struct attribute_group *disk_attr_groups[] = {
* original ptbl is freed using RCU callback. * original ptbl is freed using RCU callback.
* *
* LOCKING: * LOCKING:
* Matching bd_mutx locked. * Matching bd_mutex locked or the caller is the only user of @disk.
*/ */
static void disk_replace_part_tbl(struct gendisk *disk, static void disk_replace_part_tbl(struct gendisk *disk,
struct disk_part_tbl *new_ptbl) struct disk_part_tbl *new_ptbl)
{ {
struct disk_part_tbl *old_ptbl = disk->part_tbl; struct disk_part_tbl *old_ptbl =
rcu_dereference_protected(disk->part_tbl, 1);
rcu_assign_pointer(disk->part_tbl, new_ptbl); rcu_assign_pointer(disk->part_tbl, new_ptbl);
@ -1122,14 +1160,16 @@ static void disk_replace_part_tbl(struct gendisk *disk,
* uses RCU to allow unlocked dereferencing for stats and other stuff. * uses RCU to allow unlocked dereferencing for stats and other stuff.
* *
* LOCKING: * LOCKING:
* Matching bd_mutex locked, might sleep. * Matching bd_mutex locked or the caller is the only user of @disk.
* Might sleep.
* *
* RETURNS: * RETURNS:
* 0 on success, -errno on failure. * 0 on success, -errno on failure.
*/ */
int disk_expand_part_tbl(struct gendisk *disk, int partno) int disk_expand_part_tbl(struct gendisk *disk, int partno)
{ {
struct disk_part_tbl *old_ptbl = disk->part_tbl; struct disk_part_tbl *old_ptbl =
rcu_dereference_protected(disk->part_tbl, 1);
struct disk_part_tbl *new_ptbl; struct disk_part_tbl *new_ptbl;
int len = old_ptbl ? old_ptbl->len : 0; int len = old_ptbl ? old_ptbl->len : 0;
int i, target; int i, target;
@ -1212,6 +1252,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
struct disk_part_iter piter; struct disk_part_iter piter;
struct hd_struct *hd; struct hd_struct *hd;
char buf[BDEVNAME_SIZE]; char buf[BDEVNAME_SIZE];
unsigned int inflight[2];
int cpu; int cpu;
/* /*
@ -1225,8 +1266,9 @@ static int diskstats_show(struct seq_file *seqf, void *v)
disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0); disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0);
while ((hd = disk_part_iter_next(&piter))) { while ((hd = disk_part_iter_next(&piter))) {
cpu = part_stat_lock(); cpu = part_stat_lock();
part_round_stats(cpu, hd); part_round_stats(gp->queue, cpu, hd);
part_stat_unlock(); part_stat_unlock();
part_in_flight(gp->queue, hd, inflight);
seq_printf(seqf, "%4d %7d %s %lu %lu %lu " seq_printf(seqf, "%4d %7d %s %lu %lu %lu "
"%u %lu %lu %lu %u %u %u %u\n", "%u %lu %lu %lu %u %u %u %u\n",
MAJOR(part_devt(hd)), MINOR(part_devt(hd)), MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
@ -1239,7 +1281,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
part_stat_read(hd, merges[WRITE]), part_stat_read(hd, merges[WRITE]),
part_stat_read(hd, sectors[WRITE]), part_stat_read(hd, sectors[WRITE]),
jiffies_to_msecs(part_stat_read(hd, ticks[WRITE])), jiffies_to_msecs(part_stat_read(hd, ticks[WRITE])),
part_in_flight(hd), inflight[0],
jiffies_to_msecs(part_stat_read(hd, io_ticks)), jiffies_to_msecs(part_stat_read(hd, io_ticks)),
jiffies_to_msecs(part_stat_read(hd, time_in_queue)) jiffies_to_msecs(part_stat_read(hd, time_in_queue))
); );
@ -1321,6 +1363,14 @@ EXPORT_SYMBOL(alloc_disk);
struct gendisk *alloc_disk_node(int minors, int node_id) struct gendisk *alloc_disk_node(int minors, int node_id)
{ {
struct gendisk *disk; struct gendisk *disk;
struct disk_part_tbl *ptbl;
if (minors > DISK_MAX_PARTS) {
printk(KERN_ERR
"block: can't allocated more than %d partitions\n",
DISK_MAX_PARTS);
minors = DISK_MAX_PARTS;
}
disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id); disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
if (disk) { if (disk) {
@ -1334,7 +1384,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
kfree(disk); kfree(disk);
return NULL; return NULL;
} }
disk->part_tbl->part[0] = &disk->part0; ptbl = rcu_dereference_protected(disk->part_tbl, 1);
rcu_assign_pointer(ptbl->part[0], &disk->part0);
/* /*
* set_capacity() and get_capacity() currently don't use * set_capacity() and get_capacity() currently don't use

View File

@ -457,13 +457,12 @@ deadline_var_show(int var, char *page)
return sprintf(page, "%d\n", var); return sprintf(page, "%d\n", var);
} }
static ssize_t static void
deadline_var_store(int *var, const char *page, size_t count) deadline_var_store(int *var, const char *page)
{ {
char *p = (char *) page; char *p = (char *) page;
*var = simple_strtol(p, &p, 10); *var = simple_strtol(p, &p, 10);
return count;
} }
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ #define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
@ -487,7 +486,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
{ \ { \
struct deadline_data *dd = e->elevator_data; \ struct deadline_data *dd = e->elevator_data; \
int __data; \ int __data; \
int ret = deadline_var_store(&__data, (page), count); \ deadline_var_store(&__data, (page)); \
if (__data < (MIN)) \ if (__data < (MIN)) \
__data = (MIN); \ __data = (MIN); \
else if (__data > (MAX)) \ else if (__data > (MAX)) \
@ -496,7 +495,7 @@ static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)
*(__PTR) = msecs_to_jiffies(__data); \ *(__PTR) = msecs_to_jiffies(__data); \
else \ else \
*(__PTR) = __data; \ *(__PTR) = __data; \
return ret; \ return count; \
} }
STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1); STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1); STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);
@ -660,6 +659,7 @@ static struct elevator_type mq_deadline = {
.elevator_name = "mq-deadline", .elevator_name = "mq-deadline",
.elevator_owner = THIS_MODULE, .elevator_owner = THIS_MODULE,
}; };
MODULE_ALIAS("mq-deadline-iosched");
static int __init deadline_init(void) static int __init deadline_init(void)
{ {

View File

@ -112,11 +112,14 @@ ssize_t part_stat_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct hd_struct *p = dev_to_part(dev); struct hd_struct *p = dev_to_part(dev);
struct request_queue *q = dev_to_disk(dev)->queue;
unsigned int inflight[2];
int cpu; int cpu;
cpu = part_stat_lock(); cpu = part_stat_lock();
part_round_stats(cpu, p); part_round_stats(q, cpu, p);
part_stat_unlock(); part_stat_unlock();
part_in_flight(q, p, inflight);
return sprintf(buf, return sprintf(buf,
"%8lu %8lu %8llu %8u " "%8lu %8lu %8llu %8u "
"%8lu %8lu %8llu %8u " "%8lu %8lu %8llu %8u "
@ -130,7 +133,7 @@ ssize_t part_stat_show(struct device *dev,
part_stat_read(p, merges[WRITE]), part_stat_read(p, merges[WRITE]),
(unsigned long long)part_stat_read(p, sectors[WRITE]), (unsigned long long)part_stat_read(p, sectors[WRITE]),
jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
part_in_flight(p), inflight[0],
jiffies_to_msecs(part_stat_read(p, io_ticks)), jiffies_to_msecs(part_stat_read(p, io_ticks)),
jiffies_to_msecs(part_stat_read(p, time_in_queue))); jiffies_to_msecs(part_stat_read(p, time_in_queue)));
} }
@ -249,15 +252,20 @@ void __delete_partition(struct percpu_ref *ref)
call_rcu(&part->rcu_head, delete_partition_rcu_cb); call_rcu(&part->rcu_head, delete_partition_rcu_cb);
} }
/*
* Must be called either with bd_mutex held, before a disk can be opened or
* after all disk users are gone.
*/
void delete_partition(struct gendisk *disk, int partno) void delete_partition(struct gendisk *disk, int partno)
{ {
struct disk_part_tbl *ptbl = disk->part_tbl; struct disk_part_tbl *ptbl =
rcu_dereference_protected(disk->part_tbl, 1);
struct hd_struct *part; struct hd_struct *part;
if (partno >= ptbl->len) if (partno >= ptbl->len)
return; return;
part = ptbl->part[partno]; part = rcu_dereference_protected(ptbl->part[partno], 1);
if (!part) if (!part)
return; return;
@ -277,6 +285,10 @@ static ssize_t whole_disk_show(struct device *dev,
static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH, static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH,
whole_disk_show, NULL); whole_disk_show, NULL);
/*
* Must be called either with bd_mutex held, before a disk can be opened or
* after all disk users are gone.
*/
struct hd_struct *add_partition(struct gendisk *disk, int partno, struct hd_struct *add_partition(struct gendisk *disk, int partno,
sector_t start, sector_t len, int flags, sector_t start, sector_t len, int flags,
struct partition_meta_info *info) struct partition_meta_info *info)
@ -292,7 +304,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
err = disk_expand_part_tbl(disk, partno); err = disk_expand_part_tbl(disk, partno);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
ptbl = disk->part_tbl; ptbl = rcu_dereference_protected(disk->part_tbl, 1);
if (ptbl->part[partno]) if (ptbl->part[partno])
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
@ -391,7 +403,6 @@ out_del:
device_del(pdev); device_del(pdev);
out_put: out_put:
put_device(pdev); put_device(pdev);
blk_free_devt(devt);
return ERR_PTR(err); return ERR_PTR(err);
} }

View File

@ -1678,9 +1678,12 @@ static bool DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
Enquiry2->FirmwareID.FirmwareType = '0'; Enquiry2->FirmwareID.FirmwareType = '0';
Enquiry2->FirmwareID.TurnID = 0; Enquiry2->FirmwareID.TurnID = 0;
} }
sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d", snprintf(Controller->FirmwareVersion, sizeof(Controller->FirmwareVersion),
Enquiry2->FirmwareID.MajorVersion, Enquiry2->FirmwareID.MinorVersion, "%d.%02d-%c-%02d",
Enquiry2->FirmwareID.FirmwareType, Enquiry2->FirmwareID.TurnID); Enquiry2->FirmwareID.MajorVersion,
Enquiry2->FirmwareID.MinorVersion,
Enquiry2->FirmwareID.FirmwareType,
Enquiry2->FirmwareID.TurnID);
if (!((Controller->FirmwareVersion[0] == '5' && if (!((Controller->FirmwareVersion[0] == '5' &&
strcmp(Controller->FirmwareVersion, "5.06") >= 0) || strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
(Controller->FirmwareVersion[0] == '4' && (Controller->FirmwareVersion[0] == '4' &&
@ -6588,7 +6591,8 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
&dac960_proc_fops); &dac960_proc_fops);
} }
sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); snprintf(Controller->ControllerName, sizeof(Controller->ControllerName),
"c%d", Controller->ControllerNumber);
ControllerProcEntry = proc_mkdir(Controller->ControllerName, ControllerProcEntry = proc_mkdir(Controller->ControllerName,
DAC960_ProcDirectoryEntry); DAC960_ProcDirectoryEntry);
proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller);

View File

@ -17,6 +17,7 @@ if BLK_DEV
config BLK_DEV_NULL_BLK config BLK_DEV_NULL_BLK
tristate "Null test block driver" tristate "Null test block driver"
depends on CONFIGFS_FS
config BLK_DEV_FD config BLK_DEV_FD
tristate "Normal floppy disk support" tristate "Normal floppy disk support"

View File

@ -294,14 +294,13 @@ out:
static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio) static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio)
{ {
struct block_device *bdev = bio->bi_bdev; struct brd_device *brd = bio->bi_disk->private_data;
struct brd_device *brd = bdev->bd_disk->private_data;
struct bio_vec bvec; struct bio_vec bvec;
sector_t sector; sector_t sector;
struct bvec_iter iter; struct bvec_iter iter;
sector = bio->bi_iter.bi_sector; sector = bio->bi_iter.bi_sector;
if (bio_end_sector(bio) > get_capacity(bdev->bd_disk)) if (bio_end_sector(bio) > get_capacity(bio->bi_disk))
goto io_error; goto io_error;
bio_for_each_segment(bvec, bio, iter) { bio_for_each_segment(bvec, bio, iter) {

View File

@ -151,7 +151,7 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
op_flags |= REQ_SYNC; op_flags |= REQ_SYNC;
bio = bio_alloc_drbd(GFP_NOIO); bio = bio_alloc_drbd(GFP_NOIO);
bio->bi_bdev = bdev->md_bdev; bio_set_dev(bio, bdev->md_bdev);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
err = -EIO; err = -EIO;
if (bio_add_page(bio, device->md_io.page, size, 0) != size) if (bio_add_page(bio, device->md_io.page, size, 0) != size)

View File

@ -1019,7 +1019,7 @@ static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_ho
bm_store_page_idx(page, page_nr); bm_store_page_idx(page, page_nr);
} else } else
page = b->bm_pages[page_nr]; page = b->bm_pages[page_nr];
bio->bi_bdev = device->ldev->md_bdev; bio_set_dev(bio, device->ldev->md_bdev);
bio->bi_iter.bi_sector = on_disk_sector; bio->bi_iter.bi_sector = on_disk_sector;
/* bio_add_page of a single page to an empty bio will always succeed, /* bio_add_page of a single page to an empty bio will always succeed,
* according to api. Do we want to assert that? */ * according to api. Do we want to assert that? */

View File

@ -63,19 +63,15 @@
# define __must_hold(x) # define __must_hold(x)
#endif #endif
/* module parameter, defined in drbd_main.c */ /* shared module parameters, defined in drbd_main.c */
extern unsigned int minor_count;
extern bool disable_sendpage;
extern bool allow_oos;
void tl_abort_disk_io(struct drbd_device *device);
#ifdef CONFIG_DRBD_FAULT_INJECTION #ifdef CONFIG_DRBD_FAULT_INJECTION
extern int enable_faults; extern int drbd_enable_faults;
extern int fault_rate; extern int drbd_fault_rate;
extern int fault_devs;
#endif #endif
extern char usermode_helper[]; extern unsigned int drbd_minor_count;
extern char drbd_usermode_helper[];
extern int drbd_proc_details;
/* This is used to stop/restart our threads. /* This is used to stop/restart our threads.
@ -181,8 +177,8 @@ _drbd_insert_fault(struct drbd_device *device, unsigned int type);
static inline int static inline int
drbd_insert_fault(struct drbd_device *device, unsigned int type) { drbd_insert_fault(struct drbd_device *device, unsigned int type) {
#ifdef CONFIG_DRBD_FAULT_INJECTION #ifdef CONFIG_DRBD_FAULT_INJECTION
return fault_rate && return drbd_fault_rate &&
(enable_faults & (1<<type)) && (drbd_enable_faults & (1<<type)) &&
_drbd_insert_fault(device, type); _drbd_insert_fault(device, type);
#else #else
return 0; return 0;
@ -745,6 +741,8 @@ struct drbd_connection {
unsigned current_tle_writes; /* writes seen within this tl epoch */ unsigned current_tle_writes; /* writes seen within this tl epoch */
unsigned long last_reconnect_jif; unsigned long last_reconnect_jif;
/* empty member on older kernels without blk_start_plug() */
struct blk_plug receiver_plug;
struct drbd_thread receiver; struct drbd_thread receiver;
struct drbd_thread worker; struct drbd_thread worker;
struct drbd_thread ack_receiver; struct drbd_thread ack_receiver;
@ -1131,7 +1129,8 @@ extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_sta
extern int drbd_send_rs_deallocated(struct drbd_peer_device *, struct drbd_peer_request *); extern int drbd_send_rs_deallocated(struct drbd_peer_device *, struct drbd_peer_request *);
extern void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev); extern void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev);
extern void drbd_device_cleanup(struct drbd_device *device); extern void drbd_device_cleanup(struct drbd_device *device);
void drbd_print_uuids(struct drbd_device *device, const char *text); extern void drbd_print_uuids(struct drbd_device *device, const char *text);
extern void drbd_queue_unplug(struct drbd_device *device);
extern void conn_md_sync(struct drbd_connection *connection); extern void conn_md_sync(struct drbd_connection *connection);
extern void drbd_md_write(struct drbd_device *device, void *buffer); extern void drbd_md_write(struct drbd_device *device, void *buffer);
@ -1463,8 +1462,6 @@ extern struct drbd_resource *drbd_find_resource(const char *name);
extern void drbd_destroy_resource(struct kref *kref); extern void drbd_destroy_resource(struct kref *kref);
extern void conn_free_crypto(struct drbd_connection *connection); extern void conn_free_crypto(struct drbd_connection *connection);
extern int proc_details;
/* drbd_req */ /* drbd_req */
extern void do_submit(struct work_struct *ws); extern void do_submit(struct work_struct *ws);
extern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long); extern void __drbd_make_request(struct drbd_device *, struct bio *, unsigned long);
@ -1628,8 +1625,8 @@ static inline void drbd_generic_make_request(struct drbd_device *device,
int fault_type, struct bio *bio) int fault_type, struct bio *bio)
{ {
__release(local); __release(local);
if (!bio->bi_bdev) { if (!bio->bi_disk) {
drbd_err(device, "drbd_generic_make_request: bio->bi_bdev == NULL\n"); drbd_err(device, "drbd_generic_make_request: bio->bi_disk == NULL\n");
bio->bi_status = BLK_STS_IOERR; bio->bi_status = BLK_STS_IOERR;
bio_endio(bio); bio_endio(bio);
return; return;

View File

@ -77,41 +77,41 @@ MODULE_PARM_DESC(minor_count, "Approximate number of drbd devices ("
MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR); MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR);
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
/* allow_open_on_secondary */
MODULE_PARM_DESC(allow_oos, "DONT USE!");
/* thanks to these macros, if compiled into the kernel (not-module), /* thanks to these macros, if compiled into the kernel (not-module),
* this becomes the boot parameter drbd.minor_count */ * these become boot parameters (e.g., drbd.minor_count) */
module_param(minor_count, uint, 0444);
module_param(disable_sendpage, bool, 0644);
module_param(allow_oos, bool, 0);
module_param(proc_details, int, 0644);
#ifdef CONFIG_DRBD_FAULT_INJECTION #ifdef CONFIG_DRBD_FAULT_INJECTION
int enable_faults; int drbd_enable_faults;
int fault_rate; int drbd_fault_rate;
static int fault_count; static int drbd_fault_count;
int fault_devs; static int drbd_fault_devs;
/* bitmap of enabled faults */ /* bitmap of enabled faults */
module_param(enable_faults, int, 0664); module_param_named(enable_faults, drbd_enable_faults, int, 0664);
/* fault rate % value - applies to all enabled faults */ /* fault rate % value - applies to all enabled faults */
module_param(fault_rate, int, 0664); module_param_named(fault_rate, drbd_fault_rate, int, 0664);
/* count of faults inserted */ /* count of faults inserted */
module_param(fault_count, int, 0664); module_param_named(fault_count, drbd_fault_count, int, 0664);
/* bitmap of devices to insert faults on */ /* bitmap of devices to insert faults on */
module_param(fault_devs, int, 0644); module_param_named(fault_devs, drbd_fault_devs, int, 0644);
#endif #endif
/* module parameter, defined */ /* module parameters we can keep static */
unsigned int minor_count = DRBD_MINOR_COUNT_DEF; static bool drbd_allow_oos; /* allow_open_on_secondary */
bool disable_sendpage; static bool drbd_disable_sendpage;
bool allow_oos; MODULE_PARM_DESC(allow_oos, "DONT USE!");
int proc_details; /* Detail level in proc drbd*/ module_param_named(allow_oos, drbd_allow_oos, bool, 0);
module_param_named(disable_sendpage, drbd_disable_sendpage, bool, 0644);
/* module parameters we share */
int drbd_proc_details; /* Detail level in proc drbd*/
module_param_named(proc_details, drbd_proc_details, int, 0644);
/* module parameters shared with defaults */
unsigned int drbd_minor_count = DRBD_MINOR_COUNT_DEF;
/* Module parameter for setting the user mode helper program /* Module parameter for setting the user mode helper program
* to run. Default is /sbin/drbdadm */ * to run. Default is /sbin/drbdadm */
char usermode_helper[80] = "/sbin/drbdadm"; char drbd_usermode_helper[80] = "/sbin/drbdadm";
module_param_named(minor_count, drbd_minor_count, uint, 0444);
module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644); module_param_string(usermode_helper, drbd_usermode_helper, sizeof(drbd_usermode_helper), 0644);
/* in 2.6.x, our device mapping and config info contains our virtual gendisks /* in 2.6.x, our device mapping and config info contains our virtual gendisks
* as member "struct gendisk *vdisk;" * as member "struct gendisk *vdisk;"
@ -923,7 +923,9 @@ void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *peer_device)
} }
/* communicated if (agreed_features & DRBD_FF_WSAME) */ /* communicated if (agreed_features & DRBD_FF_WSAME) */
void assign_p_sizes_qlim(struct drbd_device *device, struct p_sizes *p, struct request_queue *q) static void
assign_p_sizes_qlim(struct drbd_device *device, struct p_sizes *p,
struct request_queue *q)
{ {
if (q) { if (q) {
p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q)); p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q));
@ -1560,7 +1562,7 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
* put_page(); and would cause either a VM_BUG directly, or * put_page(); and would cause either a VM_BUG directly, or
* __page_cache_release a page that would actually still be referenced * __page_cache_release a page that would actually still be referenced
* by someone, leading to some obscure delayed Oops somewhere else. */ * by someone, leading to some obscure delayed Oops somewhere else. */
if (disable_sendpage || (page_count(page) < 1) || PageSlab(page)) if (drbd_disable_sendpage || (page_count(page) < 1) || PageSlab(page))
return _drbd_no_send_page(peer_device, page, offset, size, msg_flags); return _drbd_no_send_page(peer_device, page, offset, size, msg_flags);
msg_flags |= MSG_NOSIGNAL; msg_flags |= MSG_NOSIGNAL;
@ -1932,7 +1934,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
if (device->state.role != R_PRIMARY) { if (device->state.role != R_PRIMARY) {
if (mode & FMODE_WRITE) if (mode & FMODE_WRITE)
rv = -EROFS; rv = -EROFS;
else if (!allow_oos) else if (!drbd_allow_oos)
rv = -EMEDIUMTYPE; rv = -EMEDIUMTYPE;
} }
@ -1952,6 +1954,19 @@ static void drbd_release(struct gendisk *gd, fmode_t mode)
mutex_unlock(&drbd_main_mutex); mutex_unlock(&drbd_main_mutex);
} }
/* need to hold resource->req_lock */
void drbd_queue_unplug(struct drbd_device *device)
{
if (device->state.pdsk >= D_INCONSISTENT && device->state.conn >= C_CONNECTED) {
D_ASSERT(device, device->state.role == R_PRIMARY);
if (test_and_clear_bit(UNPLUG_REMOTE, &device->flags)) {
drbd_queue_work_if_unqueued(
&first_peer_device(device)->connection->sender_work,
&device->unplug_work);
}
}
}
static void drbd_set_defaults(struct drbd_device *device) static void drbd_set_defaults(struct drbd_device *device)
{ {
/* Beware! The actual layout differs /* Beware! The actual layout differs
@ -2008,18 +2023,14 @@ void drbd_init_set_defaults(struct drbd_device *device)
device->unplug_work.cb = w_send_write_hint; device->unplug_work.cb = w_send_write_hint;
device->bm_io_work.w.cb = w_bitmap_io; device->bm_io_work.w.cb = w_bitmap_io;
init_timer(&device->resync_timer); setup_timer(&device->resync_timer, resync_timer_fn,
init_timer(&device->md_sync_timer); (unsigned long)device);
init_timer(&device->start_resync_timer); setup_timer(&device->md_sync_timer, md_sync_timer_fn,
init_timer(&device->request_timer); (unsigned long)device);
device->resync_timer.function = resync_timer_fn; setup_timer(&device->start_resync_timer, start_resync_timer_fn,
device->resync_timer.data = (unsigned long) device; (unsigned long)device);
device->md_sync_timer.function = md_sync_timer_fn; setup_timer(&device->request_timer, request_timer_fn,
device->md_sync_timer.data = (unsigned long) device; (unsigned long)device);
device->start_resync_timer.function = start_resync_timer_fn;
device->start_resync_timer.data = (unsigned long) device;
device->request_timer.function = request_timer_fn;
device->request_timer.data = (unsigned long) device;
init_waitqueue_head(&device->misc_wait); init_waitqueue_head(&device->misc_wait);
init_waitqueue_head(&device->state_wait); init_waitqueue_head(&device->state_wait);
@ -2131,7 +2142,7 @@ static void drbd_destroy_mempools(void)
static int drbd_create_mempools(void) static int drbd_create_mempools(void)
{ {
struct page *page; struct page *page;
const int number = (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count; const int number = (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * drbd_minor_count;
int i; int i;
/* prepare our caches and mempools */ /* prepare our caches and mempools */
@ -2167,13 +2178,12 @@ static int drbd_create_mempools(void)
goto Enomem; goto Enomem;
/* mempools */ /* mempools */
drbd_io_bio_set = bioset_create(BIO_POOL_SIZE, 0, BIOSET_NEED_RESCUER); drbd_io_bio_set = bioset_create(BIO_POOL_SIZE, 0, 0);
if (drbd_io_bio_set == NULL) if (drbd_io_bio_set == NULL)
goto Enomem; goto Enomem;
drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0, drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0,
BIOSET_NEED_BVECS | BIOSET_NEED_BVECS);
BIOSET_NEED_RESCUER);
if (drbd_md_io_bio_set == NULL) if (drbd_md_io_bio_set == NULL)
goto Enomem; goto Enomem;
@ -2409,7 +2419,6 @@ static void drbd_cleanup(void)
destroy_workqueue(retry.wq); destroy_workqueue(retry.wq);
drbd_genl_unregister(); drbd_genl_unregister();
drbd_debugfs_cleanup();
idr_for_each_entry(&drbd_devices, device, i) idr_for_each_entry(&drbd_devices, device, i)
drbd_delete_device(device); drbd_delete_device(device);
@ -2420,6 +2429,8 @@ static void drbd_cleanup(void)
drbd_free_resource(resource); drbd_free_resource(resource);
} }
drbd_debugfs_cleanup();
drbd_destroy_mempools(); drbd_destroy_mempools();
unregister_blkdev(DRBD_MAJOR, "drbd"); unregister_blkdev(DRBD_MAJOR, "drbd");
@ -2972,12 +2983,12 @@ static int __init drbd_init(void)
{ {
int err; int err;
if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) { if (drbd_minor_count < DRBD_MINOR_COUNT_MIN || drbd_minor_count > DRBD_MINOR_COUNT_MAX) {
pr_err("invalid minor_count (%d)\n", minor_count); pr_err("invalid minor_count (%d)\n", drbd_minor_count);
#ifdef MODULE #ifdef MODULE
return -EINVAL; return -EINVAL;
#else #else
minor_count = DRBD_MINOR_COUNT_DEF; drbd_minor_count = DRBD_MINOR_COUNT_DEF;
#endif #endif
} }
@ -3900,12 +3911,12 @@ _drbd_insert_fault(struct drbd_device *device, unsigned int type)
static struct fault_random_state rrs = {0, 0}; static struct fault_random_state rrs = {0, 0};
unsigned int ret = ( unsigned int ret = (
(fault_devs == 0 || (drbd_fault_devs == 0 ||
((1 << device_to_minor(device)) & fault_devs) != 0) && ((1 << device_to_minor(device)) & drbd_fault_devs) != 0) &&
(((_drbd_fault_random(&rrs) % 100) + 1) <= fault_rate)); (((_drbd_fault_random(&rrs) % 100) + 1) <= drbd_fault_rate));
if (ret) { if (ret) {
fault_count++; drbd_fault_count++;
if (__ratelimit(&drbd_ratelimit_state)) if (__ratelimit(&drbd_ratelimit_state))
drbd_warn(device, "***Simulating %s failure\n", drbd_warn(device, "***Simulating %s failure\n",

View File

@ -344,7 +344,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
(char[60]) { }, /* address */ (char[60]) { }, /* address */
NULL }; NULL };
char mb[14]; char mb[14];
char *argv[] = {usermode_helper, cmd, mb, NULL }; char *argv[] = {drbd_usermode_helper, cmd, mb, NULL };
struct drbd_connection *connection = first_peer_device(device)->connection; struct drbd_connection *connection = first_peer_device(device)->connection;
struct sib_info sib; struct sib_info sib;
int ret; int ret;
@ -359,19 +359,19 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
* write out any unsynced meta data changes now */ * write out any unsynced meta data changes now */
drbd_md_sync(device); drbd_md_sync(device);
drbd_info(device, "helper command: %s %s %s\n", usermode_helper, cmd, mb); drbd_info(device, "helper command: %s %s %s\n", drbd_usermode_helper, cmd, mb);
sib.sib_reason = SIB_HELPER_PRE; sib.sib_reason = SIB_HELPER_PRE;
sib.helper_name = cmd; sib.helper_name = cmd;
drbd_bcast_event(device, &sib); drbd_bcast_event(device, &sib);
notify_helper(NOTIFY_CALL, device, connection, cmd, 0); notify_helper(NOTIFY_CALL, device, connection, cmd, 0);
ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC); ret = call_usermodehelper(drbd_usermode_helper, argv, envp, UMH_WAIT_PROC);
if (ret) if (ret)
drbd_warn(device, "helper command: %s %s %s exit code %u (0x%x)\n", drbd_warn(device, "helper command: %s %s %s exit code %u (0x%x)\n",
usermode_helper, cmd, mb, drbd_usermode_helper, cmd, mb,
(ret >> 8) & 0xff, ret); (ret >> 8) & 0xff, ret);
else else
drbd_info(device, "helper command: %s %s %s exit code %u (0x%x)\n", drbd_info(device, "helper command: %s %s %s exit code %u (0x%x)\n",
usermode_helper, cmd, mb, drbd_usermode_helper, cmd, mb,
(ret >> 8) & 0xff, ret); (ret >> 8) & 0xff, ret);
sib.sib_reason = SIB_HELPER_POST; sib.sib_reason = SIB_HELPER_POST;
sib.helper_exit_code = ret; sib.helper_exit_code = ret;
@ -396,24 +396,24 @@ enum drbd_peer_state conn_khelper(struct drbd_connection *connection, char *cmd)
(char[60]) { }, /* address */ (char[60]) { }, /* address */
NULL }; NULL };
char *resource_name = connection->resource->name; char *resource_name = connection->resource->name;
char *argv[] = {usermode_helper, cmd, resource_name, NULL }; char *argv[] = {drbd_usermode_helper, cmd, resource_name, NULL };
int ret; int ret;
setup_khelper_env(connection, envp); setup_khelper_env(connection, envp);
conn_md_sync(connection); conn_md_sync(connection);
drbd_info(connection, "helper command: %s %s %s\n", usermode_helper, cmd, resource_name); drbd_info(connection, "helper command: %s %s %s\n", drbd_usermode_helper, cmd, resource_name);
/* TODO: conn_bcast_event() ?? */ /* TODO: conn_bcast_event() ?? */
notify_helper(NOTIFY_CALL, NULL, connection, cmd, 0); notify_helper(NOTIFY_CALL, NULL, connection, cmd, 0);
ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC); ret = call_usermodehelper(drbd_usermode_helper, argv, envp, UMH_WAIT_PROC);
if (ret) if (ret)
drbd_warn(connection, "helper command: %s %s %s exit code %u (0x%x)\n", drbd_warn(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
usermode_helper, cmd, resource_name, drbd_usermode_helper, cmd, resource_name,
(ret >> 8) & 0xff, ret); (ret >> 8) & 0xff, ret);
else else
drbd_info(connection, "helper command: %s %s %s exit code %u (0x%x)\n", drbd_info(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
usermode_helper, cmd, resource_name, drbd_usermode_helper, cmd, resource_name,
(ret >> 8) & 0xff, ret); (ret >> 8) & 0xff, ret);
/* TODO: conn_bcast_event() ?? */ /* TODO: conn_bcast_event() ?? */
notify_helper(NOTIFY_RESPONSE, NULL, connection, cmd, ret); notify_helper(NOTIFY_RESPONSE, NULL, connection, cmd, ret);
@ -1236,12 +1236,18 @@ static void fixup_discard_if_not_supported(struct request_queue *q)
static void decide_on_write_same_support(struct drbd_device *device, static void decide_on_write_same_support(struct drbd_device *device,
struct request_queue *q, struct request_queue *q,
struct request_queue *b, struct o_qlim *o) struct request_queue *b, struct o_qlim *o,
bool disable_write_same)
{ {
struct drbd_peer_device *peer_device = first_peer_device(device); struct drbd_peer_device *peer_device = first_peer_device(device);
struct drbd_connection *connection = peer_device->connection; struct drbd_connection *connection = peer_device->connection;
bool can_do = b ? b->limits.max_write_same_sectors : true; bool can_do = b ? b->limits.max_write_same_sectors : true;
if (can_do && disable_write_same) {
can_do = false;
drbd_info(peer_device, "WRITE_SAME disabled by config\n");
}
if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) { if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) {
can_do = false; can_do = false;
drbd_info(peer_device, "peer does not support WRITE_SAME\n"); drbd_info(peer_device, "peer does not support WRITE_SAME\n");
@ -1302,6 +1308,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
struct request_queue *b = NULL; struct request_queue *b = NULL;
struct disk_conf *dc; struct disk_conf *dc;
bool discard_zeroes_if_aligned = true; bool discard_zeroes_if_aligned = true;
bool disable_write_same = false;
if (bdev) { if (bdev) {
b = bdev->backing_bdev->bd_disk->queue; b = bdev->backing_bdev->bd_disk->queue;
@ -1311,6 +1318,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
dc = rcu_dereference(device->ldev->disk_conf); dc = rcu_dereference(device->ldev->disk_conf);
max_segments = dc->max_bio_bvecs; max_segments = dc->max_bio_bvecs;
discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned; discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned;
disable_write_same = dc->disable_write_same;
rcu_read_unlock(); rcu_read_unlock();
blk_set_stacking_limits(&q->limits); blk_set_stacking_limits(&q->limits);
@ -1321,7 +1329,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
blk_queue_segment_boundary(q, PAGE_SIZE-1); blk_queue_segment_boundary(q, PAGE_SIZE-1);
decide_on_discard_support(device, q, b, discard_zeroes_if_aligned); decide_on_discard_support(device, q, b, discard_zeroes_if_aligned);
decide_on_write_same_support(device, q, b, o); decide_on_write_same_support(device, q, b, o, disable_write_same);
if (b) { if (b) {
blk_queue_stack_limits(q, b); blk_queue_stack_limits(q, b);
@ -1612,7 +1620,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
if (write_ordering_changed(old_disk_conf, new_disk_conf)) if (write_ordering_changed(old_disk_conf, new_disk_conf))
drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH); drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH);
if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned) if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned
|| old_disk_conf->disable_write_same != new_disk_conf->disable_write_same)
drbd_reconsider_queue_parameters(device, device->ldev, NULL); drbd_reconsider_queue_parameters(device, device->ldev, NULL);
drbd_md_sync(device); drbd_md_sync(device);
@ -2140,34 +2149,13 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
static int adm_detach(struct drbd_device *device, int force) static int adm_detach(struct drbd_device *device, int force)
{ {
enum drbd_state_rv retcode;
void *buffer;
int ret;
if (force) { if (force) {
set_bit(FORCE_DETACH, &device->flags); set_bit(FORCE_DETACH, &device->flags);
drbd_force_state(device, NS(disk, D_FAILED)); drbd_force_state(device, NS(disk, D_FAILED));
retcode = SS_SUCCESS; return SS_SUCCESS;
goto out;
} }
drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */ return drbd_request_detach_interruptible(device);
buffer = drbd_md_get_buffer(device, __func__); /* make sure there is no in-flight meta-data IO */
if (buffer) {
retcode = drbd_request_state(device, NS(disk, D_FAILED));
drbd_md_put_buffer(device);
} else /* already <= D_FAILED */
retcode = SS_NOTHING_TO_DO;
/* D_FAILED will transition to DISKLESS. */
drbd_resume_io(device);
ret = wait_event_interruptible(device->misc_wait,
device->state.disk != D_FAILED);
if ((int)retcode == (int)SS_IS_DISKLESS)
retcode = SS_NOTHING_TO_DO;
if (ret)
retcode = ERR_INTR;
out:
return retcode;
} }
/* Detaching the disk is a process in multiple stages. First we need to lock /* Detaching the disk is a process in multiple stages. First we need to lock

View File

@ -127,7 +127,7 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se
seq_putc(seq, '='); seq_putc(seq, '=');
seq_putc(seq, '>'); seq_putc(seq, '>');
for (i = 0; i < y; i++) for (i = 0; i < y; i++)
seq_printf(seq, "."); seq_putc(seq, '.');
seq_puts(seq, "] "); seq_puts(seq, "] ");
if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T) if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
@ -179,7 +179,7 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se
seq_printf_with_thousands_grouping(seq, dbdt); seq_printf_with_thousands_grouping(seq, dbdt);
seq_puts(seq, " ("); seq_puts(seq, " (");
/* ------------------------- ~3s average ------------------------ */ /* ------------------------- ~3s average ------------------------ */
if (proc_details >= 1) { if (drbd_proc_details >= 1) {
/* this is what drbd_rs_should_slow_down() uses */ /* this is what drbd_rs_should_slow_down() uses */
i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS; i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
dt = (jiffies - device->rs_mark_time[i]) / HZ; dt = (jiffies - device->rs_mark_time[i]) / HZ;
@ -209,7 +209,7 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se
} }
seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : ""); seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
if (proc_details >= 1) { if (drbd_proc_details >= 1) {
/* 64 bit: /* 64 bit:
* we convert to sectors in the display below. */ * we convert to sectors in the display below. */
unsigned long bm_bits = drbd_bm_bits(device); unsigned long bm_bits = drbd_bm_bits(device);
@ -332,13 +332,13 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
state.conn == C_VERIFY_T) state.conn == C_VERIFY_T)
drbd_syncer_progress(device, seq, state); drbd_syncer_progress(device, seq, state);
if (proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) { if (drbd_proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
lc_seq_printf_stats(seq, device->resync); lc_seq_printf_stats(seq, device->resync);
lc_seq_printf_stats(seq, device->act_log); lc_seq_printf_stats(seq, device->act_log);
put_ldev(device); put_ldev(device);
} }
if (proc_details >= 2) if (drbd_proc_details >= 2)
seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt)); seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
} }
rcu_read_unlock(); rcu_read_unlock();

View File

@ -332,7 +332,7 @@ static void drbd_free_pages(struct drbd_device *device, struct page *page, int i
if (page == NULL) if (page == NULL)
return; return;
if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count) if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * drbd_minor_count)
i = page_chain_free(page); i = page_chain_free(page);
else { else {
struct page *tmp; struct page *tmp;
@ -1100,7 +1100,10 @@ randomize:
idr_for_each_entry(&connection->peer_devices, peer_device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
mutex_lock(peer_device->device->state_mutex); mutex_lock(peer_device->device->state_mutex);
/* avoid a race with conn_request_state( C_DISCONNECTING ) */
spin_lock_irq(&connection->resource->req_lock);
set_bit(STATE_SENT, &connection->flags); set_bit(STATE_SENT, &connection->flags);
spin_unlock_irq(&connection->resource->req_lock);
idr_for_each_entry(&connection->peer_devices, peer_device, vnr) idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
mutex_unlock(peer_device->device->state_mutex); mutex_unlock(peer_device->device->state_mutex);
@ -1194,6 +1197,14 @@ static int decode_header(struct drbd_connection *connection, void *header, struc
return 0; return 0;
} }
static void drbd_unplug_all_devices(struct drbd_connection *connection)
{
if (current->plug == &connection->receiver_plug) {
blk_finish_plug(&connection->receiver_plug);
blk_start_plug(&connection->receiver_plug);
} /* else: maybe just schedule() ?? */
}
static int drbd_recv_header(struct drbd_connection *connection, struct packet_info *pi) static int drbd_recv_header(struct drbd_connection *connection, struct packet_info *pi)
{ {
void *buffer = connection->data.rbuf; void *buffer = connection->data.rbuf;
@ -1209,6 +1220,36 @@ static int drbd_recv_header(struct drbd_connection *connection, struct packet_in
return err; return err;
} }
static int drbd_recv_header_maybe_unplug(struct drbd_connection *connection, struct packet_info *pi)
{
void *buffer = connection->data.rbuf;
unsigned int size = drbd_header_size(connection);
int err;
err = drbd_recv_short(connection->data.socket, buffer, size, MSG_NOSIGNAL|MSG_DONTWAIT);
if (err != size) {
/* If we have nothing in the receive buffer now, to reduce
* application latency, try to drain the backend queues as
* quickly as possible, and let remote TCP know what we have
* received so far. */
if (err == -EAGAIN) {
drbd_tcp_quickack(connection->data.socket);
drbd_unplug_all_devices(connection);
}
if (err > 0) {
buffer += err;
size -= err;
}
err = drbd_recv_all_warn(connection, buffer, size);
if (err)
return err;
}
err = decode_header(connection, connection->data.rbuf, pi);
connection->last_received = jiffies;
return err;
}
/* This is blkdev_issue_flush, but asynchronous. /* This is blkdev_issue_flush, but asynchronous.
* We want to submit to all component volumes in parallel, * We want to submit to all component volumes in parallel,
* then wait for all completions. * then wait for all completions.
@ -1223,7 +1264,7 @@ struct one_flush_context {
struct issue_flush_context *ctx; struct issue_flush_context *ctx;
}; };
void one_flush_endio(struct bio *bio) static void one_flush_endio(struct bio *bio)
{ {
struct one_flush_context *octx = bio->bi_private; struct one_flush_context *octx = bio->bi_private;
struct drbd_device *device = octx->device; struct drbd_device *device = octx->device;
@ -1265,7 +1306,7 @@ static void submit_one_flush(struct drbd_device *device, struct issue_flush_cont
octx->device = device; octx->device = device;
octx->ctx = ctx; octx->ctx = ctx;
bio->bi_bdev = device->ldev->backing_bdev; bio_set_dev(bio, device->ldev->backing_bdev);
bio->bi_private = octx; bio->bi_private = octx;
bio->bi_end_io = one_flush_endio; bio->bi_end_io = one_flush_endio;
bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH; bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
@ -1548,7 +1589,7 @@ next_bio:
} }
/* > peer_req->i.sector, unless this is the first bio */ /* > peer_req->i.sector, unless this is the first bio */
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = device->ldev->backing_bdev; bio_set_dev(bio, device->ldev->backing_bdev);
bio_set_op_attrs(bio, op, op_flags); bio_set_op_attrs(bio, op, op_flags);
bio->bi_private = peer_req; bio->bi_private = peer_req;
bio->bi_end_io = drbd_peer_request_endio; bio->bi_end_io = drbd_peer_request_endio;
@ -4085,7 +4126,7 @@ static int receive_uuids(struct drbd_connection *connection, struct packet_info
return config_unknown_volume(connection, pi); return config_unknown_volume(connection, pi);
device = peer_device->device; device = peer_device->device;
p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO); p_uuid = kmalloc_array(UI_EXTENDED_SIZE, sizeof(*p_uuid), GFP_NOIO);
if (!p_uuid) { if (!p_uuid) {
drbd_err(device, "kmalloc of p_uuid failed\n"); drbd_err(device, "kmalloc of p_uuid failed\n");
return false; return false;
@ -4882,8 +4923,8 @@ static void drbdd(struct drbd_connection *connection)
struct data_cmd const *cmd; struct data_cmd const *cmd;
drbd_thread_current_set_cpu(&connection->receiver); drbd_thread_current_set_cpu(&connection->receiver);
update_receiver_timing_details(connection, drbd_recv_header); update_receiver_timing_details(connection, drbd_recv_header_maybe_unplug);
if (drbd_recv_header(connection, &pi)) if (drbd_recv_header_maybe_unplug(connection, &pi))
goto err_out; goto err_out;
cmd = &drbd_cmd_handler[pi.cmd]; cmd = &drbd_cmd_handler[pi.cmd];
@ -5375,8 +5416,11 @@ int drbd_receiver(struct drbd_thread *thi)
} }
} while (h == 0); } while (h == 0);
if (h > 0) if (h > 0) {
blk_start_plug(&connection->receiver_plug);
drbdd(connection); drbdd(connection);
blk_finish_plug(&connection->receiver_plug);
}
conn_disconnect(connection); conn_disconnect(connection);

View File

@ -36,14 +36,18 @@ static bool drbd_may_do_local_read(struct drbd_device *device, sector_t sector,
/* Update disk stats at start of I/O request */ /* Update disk stats at start of I/O request */
static void _drbd_start_io_acct(struct drbd_device *device, struct drbd_request *req) static void _drbd_start_io_acct(struct drbd_device *device, struct drbd_request *req)
{ {
generic_start_io_acct(bio_data_dir(req->master_bio), req->i.size >> 9, struct request_queue *q = device->rq_queue;
&device->vdisk->part0);
generic_start_io_acct(q, bio_data_dir(req->master_bio),
req->i.size >> 9, &device->vdisk->part0);
} }
/* Update disk stats when completing request upwards */ /* Update disk stats when completing request upwards */
static void _drbd_end_io_acct(struct drbd_device *device, struct drbd_request *req) static void _drbd_end_io_acct(struct drbd_device *device, struct drbd_request *req)
{ {
generic_end_io_acct(bio_data_dir(req->master_bio), struct request_queue *q = device->rq_queue;
generic_end_io_acct(q, bio_data_dir(req->master_bio),
&device->vdisk->part0, req->start_jif); &device->vdisk->part0, req->start_jif);
} }
@ -1175,7 +1179,7 @@ drbd_submit_req_private_bio(struct drbd_request *req)
else else
type = DRBD_FAULT_DT_RD; type = DRBD_FAULT_DT_RD;
bio->bi_bdev = device->ldev->backing_bdev; bio_set_dev(bio, device->ldev->backing_bdev);
/* State may have changed since we grabbed our reference on the /* State may have changed since we grabbed our reference on the
* ->ldev member. Double check, and short-circuit to endio. * ->ldev member. Double check, and short-circuit to endio.
@ -1275,6 +1279,57 @@ static bool may_do_writes(struct drbd_device *device)
return s.disk == D_UP_TO_DATE || s.pdsk == D_UP_TO_DATE; return s.disk == D_UP_TO_DATE || s.pdsk == D_UP_TO_DATE;
} }
struct drbd_plug_cb {
struct blk_plug_cb cb;
struct drbd_request *most_recent_req;
/* do we need more? */
};
static void drbd_unplug(struct blk_plug_cb *cb, bool from_schedule)
{
struct drbd_plug_cb *plug = container_of(cb, struct drbd_plug_cb, cb);
struct drbd_resource *resource = plug->cb.data;
struct drbd_request *req = plug->most_recent_req;
kfree(cb);
if (!req)
return;
spin_lock_irq(&resource->req_lock);
/* In case the sender did not process it yet, raise the flag to
* have it followed with P_UNPLUG_REMOTE just after. */
req->rq_state |= RQ_UNPLUG;
/* but also queue a generic unplug */
drbd_queue_unplug(req->device);
kref_put(&req->kref, drbd_req_destroy);
spin_unlock_irq(&resource->req_lock);
}
static struct drbd_plug_cb* drbd_check_plugged(struct drbd_resource *resource)
{
/* A lot of text to say
* return (struct drbd_plug_cb*)blk_check_plugged(); */
struct drbd_plug_cb *plug;
struct blk_plug_cb *cb = blk_check_plugged(drbd_unplug, resource, sizeof(*plug));
if (cb)
plug = container_of(cb, struct drbd_plug_cb, cb);
else
plug = NULL;
return plug;
}
static void drbd_update_plug(struct drbd_plug_cb *plug, struct drbd_request *req)
{
struct drbd_request *tmp = plug->most_recent_req;
/* Will be sent to some peer.
* Remember to tag it with UNPLUG_REMOTE on unplug */
kref_get(&req->kref);
plug->most_recent_req = req;
if (tmp)
kref_put(&tmp->kref, drbd_req_destroy);
}
static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request *req) static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request *req)
{ {
struct drbd_resource *resource = device->resource; struct drbd_resource *resource = device->resource;
@ -1347,6 +1402,12 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request
no_remote = true; no_remote = true;
} }
if (no_remote == false) {
struct drbd_plug_cb *plug = drbd_check_plugged(resource);
if (plug)
drbd_update_plug(plug, req);
}
/* If it took the fast path in drbd_request_prepare, add it here. /* If it took the fast path in drbd_request_prepare, add it here.
* The slow path has added it already. */ * The slow path has added it already. */
if (list_empty(&req->req_pending_master_completion)) if (list_empty(&req->req_pending_master_completion))
@ -1395,7 +1456,10 @@ void __drbd_make_request(struct drbd_device *device, struct bio *bio, unsigned l
static void submit_fast_path(struct drbd_device *device, struct list_head *incoming) static void submit_fast_path(struct drbd_device *device, struct list_head *incoming)
{ {
struct blk_plug plug;
struct drbd_request *req, *tmp; struct drbd_request *req, *tmp;
blk_start_plug(&plug);
list_for_each_entry_safe(req, tmp, incoming, tl_requests) { list_for_each_entry_safe(req, tmp, incoming, tl_requests) {
const int rw = bio_data_dir(req->master_bio); const int rw = bio_data_dir(req->master_bio);
@ -1413,6 +1477,7 @@ static void submit_fast_path(struct drbd_device *device, struct list_head *incom
list_del_init(&req->tl_requests); list_del_init(&req->tl_requests);
drbd_send_and_submit(device, req); drbd_send_and_submit(device, req);
} }
blk_finish_plug(&plug);
} }
static bool prepare_al_transaction_nonblock(struct drbd_device *device, static bool prepare_al_transaction_nonblock(struct drbd_device *device,
@ -1420,12 +1485,12 @@ static bool prepare_al_transaction_nonblock(struct drbd_device *device,
struct list_head *pending, struct list_head *pending,
struct list_head *later) struct list_head *later)
{ {
struct drbd_request *req, *tmp; struct drbd_request *req;
int wake = 0; int wake = 0;
int err; int err;
spin_lock_irq(&device->al_lock); spin_lock_irq(&device->al_lock);
list_for_each_entry_safe(req, tmp, incoming, tl_requests) { while ((req = list_first_entry_or_null(incoming, struct drbd_request, tl_requests))) {
err = drbd_al_begin_io_nonblock(device, &req->i); err = drbd_al_begin_io_nonblock(device, &req->i);
if (err == -ENOBUFS) if (err == -ENOBUFS)
break; break;
@ -1442,17 +1507,20 @@ static bool prepare_al_transaction_nonblock(struct drbd_device *device,
return !list_empty(pending); return !list_empty(pending);
} }
void send_and_submit_pending(struct drbd_device *device, struct list_head *pending) static void send_and_submit_pending(struct drbd_device *device, struct list_head *pending)
{ {
struct drbd_request *req, *tmp; struct blk_plug plug;
struct drbd_request *req;
list_for_each_entry_safe(req, tmp, pending, tl_requests) { blk_start_plug(&plug);
while ((req = list_first_entry_or_null(pending, struct drbd_request, tl_requests))) {
req->rq_state |= RQ_IN_ACT_LOG; req->rq_state |= RQ_IN_ACT_LOG;
req->in_actlog_jif = jiffies; req->in_actlog_jif = jiffies;
atomic_dec(&device->ap_actlog_cnt); atomic_dec(&device->ap_actlog_cnt);
list_del_init(&req->tl_requests); list_del_init(&req->tl_requests);
drbd_send_and_submit(device, req); drbd_send_and_submit(device, req);
} }
blk_finish_plug(&plug);
} }
void do_submit(struct work_struct *ws) void do_submit(struct work_struct *ws)

View File

@ -212,6 +212,11 @@ enum drbd_req_state_bits {
/* Should call drbd_al_complete_io() for this request... */ /* Should call drbd_al_complete_io() for this request... */
__RQ_IN_ACT_LOG, __RQ_IN_ACT_LOG,
/* This was the most recent request during some blk_finish_plug()
* or its implicit from-schedule equivalent.
* We may use it as hint to send a P_UNPLUG_REMOTE */
__RQ_UNPLUG,
/* The peer has sent a retry ACK */ /* The peer has sent a retry ACK */
__RQ_POSTPONED, __RQ_POSTPONED,
@ -249,6 +254,7 @@ enum drbd_req_state_bits {
#define RQ_WSAME (1UL << __RQ_WSAME) #define RQ_WSAME (1UL << __RQ_WSAME)
#define RQ_UNMAP (1UL << __RQ_UNMAP) #define RQ_UNMAP (1UL << __RQ_UNMAP)
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG) #define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
#define RQ_UNPLUG (1UL << __RQ_UNPLUG)
#define RQ_POSTPONED (1UL << __RQ_POSTPONED) #define RQ_POSTPONED (1UL << __RQ_POSTPONED)
#define RQ_COMPLETION_SUSP (1UL << __RQ_COMPLETION_SUSP) #define RQ_COMPLETION_SUSP (1UL << __RQ_COMPLETION_SUSP)
#define RQ_EXP_RECEIVE_ACK (1UL << __RQ_EXP_RECEIVE_ACK) #define RQ_EXP_RECEIVE_ACK (1UL << __RQ_EXP_RECEIVE_ACK)

View File

@ -346,7 +346,7 @@ static enum drbd_role min_role(enum drbd_role role1, enum drbd_role role2)
enum drbd_role conn_highest_role(struct drbd_connection *connection) enum drbd_role conn_highest_role(struct drbd_connection *connection)
{ {
enum drbd_role role = R_UNKNOWN; enum drbd_role role = R_SECONDARY;
struct drbd_peer_device *peer_device; struct drbd_peer_device *peer_device;
int vnr; int vnr;
@ -579,11 +579,14 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
unsigned long flags; unsigned long flags;
union drbd_state os, ns; union drbd_state os, ns;
enum drbd_state_rv rv; enum drbd_state_rv rv;
void *buffer = NULL;
init_completion(&done); init_completion(&done);
if (f & CS_SERIALIZE) if (f & CS_SERIALIZE)
mutex_lock(device->state_mutex); mutex_lock(device->state_mutex);
if (f & CS_INHIBIT_MD_IO)
buffer = drbd_md_get_buffer(device, __func__);
spin_lock_irqsave(&device->resource->req_lock, flags); spin_lock_irqsave(&device->resource->req_lock, flags);
os = drbd_read_state(device); os = drbd_read_state(device);
@ -636,6 +639,8 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
} }
abort: abort:
if (buffer)
drbd_md_put_buffer(device);
if (f & CS_SERIALIZE) if (f & CS_SERIALIZE)
mutex_unlock(device->state_mutex); mutex_unlock(device->state_mutex);
@ -664,6 +669,47 @@ _drbd_request_state(struct drbd_device *device, union drbd_state mask,
return rv; return rv;
} }
/*
* We grab drbd_md_get_buffer(), because we don't want to "fail" the disk while
* there is IO in-flight: the transition into D_FAILED for detach purposes
* may get misinterpreted as actual IO error in a confused endio function.
*
* We wrap it all into wait_event(), to retry in case the drbd_req_state()
* returns SS_IN_TRANSIENT_STATE.
*
* To avoid potential deadlock with e.g. the receiver thread trying to grab
* drbd_md_get_buffer() while trying to get out of the "transient state", we
* need to grab and release the meta data buffer inside of that wait_event loop.
*/
static enum drbd_state_rv
request_detach(struct drbd_device *device)
{
return drbd_req_state(device, NS(disk, D_FAILED),
CS_VERBOSE | CS_ORDERED | CS_INHIBIT_MD_IO);
}
enum drbd_state_rv
drbd_request_detach_interruptible(struct drbd_device *device)
{
enum drbd_state_rv rv;
int ret;
drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */
wait_event_interruptible(device->state_wait,
(rv = request_detach(device)) != SS_IN_TRANSIENT_STATE);
drbd_resume_io(device);
ret = wait_event_interruptible(device->misc_wait,
device->state.disk != D_FAILED);
if (rv == SS_IS_DISKLESS)
rv = SS_NOTHING_TO_DO;
if (ret)
rv = ERR_INTR;
return rv;
}
enum drbd_state_rv enum drbd_state_rv
_drbd_request_state_holding_state_mutex(struct drbd_device *device, union drbd_state mask, _drbd_request_state_holding_state_mutex(struct drbd_device *device, union drbd_state mask,
union drbd_state val, enum chg_state_flags f) union drbd_state val, enum chg_state_flags f)

View File

@ -71,6 +71,10 @@ enum chg_state_flags {
CS_DC_SUSP = 1 << 10, CS_DC_SUSP = 1 << 10,
CS_DC_MASK = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK, CS_DC_MASK = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK,
CS_IGN_OUTD_FAIL = 1 << 11, CS_IGN_OUTD_FAIL = 1 << 11,
/* Make sure no meta data IO is in flight, by calling
* drbd_md_get_buffer(). Used for graceful detach. */
CS_INHIBIT_MD_IO = 1 << 12,
}; };
/* drbd_dev_state and drbd_state are different types. This is to stress the /* drbd_dev_state and drbd_state are different types. This is to stress the
@ -156,6 +160,10 @@ static inline int drbd_request_state(struct drbd_device *device,
return _drbd_request_state(device, mask, val, CS_VERBOSE + CS_ORDERED); return _drbd_request_state(device, mask, val, CS_VERBOSE + CS_ORDERED);
} }
/* for use in adm_detach() (drbd_adm_detach(), drbd_adm_down()) */
enum drbd_state_rv
drbd_request_detach_interruptible(struct drbd_device *device);
enum drbd_role conn_highest_role(struct drbd_connection *connection); enum drbd_role conn_highest_role(struct drbd_connection *connection);
enum drbd_role conn_highest_peer(struct drbd_connection *connection); enum drbd_role conn_highest_peer(struct drbd_connection *connection);
enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection); enum drbd_disk_state conn_highest_disk(struct drbd_connection *connection);

View File

@ -65,6 +65,11 @@ void drbd_md_endio(struct bio *bio)
device = bio->bi_private; device = bio->bi_private;
device->md_io.error = blk_status_to_errno(bio->bi_status); device->md_io.error = blk_status_to_errno(bio->bi_status);
/* special case: drbd_md_read() during drbd_adm_attach() */
if (device->ldev)
put_ldev(device);
bio_put(bio);
/* We grabbed an extra reference in _drbd_md_sync_page_io() to be able /* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
* to timeout on the lower level device, and eventually detach from it. * to timeout on the lower level device, and eventually detach from it.
* If this io completion runs after that timeout expired, this * If this io completion runs after that timeout expired, this
@ -79,9 +84,6 @@ void drbd_md_endio(struct bio *bio)
drbd_md_put_buffer(device); drbd_md_put_buffer(device);
device->md_io.done = 1; device->md_io.done = 1;
wake_up(&device->misc_wait); wake_up(&device->misc_wait);
bio_put(bio);
if (device->ldev) /* special case: drbd_md_read() during drbd_adm_attach() */
put_ldev(device);
} }
/* reads on behalf of the partner, /* reads on behalf of the partner,
@ -128,6 +130,14 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
block_id = peer_req->block_id; block_id = peer_req->block_id;
peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO; peer_req->flags &= ~EE_CALL_AL_COMPLETE_IO;
if (peer_req->flags & EE_WAS_ERROR) {
/* In protocol != C, we usually do not send write acks.
* In case of a write error, send the neg ack anyways. */
if (!__test_and_set_bit(__EE_SEND_WRITE_ACK, &peer_req->flags))
inc_unacked(device);
drbd_set_out_of_sync(device, peer_req->i.sector, peer_req->i.size);
}
spin_lock_irqsave(&device->resource->req_lock, flags); spin_lock_irqsave(&device->resource->req_lock, flags);
device->writ_cnt += peer_req->i.size >> 9; device->writ_cnt += peer_req->i.size >> 9;
list_move_tail(&peer_req->w.list, &device->done_ee); list_move_tail(&peer_req->w.list, &device->done_ee);
@ -195,7 +205,8 @@ void drbd_peer_request_endio(struct bio *bio)
} }
} }
void drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *device) static void
drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *device)
{ {
panic("drbd%u %s/%u potential random memory corruption caused by delayed completion of aborted local request\n", panic("drbd%u %s/%u potential random memory corruption caused by delayed completion of aborted local request\n",
device->minor, device->resource->name, device->vnr); device->minor, device->resource->name, device->vnr);
@ -1382,18 +1393,22 @@ static int drbd_send_barrier(struct drbd_connection *connection)
return conn_send_command(connection, sock, P_BARRIER, sizeof(*p), NULL, 0); return conn_send_command(connection, sock, P_BARRIER, sizeof(*p), NULL, 0);
} }
static int pd_send_unplug_remote(struct drbd_peer_device *pd)
{
struct drbd_socket *sock = &pd->connection->data;
if (!drbd_prepare_command(pd, sock))
return -EIO;
return drbd_send_command(pd, sock, P_UNPLUG_REMOTE, 0, NULL, 0);
}
int w_send_write_hint(struct drbd_work *w, int cancel) int w_send_write_hint(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = struct drbd_device *device =
container_of(w, struct drbd_device, unplug_work); container_of(w, struct drbd_device, unplug_work);
struct drbd_socket *sock;
if (cancel) if (cancel)
return 0; return 0;
sock = &first_peer_device(device)->connection->data; return pd_send_unplug_remote(first_peer_device(device));
if (!drbd_prepare_command(first_peer_device(device), sock))
return -EIO;
return drbd_send_command(first_peer_device(device), sock, P_UNPLUG_REMOTE, 0, NULL, 0);
} }
static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch) static void re_init_if_first_write(struct drbd_connection *connection, unsigned int epoch)
@ -1455,6 +1470,7 @@ int w_send_dblock(struct drbd_work *w, int cancel)
struct drbd_device *device = req->device; struct drbd_device *device = req->device;
struct drbd_peer_device *const peer_device = first_peer_device(device); struct drbd_peer_device *const peer_device = first_peer_device(device);
struct drbd_connection *connection = peer_device->connection; struct drbd_connection *connection = peer_device->connection;
bool do_send_unplug = req->rq_state & RQ_UNPLUG;
int err; int err;
if (unlikely(cancel)) { if (unlikely(cancel)) {
@ -1470,6 +1486,9 @@ int w_send_dblock(struct drbd_work *w, int cancel)
err = drbd_send_dblock(peer_device, req); err = drbd_send_dblock(peer_device, req);
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK); req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
if (do_send_unplug && !err)
pd_send_unplug_remote(peer_device);
return err; return err;
} }
@ -1484,6 +1503,7 @@ int w_send_read_req(struct drbd_work *w, int cancel)
struct drbd_device *device = req->device; struct drbd_device *device = req->device;
struct drbd_peer_device *const peer_device = first_peer_device(device); struct drbd_peer_device *const peer_device = first_peer_device(device);
struct drbd_connection *connection = peer_device->connection; struct drbd_connection *connection = peer_device->connection;
bool do_send_unplug = req->rq_state & RQ_UNPLUG;
int err; int err;
if (unlikely(cancel)) { if (unlikely(cancel)) {
@ -1501,6 +1521,9 @@ int w_send_read_req(struct drbd_work *w, int cancel)
req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK); req_mod(req, err ? SEND_FAILED : HANDED_OVER_TO_NETWORK);
if (do_send_unplug && !err)
pd_send_unplug_remote(peer_device);
return err; return err;
} }
@ -1513,7 +1536,7 @@ int w_restart_disk_io(struct drbd_work *w, int cancel)
drbd_al_begin_io(device, &req->i); drbd_al_begin_io(device, &req->i);
drbd_req_make_private_bio(req, req->master_bio); drbd_req_make_private_bio(req, req->master_bio);
req->private_bio->bi_bdev = device->ldev->backing_bdev; bio_set_dev(req->private_bio, device->ldev->backing_bdev);
generic_make_request(req->private_bio); generic_make_request(req->private_bio);
return 0; return 0;
@ -1733,6 +1756,11 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
return; return;
} }
if (!connection) {
drbd_err(device, "No connection to peer, aborting!\n");
return;
}
if (!test_bit(B_RS_H_DONE, &device->flags)) { if (!test_bit(B_RS_H_DONE, &device->flags)) {
if (side == C_SYNC_TARGET) { if (side == C_SYNC_TARGET) {
/* Since application IO was locked out during C_WF_BITMAP_T and /* Since application IO was locked out during C_WF_BITMAP_T and

View File

@ -4134,7 +4134,7 @@ static int __floppy_read_block_0(struct block_device *bdev, int drive)
cbdata.drive = drive; cbdata.drive = drive;
bio_init(&bio, &bio_vec, 1); bio_init(&bio, &bio_vec, 1);
bio.bi_bdev = bdev; bio_set_dev(&bio, bdev);
bio_add_page(&bio, page, size, 0); bio_add_page(&bio, page, size, 0);
bio.bi_iter.bi_sector = 0; bio.bi_iter.bi_sector = 0;

View File

@ -1966,10 +1966,6 @@ static int __init loop_init(void)
struct loop_device *lo; struct loop_device *lo;
int err; int err;
err = misc_register(&loop_misc);
if (err < 0)
return err;
part_shift = 0; part_shift = 0;
if (max_part > 0) { if (max_part > 0) {
part_shift = fls(max_part); part_shift = fls(max_part);
@ -1987,12 +1983,12 @@ static int __init loop_init(void)
if ((1UL << part_shift) > DISK_MAX_PARTS) { if ((1UL << part_shift) > DISK_MAX_PARTS) {
err = -EINVAL; err = -EINVAL;
goto misc_out; goto err_out;
} }
if (max_loop > 1UL << (MINORBITS - part_shift)) { if (max_loop > 1UL << (MINORBITS - part_shift)) {
err = -EINVAL; err = -EINVAL;
goto misc_out; goto err_out;
} }
/* /*
@ -2011,6 +2007,11 @@ static int __init loop_init(void)
range = 1UL << MINORBITS; range = 1UL << MINORBITS;
} }
err = misc_register(&loop_misc);
if (err < 0)
goto err_out;
if (register_blkdev(LOOP_MAJOR, "loop")) { if (register_blkdev(LOOP_MAJOR, "loop")) {
err = -EIO; err = -EIO;
goto misc_out; goto misc_out;
@ -2030,6 +2031,7 @@ static int __init loop_init(void)
misc_out: misc_out:
misc_deregister(&loop_misc); misc_deregister(&loop_misc);
err_out:
return err; return err;
} }

View File

@ -128,7 +128,7 @@ static struct dentry *nbd_dbg_dir;
#define NBD_MAGIC 0x68797548 #define NBD_MAGIC 0x68797548
static unsigned int nbds_max = 16; static unsigned int nbds_max = 16;
static int max_part; static int max_part = 16;
static struct workqueue_struct *recv_workqueue; static struct workqueue_struct *recv_workqueue;
static int part_shift; static int part_shift;
@ -165,7 +165,7 @@ static ssize_t pid_show(struct device *dev,
return sprintf(buf, "%d\n", task_pid_nr(nbd->task_recv)); return sprintf(buf, "%d\n", task_pid_nr(nbd->task_recv));
} }
static struct device_attribute pid_attr = { static const struct device_attribute pid_attr = {
.attr = { .name = "pid", .mode = S_IRUGO}, .attr = { .name = "pid", .mode = S_IRUGO},
.show = pid_show, .show = pid_show,
}; };
@ -1584,6 +1584,15 @@ again:
} }
} else { } else {
nbd = idr_find(&nbd_index_idr, index); nbd = idr_find(&nbd_index_idr, index);
if (!nbd) {
ret = nbd_dev_add(index);
if (ret < 0) {
mutex_unlock(&nbd_index_mutex);
printk(KERN_ERR "nbd: failed to add new device\n");
return ret;
}
nbd = idr_find(&nbd_index_idr, index);
}
} }
if (!nbd) { if (!nbd) {
printk(KERN_ERR "nbd: couldn't find device at index %d\n", printk(KERN_ERR "nbd: couldn't find device at index %d\n",
@ -2137,4 +2146,4 @@ MODULE_LICENSE("GPL");
module_param(nbds_max, int, 0444); module_param(nbds_max, int, 0444);
MODULE_PARM_DESC(nbds_max, "number of network block devices to initialize (default: 16)"); MODULE_PARM_DESC(nbds_max, "number of network block devices to initialize (default: 16)");
module_param(max_part, int, 0444); module_param(max_part, int, 0444);
MODULE_PARM_DESC(max_part, "number of partitions per device (default: 0)"); MODULE_PARM_DESC(max_part, "number of partitions per device (default: 16)");

File diff suppressed because it is too large Load Diff

View File

@ -1028,7 +1028,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
bio = pkt->r_bios[f]; bio = pkt->r_bios[f];
bio_reset(bio); bio_reset(bio);
bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9); bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
bio->bi_bdev = pd->bdev; bio_set_dev(bio, pd->bdev);
bio->bi_end_io = pkt_end_io_read; bio->bi_end_io = pkt_end_io_read;
bio->bi_private = pkt; bio->bi_private = pkt;
@ -1122,7 +1122,7 @@ static int pkt_start_recovery(struct packet_data *pkt)
pkt->sector = new_sector; pkt->sector = new_sector;
bio_reset(pkt->bio); bio_reset(pkt->bio);
pkt->bio->bi_bdev = pd->bdev; bio_set_set(pkt->bio, pd->bdev);
bio_set_op_attrs(pkt->bio, REQ_OP_WRITE, 0); bio_set_op_attrs(pkt->bio, REQ_OP_WRITE, 0);
pkt->bio->bi_iter.bi_sector = new_sector; pkt->bio->bi_iter.bi_sector = new_sector;
pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE; pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE;
@ -1267,7 +1267,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
bio_reset(pkt->w_bio); bio_reset(pkt->w_bio);
pkt->w_bio->bi_iter.bi_sector = pkt->sector; pkt->w_bio->bi_iter.bi_sector = pkt->sector;
pkt->w_bio->bi_bdev = pd->bdev; bio_set_dev(pkt->w_bio, pd->bdev);
pkt->w_bio->bi_end_io = pkt_end_io_packet_write; pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
pkt->w_bio->bi_private = pkt; pkt->w_bio->bi_private = pkt;
@ -2314,7 +2314,7 @@ static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio)
psd->pd = pd; psd->pd = pd;
psd->bio = bio; psd->bio = bio;
cloned_bio->bi_bdev = pd->bdev; bio_set_dev(cloned_bio, pd->bdev);
cloned_bio->bi_private = psd; cloned_bio->bi_private = psd;
cloned_bio->bi_end_io = pkt_end_io_read_cloned; cloned_bio->bi_end_io = pkt_end_io_read_cloned;
pd->stats.secs_r += bio_sectors(bio); pd->stats.secs_r += bio_sectors(bio);
@ -2415,8 +2415,7 @@ static blk_qc_t pkt_make_request(struct request_queue *q, struct bio *bio)
pd = q->queuedata; pd = q->queuedata;
if (!pd) { if (!pd) {
pr_err("%s incorrect request queue\n", pr_err("%s incorrect request queue\n", bio_devname(bio, b));
bdevname(bio->bi_bdev, b));
goto end_io; goto end_io;
} }

View File

@ -112,7 +112,7 @@ static const struct block_device_operations rsxx_fops = {
static void disk_stats_start(struct rsxx_cardinfo *card, struct bio *bio) static void disk_stats_start(struct rsxx_cardinfo *card, struct bio *bio)
{ {
generic_start_io_acct(bio_data_dir(bio), bio_sectors(bio), generic_start_io_acct(card->queue, bio_data_dir(bio), bio_sectors(bio),
&card->gendisk->part0); &card->gendisk->part0);
} }
@ -120,8 +120,8 @@ static void disk_stats_complete(struct rsxx_cardinfo *card,
struct bio *bio, struct bio *bio,
unsigned long start_time) unsigned long start_time)
{ {
generic_end_io_acct(bio_data_dir(bio), &card->gendisk->part0, generic_end_io_acct(card->queue, bio_data_dir(bio),
start_time); &card->gendisk->part0, start_time);
} }
static void bio_dma_done_cb(struct rsxx_cardinfo *card, static void bio_dma_done_cb(struct rsxx_cardinfo *card,

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,15 @@
/* Copyright 2012 STEC, Inc. /*
* Copyright 2012 STEC, Inc.
* Copyright (c) 2017 Western Digital Corporation or its affiliates.
* *
* This file is licensed under the terms of the 3-clause * This file is part of the Linux kernel, and is made available under
* BSD License (http://opensource.org/licenses/BSD-3-Clause) * the terms of the GNU General Public License version 2.
* or the GNU GPL-2.0 (http://www.gnu.org/licenses/gpl-2.0.html),
* at your option. Both licenses are also available in the LICENSE file
* distributed with this project. This file may not be copied, modified,
* or distributed except in accordance with those terms.
*/ */
#ifndef SKD_S1120_H #ifndef SKD_S1120_H
#define SKD_S1120_H #define SKD_S1120_H
#pragma pack(push, s1120_h, 1)
/* /*
* Q-channel, 64-bit r/w * Q-channel, 64-bit r/w
*/ */
@ -30,7 +26,7 @@
#define FIT_QCMD_MSGSIZE_128 (0x1 << 4) #define FIT_QCMD_MSGSIZE_128 (0x1 << 4)
#define FIT_QCMD_MSGSIZE_256 (0x2 << 4) #define FIT_QCMD_MSGSIZE_256 (0x2 << 4)
#define FIT_QCMD_MSGSIZE_512 (0x3 << 4) #define FIT_QCMD_MSGSIZE_512 (0x3 << 4)
#define FIT_QCMD_BASE_ADDRESS_MASK (0xFFFFFFFFFFFFFFC0ull) #define FIT_QCMD_ALIGN L1_CACHE_BYTES
/* /*
* Control, 32-bit r/w * Control, 32-bit r/w
@ -250,7 +246,7 @@ struct fit_msg_hdr {
* 20-23 of the FIT_MTD_FITFW_INIT response. * 20-23 of the FIT_MTD_FITFW_INIT response.
*/ */
struct fit_completion_entry_v1 { struct fit_completion_entry_v1 {
uint32_t num_returned_bytes; __be32 num_returned_bytes;
uint16_t tag; uint16_t tag;
uint8_t status; /* SCSI status */ uint8_t status; /* SCSI status */
uint8_t cycle; uint8_t cycle;
@ -278,7 +274,7 @@ struct fit_comp_error_info {
uint16_t sks_low; /* 10: Sense Key Specific (LSW) */ uint16_t sks_low; /* 10: Sense Key Specific (LSW) */
uint16_t reserved3; /* 12: Part of additional sense bytes (unused) */ uint16_t reserved3; /* 12: Part of additional sense bytes (unused) */
uint16_t uec; /* 14: Additional Sense Bytes */ uint16_t uec; /* 14: Additional Sense Bytes */
uint64_t per; /* 16: Additional Sense Bytes */ uint64_t per __packed; /* 16: Additional Sense Bytes */
uint8_t reserved4[2]; /* 1E: Additional Sense Bytes (unused) */ uint8_t reserved4[2]; /* 1E: Additional Sense Bytes (unused) */
}; };
@ -292,11 +288,11 @@ struct fit_comp_error_info {
* Version one has the last 32 bits sg_list_len_bytes; * Version one has the last 32 bits sg_list_len_bytes;
*/ */
struct skd_command_header { struct skd_command_header {
uint64_t sg_list_dma_address; __be64 sg_list_dma_address;
uint16_t tag; uint16_t tag;
uint8_t attribute; uint8_t attribute;
uint8_t add_cdb_len; /* In 32 bit words */ uint8_t add_cdb_len; /* In 32 bit words */
uint32_t sg_list_len_bytes; __be32 sg_list_len_bytes;
}; };
struct skd_scsi_request { struct skd_scsi_request {
@ -309,22 +305,20 @@ struct driver_inquiry_data {
uint8_t peripheral_device_type:5; uint8_t peripheral_device_type:5;
uint8_t qualifier:3; uint8_t qualifier:3;
uint8_t page_code; uint8_t page_code;
uint16_t page_length; __be16 page_length;
uint16_t pcie_bus_number; __be16 pcie_bus_number;
uint8_t pcie_device_number; uint8_t pcie_device_number;
uint8_t pcie_function_number; uint8_t pcie_function_number;
uint8_t pcie_link_speed; uint8_t pcie_link_speed;
uint8_t pcie_link_lanes; uint8_t pcie_link_lanes;
uint16_t pcie_vendor_id; __be16 pcie_vendor_id;
uint16_t pcie_device_id; __be16 pcie_device_id;
uint16_t pcie_subsystem_vendor_id; __be16 pcie_subsystem_vendor_id;
uint16_t pcie_subsystem_device_id; __be16 pcie_subsystem_device_id;
uint8_t reserved1[2]; uint8_t reserved1[2];
uint8_t reserved2[3]; uint8_t reserved2[3];
uint8_t driver_version_length; uint8_t driver_version_length;
uint8_t driver_version[0x14]; uint8_t driver_version[0x14];
}; };
#pragma pack(pop, s1120_h)
#endif /* SKD_S1120_H */ #endif /* SKD_S1120_H */

View File

@ -265,7 +265,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
} }
spin_lock_irqsave(&vblk->vqs[qid].lock, flags); spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
if (req_op(req) == REQ_OP_SCSI_IN || req_op(req) == REQ_OP_SCSI_OUT) if (blk_rq_is_scsi(req))
err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num); err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num);
else else
err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);

View File

@ -705,9 +705,9 @@ static unsigned int xen_blkbk_unmap_prepare(
GNTMAP_host_map, pages[i]->handle); GNTMAP_host_map, pages[i]->handle);
pages[i]->handle = BLKBACK_INVALID_HANDLE; pages[i]->handle = BLKBACK_INVALID_HANDLE;
invcount++; invcount++;
} }
return invcount; return invcount;
} }
static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_queue_data *data) static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_queue_data *data)
@ -1251,6 +1251,7 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
break; break;
case BLKIF_OP_WRITE_BARRIER: case BLKIF_OP_WRITE_BARRIER:
drain = true; drain = true;
/* fall through */
case BLKIF_OP_FLUSH_DISKCACHE: case BLKIF_OP_FLUSH_DISKCACHE:
ring->st_f_req++; ring->st_f_req++;
operation = REQ_OP_WRITE; operation = REQ_OP_WRITE;
@ -1362,7 +1363,7 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
goto fail_put_bio; goto fail_put_bio;
biolist[nbio++] = bio; biolist[nbio++] = bio;
bio->bi_bdev = preq.bdev; bio_set_dev(bio, preq.bdev);
bio->bi_private = pending_req; bio->bi_private = pending_req;
bio->bi_end_io = end_block_io_op; bio->bi_end_io = end_block_io_op;
bio->bi_iter.bi_sector = preq.sector_number; bio->bi_iter.bi_sector = preq.sector_number;
@ -1381,7 +1382,7 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
goto fail_put_bio; goto fail_put_bio;
biolist[nbio++] = bio; biolist[nbio++] = bio;
bio->bi_bdev = preq.bdev; bio_set_dev(bio, preq.bdev);
bio->bi_private = pending_req; bio->bi_private = pending_req;
bio->bi_end_io = end_block_io_op; bio->bi_end_io = end_block_io_op;
bio_set_op_attrs(bio, operation, operation_flags); bio_set_op_attrs(bio, operation, operation_flags);

View File

@ -816,7 +816,8 @@ static void frontend_changed(struct xenbus_device *dev,
xenbus_switch_state(dev, XenbusStateClosed); xenbus_switch_state(dev, XenbusStateClosed);
if (xenbus_dev_is_online(dev)) if (xenbus_dev_is_online(dev))
break; break;
/* fall through if not online */ /* fall through */
/* if not online */
case XenbusStateUnknown: case XenbusStateUnknown:
/* implies xen_blkif_disconnect() via xen_blkbk_remove() */ /* implies xen_blkif_disconnect() via xen_blkbk_remove() */
device_unregister(&dev->dev); device_unregister(&dev->dev);

View File

@ -2456,7 +2456,7 @@ static void blkback_changed(struct xenbus_device *dev,
case XenbusStateClosed: case XenbusStateClosed:
if (dev->state == XenbusStateClosed) if (dev->state == XenbusStateClosed)
break; break;
/* Missed the backend's Closing state -- fallthrough */ /* fall through */
case XenbusStateClosing: case XenbusStateClosing:
if (info) if (info)
blkfront_closing(info); blkfront_closing(info);

View File

@ -467,7 +467,7 @@ static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec,
return -ENOMEM; return -ENOMEM;
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9); bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
bio->bi_bdev = zram->bdev; bio_set_dev(bio, zram->bdev);
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, bvec->bv_offset)) { if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, bvec->bv_offset)) {
bio_put(bio); bio_put(bio);
return -EIO; return -EIO;
@ -561,7 +561,7 @@ static int write_to_bdev(struct zram *zram, struct bio_vec *bvec,
} }
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9); bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
bio->bi_bdev = zram->bdev; bio_set_dev(bio, zram->bdev);
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len,
bvec->bv_offset)) { bvec->bv_offset)) {
bio_put(bio); bio_put(bio);
@ -1171,9 +1171,10 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
{ {
unsigned long start_time = jiffies; unsigned long start_time = jiffies;
int rw_acct = is_write ? REQ_OP_WRITE : REQ_OP_READ; int rw_acct = is_write ? REQ_OP_WRITE : REQ_OP_READ;
struct request_queue *q = zram->disk->queue;
int ret; int ret;
generic_start_io_acct(rw_acct, bvec->bv_len >> SECTOR_SHIFT, generic_start_io_acct(q, rw_acct, bvec->bv_len >> SECTOR_SHIFT,
&zram->disk->part0); &zram->disk->part0);
if (!is_write) { if (!is_write) {
@ -1185,7 +1186,7 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
ret = zram_bvec_write(zram, bvec, index, offset, bio); ret = zram_bvec_write(zram, bvec, index, offset, bio);
} }
generic_end_io_acct(rw_acct, &zram->disk->part0, start_time); generic_end_io_acct(q, rw_acct, &zram->disk->part0, start_time);
if (unlikely(ret < 0)) { if (unlikely(ret < 0)) {
if (!is_write) if (!is_write)

View File

@ -72,7 +72,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
drive->failed_pc = NULL; drive->failed_pc = NULL;
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
(req_op(rq) == REQ_OP_SCSI_IN || req_op(rq) == REQ_OP_SCSI_OUT)) blk_rq_is_scsi(rq))
uptodate = 1; /* FIXME */ uptodate = 1; /* FIXME */
else if (pc->c[0] == GPCMD_REQUEST_SENSE) { else if (pc->c[0] == GPCMD_REQUEST_SENSE) {

View File

@ -49,7 +49,7 @@ void bch_btree_verify(struct btree *b)
v->keys.ops = b->keys.ops; v->keys.ops = b->keys.ops;
bio = bch_bbio_alloc(b->c); bio = bch_bbio_alloc(b->c);
bio->bi_bdev = PTR_CACHE(b->c, &b->key, 0)->bdev; bio_set_dev(bio, PTR_CACHE(b->c, &b->key, 0)->bdev);
bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0); bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0);
bio->bi_iter.bi_size = KEY_SIZE(&v->key) << 9; bio->bi_iter.bi_size = KEY_SIZE(&v->key) << 9;
bio->bi_opf = REQ_OP_READ | REQ_META; bio->bi_opf = REQ_OP_READ | REQ_META;

View File

@ -34,7 +34,7 @@ void __bch_submit_bbio(struct bio *bio, struct cache_set *c)
struct bbio *b = container_of(bio, struct bbio, bio); struct bbio *b = container_of(bio, struct bbio, bio);
bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0); bio->bi_iter.bi_sector = PTR_OFFSET(&b->key, 0);
bio->bi_bdev = PTR_CACHE(c, &b->key, 0)->bdev; bio_set_dev(bio, PTR_CACHE(c, &b->key, 0)->bdev);
b->submit_time_us = local_clock_us(); b->submit_time_us = local_clock_us();
closure_bio_submit(bio, bio->bi_private); closure_bio_submit(bio, bio->bi_private);

View File

@ -53,7 +53,7 @@ reread: left = ca->sb.bucket_size - offset;
bio_reset(bio); bio_reset(bio);
bio->bi_iter.bi_sector = bucket + offset; bio->bi_iter.bi_sector = bucket + offset;
bio->bi_bdev = ca->bdev; bio_set_dev(bio, ca->bdev);
bio->bi_iter.bi_size = len << 9; bio->bi_iter.bi_size = len << 9;
bio->bi_end_io = journal_read_endio; bio->bi_end_io = journal_read_endio;
@ -452,7 +452,7 @@ static void do_journal_discard(struct cache *ca)
bio_set_op_attrs(bio, REQ_OP_DISCARD, 0); bio_set_op_attrs(bio, REQ_OP_DISCARD, 0);
bio->bi_iter.bi_sector = bucket_to_sector(ca->set, bio->bi_iter.bi_sector = bucket_to_sector(ca->set,
ca->sb.d[ja->discard_idx]); ca->sb.d[ja->discard_idx]);
bio->bi_bdev = ca->bdev; bio_set_dev(bio, ca->bdev);
bio->bi_iter.bi_size = bucket_bytes(ca); bio->bi_iter.bi_size = bucket_bytes(ca);
bio->bi_end_io = journal_discard_endio; bio->bi_end_io = journal_discard_endio;
@ -623,7 +623,7 @@ static void journal_write_unlocked(struct closure *cl)
bio_reset(bio); bio_reset(bio);
bio->bi_iter.bi_sector = PTR_OFFSET(k, i); bio->bi_iter.bi_sector = PTR_OFFSET(k, i);
bio->bi_bdev = ca->bdev; bio_set_dev(bio, ca->bdev);
bio->bi_iter.bi_size = sectors << 9; bio->bi_iter.bi_size = sectors << 9;
bio->bi_end_io = journal_write_endio; bio->bi_end_io = journal_write_endio;

View File

@ -607,7 +607,8 @@ static void request_endio(struct bio *bio)
static void bio_complete(struct search *s) static void bio_complete(struct search *s)
{ {
if (s->orig_bio) { if (s->orig_bio) {
generic_end_io_acct(bio_data_dir(s->orig_bio), struct request_queue *q = s->orig_bio->bi_disk->queue;
generic_end_io_acct(q, bio_data_dir(s->orig_bio),
&s->d->disk->part0, s->start_time); &s->d->disk->part0, s->start_time);
trace_bcache_request_end(s->d, s->orig_bio); trace_bcache_request_end(s->d, s->orig_bio);
@ -734,7 +735,7 @@ static void cached_dev_read_done(struct closure *cl)
if (s->iop.bio) { if (s->iop.bio) {
bio_reset(s->iop.bio); bio_reset(s->iop.bio);
s->iop.bio->bi_iter.bi_sector = s->cache_miss->bi_iter.bi_sector; s->iop.bio->bi_iter.bi_sector = s->cache_miss->bi_iter.bi_sector;
s->iop.bio->bi_bdev = s->cache_miss->bi_bdev; bio_copy_dev(s->iop.bio, s->cache_miss);
s->iop.bio->bi_iter.bi_size = s->insert_bio_sectors << 9; s->iop.bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
bch_bio_map(s->iop.bio, NULL); bch_bio_map(s->iop.bio, NULL);
@ -793,7 +794,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
!(bio->bi_opf & REQ_META) && !(bio->bi_opf & REQ_META) &&
s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA) s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA)
reada = min_t(sector_t, dc->readahead >> 9, reada = min_t(sector_t, dc->readahead >> 9,
bdev_sectors(bio->bi_bdev) - bio_end_sector(bio)); get_capacity(bio->bi_disk) - bio_end_sector(bio));
s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada); s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada);
@ -819,7 +820,7 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
goto out_submit; goto out_submit;
cache_bio->bi_iter.bi_sector = miss->bi_iter.bi_sector; cache_bio->bi_iter.bi_sector = miss->bi_iter.bi_sector;
cache_bio->bi_bdev = miss->bi_bdev; bio_copy_dev(cache_bio, miss);
cache_bio->bi_iter.bi_size = s->insert_bio_sectors << 9; cache_bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
cache_bio->bi_end_io = request_endio; cache_bio->bi_end_io = request_endio;
@ -918,7 +919,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0, struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0,
dc->disk.bio_split); dc->disk.bio_split);
flush->bi_bdev = bio->bi_bdev; bio_copy_dev(flush, bio);
flush->bi_end_io = request_endio; flush->bi_end_io = request_endio;
flush->bi_private = cl; flush->bi_private = cl;
flush->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; flush->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
@ -955,13 +956,13 @@ static blk_qc_t cached_dev_make_request(struct request_queue *q,
struct bio *bio) struct bio *bio)
{ {
struct search *s; struct search *s;
struct bcache_device *d = bio->bi_bdev->bd_disk->private_data; struct bcache_device *d = bio->bi_disk->private_data;
struct cached_dev *dc = container_of(d, struct cached_dev, disk); struct cached_dev *dc = container_of(d, struct cached_dev, disk);
int rw = bio_data_dir(bio); int rw = bio_data_dir(bio);
generic_start_io_acct(rw, bio_sectors(bio), &d->disk->part0); generic_start_io_acct(q, rw, bio_sectors(bio), &d->disk->part0);
bio->bi_bdev = dc->bdev; bio_set_dev(bio, dc->bdev);
bio->bi_iter.bi_sector += dc->sb.data_offset; bio->bi_iter.bi_sector += dc->sb.data_offset;
if (cached_dev_get(dc)) { if (cached_dev_get(dc)) {
@ -1071,10 +1072,10 @@ static blk_qc_t flash_dev_make_request(struct request_queue *q,
{ {
struct search *s; struct search *s;
struct closure *cl; struct closure *cl;
struct bcache_device *d = bio->bi_bdev->bd_disk->private_data; struct bcache_device *d = bio->bi_disk->private_data;
int rw = bio_data_dir(bio); int rw = bio_data_dir(bio);
generic_start_io_acct(rw, bio_sectors(bio), &d->disk->part0); generic_start_io_acct(q, rw, bio_sectors(bio), &d->disk->part0);
s = search_alloc(bio, d); s = search_alloc(bio, d);
cl = &s->cl; cl = &s->cl;

View File

@ -257,7 +257,7 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
closure_init(cl, parent); closure_init(cl, parent);
bio_reset(bio); bio_reset(bio);
bio->bi_bdev = dc->bdev; bio_set_dev(bio, dc->bdev);
bio->bi_end_io = write_bdev_super_endio; bio->bi_end_io = write_bdev_super_endio;
bio->bi_private = dc; bio->bi_private = dc;
@ -303,7 +303,7 @@ void bcache_write_super(struct cache_set *c)
SET_CACHE_SYNC(&ca->sb, CACHE_SYNC(&c->sb)); SET_CACHE_SYNC(&ca->sb, CACHE_SYNC(&c->sb));
bio_reset(bio); bio_reset(bio);
bio->bi_bdev = ca->bdev; bio_set_dev(bio, ca->bdev);
bio->bi_end_io = write_super_endio; bio->bi_end_io = write_super_endio;
bio->bi_private = ca; bio->bi_private = ca;
@ -508,7 +508,7 @@ static void prio_io(struct cache *ca, uint64_t bucket, int op,
closure_init_stack(cl); closure_init_stack(cl);
bio->bi_iter.bi_sector = bucket * ca->sb.bucket_size; bio->bi_iter.bi_sector = bucket * ca->sb.bucket_size;
bio->bi_bdev = ca->bdev; bio_set_dev(bio, ca->bdev);
bio->bi_iter.bi_size = bucket_bytes(ca); bio->bi_iter.bi_size = bucket_bytes(ca);
bio->bi_end_io = prio_endio; bio->bi_end_io = prio_endio;

View File

@ -181,7 +181,7 @@ static void write_dirty(struct closure *cl)
dirty_init(w); dirty_init(w);
bio_set_op_attrs(&io->bio, REQ_OP_WRITE, 0); bio_set_op_attrs(&io->bio, REQ_OP_WRITE, 0);
io->bio.bi_iter.bi_sector = KEY_START(&w->key); io->bio.bi_iter.bi_sector = KEY_START(&w->key);
io->bio.bi_bdev = io->dc->bdev; bio_set_dev(&io->bio, io->dc->bdev);
io->bio.bi_end_io = dirty_endio; io->bio.bi_end_io = dirty_endio;
closure_bio_submit(&io->bio, cl); closure_bio_submit(&io->bio, cl);
@ -250,8 +250,7 @@ static void read_dirty(struct cached_dev *dc)
dirty_init(w); dirty_init(w);
bio_set_op_attrs(&io->bio, REQ_OP_READ, 0); bio_set_op_attrs(&io->bio, REQ_OP_READ, 0);
io->bio.bi_iter.bi_sector = PTR_OFFSET(&w->key, 0); io->bio.bi_iter.bi_sector = PTR_OFFSET(&w->key, 0);
io->bio.bi_bdev = PTR_CACHE(dc->disk.c, bio_set_dev(&io->bio, PTR_CACHE(dc->disk.c, &w->key, 0)->bdev);
&w->key, 0)->bdev;
io->bio.bi_end_io = read_dirty_endio; io->bio.bi_end_io = read_dirty_endio;
if (bio_alloc_pages(&io->bio, GFP_KERNEL)) if (bio_alloc_pages(&io->bio, GFP_KERNEL))

View File

@ -18,21 +18,24 @@
*/ */
struct dm_bio_details { struct dm_bio_details {
struct block_device *bi_bdev; struct gendisk *bi_disk;
u8 bi_partno;
unsigned long bi_flags; unsigned long bi_flags;
struct bvec_iter bi_iter; struct bvec_iter bi_iter;
}; };
static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio) static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
{ {
bd->bi_bdev = bio->bi_bdev; bd->bi_disk = bio->bi_disk;
bd->bi_partno = bio->bi_partno;
bd->bi_flags = bio->bi_flags; bd->bi_flags = bio->bi_flags;
bd->bi_iter = bio->bi_iter; bd->bi_iter = bio->bi_iter;
} }
static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio) static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
{ {
bio->bi_bdev = bd->bi_bdev; bio->bi_disk = bd->bi_disk;
bio->bi_partno = bd->bi_partno;
bio->bi_flags = bd->bi_flags; bio->bi_flags = bd->bi_flags;
bio->bi_iter = bd->bi_iter; bio->bi_iter = bd->bi_iter;
} }

View File

@ -616,7 +616,7 @@ static void use_inline_bio(struct dm_buffer *b, int rw, sector_t sector,
bio_init(&b->bio, b->bio_vec, DM_BUFIO_INLINE_VECS); bio_init(&b->bio, b->bio_vec, DM_BUFIO_INLINE_VECS);
b->bio.bi_iter.bi_sector = sector; b->bio.bi_iter.bi_sector = sector;
b->bio.bi_bdev = b->c->bdev; bio_set_dev(&b->bio, b->c->bdev);
b->bio.bi_end_io = inline_endio; b->bio.bi_end_io = inline_endio;
/* /*
* Use of .bi_private isn't a problem here because * Use of .bi_private isn't a problem here because

View File

@ -833,7 +833,7 @@ static bool is_discarded_oblock(struct cache *cache, dm_oblock_t b)
*--------------------------------------------------------------*/ *--------------------------------------------------------------*/
static void remap_to_origin(struct cache *cache, struct bio *bio) static void remap_to_origin(struct cache *cache, struct bio *bio)
{ {
bio->bi_bdev = cache->origin_dev->bdev; bio_set_dev(bio, cache->origin_dev->bdev);
} }
static void remap_to_cache(struct cache *cache, struct bio *bio, static void remap_to_cache(struct cache *cache, struct bio *bio,
@ -842,7 +842,7 @@ static void remap_to_cache(struct cache *cache, struct bio *bio,
sector_t bi_sector = bio->bi_iter.bi_sector; sector_t bi_sector = bio->bi_iter.bi_sector;
sector_t block = from_cblock(cblock); sector_t block = from_cblock(cblock);
bio->bi_bdev = cache->cache_dev->bdev; bio_set_dev(bio, cache->cache_dev->bdev);
if (!block_size_is_power_of_two(cache)) if (!block_size_is_power_of_two(cache))
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector =
(block * cache->sectors_per_block) + (block * cache->sectors_per_block) +

View File

@ -932,9 +932,6 @@ static int dm_crypt_integrity_io_alloc(struct dm_crypt_io *io, struct bio *bio)
bip->bip_iter.bi_size = tag_len; bip->bip_iter.bi_size = tag_len;
bip->bip_iter.bi_sector = io->cc->start + io->sector; bip->bip_iter.bi_sector = io->cc->start + io->sector;
/* We own the metadata, do not let bio_free to release it */
bip->bip_flags &= ~BIP_BLOCK_INTEGRITY;
ret = bio_integrity_add_page(bio, virt_to_page(io->integrity_metadata), ret = bio_integrity_add_page(bio, virt_to_page(io->integrity_metadata),
tag_len, offset_in_page(io->integrity_metadata)); tag_len, offset_in_page(io->integrity_metadata));
if (unlikely(ret != tag_len)) if (unlikely(ret != tag_len))
@ -1546,7 +1543,7 @@ static void clone_init(struct dm_crypt_io *io, struct bio *clone)
clone->bi_private = io; clone->bi_private = io;
clone->bi_end_io = crypt_endio; clone->bi_end_io = crypt_endio;
clone->bi_bdev = cc->dev->bdev; bio_set_dev(clone, cc->dev->bdev);
clone->bi_opf = io->base_bio->bi_opf; clone->bi_opf = io->base_bio->bi_opf;
} }
@ -2795,7 +2792,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
*/ */
if (unlikely(bio->bi_opf & REQ_PREFLUSH || if (unlikely(bio->bi_opf & REQ_PREFLUSH ||
bio_op(bio) == REQ_OP_DISCARD)) { bio_op(bio) == REQ_OP_DISCARD)) {
bio->bi_bdev = cc->dev->bdev; bio_set_dev(bio, cc->dev->bdev);
if (bio_sectors(bio)) if (bio_sectors(bio))
bio->bi_iter.bi_sector = cc->start + bio->bi_iter.bi_sector = cc->start +
dm_target_offset(ti, bio->bi_iter.bi_sector); dm_target_offset(ti, bio->bi_iter.bi_sector);

View File

@ -282,7 +282,7 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
struct delay_c *dc = ti->private; struct delay_c *dc = ti->private;
if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) { if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) {
bio->bi_bdev = dc->dev_write->bdev; bio_set_dev(bio, dc->dev_write->bdev);
if (bio_sectors(bio)) if (bio_sectors(bio))
bio->bi_iter.bi_sector = dc->start_write + bio->bi_iter.bi_sector = dc->start_write +
dm_target_offset(ti, bio->bi_iter.bi_sector); dm_target_offset(ti, bio->bi_iter.bi_sector);
@ -290,7 +290,7 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
return delay_bio(dc, dc->write_delay, bio); return delay_bio(dc, dc->write_delay, bio);
} }
bio->bi_bdev = dc->dev_read->bdev; bio_set_dev(bio, dc->dev_read->bdev);
bio->bi_iter.bi_sector = dc->start_read + bio->bi_iter.bi_sector = dc->start_read +
dm_target_offset(ti, bio->bi_iter.bi_sector); dm_target_offset(ti, bio->bi_iter.bi_sector);

View File

@ -1192,7 +1192,7 @@ static dm_block_t get_block(struct era *era, struct bio *bio)
static void remap_to_origin(struct era *era, struct bio *bio) static void remap_to_origin(struct era *era, struct bio *bio)
{ {
bio->bi_bdev = era->origin_dev->bdev; bio_set_dev(bio, era->origin_dev->bdev);
} }
/*---------------------------------------------------------------- /*----------------------------------------------------------------

View File

@ -274,7 +274,7 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
{ {
struct flakey_c *fc = ti->private; struct flakey_c *fc = ti->private;
bio->bi_bdev = fc->dev->bdev; bio_set_dev(bio, fc->dev->bdev);
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET) if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector =
flakey_map_sector(ti, bio->bi_iter.bi_sector); flakey_map_sector(ti, bio->bi_iter.bi_sector);

View File

@ -250,7 +250,8 @@ struct dm_integrity_io {
struct completion *completion; struct completion *completion;
struct block_device *orig_bi_bdev; struct gendisk *orig_bi_disk;
u8 orig_bi_partno;
bio_end_io_t *orig_bi_end_io; bio_end_io_t *orig_bi_end_io;
struct bio_integrity_payload *orig_bi_integrity; struct bio_integrity_payload *orig_bi_integrity;
struct bvec_iter orig_bi_iter; struct bvec_iter orig_bi_iter;
@ -1164,7 +1165,8 @@ static void integrity_end_io(struct bio *bio)
struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io)); struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io));
bio->bi_iter = dio->orig_bi_iter; bio->bi_iter = dio->orig_bi_iter;
bio->bi_bdev = dio->orig_bi_bdev; bio->bi_disk = dio->orig_bi_disk;
bio->bi_partno = dio->orig_bi_partno;
if (dio->orig_bi_integrity) { if (dio->orig_bi_integrity) {
bio->bi_integrity = dio->orig_bi_integrity; bio->bi_integrity = dio->orig_bi_integrity;
bio->bi_opf |= REQ_INTEGRITY; bio->bi_opf |= REQ_INTEGRITY;
@ -1681,8 +1683,9 @@ sleep:
dio->orig_bi_iter = bio->bi_iter; dio->orig_bi_iter = bio->bi_iter;
dio->orig_bi_bdev = bio->bi_bdev; dio->orig_bi_disk = bio->bi_disk;
bio->bi_bdev = ic->dev->bdev; dio->orig_bi_partno = bio->bi_partno;
bio_set_dev(bio, ic->dev->bdev);
dio->orig_bi_integrity = bio_integrity(bio); dio->orig_bi_integrity = bio_integrity(bio);
bio->bi_integrity = NULL; bio->bi_integrity = NULL;

View File

@ -347,7 +347,7 @@ static void do_region(int op, int op_flags, unsigned region,
bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
bio->bi_iter.bi_sector = where->sector + (where->count - remaining); bio->bi_iter.bi_sector = where->sector + (where->count - remaining);
bio->bi_bdev = where->bdev; bio_set_dev(bio, where->bdev);
bio->bi_end_io = endio; bio->bi_end_io = endio;
bio_set_op_attrs(bio, op, op_flags); bio_set_op_attrs(bio, op, op_flags);
store_io_and_region_in_bio(bio, io, region); store_io_and_region_in_bio(bio, io, region);

View File

@ -88,7 +88,7 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio)
{ {
struct linear_c *lc = ti->private; struct linear_c *lc = ti->private;
bio->bi_bdev = lc->dev->bdev; bio_set_dev(bio, lc->dev->bdev);
if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET) if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET)
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector =
linear_map_sector(ti, bio->bi_iter.bi_sector); linear_map_sector(ti, bio->bi_iter.bi_sector);

View File

@ -198,7 +198,7 @@ static int write_metadata(struct log_writes_c *lc, void *entry,
} }
bio->bi_iter.bi_size = 0; bio->bi_iter.bi_size = 0;
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = lc->logdev->bdev; bio_set_dev(bio, lc->logdev->bdev);
bio->bi_end_io = log_end_io; bio->bi_end_io = log_end_io;
bio->bi_private = lc; bio->bi_private = lc;
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
@ -263,7 +263,7 @@ static int log_one_block(struct log_writes_c *lc,
} }
bio->bi_iter.bi_size = 0; bio->bi_iter.bi_size = 0;
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = lc->logdev->bdev; bio_set_dev(bio, lc->logdev->bdev);
bio->bi_end_io = log_end_io; bio->bi_end_io = log_end_io;
bio->bi_private = lc; bio->bi_private = lc;
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
@ -285,7 +285,7 @@ static int log_one_block(struct log_writes_c *lc,
} }
bio->bi_iter.bi_size = 0; bio->bi_iter.bi_size = 0;
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio->bi_bdev = lc->logdev->bdev; bio_set_dev(bio, lc->logdev->bdev);
bio->bi_end_io = log_end_io; bio->bi_end_io = log_end_io;
bio->bi_private = lc; bio->bi_private = lc;
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
@ -539,7 +539,7 @@ static void normal_map_bio(struct dm_target *ti, struct bio *bio)
{ {
struct log_writes_c *lc = ti->private; struct log_writes_c *lc = ti->private;
bio->bi_bdev = lc->dev->bdev; bio_set_dev(bio, lc->dev->bdev);
} }
static int log_writes_map(struct dm_target *ti, struct bio *bio) static int log_writes_map(struct dm_target *ti, struct bio *bio)

View File

@ -565,7 +565,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m
mpio->nr_bytes = nr_bytes; mpio->nr_bytes = nr_bytes;
bio->bi_status = 0; bio->bi_status = 0;
bio->bi_bdev = pgpath->path.dev->bdev; bio_set_dev(bio, pgpath->path.dev->bdev);
bio->bi_opf |= REQ_FAILFAST_TRANSPORT; bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
if (pgpath->pg->ps.type->start_io) if (pgpath->pg->ps.type->start_io)

View File

@ -145,7 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list)
struct dm_raid1_bio_record { struct dm_raid1_bio_record {
struct mirror *m; struct mirror *m;
/* if details->bi_bdev == NULL, details were not saved */ /* if details->bi_disk == NULL, details were not saved */
struct dm_bio_details details; struct dm_bio_details details;
region_t write_region; region_t write_region;
}; };
@ -464,7 +464,7 @@ static sector_t map_sector(struct mirror *m, struct bio *bio)
static void map_bio(struct mirror *m, struct bio *bio) static void map_bio(struct mirror *m, struct bio *bio)
{ {
bio->bi_bdev = m->dev->bdev; bio_set_dev(bio, m->dev->bdev);
bio->bi_iter.bi_sector = map_sector(m, bio); bio->bi_iter.bi_sector = map_sector(m, bio);
} }
@ -1199,7 +1199,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
struct dm_raid1_bio_record *bio_record = struct dm_raid1_bio_record *bio_record =
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
bio_record->details.bi_bdev = NULL; bio_record->details.bi_disk = NULL;
if (rw == WRITE) { if (rw == WRITE) {
/* Save region for mirror_end_io() handler */ /* Save region for mirror_end_io() handler */
@ -1266,7 +1266,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
goto out; goto out;
if (unlikely(*error)) { if (unlikely(*error)) {
if (!bio_record->details.bi_bdev) { if (!bio_record->details.bi_disk) {
/* /*
* There wasn't enough memory to record necessary * There wasn't enough memory to record necessary
* information for a retry or there was no other * information for a retry or there was no other
@ -1291,7 +1291,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
bd = &bio_record->details; bd = &bio_record->details;
dm_bio_restore(bd, bio); dm_bio_restore(bd, bio);
bio_record->details.bi_bdev = NULL; bio_record->details.bi_disk = NULL;
bio->bi_status = 0; bio->bi_status = 0;
queue_bio(ms, bio, rw); queue_bio(ms, bio, rw);
@ -1301,7 +1301,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
} }
out: out:
bio_record->details.bi_bdev = NULL; bio_record->details.bi_disk = NULL;
return DM_ENDIO_DONE; return DM_ENDIO_DONE;
} }

View File

@ -1663,7 +1663,7 @@ __find_pending_exception(struct dm_snapshot *s,
static void remap_exception(struct dm_snapshot *s, struct dm_exception *e, static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
struct bio *bio, chunk_t chunk) struct bio *bio, chunk_t chunk)
{ {
bio->bi_bdev = s->cow->bdev; bio_set_dev(bio, s->cow->bdev);
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector =
chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) + chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) +
(chunk - e->old_chunk)) + (chunk - e->old_chunk)) +
@ -1681,7 +1681,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
init_tracked_chunk(bio); init_tracked_chunk(bio);
if (bio->bi_opf & REQ_PREFLUSH) { if (bio->bi_opf & REQ_PREFLUSH) {
bio->bi_bdev = s->cow->bdev; bio_set_dev(bio, s->cow->bdev);
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;
} }
@ -1769,7 +1769,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
goto out; goto out;
} }
} else { } else {
bio->bi_bdev = s->origin->bdev; bio_set_dev(bio, s->origin->bdev);
track_chunk(s, bio, chunk); track_chunk(s, bio, chunk);
} }
@ -1802,9 +1802,9 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
if (bio->bi_opf & REQ_PREFLUSH) { if (bio->bi_opf & REQ_PREFLUSH) {
if (!dm_bio_get_target_bio_nr(bio)) if (!dm_bio_get_target_bio_nr(bio))
bio->bi_bdev = s->origin->bdev; bio_set_dev(bio, s->origin->bdev);
else else
bio->bi_bdev = s->cow->bdev; bio_set_dev(bio, s->cow->bdev);
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;
} }
@ -1824,7 +1824,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
chunk >= s->first_merging_chunk && chunk >= s->first_merging_chunk &&
chunk < (s->first_merging_chunk + chunk < (s->first_merging_chunk +
s->num_merging_chunks)) { s->num_merging_chunks)) {
bio->bi_bdev = s->origin->bdev; bio_set_dev(bio, s->origin->bdev);
bio_list_add(&s->bios_queued_during_merge, bio); bio_list_add(&s->bios_queued_during_merge, bio);
r = DM_MAPIO_SUBMITTED; r = DM_MAPIO_SUBMITTED;
goto out_unlock; goto out_unlock;
@ -1838,7 +1838,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
} }
redirect_to_origin: redirect_to_origin:
bio->bi_bdev = s->origin->bdev; bio_set_dev(bio, s->origin->bdev);
if (bio_data_dir(bio) == WRITE) { if (bio_data_dir(bio) == WRITE) {
up_write(&s->lock); up_write(&s->lock);
@ -2285,7 +2285,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio)
struct dm_origin *o = ti->private; struct dm_origin *o = ti->private;
unsigned available_sectors; unsigned available_sectors;
bio->bi_bdev = o->dev->bdev; bio_set_dev(bio, o->dev->bdev);
if (unlikely(bio->bi_opf & REQ_PREFLUSH)) if (unlikely(bio->bi_opf & REQ_PREFLUSH))
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;

View File

@ -270,7 +270,7 @@ static int stripe_map_range(struct stripe_c *sc, struct bio *bio,
stripe_map_range_sector(sc, bio_end_sector(bio), stripe_map_range_sector(sc, bio_end_sector(bio),
target_stripe, &end); target_stripe, &end);
if (begin < end) { if (begin < end) {
bio->bi_bdev = sc->stripe[target_stripe].dev->bdev; bio_set_dev(bio, sc->stripe[target_stripe].dev->bdev);
bio->bi_iter.bi_sector = begin + bio->bi_iter.bi_sector = begin +
sc->stripe[target_stripe].physical_start; sc->stripe[target_stripe].physical_start;
bio->bi_iter.bi_size = to_bytes(end - begin); bio->bi_iter.bi_size = to_bytes(end - begin);
@ -291,7 +291,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
if (bio->bi_opf & REQ_PREFLUSH) { if (bio->bi_opf & REQ_PREFLUSH) {
target_bio_nr = dm_bio_get_target_bio_nr(bio); target_bio_nr = dm_bio_get_target_bio_nr(bio);
BUG_ON(target_bio_nr >= sc->stripes); BUG_ON(target_bio_nr >= sc->stripes);
bio->bi_bdev = sc->stripe[target_bio_nr].dev->bdev; bio_set_dev(bio, sc->stripe[target_bio_nr].dev->bdev);
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;
} }
if (unlikely(bio_op(bio) == REQ_OP_DISCARD) || if (unlikely(bio_op(bio) == REQ_OP_DISCARD) ||
@ -306,7 +306,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
&stripe, &bio->bi_iter.bi_sector); &stripe, &bio->bi_iter.bi_sector);
bio->bi_iter.bi_sector += sc->stripe[stripe].physical_start; bio->bi_iter.bi_sector += sc->stripe[stripe].physical_start;
bio->bi_bdev = sc->stripe[stripe].dev->bdev; bio_set_dev(bio, sc->stripe[stripe].dev->bdev);
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;
} }
@ -430,9 +430,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
return DM_ENDIO_DONE; return DM_ENDIO_DONE;
memset(major_minor, 0, sizeof(major_minor)); memset(major_minor, 0, sizeof(major_minor));
sprintf(major_minor, "%d:%d", sprintf(major_minor, "%d:%d", MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)));
MAJOR(disk_devt(bio->bi_bdev->bd_disk)),
MINOR(disk_devt(bio->bi_bdev->bd_disk)));
/* /*
* Test to see which stripe drive triggered the event * Test to see which stripe drive triggered the event

View File

@ -322,7 +322,7 @@ static int switch_map(struct dm_target *ti, struct bio *bio)
sector_t offset = dm_target_offset(ti, bio->bi_iter.bi_sector); sector_t offset = dm_target_offset(ti, bio->bi_iter.bi_sector);
unsigned path_nr = switch_get_path_nr(sctx, offset); unsigned path_nr = switch_get_path_nr(sctx, offset);
bio->bi_bdev = sctx->path_list[path_nr].dmdev->bdev; bio_set_dev(bio, sctx->path_list[path_nr].dmdev->bdev);
bio->bi_iter.bi_sector = sctx->path_list[path_nr].start + offset; bio->bi_iter.bi_sector = sctx->path_list[path_nr].start + offset;
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;

View File

@ -679,7 +679,7 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
struct pool *pool = tc->pool; struct pool *pool = tc->pool;
sector_t bi_sector = bio->bi_iter.bi_sector; sector_t bi_sector = bio->bi_iter.bi_sector;
bio->bi_bdev = tc->pool_dev->bdev; bio_set_dev(bio, tc->pool_dev->bdev);
if (block_size_is_power_of_two(pool)) if (block_size_is_power_of_two(pool))
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector =
(block << pool->sectors_per_block_shift) | (block << pool->sectors_per_block_shift) |
@ -691,7 +691,7 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
static void remap_to_origin(struct thin_c *tc, struct bio *bio) static void remap_to_origin(struct thin_c *tc, struct bio *bio)
{ {
bio->bi_bdev = tc->origin_dev->bdev; bio_set_dev(bio, tc->origin_dev->bdev);
} }
static int bio_triggers_commit(struct thin_c *tc, struct bio *bio) static int bio_triggers_commit(struct thin_c *tc, struct bio *bio)
@ -3313,7 +3313,7 @@ static int pool_map(struct dm_target *ti, struct bio *bio)
* As this is a singleton target, ti->begin is always zero. * As this is a singleton target, ti->begin is always zero.
*/ */
spin_lock_irqsave(&pool->lock, flags); spin_lock_irqsave(&pool->lock, flags);
bio->bi_bdev = pt->data_dev->bdev; bio_set_dev(bio, pt->data_dev->bdev);
r = DM_MAPIO_REMAPPED; r = DM_MAPIO_REMAPPED;
spin_unlock_irqrestore(&pool->lock, flags); spin_unlock_irqrestore(&pool->lock, flags);

View File

@ -637,7 +637,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
struct dm_verity *v = ti->private; struct dm_verity *v = ti->private;
struct dm_verity_io *io; struct dm_verity_io *io;
bio->bi_bdev = v->data_dev->bdev; bio_set_dev(bio, v->data_dev->bdev);
bio->bi_iter.bi_sector = verity_map_sector(v, bio->bi_iter.bi_sector); bio->bi_iter.bi_sector = verity_map_sector(v, bio->bi_iter.bi_sector);
if (((unsigned)bio->bi_iter.bi_sector | bio_sectors(bio)) & if (((unsigned)bio->bi_iter.bi_sector | bio_sectors(bio)) &

View File

@ -409,7 +409,7 @@ static struct dmz_mblock *dmz_fetch_mblock(struct dmz_metadata *zmd,
} }
bio->bi_iter.bi_sector = dmz_blk2sect(block); bio->bi_iter.bi_sector = dmz_blk2sect(block);
bio->bi_bdev = zmd->dev->bdev; bio_set_dev(bio, zmd->dev->bdev);
bio->bi_private = mblk; bio->bi_private = mblk;
bio->bi_end_io = dmz_mblock_bio_end_io; bio->bi_end_io = dmz_mblock_bio_end_io;
bio_set_op_attrs(bio, REQ_OP_READ, REQ_META | REQ_PRIO); bio_set_op_attrs(bio, REQ_OP_READ, REQ_META | REQ_PRIO);
@ -564,7 +564,7 @@ static void dmz_write_mblock(struct dmz_metadata *zmd, struct dmz_mblock *mblk,
set_bit(DMZ_META_WRITING, &mblk->state); set_bit(DMZ_META_WRITING, &mblk->state);
bio->bi_iter.bi_sector = dmz_blk2sect(block); bio->bi_iter.bi_sector = dmz_blk2sect(block);
bio->bi_bdev = zmd->dev->bdev; bio_set_dev(bio, zmd->dev->bdev);
bio->bi_private = mblk; bio->bi_private = mblk;
bio->bi_end_io = dmz_mblock_bio_end_io; bio->bi_end_io = dmz_mblock_bio_end_io;
bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_META | REQ_PRIO); bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_META | REQ_PRIO);
@ -586,7 +586,7 @@ static int dmz_rdwr_block(struct dmz_metadata *zmd, int op, sector_t block,
return -ENOMEM; return -ENOMEM;
bio->bi_iter.bi_sector = dmz_blk2sect(block); bio->bi_iter.bi_sector = dmz_blk2sect(block);
bio->bi_bdev = zmd->dev->bdev; bio_set_dev(bio, zmd->dev->bdev);
bio_set_op_attrs(bio, op, REQ_SYNC | REQ_META | REQ_PRIO); bio_set_op_attrs(bio, op, REQ_SYNC | REQ_META | REQ_PRIO);
bio_add_page(bio, page, DMZ_BLOCK_SIZE, 0); bio_add_page(bio, page, DMZ_BLOCK_SIZE, 0);
ret = submit_bio_wait(bio); ret = submit_bio_wait(bio);

View File

@ -238,7 +238,7 @@ static void dmz_submit_write_bio(struct dmz_target *dmz, struct dm_zone *zone,
struct dmz_bioctx *bioctx = dm_per_bio_data(bio, sizeof(struct dmz_bioctx)); struct dmz_bioctx *bioctx = dm_per_bio_data(bio, sizeof(struct dmz_bioctx));
/* Setup and submit the BIO */ /* Setup and submit the BIO */
bio->bi_bdev = dmz->dev->bdev; bio_set_dev(bio, dmz->dev->bdev);
bio->bi_iter.bi_sector = dmz_start_sect(dmz->metadata, zone) + dmz_blk2sect(chunk_block); bio->bi_iter.bi_sector = dmz_start_sect(dmz->metadata, zone) + dmz_blk2sect(chunk_block);
atomic_inc(&bioctx->ref); atomic_inc(&bioctx->ref);
generic_make_request(bio); generic_make_request(bio);
@ -586,7 +586,7 @@ static int dmz_map(struct dm_target *ti, struct bio *bio)
(unsigned long long)dmz_chunk_block(dmz->dev, dmz_bio_block(bio)), (unsigned long long)dmz_chunk_block(dmz->dev, dmz_bio_block(bio)),
(unsigned int)dmz_bio_blocks(bio)); (unsigned int)dmz_bio_blocks(bio));
bio->bi_bdev = dev->bdev; bio_set_dev(bio, dev->bdev);
if (!nr_sectors && bio_op(bio) != REQ_OP_WRITE) if (!nr_sectors && bio_op(bio) != REQ_OP_WRITE)
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;

View File

@ -510,7 +510,7 @@ static void start_io_acct(struct dm_io *io)
io->start_time = jiffies; io->start_time = jiffies;
cpu = part_stat_lock(); cpu = part_stat_lock();
part_round_stats(cpu, &dm_disk(md)->part0); part_round_stats(md->queue, cpu, &dm_disk(md)->part0);
part_stat_unlock(); part_stat_unlock();
atomic_set(&dm_disk(md)->part0.in_flight[rw], atomic_set(&dm_disk(md)->part0.in_flight[rw],
atomic_inc_return(&md->pending[rw])); atomic_inc_return(&md->pending[rw]));
@ -529,7 +529,7 @@ static void end_io_acct(struct dm_io *io)
int pending; int pending;
int rw = bio_data_dir(bio); int rw = bio_data_dir(bio);
generic_end_io_acct(rw, &dm_disk(md)->part0, io->start_time); generic_end_io_acct(md->queue, rw, &dm_disk(md)->part0, io->start_time);
if (unlikely(dm_stats_used(&md->stats))) if (unlikely(dm_stats_used(&md->stats)))
dm_stats_account_io(&md->stats, bio_data_dir(bio), dm_stats_account_io(&md->stats, bio_data_dir(bio),
@ -841,10 +841,10 @@ static void clone_endio(struct bio *bio)
if (unlikely(error == BLK_STS_TARGET)) { if (unlikely(error == BLK_STS_TARGET)) {
if (bio_op(bio) == REQ_OP_WRITE_SAME && if (bio_op(bio) == REQ_OP_WRITE_SAME &&
!bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors) !bio->bi_disk->queue->limits.max_write_same_sectors)
disable_write_same(md); disable_write_same(md);
if (bio_op(bio) == REQ_OP_WRITE_ZEROES && if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
!bdev_get_queue(bio->bi_bdev)->limits.max_write_zeroes_sectors) !bio->bi_disk->queue->limits.max_write_zeroes_sectors)
disable_write_zeroes(md); disable_write_zeroes(md);
} }
@ -1205,8 +1205,8 @@ static void __map_bio(struct dm_target_io *tio)
break; break;
case DM_MAPIO_REMAPPED: case DM_MAPIO_REMAPPED:
/* the bio has been remapped so dispatch it */ /* the bio has been remapped so dispatch it */
trace_block_bio_remap(bdev_get_queue(clone->bi_bdev), clone, trace_block_bio_remap(clone->bi_disk->queue, clone,
tio->io->bio->bi_bdev->bd_dev, sector); bio_dev(tio->io->bio), sector);
generic_make_request(clone); generic_make_request(clone);
break; break;
case DM_MAPIO_KILL: case DM_MAPIO_KILL:
@ -1532,7 +1532,7 @@ static blk_qc_t dm_make_request(struct request_queue *q, struct bio *bio)
map = dm_get_live_table(md, &srcu_idx); map = dm_get_live_table(md, &srcu_idx);
generic_start_io_acct(rw, bio_sectors(bio), &dm_disk(md)->part0); generic_start_io_acct(q, rw, bio_sectors(bio), &dm_disk(md)->part0);
/* if we're suspended, we have to queue this io for later */ /* if we're suspended, we have to queue this io for later */
if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) { if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
@ -1786,7 +1786,7 @@ static struct mapped_device *alloc_dev(int minor)
goto bad; goto bad;
bio_init(&md->flush_bio, NULL, 0); bio_init(&md->flush_bio, NULL, 0);
md->flush_bio.bi_bdev = md->bdev; bio_set_dev(&md->flush_bio, md->bdev);
md->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC; md->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC;
dm_stats_init(&md->stats); dm_stats_init(&md->stats);

View File

@ -216,12 +216,12 @@ static bool faulty_make_request(struct mddev *mddev, struct bio *bio)
if (failit) { if (failit) {
struct bio *b = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set); struct bio *b = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
b->bi_bdev = conf->rdev->bdev; bio_set_dev(b, conf->rdev->bdev);
b->bi_private = bio; b->bi_private = bio;
b->bi_end_io = faulty_fail; b->bi_end_io = faulty_fail;
bio = b; bio = b;
} else } else
bio->bi_bdev = conf->rdev->bdev; bio_set_dev(bio, conf->rdev->bdev);
generic_make_request(bio); generic_make_request(bio);
return true; return true;

View File

@ -275,17 +275,17 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio)
bio = split; bio = split;
} }
bio->bi_bdev = tmp_dev->rdev->bdev; bio_set_dev(bio, tmp_dev->rdev->bdev);
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector - bio->bi_iter.bi_sector = bio->bi_iter.bi_sector -
start_sector + data_offset; start_sector + data_offset;
if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) { !blk_queue_discard(bio->bi_disk->queue))) {
/* Just ignore it */ /* Just ignore it */
bio_endio(bio); bio_endio(bio);
} else { } else {
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(bio->bi_bdev), trace_block_bio_remap(bio->bi_disk->queue,
bio, disk_devt(mddev->gendisk), bio, disk_devt(mddev->gendisk),
bio_sector); bio_sector);
mddev_check_writesame(mddev, bio); mddev_check_writesame(mddev, bio);

View File

@ -422,7 +422,7 @@ static void submit_flushes(struct work_struct *ws)
bi = bio_alloc_mddev(GFP_NOIO, 0, mddev); bi = bio_alloc_mddev(GFP_NOIO, 0, mddev);
bi->bi_end_io = md_end_flush; bi->bi_end_io = md_end_flush;
bi->bi_private = rdev; bi->bi_private = rdev;
bi->bi_bdev = rdev->bdev; bio_set_dev(bi, rdev->bdev);
bi->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; bi->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
atomic_inc(&mddev->flush_pending); atomic_inc(&mddev->flush_pending);
submit_bio(bi); submit_bio(bi);
@ -772,7 +772,7 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
bio->bi_bdev = rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev; bio_set_dev(bio, rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
bio_add_page(bio, page, size, 0); bio_add_page(bio, page, size, 0);
bio->bi_private = rdev; bio->bi_private = rdev;
@ -803,8 +803,10 @@ int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
struct bio *bio = md_bio_alloc_sync(rdev->mddev); struct bio *bio = md_bio_alloc_sync(rdev->mddev);
int ret; int ret;
bio->bi_bdev = (metadata_op && rdev->meta_bdev) ? if (metadata_op && rdev->meta_bdev)
rdev->meta_bdev : rdev->bdev; bio_set_dev(bio, rdev->meta_bdev);
else
bio_set_dev(bio, rdev->bdev);
bio_set_op_attrs(bio, op, op_flags); bio_set_op_attrs(bio, op, op_flags);
if (metadata_op) if (metadata_op)
bio->bi_iter.bi_sector = sector + rdev->sb_start; bio->bi_iter.bi_sector = sector + rdev->sb_start;

View File

@ -509,6 +509,11 @@ static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sect
atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io); atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
} }
static inline void md_sync_acct_bio(struct bio *bio, unsigned long nr_sectors)
{
atomic_add(nr_sectors, &bio->bi_disk->sync_io);
}
struct md_personality struct md_personality
{ {
char *name; char *name;
@ -721,14 +726,14 @@ static inline void mddev_clear_unsupported_flags(struct mddev *mddev,
static inline void mddev_check_writesame(struct mddev *mddev, struct bio *bio) static inline void mddev_check_writesame(struct mddev *mddev, struct bio *bio)
{ {
if (bio_op(bio) == REQ_OP_WRITE_SAME && if (bio_op(bio) == REQ_OP_WRITE_SAME &&
!bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors) !bio->bi_disk->queue->limits.max_write_same_sectors)
mddev->queue->limits.max_write_same_sectors = 0; mddev->queue->limits.max_write_same_sectors = 0;
} }
static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio) static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio)
{ {
if (bio_op(bio) == REQ_OP_WRITE_ZEROES && if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
!bdev_get_queue(bio->bi_bdev)->limits.max_write_zeroes_sectors) !bio->bi_disk->queue->limits.max_write_zeroes_sectors)
mddev->queue->limits.max_write_zeroes_sectors = 0; mddev->queue->limits.max_write_zeroes_sectors = 0;
} }
#endif /* _MD_MD_H */ #endif /* _MD_MD_H */

View File

@ -134,7 +134,7 @@ static bool multipath_make_request(struct mddev *mddev, struct bio * bio)
__bio_clone_fast(&mp_bh->bio, bio); __bio_clone_fast(&mp_bh->bio, bio);
mp_bh->bio.bi_iter.bi_sector += multipath->rdev->data_offset; mp_bh->bio.bi_iter.bi_sector += multipath->rdev->data_offset;
mp_bh->bio.bi_bdev = multipath->rdev->bdev; bio_set_dev(&mp_bh->bio, multipath->rdev->bdev);
mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT; mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT;
mp_bh->bio.bi_end_io = multipath_end_request; mp_bh->bio.bi_end_io = multipath_end_request;
mp_bh->bio.bi_private = mp_bh; mp_bh->bio.bi_private = mp_bh;
@ -345,17 +345,17 @@ static void multipathd(struct md_thread *thread)
if ((mp_bh->path = multipath_map (conf))<0) { if ((mp_bh->path = multipath_map (conf))<0) {
pr_err("multipath: %s: unrecoverable IO read error for block %llu\n", pr_err("multipath: %s: unrecoverable IO read error for block %llu\n",
bdevname(bio->bi_bdev,b), bio_devname(bio, b),
(unsigned long long)bio->bi_iter.bi_sector); (unsigned long long)bio->bi_iter.bi_sector);
multipath_end_bh_io(mp_bh, BLK_STS_IOERR); multipath_end_bh_io(mp_bh, BLK_STS_IOERR);
} else { } else {
pr_err("multipath: %s: redirecting sector %llu to another IO path\n", pr_err("multipath: %s: redirecting sector %llu to another IO path\n",
bdevname(bio->bi_bdev,b), bio_devname(bio, b),
(unsigned long long)bio->bi_iter.bi_sector); (unsigned long long)bio->bi_iter.bi_sector);
*bio = *(mp_bh->master_bio); *bio = *(mp_bh->master_bio);
bio->bi_iter.bi_sector += bio->bi_iter.bi_sector +=
conf->multipaths[mp_bh->path].rdev->data_offset; conf->multipaths[mp_bh->path].rdev->data_offset;
bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev; bio_set_dev(bio, conf->multipaths[mp_bh->path].rdev->bdev);
bio->bi_opf |= REQ_FAILFAST_TRANSPORT; bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
bio->bi_end_io = multipath_end_request; bio->bi_end_io = multipath_end_request;
bio->bi_private = mp_bh; bio->bi_private = mp_bh;

View File

@ -588,14 +588,13 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
zone = find_zone(mddev->private, &sector); zone = find_zone(mddev->private, &sector);
tmp_dev = map_sector(mddev, zone, sector, &sector); tmp_dev = map_sector(mddev, zone, sector, &sector);
bio->bi_bdev = tmp_dev->bdev; bio_set_dev(bio, tmp_dev->bdev);
bio->bi_iter.bi_sector = sector + zone->dev_start + bio->bi_iter.bi_sector = sector + zone->dev_start +
tmp_dev->data_offset; tmp_dev->data_offset;
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(bio->bi_bdev), trace_block_bio_remap(bio->bi_disk->queue, bio,
bio, disk_devt(mddev->gendisk), disk_devt(mddev->gendisk), bio_sector);
bio_sector);
mddev_check_writesame(mddev, bio); mddev_check_writesame(mddev, bio);
mddev_check_write_zeroes(mddev, bio); mddev_check_write_zeroes(mddev, bio);
generic_make_request(bio); generic_make_request(bio);

View File

@ -786,13 +786,13 @@ static void flush_bio_list(struct r1conf *conf, struct bio *bio)
while (bio) { /* submit pending writes */ while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next; struct bio *next = bio->bi_next;
struct md_rdev *rdev = (void*)bio->bi_bdev; struct md_rdev *rdev = (void *)bio->bi_disk;
bio->bi_next = NULL; bio->bi_next = NULL;
bio->bi_bdev = rdev->bdev; bio_set_dev(bio, rdev->bdev);
if (test_bit(Faulty, &rdev->flags)) { if (test_bit(Faulty, &rdev->flags)) {
bio_io_error(bio); bio_io_error(bio);
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) !blk_queue_discard(bio->bi_disk->queue)))
/* Just ignore it */ /* Just ignore it */
bio_endio(bio); bio_endio(bio);
else else
@ -1273,7 +1273,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
read_bio->bi_iter.bi_sector = r1_bio->sector + read_bio->bi_iter.bi_sector = r1_bio->sector +
mirror->rdev->data_offset; mirror->rdev->data_offset;
read_bio->bi_bdev = mirror->rdev->bdev; bio_set_dev(read_bio, mirror->rdev->bdev);
read_bio->bi_end_io = raid1_end_read_request; read_bio->bi_end_io = raid1_end_read_request;
bio_set_op_attrs(read_bio, op, do_sync); bio_set_op_attrs(read_bio, op, do_sync);
if (test_bit(FailFast, &mirror->rdev->flags) && if (test_bit(FailFast, &mirror->rdev->flags) &&
@ -1282,9 +1282,8 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
read_bio->bi_private = r1_bio; read_bio->bi_private = r1_bio;
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(read_bio->bi_bdev), trace_block_bio_remap(read_bio->bi_disk->queue, read_bio,
read_bio, disk_devt(mddev->gendisk), disk_devt(mddev->gendisk), r1_bio->sector);
r1_bio->sector);
generic_make_request(read_bio); generic_make_request(read_bio);
} }
@ -1496,7 +1495,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
mbio->bi_iter.bi_sector = (r1_bio->sector + mbio->bi_iter.bi_sector = (r1_bio->sector +
conf->mirrors[i].rdev->data_offset); conf->mirrors[i].rdev->data_offset);
mbio->bi_bdev = conf->mirrors[i].rdev->bdev; bio_set_dev(mbio, conf->mirrors[i].rdev->bdev);
mbio->bi_end_io = raid1_end_write_request; mbio->bi_end_io = raid1_end_write_request;
mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA)); mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
if (test_bit(FailFast, &conf->mirrors[i].rdev->flags) && if (test_bit(FailFast, &conf->mirrors[i].rdev->flags) &&
@ -1508,11 +1507,11 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
atomic_inc(&r1_bio->remaining); atomic_inc(&r1_bio->remaining);
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(mbio->bi_bdev), trace_block_bio_remap(mbio->bi_disk->queue,
mbio, disk_devt(mddev->gendisk), mbio, disk_devt(mddev->gendisk),
r1_bio->sector); r1_bio->sector);
/* flush_pending_writes() needs access to the rdev so...*/ /* flush_pending_writes() needs access to the rdev so...*/
mbio->bi_bdev = (void*)conf->mirrors[i].rdev; mbio->bi_disk = (void *)conf->mirrors[i].rdev;
cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug)); cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug));
if (cb) if (cb)
@ -1990,8 +1989,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
* Don't fail devices as that won't really help. * Don't fail devices as that won't really help.
*/ */
pr_crit_ratelimited("md/raid1:%s: %s: unrecoverable I/O read error for block %llu\n", pr_crit_ratelimited("md/raid1:%s: %s: unrecoverable I/O read error for block %llu\n",
mdname(mddev), mdname(mddev), bio_devname(bio, b),
bdevname(bio->bi_bdev, b),
(unsigned long long)r1_bio->sector); (unsigned long long)r1_bio->sector);
for (d = 0; d < conf->raid_disks * 2; d++) { for (d = 0; d < conf->raid_disks * 2; d++) {
rdev = conf->mirrors[d].rdev; rdev = conf->mirrors[d].rdev;
@ -2082,7 +2080,7 @@ static void process_checks(struct r1bio *r1_bio)
b->bi_status = status; b->bi_status = status;
b->bi_iter.bi_sector = r1_bio->sector + b->bi_iter.bi_sector = r1_bio->sector +
conf->mirrors[i].rdev->data_offset; conf->mirrors[i].rdev->data_offset;
b->bi_bdev = conf->mirrors[i].rdev->bdev; bio_set_dev(b, conf->mirrors[i].rdev->bdev);
b->bi_end_io = end_sync_read; b->bi_end_io = end_sync_read;
rp->raid_bio = r1_bio; rp->raid_bio = r1_bio;
b->bi_private = rp; b->bi_private = rp;
@ -2350,7 +2348,7 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
bio_trim(wbio, sector - r1_bio->sector, sectors); bio_trim(wbio, sector - r1_bio->sector, sectors);
wbio->bi_iter.bi_sector += rdev->data_offset; wbio->bi_iter.bi_sector += rdev->data_offset;
wbio->bi_bdev = rdev->bdev; bio_set_dev(wbio, rdev->bdev);
if (submit_bio_wait(wbio) < 0) if (submit_bio_wait(wbio) < 0)
/* failure! */ /* failure! */
@ -2440,7 +2438,6 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
struct mddev *mddev = conf->mddev; struct mddev *mddev = conf->mddev;
struct bio *bio; struct bio *bio;
struct md_rdev *rdev; struct md_rdev *rdev;
dev_t bio_dev;
sector_t bio_sector; sector_t bio_sector;
clear_bit(R1BIO_ReadError, &r1_bio->state); clear_bit(R1BIO_ReadError, &r1_bio->state);
@ -2454,7 +2451,6 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
*/ */
bio = r1_bio->bios[r1_bio->read_disk]; bio = r1_bio->bios[r1_bio->read_disk];
bio_dev = bio->bi_bdev->bd_dev;
bio_sector = conf->mirrors[r1_bio->read_disk].rdev->data_offset + r1_bio->sector; bio_sector = conf->mirrors[r1_bio->read_disk].rdev->data_offset + r1_bio->sector;
bio_put(bio); bio_put(bio);
r1_bio->bios[r1_bio->read_disk] = NULL; r1_bio->bios[r1_bio->read_disk] = NULL;
@ -2727,7 +2723,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
if (bio->bi_end_io) { if (bio->bi_end_io) {
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
bio->bi_iter.bi_sector = sector_nr + rdev->data_offset; bio->bi_iter.bi_sector = sector_nr + rdev->data_offset;
bio->bi_bdev = rdev->bdev; bio_set_dev(bio, rdev->bdev);
if (test_bit(FailFast, &rdev->flags)) if (test_bit(FailFast, &rdev->flags))
bio->bi_opf |= MD_FAILFAST; bio->bi_opf |= MD_FAILFAST;
} }
@ -2853,7 +2849,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
bio = r1_bio->bios[i]; bio = r1_bio->bios[i];
if (bio->bi_end_io == end_sync_read) { if (bio->bi_end_io == end_sync_read) {
read_targets--; read_targets--;
md_sync_acct(bio->bi_bdev, nr_sectors); md_sync_acct_bio(bio, nr_sectors);
if (read_targets == 1) if (read_targets == 1)
bio->bi_opf &= ~MD_FAILFAST; bio->bi_opf &= ~MD_FAILFAST;
generic_make_request(bio); generic_make_request(bio);
@ -2862,7 +2858,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
} else { } else {
atomic_set(&r1_bio->remaining, 1); atomic_set(&r1_bio->remaining, 1);
bio = r1_bio->bios[r1_bio->read_disk]; bio = r1_bio->bios[r1_bio->read_disk];
md_sync_acct(bio->bi_bdev, nr_sectors); md_sync_acct_bio(bio, nr_sectors);
if (read_targets == 1) if (read_targets == 1)
bio->bi_opf &= ~MD_FAILFAST; bio->bi_opf &= ~MD_FAILFAST;
generic_make_request(bio); generic_make_request(bio);

View File

@ -901,13 +901,13 @@ static void flush_pending_writes(struct r10conf *conf)
while (bio) { /* submit pending writes */ while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next; struct bio *next = bio->bi_next;
struct md_rdev *rdev = (void*)bio->bi_bdev; struct md_rdev *rdev = (void*)bio->bi_disk;
bio->bi_next = NULL; bio->bi_next = NULL;
bio->bi_bdev = rdev->bdev; bio_set_dev(bio, rdev->bdev);
if (test_bit(Faulty, &rdev->flags)) { if (test_bit(Faulty, &rdev->flags)) {
bio_io_error(bio); bio_io_error(bio);
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) !blk_queue_discard(bio->bi_disk->queue)))
/* Just ignore it */ /* Just ignore it */
bio_endio(bio); bio_endio(bio);
else else
@ -1085,13 +1085,13 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
while (bio) { /* submit pending writes */ while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next; struct bio *next = bio->bi_next;
struct md_rdev *rdev = (void*)bio->bi_bdev; struct md_rdev *rdev = (void*)bio->bi_disk;
bio->bi_next = NULL; bio->bi_next = NULL;
bio->bi_bdev = rdev->bdev; bio_set_dev(bio, rdev->bdev);
if (test_bit(Faulty, &rdev->flags)) { if (test_bit(Faulty, &rdev->flags)) {
bio_io_error(bio); bio_io_error(bio);
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) !blk_queue_discard(bio->bi_disk->queue)))
/* Just ignore it */ /* Just ignore it */
bio_endio(bio); bio_endio(bio);
else else
@ -1200,7 +1200,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr + read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr +
choose_data_offset(r10_bio, rdev); choose_data_offset(r10_bio, rdev);
read_bio->bi_bdev = rdev->bdev; bio_set_dev(read_bio, rdev->bdev);
read_bio->bi_end_io = raid10_end_read_request; read_bio->bi_end_io = raid10_end_read_request;
bio_set_op_attrs(read_bio, op, do_sync); bio_set_op_attrs(read_bio, op, do_sync);
if (test_bit(FailFast, &rdev->flags) && if (test_bit(FailFast, &rdev->flags) &&
@ -1209,7 +1209,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
read_bio->bi_private = r10_bio; read_bio->bi_private = r10_bio;
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(read_bio->bi_bdev), trace_block_bio_remap(read_bio->bi_disk->queue,
read_bio, disk_devt(mddev->gendisk), read_bio, disk_devt(mddev->gendisk),
r10_bio->sector); r10_bio->sector);
generic_make_request(read_bio); generic_make_request(read_bio);
@ -1249,7 +1249,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr + mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
choose_data_offset(r10_bio, rdev)); choose_data_offset(r10_bio, rdev));
mbio->bi_bdev = rdev->bdev; bio_set_dev(mbio, rdev->bdev);
mbio->bi_end_io = raid10_end_write_request; mbio->bi_end_io = raid10_end_write_request;
bio_set_op_attrs(mbio, op, do_sync | do_fua); bio_set_op_attrs(mbio, op, do_sync | do_fua);
if (!replacement && test_bit(FailFast, if (!replacement && test_bit(FailFast,
@ -1259,11 +1259,11 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
mbio->bi_private = r10_bio; mbio->bi_private = r10_bio;
if (conf->mddev->gendisk) if (conf->mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(mbio->bi_bdev), trace_block_bio_remap(mbio->bi_disk->queue,
mbio, disk_devt(conf->mddev->gendisk), mbio, disk_devt(conf->mddev->gendisk),
r10_bio->sector); r10_bio->sector);
/* flush_pending_writes() needs access to the rdev so...*/ /* flush_pending_writes() needs access to the rdev so...*/
mbio->bi_bdev = (void *)rdev; mbio->bi_disk = (void *)rdev;
atomic_inc(&r10_bio->remaining); atomic_inc(&r10_bio->remaining);
@ -2094,7 +2094,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
if (test_bit(FailFast, &conf->mirrors[d].rdev->flags)) if (test_bit(FailFast, &conf->mirrors[d].rdev->flags))
tbio->bi_opf |= MD_FAILFAST; tbio->bi_opf |= MD_FAILFAST;
tbio->bi_iter.bi_sector += conf->mirrors[d].rdev->data_offset; tbio->bi_iter.bi_sector += conf->mirrors[d].rdev->data_offset;
tbio->bi_bdev = conf->mirrors[d].rdev->bdev; bio_set_dev(tbio, conf->mirrors[d].rdev->bdev);
generic_make_request(tbio); generic_make_request(tbio);
} }
@ -2552,7 +2552,7 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
wsector = r10_bio->devs[i].addr + (sector - r10_bio->sector); wsector = r10_bio->devs[i].addr + (sector - r10_bio->sector);
wbio->bi_iter.bi_sector = wsector + wbio->bi_iter.bi_sector = wsector +
choose_data_offset(r10_bio, rdev); choose_data_offset(r10_bio, rdev);
wbio->bi_bdev = rdev->bdev; bio_set_dev(wbio, rdev->bdev);
bio_set_op_attrs(wbio, REQ_OP_WRITE, 0); bio_set_op_attrs(wbio, REQ_OP_WRITE, 0);
if (submit_bio_wait(wbio) < 0) if (submit_bio_wait(wbio) < 0)
@ -2575,7 +2575,6 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
struct bio *bio; struct bio *bio;
struct r10conf *conf = mddev->private; struct r10conf *conf = mddev->private;
struct md_rdev *rdev = r10_bio->devs[slot].rdev; struct md_rdev *rdev = r10_bio->devs[slot].rdev;
dev_t bio_dev;
sector_t bio_last_sector; sector_t bio_last_sector;
/* we got a read error. Maybe the drive is bad. Maybe just /* we got a read error. Maybe the drive is bad. Maybe just
@ -2587,7 +2586,6 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
* frozen. * frozen.
*/ */
bio = r10_bio->devs[slot].bio; bio = r10_bio->devs[slot].bio;
bio_dev = bio->bi_bdev->bd_dev;
bio_last_sector = r10_bio->devs[slot].addr + rdev->data_offset + r10_bio->sectors; bio_last_sector = r10_bio->devs[slot].addr + rdev->data_offset + r10_bio->sectors;
bio_put(bio); bio_put(bio);
r10_bio->devs[slot].bio = NULL; r10_bio->devs[slot].bio = NULL;
@ -2950,7 +2948,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
/* Again, very different code for resync and recovery. /* Again, very different code for resync and recovery.
* Both must result in an r10bio with a list of bios that * Both must result in an r10bio with a list of bios that
* have bi_end_io, bi_sector, bi_bdev set, * have bi_end_io, bi_sector, bi_disk set,
* and bi_private set to the r10bio. * and bi_private set to the r10bio.
* For recovery, we may actually create several r10bios * For recovery, we may actually create several r10bios
* with 2 bios in each, that correspond to the bios in the main one. * with 2 bios in each, that correspond to the bios in the main one.
@ -3095,7 +3093,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
from_addr = r10_bio->devs[j].addr; from_addr = r10_bio->devs[j].addr;
bio->bi_iter.bi_sector = from_addr + bio->bi_iter.bi_sector = from_addr +
rdev->data_offset; rdev->data_offset;
bio->bi_bdev = rdev->bdev; bio_set_dev(bio, rdev->bdev);
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
/* and we write to 'i' (if not in_sync) */ /* and we write to 'i' (if not in_sync) */
@ -3117,7 +3115,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
bio->bi_iter.bi_sector = to_addr bio->bi_iter.bi_sector = to_addr
+ mrdev->data_offset; + mrdev->data_offset;
bio->bi_bdev = mrdev->bdev; bio_set_dev(bio, mrdev->bdev);
atomic_inc(&r10_bio->remaining); atomic_inc(&r10_bio->remaining);
} else } else
r10_bio->devs[1].bio->bi_end_io = NULL; r10_bio->devs[1].bio->bi_end_io = NULL;
@ -3143,7 +3141,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
bio->bi_iter.bi_sector = to_addr + bio->bi_iter.bi_sector = to_addr +
mreplace->data_offset; mreplace->data_offset;
bio->bi_bdev = mreplace->bdev; bio_set_dev(bio, mreplace->bdev);
atomic_inc(&r10_bio->remaining); atomic_inc(&r10_bio->remaining);
break; break;
} }
@ -3289,7 +3287,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
if (test_bit(FailFast, &rdev->flags)) if (test_bit(FailFast, &rdev->flags))
bio->bi_opf |= MD_FAILFAST; bio->bi_opf |= MD_FAILFAST;
bio->bi_iter.bi_sector = sector + rdev->data_offset; bio->bi_iter.bi_sector = sector + rdev->data_offset;
bio->bi_bdev = rdev->bdev; bio_set_dev(bio, rdev->bdev);
count++; count++;
rdev = rcu_dereference(conf->mirrors[d].replacement); rdev = rcu_dereference(conf->mirrors[d].replacement);
@ -3311,7 +3309,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
if (test_bit(FailFast, &rdev->flags)) if (test_bit(FailFast, &rdev->flags))
bio->bi_opf |= MD_FAILFAST; bio->bi_opf |= MD_FAILFAST;
bio->bi_iter.bi_sector = sector + rdev->data_offset; bio->bi_iter.bi_sector = sector + rdev->data_offset;
bio->bi_bdev = rdev->bdev; bio_set_dev(bio, rdev->bdev);
count++; count++;
rcu_read_unlock(); rcu_read_unlock();
} }
@ -3367,7 +3365,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
r10_bio->sectors = nr_sectors; r10_bio->sectors = nr_sectors;
if (bio->bi_end_io == end_sync_read) { if (bio->bi_end_io == end_sync_read) {
md_sync_acct(bio->bi_bdev, nr_sectors); md_sync_acct_bio(bio, nr_sectors);
bio->bi_status = 0; bio->bi_status = 0;
generic_make_request(bio); generic_make_request(bio);
} }
@ -4383,7 +4381,7 @@ read_more:
read_bio = bio_alloc_mddev(GFP_KERNEL, RESYNC_PAGES, mddev); read_bio = bio_alloc_mddev(GFP_KERNEL, RESYNC_PAGES, mddev);
read_bio->bi_bdev = rdev->bdev; bio_set_dev(read_bio, rdev->bdev);
read_bio->bi_iter.bi_sector = (r10_bio->devs[r10_bio->read_slot].addr read_bio->bi_iter.bi_sector = (r10_bio->devs[r10_bio->read_slot].addr
+ rdev->data_offset); + rdev->data_offset);
read_bio->bi_private = r10_bio; read_bio->bi_private = r10_bio;
@ -4417,7 +4415,7 @@ read_more:
if (!rdev2 || test_bit(Faulty, &rdev2->flags)) if (!rdev2 || test_bit(Faulty, &rdev2->flags))
continue; continue;
b->bi_bdev = rdev2->bdev; bio_set_dev(b, rdev2->bdev);
b->bi_iter.bi_sector = r10_bio->devs[s/2].addr + b->bi_iter.bi_sector = r10_bio->devs[s/2].addr +
rdev2->new_data_offset; rdev2->new_data_offset;
b->bi_end_io = end_reshape_write; b->bi_end_io = end_reshape_write;
@ -4449,7 +4447,7 @@ read_more:
r10_bio->sectors = nr_sectors; r10_bio->sectors = nr_sectors;
/* Now submit the read */ /* Now submit the read */
md_sync_acct(read_bio->bi_bdev, r10_bio->sectors); md_sync_acct_bio(read_bio, r10_bio->sectors);
atomic_inc(&r10_bio->remaining); atomic_inc(&r10_bio->remaining);
read_bio->bi_next = NULL; read_bio->bi_next = NULL;
generic_make_request(read_bio); generic_make_request(read_bio);
@ -4511,7 +4509,7 @@ static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio)
} }
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
rcu_read_unlock(); rcu_read_unlock();
md_sync_acct(b->bi_bdev, r10_bio->sectors); md_sync_acct_bio(b, r10_bio->sectors);
atomic_inc(&r10_bio->remaining); atomic_inc(&r10_bio->remaining);
b->bi_next = NULL; b->bi_next = NULL;
generic_make_request(b); generic_make_request(b);

View File

@ -745,7 +745,7 @@ static struct bio *r5l_bio_alloc(struct r5l_log *log)
struct bio *bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, log->bs); struct bio *bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, log->bs);
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
bio->bi_bdev = log->rdev->bdev; bio_set_dev(bio, log->rdev->bdev);
bio->bi_iter.bi_sector = log->rdev->data_offset + log->log_start; bio->bi_iter.bi_sector = log->rdev->data_offset + log->log_start;
return bio; return bio;
@ -1313,7 +1313,7 @@ void r5l_flush_stripe_to_raid(struct r5l_log *log)
if (!do_flush) if (!do_flush)
return; return;
bio_reset(&log->flush_bio); bio_reset(&log->flush_bio);
log->flush_bio.bi_bdev = log->rdev->bdev; bio_set_dev(&log->flush_bio, log->rdev->bdev);
log->flush_bio.bi_end_io = r5l_log_flush_endio; log->flush_bio.bi_end_io = r5l_log_flush_endio;
log->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; log->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
submit_bio(&log->flush_bio); submit_bio(&log->flush_bio);
@ -1691,7 +1691,7 @@ static int r5l_recovery_fetch_ra_pool(struct r5l_log *log,
sector_t offset) sector_t offset)
{ {
bio_reset(ctx->ra_bio); bio_reset(ctx->ra_bio);
ctx->ra_bio->bi_bdev = log->rdev->bdev; bio_set_dev(ctx->ra_bio, log->rdev->bdev);
bio_set_op_attrs(ctx->ra_bio, REQ_OP_READ, 0); bio_set_op_attrs(ctx->ra_bio, REQ_OP_READ, 0);
ctx->ra_bio->bi_iter.bi_sector = log->rdev->data_offset + offset; ctx->ra_bio->bi_iter.bi_sector = log->rdev->data_offset + offset;

View File

@ -415,7 +415,7 @@ static void ppl_submit_iounit_bio(struct ppl_io_unit *io, struct bio *bio)
pr_debug("%s: seq: %llu size: %u sector: %llu dev: %s\n", pr_debug("%s: seq: %llu size: %u sector: %llu dev: %s\n",
__func__, io->seq, bio->bi_iter.bi_size, __func__, io->seq, bio->bi_iter.bi_size,
(unsigned long long)bio->bi_iter.bi_sector, (unsigned long long)bio->bi_iter.bi_sector,
bdevname(bio->bi_bdev, b)); bio_devname(bio, b));
submit_bio(bio); submit_bio(bio);
} }
@ -453,7 +453,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
bio->bi_end_io = ppl_log_endio; bio->bi_end_io = ppl_log_endio;
bio->bi_opf = REQ_OP_WRITE | REQ_FUA; bio->bi_opf = REQ_OP_WRITE | REQ_FUA;
bio->bi_bdev = log->rdev->bdev; bio_set_dev(bio, log->rdev->bdev);
bio->bi_iter.bi_sector = log->rdev->ppl.sector; bio->bi_iter.bi_sector = log->rdev->ppl.sector;
bio_add_page(bio, io->header_page, PAGE_SIZE, 0); bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
@ -468,7 +468,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES,
ppl_conf->bs); ppl_conf->bs);
bio->bi_opf = prev->bi_opf; bio->bi_opf = prev->bi_opf;
bio->bi_bdev = prev->bi_bdev; bio_copy_dev(bio, prev);
bio->bi_iter.bi_sector = bio_end_sector(prev); bio->bi_iter.bi_sector = bio_end_sector(prev);
bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0); bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0);

View File

@ -1096,7 +1096,7 @@ again:
set_bit(STRIPE_IO_STARTED, &sh->state); set_bit(STRIPE_IO_STARTED, &sh->state);
bi->bi_bdev = rdev->bdev; bio_set_dev(bi, rdev->bdev);
bio_set_op_attrs(bi, op, op_flags); bio_set_op_attrs(bi, op, op_flags);
bi->bi_end_io = op_is_write(op) bi->bi_end_io = op_is_write(op)
? raid5_end_write_request ? raid5_end_write_request
@ -1145,7 +1145,7 @@ again:
set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
if (conf->mddev->gendisk) if (conf->mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), trace_block_bio_remap(bi->bi_disk->queue,
bi, disk_devt(conf->mddev->gendisk), bi, disk_devt(conf->mddev->gendisk),
sh->dev[i].sector); sh->dev[i].sector);
if (should_defer && op_is_write(op)) if (should_defer && op_is_write(op))
@ -1160,7 +1160,7 @@ again:
set_bit(STRIPE_IO_STARTED, &sh->state); set_bit(STRIPE_IO_STARTED, &sh->state);
rbi->bi_bdev = rrdev->bdev; bio_set_dev(rbi, rrdev->bdev);
bio_set_op_attrs(rbi, op, op_flags); bio_set_op_attrs(rbi, op, op_flags);
BUG_ON(!op_is_write(op)); BUG_ON(!op_is_write(op));
rbi->bi_end_io = raid5_end_write_request; rbi->bi_end_io = raid5_end_write_request;
@ -1193,7 +1193,7 @@ again:
if (op == REQ_OP_DISCARD) if (op == REQ_OP_DISCARD)
rbi->bi_vcnt = 0; rbi->bi_vcnt = 0;
if (conf->mddev->gendisk) if (conf->mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), trace_block_bio_remap(rbi->bi_disk->queue,
rbi, disk_devt(conf->mddev->gendisk), rbi, disk_devt(conf->mddev->gendisk),
sh->dev[i].sector); sh->dev[i].sector);
if (should_defer && op_is_write(op)) if (should_defer && op_is_write(op))
@ -5092,10 +5092,12 @@ static int raid5_congested(struct mddev *mddev, int bits)
static int in_chunk_boundary(struct mddev *mddev, struct bio *bio) static int in_chunk_boundary(struct mddev *mddev, struct bio *bio)
{ {
struct r5conf *conf = mddev->private; struct r5conf *conf = mddev->private;
sector_t sector = bio->bi_iter.bi_sector + get_start_sect(bio->bi_bdev); sector_t sector = bio->bi_iter.bi_sector;
unsigned int chunk_sectors; unsigned int chunk_sectors;
unsigned int bio_sectors = bio_sectors(bio); unsigned int bio_sectors = bio_sectors(bio);
WARN_ON_ONCE(bio->bi_partno);
chunk_sectors = min(conf->chunk_sectors, conf->prev_chunk_sectors); chunk_sectors = min(conf->chunk_sectors, conf->prev_chunk_sectors);
return chunk_sectors >= return chunk_sectors >=
((sector & (chunk_sectors - 1)) + bio_sectors); ((sector & (chunk_sectors - 1)) + bio_sectors);
@ -5231,7 +5233,7 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio)
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
rcu_read_unlock(); rcu_read_unlock();
raid_bio->bi_next = (void*)rdev; raid_bio->bi_next = (void*)rdev;
align_bi->bi_bdev = rdev->bdev; bio_set_dev(align_bi, rdev->bdev);
bio_clear_flag(align_bi, BIO_SEG_VALID); bio_clear_flag(align_bi, BIO_SEG_VALID);
if (is_badblock(rdev, align_bi->bi_iter.bi_sector, if (is_badblock(rdev, align_bi->bi_iter.bi_sector,
@ -5253,7 +5255,7 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio)
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), trace_block_bio_remap(align_bi->bi_disk->queue,
align_bi, disk_devt(mddev->gendisk), align_bi, disk_devt(mddev->gendisk),
raid_bio->bi_iter.bi_sector); raid_bio->bi_iter.bi_sector);
generic_make_request(align_bi); generic_make_request(align_bi);

View File

@ -390,21 +390,22 @@ int nd_region_activate(struct nd_region *nd_region);
void __nd_iostat_start(struct bio *bio, unsigned long *start); void __nd_iostat_start(struct bio *bio, unsigned long *start);
static inline bool nd_iostat_start(struct bio *bio, unsigned long *start) static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
{ {
struct gendisk *disk = bio->bi_bdev->bd_disk; struct gendisk *disk = bio->bi_disk;
if (!blk_queue_io_stat(disk->queue)) if (!blk_queue_io_stat(disk->queue))
return false; return false;
*start = jiffies; *start = jiffies;
generic_start_io_acct(bio_data_dir(bio), generic_start_io_acct(disk->queue, bio_data_dir(bio),
bio_sectors(bio), &disk->part0); bio_sectors(bio), &disk->part0);
return true; return true;
} }
static inline void nd_iostat_end(struct bio *bio, unsigned long start) static inline void nd_iostat_end(struct bio *bio, unsigned long start)
{ {
struct gendisk *disk = bio->bi_bdev->bd_disk; struct gendisk *disk = bio->bi_disk;
generic_end_io_acct(bio_data_dir(bio), &disk->part0, start); generic_end_io_acct(disk->queue, bio_data_dir(bio), &disk->part0,
start);
} }
static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector, static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
unsigned int len) unsigned int len)

View File

@ -613,11 +613,7 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
if (!disk) if (!disk)
goto submit; goto submit;
bio->bi_bdev = bdget_disk(disk, 0); bio->bi_disk = disk;
if (!bio->bi_bdev) {
ret = -ENODEV;
goto out_unmap;
}
if (meta_buffer && meta_len) { if (meta_buffer && meta_len) {
struct bio_integrity_payload *bip; struct bio_integrity_payload *bip;
@ -668,11 +664,8 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
out_free_meta: out_free_meta:
kfree(meta); kfree(meta);
out_unmap: out_unmap:
if (bio) { if (bio)
if (disk && bio->bi_bdev)
bdput(bio->bi_bdev);
blk_rq_unmap_user(bio); blk_rq_unmap_user(bio);
}
out: out:
blk_mq_free_request(req); blk_mq_free_request(req);
return ret; return ret;

View File

@ -2168,7 +2168,6 @@ static const struct blk_mq_ops nvme_fc_mq_ops = {
.complete = nvme_fc_complete_rq, .complete = nvme_fc_complete_rq,
.init_request = nvme_fc_init_request, .init_request = nvme_fc_init_request,
.exit_request = nvme_fc_exit_request, .exit_request = nvme_fc_exit_request,
.reinit_request = nvme_fc_reinit_request,
.init_hctx = nvme_fc_init_hctx, .init_hctx = nvme_fc_init_hctx,
.poll = nvme_fc_poll, .poll = nvme_fc_poll,
.timeout = nvme_fc_timeout, .timeout = nvme_fc_timeout,
@ -2269,7 +2268,7 @@ nvme_fc_reinit_io_queues(struct nvme_fc_ctrl *ctrl)
nvme_fc_init_io_queues(ctrl); nvme_fc_init_io_queues(ctrl);
ret = blk_mq_reinit_tagset(&ctrl->tag_set); ret = blk_mq_reinit_tagset(&ctrl->tag_set, nvme_fc_reinit_request);
if (ret) if (ret)
goto out_free_io_queues; goto out_free_io_queues;
@ -2655,7 +2654,6 @@ static const struct blk_mq_ops nvme_fc_admin_mq_ops = {
.complete = nvme_fc_complete_rq, .complete = nvme_fc_complete_rq,
.init_request = nvme_fc_init_request, .init_request = nvme_fc_init_request,
.exit_request = nvme_fc_exit_request, .exit_request = nvme_fc_exit_request,
.reinit_request = nvme_fc_reinit_request,
.init_hctx = nvme_fc_init_admin_hctx, .init_hctx = nvme_fc_init_admin_hctx,
.timeout = nvme_fc_timeout, .timeout = nvme_fc_timeout,
}; };

View File

@ -643,17 +643,9 @@ static int nvme_nvm_submit_user_cmd(struct request_queue *q,
vcmd->ph_rw.metadata = cpu_to_le64(metadata_dma); vcmd->ph_rw.metadata = cpu_to_le64(metadata_dma);
} }
if (!disk) bio->bi_disk = disk;
goto submit;
bio->bi_bdev = bdget_disk(disk, 0);
if (!bio->bi_bdev) {
ret = -ENODEV;
goto err_meta;
}
} }
submit:
blk_execute_rq(q, NULL, rq, 0); blk_execute_rq(q, NULL, rq, 0);
if (nvme_req(rq)->flags & NVME_REQ_CANCELLED) if (nvme_req(rq)->flags & NVME_REQ_CANCELLED)
@ -673,11 +665,8 @@ err_meta:
if (meta_buf && meta_len) if (meta_buf && meta_len)
dma_pool_free(dev->dma_pool, metadata, metadata_dma); dma_pool_free(dev->dma_pool, metadata, metadata_dma);
err_map: err_map:
if (bio) { if (bio)
if (disk && bio->bi_bdev)
bdput(bio->bi_bdev);
blk_rq_unmap_user(bio); blk_rq_unmap_user(bio);
}
err_ppa: err_ppa:
if (ppa_buf && ppa_len) if (ppa_buf && ppa_len)
dma_pool_free(dev->dma_pool, ppa_list, ppa_dma); dma_pool_free(dev->dma_pool, ppa_list, ppa_dma);

View File

@ -711,14 +711,16 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
if (ctrl->ctrl.queue_count > 1) { if (ctrl->ctrl.queue_count > 1) {
nvme_rdma_free_io_queues(ctrl); nvme_rdma_free_io_queues(ctrl);
ret = blk_mq_reinit_tagset(&ctrl->tag_set); ret = blk_mq_reinit_tagset(&ctrl->tag_set,
nvme_rdma_reinit_request);
if (ret) if (ret)
goto requeue; goto requeue;
} }
nvme_rdma_stop_and_free_queue(&ctrl->queues[0]); nvme_rdma_stop_and_free_queue(&ctrl->queues[0]);
ret = blk_mq_reinit_tagset(&ctrl->admin_tag_set); ret = blk_mq_reinit_tagset(&ctrl->admin_tag_set,
nvme_rdma_reinit_request);
if (ret) if (ret)
goto requeue; goto requeue;
@ -1521,7 +1523,6 @@ static const struct blk_mq_ops nvme_rdma_mq_ops = {
.complete = nvme_rdma_complete_rq, .complete = nvme_rdma_complete_rq,
.init_request = nvme_rdma_init_request, .init_request = nvme_rdma_init_request,
.exit_request = nvme_rdma_exit_request, .exit_request = nvme_rdma_exit_request,
.reinit_request = nvme_rdma_reinit_request,
.init_hctx = nvme_rdma_init_hctx, .init_hctx = nvme_rdma_init_hctx,
.poll = nvme_rdma_poll, .poll = nvme_rdma_poll,
.timeout = nvme_rdma_timeout, .timeout = nvme_rdma_timeout,
@ -1533,7 +1534,6 @@ static const struct blk_mq_ops nvme_rdma_admin_mq_ops = {
.complete = nvme_rdma_complete_rq, .complete = nvme_rdma_complete_rq,
.init_request = nvme_rdma_init_request, .init_request = nvme_rdma_init_request,
.exit_request = nvme_rdma_exit_request, .exit_request = nvme_rdma_exit_request,
.reinit_request = nvme_rdma_reinit_request,
.init_hctx = nvme_rdma_init_admin_hctx, .init_hctx = nvme_rdma_init_admin_hctx,
.timeout = nvme_rdma_timeout, .timeout = nvme_rdma_timeout,
}; };
@ -1731,7 +1731,8 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
} }
if (ctrl->ctrl.queue_count > 1) { if (ctrl->ctrl.queue_count > 1) {
ret = blk_mq_reinit_tagset(&ctrl->tag_set); ret = blk_mq_reinit_tagset(&ctrl->tag_set,
nvme_rdma_reinit_request);
if (ret) if (ret)
goto del_dead_ctrl; goto del_dead_ctrl;

Some files were not shown because too many files have changed in this diff Show More