mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'for-4.8/core' of git://git.kernel.dk/linux-block
Pull core block updates from Jens Axboe:
- the big change is the cleanup from Mike Christie, cleaning up our
uses of command types and modified flags. This is what will throw
some merge conflicts
- regression fix for the above for btrfs, from Vincent
- following up to the above, better packing of struct request from
Christoph
- a 2038 fix for blktrace from Arnd
- a few trivial/spelling fixes from Bart Van Assche
- a front merge check fix from Damien, which could cause issues on
SMR drives
- Atari partition fix from Gabriel
- convert cfq to highres timers, since jiffies isn't granular enough
for some devices these days. From Jan and Jeff
- CFQ priority boost fix idle classes, from me
- cleanup series from Ming, improving our bio/bvec iteration
- a direct issue fix for blk-mq from Omar
- fix for plug merging not involving the IO scheduler, like we do for
other types of merges. From Tahsin
- expose DAX type internally and through sysfs. From Toshi and Yigal
* 'for-4.8/core' of git://git.kernel.dk/linux-block: (76 commits)
block: Fix front merge check
block: do not merge requests without consulting with io scheduler
block: Fix spelling in a source code comment
block: expose QUEUE_FLAG_DAX in sysfs
block: add QUEUE_FLAG_DAX for devices to advertise their DAX support
Btrfs: fix comparison in __btrfs_map_block()
block: atari: Return early for unsupported sector size
Doc: block: Fix a typo in queue-sysfs.txt
cfq-iosched: Charge at least 1 jiffie instead of 1 ns
cfq-iosched: Fix regression in bonnie++ rewrite performance
cfq-iosched: Convert slice_resid from u64 to s64
block: Convert fifo_time from ulong to u64
blktrace: avoid using timespec
block/blk-cgroup.c: Declare local symbols static
block/bio-integrity.c: Add #include "blk.h"
block/partition-generic.c: Remove a set-but-not-used variable
block: bio: kill BIO_MAX_SIZE
cfq-iosched: temporarily boost queue priority for idle classes
block: drbd: avoid to use BIO_MAX_SIZE
block: bio: remove BIO_MAX_SECTORS
...
This commit is contained in:
commit
d05d7f4079
199 files changed
+1919
-1524
No files matched your search
@@ -53,7 +53,7 @@ disk.
|
||||
|
||||
logical_block_size (RO)
|
||||
-----------------------
|
||||
This is the logcal block size of the device, in bytes.
|
||||
This is the logical block size of the device, in bytes.
|
||||
|
||||
max_hw_sectors_kb (RO)
|
||||
----------------------
|
||||
|
||||
@@ -20,11 +20,11 @@ a forced cache flush, and the Force Unit Access (FUA) flag for requests.
|
||||
Explicit cache flushes
|
||||
----------------------
|
||||
|
||||
The REQ_FLUSH flag can be OR ed into the r/w flags of a bio submitted from
|
||||
The REQ_PREFLUSH flag can be OR ed into the r/w flags of a bio submitted from
|
||||
the filesystem and will make sure the volatile cache of the storage device
|
||||
has been flushed before the actual I/O operation is started. This explicitly
|
||||
guarantees that previously completed write requests are on non-volatile
|
||||
storage before the flagged bio starts. In addition the REQ_FLUSH flag can be
|
||||
storage before the flagged bio starts. In addition the REQ_PREFLUSH flag can be
|
||||
set on an otherwise empty bio structure, which causes only an explicit cache
|
||||
flush without any dependent I/O. It is recommend to use
|
||||
the blkdev_issue_flush() helper for a pure cache flush.
|
||||
@@ -41,21 +41,21 @@ signaled after the data has been committed to non-volatile storage.
|
||||
Implementation details for filesystems
|
||||
--------------------------------------
|
||||
|
||||
Filesystems can simply set the REQ_FLUSH and REQ_FUA bits and do not have to
|
||||
Filesystems can simply set the REQ_PREFLUSH and REQ_FUA bits and do not have to
|
||||
worry if the underlying devices need any explicit cache flushing and how
|
||||
the Forced Unit Access is implemented. The REQ_FLUSH and REQ_FUA flags
|
||||
the Forced Unit Access is implemented. The REQ_PREFLUSH and REQ_FUA flags
|
||||
may both be set on a single bio.
|
||||
|
||||
|
||||
Implementation details for make_request_fn based block drivers
|
||||
--------------------------------------------------------------
|
||||
|
||||
These drivers will always see the REQ_FLUSH and REQ_FUA bits as they sit
|
||||
These drivers will always see the REQ_PREFLUSH and REQ_FUA bits as they sit
|
||||
directly below the submit_bio interface. For remapping drivers the REQ_FUA
|
||||
bits need to be propagated to underlying devices, and a global flush needs
|
||||
to be implemented for bios with the REQ_FLUSH bit set. For real device
|
||||
drivers that do not have a volatile cache the REQ_FLUSH and REQ_FUA bits
|
||||
on non-empty bios can simply be ignored, and REQ_FLUSH requests without
|
||||
to be implemented for bios with the REQ_PREFLUSH bit set. For real device
|
||||
drivers that do not have a volatile cache the REQ_PREFLUSH and REQ_FUA bits
|
||||
on non-empty bios can simply be ignored, and REQ_PREFLUSH requests without
|
||||
data can be completed successfully without doing any work. Drivers for
|
||||
devices with volatile caches need to implement the support for these
|
||||
flags themselves without any help from the block layer.
|
||||
@@ -65,17 +65,17 @@ Implementation details for request_fn based block drivers
|
||||
--------------------------------------------------------------
|
||||
|
||||
For devices that do not support volatile write caches there is no driver
|
||||
support required, the block layer completes empty REQ_FLUSH requests before
|
||||
entering the driver and strips off the REQ_FLUSH and REQ_FUA bits from
|
||||
support required, the block layer completes empty REQ_PREFLUSH requests before
|
||||
entering the driver and strips off the REQ_PREFLUSH and REQ_FUA bits from
|
||||
requests that have a payload. For devices with volatile write caches the
|
||||
driver needs to tell the block layer that it supports flushing caches by
|
||||
doing:
|
||||
|
||||
blk_queue_write_cache(sdkp->disk->queue, true, false);
|
||||
|
||||
and handle empty REQ_FLUSH requests in its prep_fn/request_fn. Note that
|
||||
REQ_FLUSH requests with a payload are automatically turned into a sequence
|
||||
of an empty REQ_FLUSH request followed by the actual write by the block
|
||||
and handle empty REQ_OP_FLUSH requests in its prep_fn/request_fn. Note that
|
||||
REQ_PREFLUSH requests with a payload are automatically turned into a sequence
|
||||
of an empty REQ_OP_FLUSH request followed by the actual write by the block
|
||||
layer. For devices that also support the FUA bit the block layer needs
|
||||
to be told to pass through the REQ_FUA bit using:
|
||||
|
||||
@@ -83,4 +83,4 @@ to be told to pass through the REQ_FUA bit using:
|
||||
|
||||
and the driver must handle write requests that have the REQ_FUA bit set
|
||||
in prep_fn/request_fn. If the FUA bit is not natively supported the block
|
||||
layer turns it into an empty REQ_FLUSH request after the actual write.
|
||||
layer turns it into an empty REQ_OP_FLUSH request after the actual write.
|
||||
@@ -14,14 +14,14 @@ Log Ordering
|
||||
|
||||
We log things in order of completion once we are sure the write is no longer in
|
||||
cache. This means that normal WRITE requests are not actually logged until the
|
||||
next REQ_FLUSH request. This is to make it easier for userspace to replay the
|
||||
log in a way that correlates to what is on disk and not what is in cache, to
|
||||
make it easier to detect improper waiting/flushing.
|
||||
next REQ_PREFLUSH request. This is to make it easier for userspace to replay
|
||||
the log in a way that correlates to what is on disk and not what is in cache,
|
||||
to make it easier to detect improper waiting/flushing.
|
||||
|
||||
This works by attaching all WRITE requests to a list once the write completes.
|
||||
Once we see a REQ_FLUSH request we splice this list onto the request and once
|
||||
Once we see a REQ_PREFLUSH request we splice this list onto the request and once
|
||||
the FLUSH request completes we log all of the WRITEs and then the FLUSH. Only
|
||||
completed WRITEs, at the time the REQ_FLUSH is issued, are added in order to
|
||||
completed WRITEs, at the time the REQ_PREFLUSH is issued, are added in order to
|
||||
simulate the worst case scenario with regard to power failures. Consider the
|
||||
following example (W means write, C means complete):
|
||||
|
||||
|
||||
@@ -1286,7 +1286,7 @@ static void do_ubd_request(struct request_queue *q)
|
||||
|
||||
req = dev->request;
|
||||
|
||||
if (req->cmd_flags & REQ_FLUSH) {
|
||||
if (req_op(req) == REQ_OP_FLUSH) {
|
||||
io_req = kmalloc(sizeof(struct io_thread_req),
|
||||
GFP_ATOMIC);
|
||||
if (io_req == NULL) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/bio.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/slab.h>
|
||||
#include "blk.h"
|
||||
|
||||
#define BIP_INLINE_VECS 4
|
||||
|
||||
|
||||
+9
-11
@@ -656,16 +656,15 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
|
||||
bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
|
||||
if (!bio)
|
||||
return NULL;
|
||||
|
||||
bio->bi_bdev = bio_src->bi_bdev;
|
||||
bio->bi_rw = bio_src->bi_rw;
|
||||
bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
|
||||
bio->bi_iter.bi_size = bio_src->bi_iter.bi_size;
|
||||
|
||||
if (bio->bi_rw & REQ_DISCARD)
|
||||
if (bio_op(bio) == REQ_OP_DISCARD)
|
||||
goto integrity_clone;
|
||||
|
||||
if (bio->bi_rw & REQ_WRITE_SAME) {
|
||||
if (bio_op(bio) == REQ_OP_WRITE_SAME) {
|
||||
bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
|
||||
goto integrity_clone;
|
||||
}
|
||||
@@ -854,21 +853,20 @@ static void submit_bio_wait_endio(struct bio *bio)
|
||||
|
||||
/**
|
||||
* submit_bio_wait - submit a bio, and wait until it completes
|
||||
* @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
|
||||
* @bio: The &struct bio which describes the I/O
|
||||
*
|
||||
* Simple wrapper around submit_bio(). Returns 0 on success, or the error from
|
||||
* bio_endio() on failure.
|
||||
*/
|
||||
int submit_bio_wait(int rw, struct bio *bio)
|
||||
int submit_bio_wait(struct bio *bio)
|
||||
{
|
||||
struct submit_bio_ret ret;
|
||||
|
||||
rw |= REQ_SYNC;
|
||||
init_completion(&ret.event);
|
||||
bio->bi_private = &ret;
|
||||
bio->bi_end_io = submit_bio_wait_endio;
|
||||
submit_bio(rw, bio);
|
||||
bio->bi_rw |= REQ_SYNC;
|
||||
submit_bio(bio);
|
||||
wait_for_completion_io(&ret.event);
|
||||
|
||||
return ret.error;
|
||||
@@ -1167,7 +1165,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
|
||||
goto out_bmd;
|
||||
|
||||
if (iter->type & WRITE)
|
||||
bio->bi_rw |= REQ_WRITE;
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
|
||||
ret = 0;
|
||||
|
||||
@@ -1337,7 +1335,7 @@ struct bio *bio_map_user_iov(struct request_queue *q,
|
||||
* set data direction, and check if mapped pages need bouncing
|
||||
*/
|
||||
if (iter->type & WRITE)
|
||||
bio->bi_rw |= REQ_WRITE;
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
|
||||
bio_set_flag(bio, BIO_USER_MAPPED);
|
||||
|
||||
@@ -1530,7 +1528,7 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
|
||||
bio->bi_private = data;
|
||||
} else {
|
||||
bio->bi_end_io = bio_copy_kern_endio;
|
||||
bio->bi_rw |= REQ_WRITE;
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
}
|
||||
|
||||
return bio;
|
||||
@@ -1785,7 +1783,7 @@ struct bio *bio_split(struct bio *bio, int sectors,
|
||||
* Discards need a mutable bio_vec to accommodate the payload
|
||||
* required by the DSM TRIM and UNMAP commands.
|
||||
*/
|
||||
if (bio->bi_rw & REQ_DISCARD)
|
||||
if (bio_op(bio) == REQ_OP_DISCARD)
|
||||
split = bio_clone_bioset(bio, gfp, bs);
|
||||
else
|
||||
split = bio_clone_fast(bio, gfp, bs);
|
||||
|
||||
+2
-2
@@ -905,7 +905,7 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cftype blkcg_files[] = {
|
||||
static struct cftype blkcg_files[] = {
|
||||
{
|
||||
.name = "stat",
|
||||
.flags = CFTYPE_NOT_ON_ROOT,
|
||||
@@ -914,7 +914,7 @@ struct cftype blkcg_files[] = {
|
||||
{ } /* terminate */
|
||||
};
|
||||
|
||||
struct cftype blkcg_legacy_files[] = {
|
||||
static struct cftype blkcg_legacy_files[] = {
|
||||
{
|
||||
.name = "reset_stats",
|
||||
.write_u64 = blkcg_reset_stats,
|
||||
|
||||
+51
-45
@@ -959,10 +959,10 @@ static void __freed_request(struct request_list *rl, int sync)
|
||||
* A request has just been released. Account for it, update the full and
|
||||
* congestion status, wake up any waiters. Called under q->queue_lock.
|
||||
*/
|
||||
static void freed_request(struct request_list *rl, unsigned int flags)
|
||||
static void freed_request(struct request_list *rl, int op, unsigned int flags)
|
||||
{
|
||||
struct request_queue *q = rl->q;
|
||||
int sync = rw_is_sync(flags);
|
||||
int sync = rw_is_sync(op, flags);
|
||||
|
||||
q->nr_rqs[sync]--;
|
||||
rl->count[sync]--;
|
||||
@@ -1029,7 +1029,7 @@ static bool blk_rq_should_init_elevator(struct bio *bio)
|
||||
* Flush requests do not use the elevator so skip initialization.
|
||||
* This allows a request to share the flush and elevator data.
|
||||
*/
|
||||
if (bio->bi_rw & (REQ_FLUSH | REQ_FUA))
|
||||
if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -1054,7 +1054,8 @@ static struct io_context *rq_ioc(struct bio *bio)
|
||||
/**
|
||||
* __get_request - get a free request
|
||||
* @rl: request list to allocate from
|
||||
* @rw_flags: RW and SYNC flags
|
||||
* @op: REQ_OP_READ/REQ_OP_WRITE
|
||||
* @op_flags: rq_flag_bits
|
||||
* @bio: bio to allocate request for (can be %NULL)
|
||||
* @gfp_mask: allocation mask
|
||||
*
|
||||
@@ -1065,21 +1066,22 @@ static struct io_context *rq_ioc(struct bio *bio)
|
||||
* Returns ERR_PTR on failure, with @q->queue_lock held.
|
||||
* Returns request pointer on success, with @q->queue_lock *not held*.
|
||||
*/
|
||||
static struct request *__get_request(struct request_list *rl, int rw_flags,
|
||||
struct bio *bio, gfp_t gfp_mask)
|
||||
static struct request *__get_request(struct request_list *rl, int op,
|
||||
int op_flags, struct bio *bio,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
struct request_queue *q = rl->q;
|
||||
struct request *rq;
|
||||
struct elevator_type *et = q->elevator->type;
|
||||
struct io_context *ioc = rq_ioc(bio);
|
||||
struct io_cq *icq = NULL;
|
||||
const bool is_sync = rw_is_sync(rw_flags) != 0;
|
||||
const bool is_sync = rw_is_sync(op, op_flags) != 0;
|
||||
int may_queue;
|
||||
|
||||
if (unlikely(blk_queue_dying(q)))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
may_queue = elv_may_queue(q, rw_flags);
|
||||
may_queue = elv_may_queue(q, op, op_flags);
|
||||
if (may_queue == ELV_MQUEUE_NO)
|
||||
goto rq_starved;
|
||||
|
||||
@@ -1123,7 +1125,7 @@ static struct request *__get_request(struct request_list *rl, int rw_flags,
|
||||
|
||||
/*
|
||||
* Decide whether the new request will be managed by elevator. If
|
||||
* so, mark @rw_flags and increment elvpriv. Non-zero elvpriv will
|
||||
* so, mark @op_flags and increment elvpriv. Non-zero elvpriv will
|
||||
* prevent the current elevator from being destroyed until the new
|
||||
* request is freed. This guarantees icq's won't be destroyed and
|
||||
* makes creating new ones safe.
|
||||
@@ -1132,14 +1134,14 @@ static struct request *__get_request(struct request_list *rl, int rw_flags,
|
||||
* it will be created after releasing queue_lock.
|
||||
*/
|
||||
if (blk_rq_should_init_elevator(bio) && !blk_queue_bypass(q)) {
|
||||
rw_flags |= REQ_ELVPRIV;
|
||||
op_flags |= REQ_ELVPRIV;
|
||||
q->nr_rqs_elvpriv++;
|
||||
if (et->icq_cache && ioc)
|
||||
icq = ioc_lookup_icq(ioc, q);
|
||||
}
|
||||
|
||||
if (blk_queue_io_stat(q))
|
||||
rw_flags |= REQ_IO_STAT;
|
||||
op_flags |= REQ_IO_STAT;
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
/* allocate and init request */
|
||||
@@ -1149,10 +1151,10 @@ static struct request *__get_request(struct request_list *rl, int rw_flags,
|
||||
|
||||
blk_rq_init(q, rq);
|
||||
blk_rq_set_rl(rq, rl);
|
||||
rq->cmd_flags = rw_flags | REQ_ALLOCED;
|
||||
req_set_op_attrs(rq, op, op_flags | REQ_ALLOCED);
|
||||
|
||||
/* init elvpriv */
|
||||
if (rw_flags & REQ_ELVPRIV) {
|
||||
if (op_flags & REQ_ELVPRIV) {
|
||||
if (unlikely(et->icq_cache && !icq)) {
|
||||
if (ioc)
|
||||
icq = ioc_create_icq(ioc, q, gfp_mask);
|
||||
@@ -1178,7 +1180,7 @@ out:
|
||||
if (ioc_batching(q, ioc))
|
||||
ioc->nr_batch_requests--;
|
||||
|
||||
trace_block_getrq(q, bio, rw_flags & 1);
|
||||
trace_block_getrq(q, bio, op);
|
||||
return rq;
|
||||
|
||||
fail_elvpriv:
|
||||
@@ -1208,7 +1210,7 @@ fail_alloc:
|
||||
* queue, but this is pretty rare.
|
||||
*/
|
||||
spin_lock_irq(q->queue_lock);
|
||||
freed_request(rl, rw_flags);
|
||||
freed_request(rl, op, op_flags);
|
||||
|
||||
/*
|
||||
* in the very unlikely event that allocation failed and no
|
||||
@@ -1226,7 +1228,8 @@ rq_starved:
|
||||
/**
|
||||
* get_request - get a free request
|
||||
* @q: request_queue to allocate request from
|
||||
* @rw_flags: RW and SYNC flags
|
||||
* @op: REQ_OP_READ/REQ_OP_WRITE
|
||||
* @op_flags: rq_flag_bits
|
||||
* @bio: bio to allocate request for (can be %NULL)
|
||||
* @gfp_mask: allocation mask
|
||||
*
|
||||
@@ -1237,17 +1240,18 @@ rq_starved:
|
||||
* Returns ERR_PTR on failure, with @q->queue_lock held.
|
||||
* Returns request pointer on success, with @q->queue_lock *not held*.
|
||||
*/
|
||||
static struct request *get_request(struct request_queue *q, int rw_flags,
|
||||
struct bio *bio, gfp_t gfp_mask)
|
||||
static struct request *get_request(struct request_queue *q, int op,
|
||||
int op_flags, struct bio *bio,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
const bool is_sync = rw_is_sync(rw_flags) != 0;
|
||||
const bool is_sync = rw_is_sync(op, op_flags) != 0;
|
||||
DEFINE_WAIT(wait);
|
||||
struct request_list *rl;
|
||||
struct request *rq;
|
||||
|
||||
rl = blk_get_rl(q, bio); /* transferred to @rq on success */
|
||||
retry:
|
||||
rq = __get_request(rl, rw_flags, bio, gfp_mask);
|
||||
rq = __get_request(rl, op, op_flags, bio, gfp_mask);
|
||||
if (!IS_ERR(rq))
|
||||
return rq;
|
||||
|
||||
@@ -1260,7 +1264,7 @@ retry:
|
||||
prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
|
||||
trace_block_sleeprq(q, bio, rw_flags & 1);
|
||||
trace_block_sleeprq(q, bio, op);
|
||||
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
io_schedule();
|
||||
@@ -1289,7 +1293,7 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw,
|
||||
create_io_context(gfp_mask, q->node);
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
rq = get_request(q, rw, NULL, gfp_mask);
|
||||
rq = get_request(q, rw, 0, NULL, gfp_mask);
|
||||
if (IS_ERR(rq))
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
/* q->queue_lock is unlocked at this point */
|
||||
@@ -1491,13 +1495,14 @@ void __blk_put_request(struct request_queue *q, struct request *req)
|
||||
*/
|
||||
if (req->cmd_flags & REQ_ALLOCED) {
|
||||
unsigned int flags = req->cmd_flags;
|
||||
int op = req_op(req);
|
||||
struct request_list *rl = blk_rq_rl(req);
|
||||
|
||||
BUG_ON(!list_empty(&req->queuelist));
|
||||
BUG_ON(ELV_ON_HASH(req));
|
||||
|
||||
blk_free_request(rl, req);
|
||||
freed_request(rl, flags);
|
||||
freed_request(rl, op, flags);
|
||||
blk_put_rl(rl);
|
||||
}
|
||||
}
|
||||
@@ -1712,7 +1717,7 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
const bool sync = !!(bio->bi_rw & REQ_SYNC);
|
||||
struct blk_plug *plug;
|
||||
int el_ret, rw_flags, where = ELEVATOR_INSERT_SORT;
|
||||
int el_ret, rw_flags = 0, where = ELEVATOR_INSERT_SORT;
|
||||
struct request *req;
|
||||
unsigned int request_count = 0;
|
||||
|
||||
@@ -1731,7 +1736,7 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
|
||||
return BLK_QC_T_NONE;
|
||||
}
|
||||
|
||||
if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) {
|
||||
if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) {
|
||||
spin_lock_irq(q->queue_lock);
|
||||
where = ELEVATOR_INSERT_FLUSH;
|
||||
goto get_rq;
|
||||
@@ -1772,15 +1777,19 @@ get_rq:
|
||||
* but we need to set it earlier to expose the sync flag to the
|
||||
* rq allocator and io schedulers.
|
||||
*/
|
||||
rw_flags = bio_data_dir(bio);
|
||||
if (sync)
|
||||
rw_flags |= REQ_SYNC;
|
||||
|
||||
/*
|
||||
* Add in META/PRIO flags, if set, before we get to the IO scheduler
|
||||
*/
|
||||
rw_flags |= (bio->bi_rw & (REQ_META | REQ_PRIO));
|
||||
|
||||
/*
|
||||
* Grab a free request. This is might sleep but can not fail.
|
||||
* Returns with the queue unlocked.
|
||||
*/
|
||||
req = get_request(q, rw_flags, bio, GFP_NOIO);
|
||||
req = get_request(q, bio_data_dir(bio), rw_flags, bio, GFP_NOIO);
|
||||
if (IS_ERR(req)) {
|
||||
bio->bi_error = PTR_ERR(req);
|
||||
bio_endio(bio);
|
||||
@@ -1849,7 +1858,7 @@ static void handle_bad_sector(struct bio *bio)
|
||||
char b[BDEVNAME_SIZE];
|
||||
|
||||
printk(KERN_INFO "attempt to access beyond end of device\n");
|
||||
printk(KERN_INFO "%s: rw=%ld, want=%Lu, limit=%Lu\n",
|
||||
printk(KERN_INFO "%s: rw=%d, want=%Lu, limit=%Lu\n",
|
||||
bdevname(bio->bi_bdev, b),
|
||||
bio->bi_rw,
|
||||
(unsigned long long)bio_end_sector(bio),
|
||||
@@ -1964,23 +1973,23 @@ generic_make_request_checks(struct bio *bio)
|
||||
* drivers without flush support don't have to worry
|
||||
* about them.
|
||||
*/
|
||||
if ((bio->bi_rw & (REQ_FLUSH | REQ_FUA)) &&
|
||||
if ((bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) &&
|
||||
!test_bit(QUEUE_FLAG_WC, &q->queue_flags)) {
|
||||
bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA);
|
||||
bio->bi_rw &= ~(REQ_PREFLUSH | REQ_FUA);
|
||||
if (!nr_sectors) {
|
||||
err = 0;
|
||||
goto end_io;
|
||||
}
|
||||
}
|
||||
|
||||
if ((bio->bi_rw & REQ_DISCARD) &&
|
||||
if ((bio_op(bio) == REQ_OP_DISCARD) &&
|
||||
(!blk_queue_discard(q) ||
|
||||
((bio->bi_rw & REQ_SECURE) && !blk_queue_secdiscard(q)))) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto end_io;
|
||||
}
|
||||
|
||||
if (bio->bi_rw & REQ_WRITE_SAME && !bdev_write_same(bio->bi_bdev)) {
|
||||
if (bio_op(bio) == REQ_OP_WRITE_SAME && !bdev_write_same(bio->bi_bdev)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto end_io;
|
||||
}
|
||||
@@ -2094,7 +2103,6 @@ EXPORT_SYMBOL(generic_make_request);
|
||||
|
||||
/**
|
||||
* submit_bio - submit a bio to the block device layer for I/O
|
||||
* @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
|
||||
* @bio: The &struct bio which describes the I/O
|
||||
*
|
||||
* submit_bio() is very similar in purpose to generic_make_request(), and
|
||||
@@ -2102,10 +2110,8 @@ EXPORT_SYMBOL(generic_make_request);
|
||||
* interfaces; @bio must be presetup and ready for I/O.
|
||||
*
|
||||
*/
|
||||
blk_qc_t submit_bio(int rw, struct bio *bio)
|
||||
blk_qc_t submit_bio(struct bio *bio)
|
||||
{
|
||||
bio->bi_rw |= rw;
|
||||
|
||||
/*
|
||||
* If it's a regular read/write or a barrier with data attached,
|
||||
* go through the normal accounting stuff before submission.
|
||||
@@ -2113,12 +2119,12 @@ blk_qc_t submit_bio(int rw, struct bio *bio)
|
||||
if (bio_has_data(bio)) {
|
||||
unsigned int count;
|
||||
|
||||
if (unlikely(rw & REQ_WRITE_SAME))
|
||||
if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
|
||||
count = bdev_logical_block_size(bio->bi_bdev) >> 9;
|
||||
else
|
||||
count = bio_sectors(bio);
|
||||
|
||||
if (rw & WRITE) {
|
||||
if (op_is_write(bio_op(bio))) {
|
||||
count_vm_events(PGPGOUT, count);
|
||||
} else {
|
||||
task_io_account_read(bio->bi_iter.bi_size);
|
||||
@@ -2129,7 +2135,7 @@ blk_qc_t submit_bio(int rw, struct bio *bio)
|
||||
char b[BDEVNAME_SIZE];
|
||||
printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)\n",
|
||||
current->comm, task_pid_nr(current),
|
||||
(rw & WRITE) ? "WRITE" : "READ",
|
||||
op_is_write(bio_op(bio)) ? "WRITE" : "READ",
|
||||
(unsigned long long)bio->bi_iter.bi_sector,
|
||||
bdevname(bio->bi_bdev, b),
|
||||
count);
|
||||
@@ -2160,7 +2166,7 @@ EXPORT_SYMBOL(submit_bio);
|
||||
static int blk_cloned_rq_check_limits(struct request_queue *q,
|
||||
struct request *rq)
|
||||
{
|
||||
if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, rq->cmd_flags)) {
|
||||
if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, req_op(rq))) {
|
||||
printk(KERN_ERR "%s: over max size limit.\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
@@ -2216,7 +2222,7 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
|
||||
*/
|
||||
BUG_ON(blk_queued_rq(rq));
|
||||
|
||||
if (rq->cmd_flags & (REQ_FLUSH|REQ_FUA))
|
||||
if (rq->cmd_flags & (REQ_PREFLUSH | REQ_FUA))
|
||||
where = ELEVATOR_INSERT_FLUSH;
|
||||
|
||||
add_acct_request(q, rq, where);
|
||||
@@ -2979,8 +2985,7 @@ EXPORT_SYMBOL_GPL(__blk_end_request_err);
|
||||
void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
|
||||
struct bio *bio)
|
||||
{
|
||||
/* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw */
|
||||
rq->cmd_flags |= bio->bi_rw & REQ_WRITE;
|
||||
req_set_op(rq, bio_op(bio));
|
||||
|
||||
if (bio_has_data(bio))
|
||||
rq->nr_phys_segments = bio_phys_segments(q, bio);
|
||||
@@ -3065,7 +3070,8 @@ EXPORT_SYMBOL_GPL(blk_rq_unprep_clone);
|
||||
static void __blk_rq_prep_clone(struct request *dst, struct request *src)
|
||||
{
|
||||
dst->cpu = src->cpu;
|
||||
dst->cmd_flags |= (src->cmd_flags & REQ_CLONE_MASK) | REQ_NOMERGE;
|
||||
req_set_op_attrs(dst, req_op(src),
|
||||
(src->cmd_flags & REQ_CLONE_MASK) | REQ_NOMERGE);
|
||||
dst->cmd_type = src->cmd_type;
|
||||
dst->__sector = blk_rq_pos(src);
|
||||
dst->__data_len = blk_rq_bytes(src);
|
||||
@@ -3310,7 +3316,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)
|
||||
/*
|
||||
* rq is already accounted, so use raw insert
|
||||
*/
|
||||
if (rq->cmd_flags & (REQ_FLUSH | REQ_FUA))
|
||||
if (rq->cmd_flags & (REQ_PREFLUSH | REQ_FUA))
|
||||
__elv_add_request(q, rq, ELEVATOR_INSERT_FLUSH);
|
||||
else
|
||||
__elv_add_request(q, rq, ELEVATOR_INSERT_SORT_MERGE);
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
|
||||
|
||||
/*
|
||||
* don't check dying flag for MQ because the request won't
|
||||
* be resued after dying flag is set
|
||||
* be reused after dying flag is set
|
||||
*/
|
||||
if (q->mq_ops) {
|
||||
blk_mq_insert_request(rq, at_head, true, false);
|
||||
|
||||
+12
-11
@@ -10,8 +10,8 @@
|
||||
* optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request
|
||||
* properties and hardware capability.
|
||||
*
|
||||
* If a request doesn't have data, only REQ_FLUSH makes sense, which
|
||||
* indicates a simple flush request. If there is data, REQ_FLUSH indicates
|
||||
* If a request doesn't have data, only REQ_PREFLUSH makes sense, which
|
||||
* indicates a simple flush request. If there is data, REQ_PREFLUSH indicates
|
||||
* that the device cache should be flushed before the data is executed, and
|
||||
* REQ_FUA means that the data must be on non-volatile media on request
|
||||
* completion.
|
||||
@@ -20,16 +20,16 @@
|
||||
* difference. The requests are either completed immediately if there's no
|
||||
* data or executed as normal requests otherwise.
|
||||
*
|
||||
* If the device has writeback cache and supports FUA, REQ_FLUSH 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.
|
||||
*
|
||||
* If the device has writeback cache and doesn't support FUA, REQ_FLUSH is
|
||||
* translated to PREFLUSH and REQ_FUA to POSTFLUSH.
|
||||
* If the device has writeback cache and doesn't support FUA, REQ_PREFLUSH
|
||||
* is translated to PREFLUSH and REQ_FUA to POSTFLUSH.
|
||||
*
|
||||
* The actual execution of flush is double buffered. Whenever a request
|
||||
* needs to execute PRE or POSTFLUSH, it queues at
|
||||
* fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a
|
||||
* 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
|
||||
* step. This allows arbitrary merging of different types of FLUSH/FUA
|
||||
* requests.
|
||||
@@ -103,7 +103,7 @@ static unsigned int blk_flush_policy(unsigned long fflags, struct request *rq)
|
||||
policy |= REQ_FSEQ_DATA;
|
||||
|
||||
if (fflags & (1UL << QUEUE_FLAG_WC)) {
|
||||
if (rq->cmd_flags & REQ_FLUSH)
|
||||
if (rq->cmd_flags & REQ_PREFLUSH)
|
||||
policy |= REQ_FSEQ_PREFLUSH;
|
||||
if (!(fflags & (1UL << QUEUE_FLAG_FUA)) &&
|
||||
(rq->cmd_flags & REQ_FUA))
|
||||
@@ -330,7 +330,7 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq)
|
||||
}
|
||||
|
||||
flush_rq->cmd_type = REQ_TYPE_FS;
|
||||
flush_rq->cmd_flags = WRITE_FLUSH | REQ_FLUSH_SEQ;
|
||||
req_set_op_attrs(flush_rq, REQ_OP_FLUSH, WRITE_FLUSH | REQ_FLUSH_SEQ);
|
||||
flush_rq->rq_disk = first_rq->rq_disk;
|
||||
flush_rq->end_io = flush_end_io;
|
||||
|
||||
@@ -391,9 +391,9 @@ void blk_insert_flush(struct request *rq)
|
||||
|
||||
/*
|
||||
* @policy now records what operations need to be done. Adjust
|
||||
* REQ_FLUSH and FUA for the driver.
|
||||
* REQ_PREFLUSH and FUA for the driver.
|
||||
*/
|
||||
rq->cmd_flags &= ~REQ_FLUSH;
|
||||
rq->cmd_flags &= ~REQ_PREFLUSH;
|
||||
if (!(fflags & (1UL << QUEUE_FLAG_FUA)))
|
||||
rq->cmd_flags &= ~REQ_FUA;
|
||||
|
||||
@@ -485,8 +485,9 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
|
||||
|
||||
bio = bio_alloc(gfp_mask, 0);
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, WRITE_FLUSH);
|
||||
|
||||
ret = submit_bio_wait(WRITE_FLUSH, bio);
|
||||
ret = submit_bio_wait(bio);
|
||||
|
||||
/*
|
||||
* The driver must store the error location in ->bi_sector, if
|
||||
|
||||
+17
-14
@@ -9,21 +9,22 @@
|
||||
|
||||
#include "blk.h"
|
||||
|
||||
static struct bio *next_bio(struct bio *bio, int rw, unsigned int nr_pages,
|
||||
static struct bio *next_bio(struct bio *bio, unsigned int nr_pages,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct bio *new = bio_alloc(gfp, nr_pages);
|
||||
|
||||
if (bio) {
|
||||
bio_chain(bio, new);
|
||||
submit_bio(rw, bio);
|
||||
submit_bio(bio);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
||||
sector_t nr_sects, gfp_t gfp_mask, int type, struct bio **biop)
|
||||
sector_t nr_sects, gfp_t gfp_mask, int op_flags,
|
||||
struct bio **biop)
|
||||
{
|
||||
struct request_queue *q = bdev_get_queue(bdev);
|
||||
struct bio *bio = *biop;
|
||||
@@ -34,7 +35,7 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
||||
return -ENXIO;
|
||||
if (!blk_queue_discard(q))
|
||||
return -EOPNOTSUPP;
|
||||
if ((type & REQ_SECURE) && !blk_queue_secdiscard(q))
|
||||
if ((op_flags & REQ_SECURE) && !blk_queue_secdiscard(q))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Zero-sector (unknown) and one-sector granularities are the same. */
|
||||
@@ -62,9 +63,10 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
||||
req_sects = end_sect - sector;
|
||||
}
|
||||
|
||||
bio = next_bio(bio, type, 1, gfp_mask);
|
||||
bio = next_bio(bio, 1, gfp_mask);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_op_attrs(bio, REQ_OP_DISCARD, op_flags);
|
||||
|
||||
bio->bi_iter.bi_size = req_sects << 9;
|
||||
nr_sects -= req_sects;
|
||||
@@ -98,19 +100,19 @@ EXPORT_SYMBOL(__blkdev_issue_discard);
|
||||
int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
||||
sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
|
||||
{
|
||||
int type = REQ_WRITE | REQ_DISCARD;
|
||||
int op_flags = 0;
|
||||
struct bio *bio = NULL;
|
||||
struct blk_plug plug;
|
||||
int ret;
|
||||
|
||||
if (flags & BLKDEV_DISCARD_SECURE)
|
||||
type |= REQ_SECURE;
|
||||
op_flags |= REQ_SECURE;
|
||||
|
||||
blk_start_plug(&plug);
|
||||
ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, type,
|
||||
ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, op_flags,
|
||||
&bio);
|
||||
if (!ret && bio) {
|
||||
ret = submit_bio_wait(type, bio);
|
||||
ret = submit_bio_wait(bio);
|
||||
if (ret == -EOPNOTSUPP)
|
||||
ret = 0;
|
||||
bio_put(bio);
|
||||
@@ -148,13 +150,14 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
|
||||
max_write_same_sectors = UINT_MAX >> 9;
|
||||
|
||||
while (nr_sects) {
|
||||
bio = next_bio(bio, REQ_WRITE | REQ_WRITE_SAME, 1, gfp_mask);
|
||||
bio = next_bio(bio, 1, gfp_mask);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio->bi_vcnt = 1;
|
||||
bio->bi_io_vec->bv_page = page;
|
||||
bio->bi_io_vec->bv_offset = 0;
|
||||
bio->bi_io_vec->bv_len = bdev_logical_block_size(bdev);
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE_SAME, 0);
|
||||
|
||||
if (nr_sects > max_write_same_sectors) {
|
||||
bio->bi_iter.bi_size = max_write_same_sectors << 9;
|
||||
@@ -167,7 +170,7 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
|
||||
}
|
||||
|
||||
if (bio) {
|
||||
ret = submit_bio_wait(REQ_WRITE | REQ_WRITE_SAME, bio);
|
||||
ret = submit_bio_wait(bio);
|
||||
bio_put(bio);
|
||||
}
|
||||
return ret != -EOPNOTSUPP ? ret : 0;
|
||||
@@ -193,11 +196,11 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
|
||||
unsigned int sz;
|
||||
|
||||
while (nr_sects != 0) {
|
||||
bio = next_bio(bio, WRITE,
|
||||
min(nr_sects, (sector_t)BIO_MAX_PAGES),
|
||||
bio = next_bio(bio, min(nr_sects, (sector_t)BIO_MAX_PAGES),
|
||||
gfp_mask);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio->bi_bdev = bdev;
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
|
||||
while (nr_sects != 0) {
|
||||
sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects);
|
||||
@@ -210,7 +213,7 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
|
||||
}
|
||||
|
||||
if (bio) {
|
||||
ret = submit_bio_wait(WRITE, bio);
|
||||
ret = submit_bio_wait(bio);
|
||||
bio_put(bio);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+1
-1
@@ -224,7 +224,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
|
||||
return PTR_ERR(bio);
|
||||
|
||||
if (!reading)
|
||||
bio->bi_rw |= REQ_WRITE;
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
|
||||
if (do_copy)
|
||||
rq->cmd_flags |= REQ_COPY_USER;
|
||||
|
||||
+22
-14
@@ -172,9 +172,9 @@ void blk_queue_split(struct request_queue *q, struct bio **bio,
|
||||
struct bio *split, *res;
|
||||
unsigned nsegs;
|
||||
|
||||
if ((*bio)->bi_rw & REQ_DISCARD)
|
||||
if (bio_op(*bio) == REQ_OP_DISCARD)
|
||||
split = blk_bio_discard_split(q, *bio, bs, &nsegs);
|
||||
else if ((*bio)->bi_rw & REQ_WRITE_SAME)
|
||||
else if (bio_op(*bio) == REQ_OP_WRITE_SAME)
|
||||
split = blk_bio_write_same_split(q, *bio, bs, &nsegs);
|
||||
else
|
||||
split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs);
|
||||
@@ -213,10 +213,10 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
|
||||
* This should probably be returning 0, but blk_add_request_payload()
|
||||
* (Christoph!!!!)
|
||||
*/
|
||||
if (bio->bi_rw & REQ_DISCARD)
|
||||
if (bio_op(bio) == REQ_OP_DISCARD)
|
||||
return 1;
|
||||
|
||||
if (bio->bi_rw & REQ_WRITE_SAME)
|
||||
if (bio_op(bio) == REQ_OP_WRITE_SAME)
|
||||
return 1;
|
||||
|
||||
fbio = bio;
|
||||
@@ -385,7 +385,7 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
|
||||
nsegs = 0;
|
||||
cluster = blk_queue_cluster(q);
|
||||
|
||||
if (bio->bi_rw & REQ_DISCARD) {
|
||||
if (bio_op(bio) == REQ_OP_DISCARD) {
|
||||
/*
|
||||
* This is a hack - drivers should be neither modifying the
|
||||
* biovec, nor relying on bi_vcnt - but because of
|
||||
@@ -400,7 +400,7 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bio->bi_rw & REQ_WRITE_SAME) {
|
||||
if (bio_op(bio) == REQ_OP_WRITE_SAME) {
|
||||
single_segment:
|
||||
*sg = sglist;
|
||||
bvec = bio_iovec(bio);
|
||||
@@ -439,7 +439,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
|
||||
}
|
||||
|
||||
if (q->dma_drain_size && q->dma_drain_needed(rq)) {
|
||||
if (rq->cmd_flags & REQ_WRITE)
|
||||
if (op_is_write(req_op(rq)))
|
||||
memset(q->dma_drain_buffer, 0, q->dma_drain_size);
|
||||
|
||||
sg_unmark_end(sg);
|
||||
@@ -500,7 +500,7 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req,
|
||||
integrity_req_gap_back_merge(req, bio))
|
||||
return 0;
|
||||
if (blk_rq_sectors(req) + bio_sectors(bio) >
|
||||
blk_rq_get_max_sectors(req)) {
|
||||
blk_rq_get_max_sectors(req, blk_rq_pos(req))) {
|
||||
req->cmd_flags |= REQ_NOMERGE;
|
||||
if (req == q->last_merge)
|
||||
q->last_merge = NULL;
|
||||
@@ -524,7 +524,7 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
|
||||
integrity_req_gap_front_merge(req, bio))
|
||||
return 0;
|
||||
if (blk_rq_sectors(req) + bio_sectors(bio) >
|
||||
blk_rq_get_max_sectors(req)) {
|
||||
blk_rq_get_max_sectors(req, bio->bi_iter.bi_sector)) {
|
||||
req->cmd_flags |= REQ_NOMERGE;
|
||||
if (req == q->last_merge)
|
||||
q->last_merge = NULL;
|
||||
@@ -570,7 +570,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
|
||||
* Will it become too large?
|
||||
*/
|
||||
if ((blk_rq_sectors(req) + blk_rq_sectors(next)) >
|
||||
blk_rq_get_max_sectors(req))
|
||||
blk_rq_get_max_sectors(req, blk_rq_pos(req)))
|
||||
return 0;
|
||||
|
||||
total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
|
||||
@@ -649,7 +649,8 @@ static int attempt_merge(struct request_queue *q, struct request *req,
|
||||
if (!rq_mergeable(req) || !rq_mergeable(next))
|
||||
return 0;
|
||||
|
||||
if (!blk_check_merge_flags(req->cmd_flags, next->cmd_flags))
|
||||
if (!blk_check_merge_flags(req->cmd_flags, req_op(req), next->cmd_flags,
|
||||
req_op(next)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -663,7 +664,7 @@ static int attempt_merge(struct request_queue *q, struct request *req,
|
||||
|| req_no_special_merge(next))
|
||||
return 0;
|
||||
|
||||
if (req->cmd_flags & REQ_WRITE_SAME &&
|
||||
if (req_op(req) == REQ_OP_WRITE_SAME &&
|
||||
!blk_write_same_mergeable(req->bio, next->bio))
|
||||
return 0;
|
||||
|
||||
@@ -743,6 +744,12 @@ int attempt_front_merge(struct request_queue *q, struct request *rq)
|
||||
int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
|
||||
struct request *next)
|
||||
{
|
||||
struct elevator_queue *e = q->elevator;
|
||||
|
||||
if (e->type->ops.elevator_allow_rq_merge_fn)
|
||||
if (!e->type->ops.elevator_allow_rq_merge_fn(q, rq, next))
|
||||
return 0;
|
||||
|
||||
return attempt_merge(q, rq, next);
|
||||
}
|
||||
|
||||
@@ -751,7 +758,8 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
|
||||
if (!rq_mergeable(rq) || !bio_mergeable(bio))
|
||||
return false;
|
||||
|
||||
if (!blk_check_merge_flags(rq->cmd_flags, bio->bi_rw))
|
||||
if (!blk_check_merge_flags(rq->cmd_flags, req_op(rq), bio->bi_rw,
|
||||
bio_op(bio)))
|
||||
return false;
|
||||
|
||||
/* different data direction or already started, don't merge */
|
||||
@@ -767,7 +775,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
|
||||
return false;
|
||||
|
||||
/* must be using the same buffer */
|
||||
if (rq->cmd_flags & REQ_WRITE_SAME &&
|
||||
if (req_op(rq) == REQ_OP_WRITE_SAME &&
|
||||
!blk_write_same_mergeable(rq->bio, bio))
|
||||
return false;
|
||||
|
||||
|
||||
+22
-20
@@ -159,16 +159,17 @@ bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx)
|
||||
EXPORT_SYMBOL(blk_mq_can_queue);
|
||||
|
||||
static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
|
||||
struct request *rq, unsigned int rw_flags)
|
||||
struct request *rq, int op,
|
||||
unsigned int op_flags)
|
||||
{
|
||||
if (blk_queue_io_stat(q))
|
||||
rw_flags |= REQ_IO_STAT;
|
||||
op_flags |= REQ_IO_STAT;
|
||||
|
||||
INIT_LIST_HEAD(&rq->queuelist);
|
||||
/* csd/requeue_work/fifo_time is initialized before use */
|
||||
rq->q = q;
|
||||
rq->mq_ctx = ctx;
|
||||
rq->cmd_flags |= rw_flags;
|
||||
req_set_op_attrs(rq, op, op_flags);
|
||||
/* do not touch atomic flags, it needs atomic ops against the timer */
|
||||
rq->cpu = -1;
|
||||
INIT_HLIST_NODE(&rq->hash);
|
||||
@@ -203,11 +204,11 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
|
||||
rq->end_io_data = NULL;
|
||||
rq->next_rq = NULL;
|
||||
|
||||
ctx->rq_dispatched[rw_is_sync(rw_flags)]++;
|
||||
ctx->rq_dispatched[rw_is_sync(op, op_flags)]++;
|
||||
}
|
||||
|
||||
static struct request *
|
||||
__blk_mq_alloc_request(struct blk_mq_alloc_data *data, int rw)
|
||||
__blk_mq_alloc_request(struct blk_mq_alloc_data *data, int op, int op_flags)
|
||||
{
|
||||
struct request *rq;
|
||||
unsigned int tag;
|
||||
@@ -222,7 +223,7 @@ __blk_mq_alloc_request(struct blk_mq_alloc_data *data, int rw)
|
||||
}
|
||||
|
||||
rq->tag = tag;
|
||||
blk_mq_rq_ctx_init(data->q, data->ctx, rq, rw);
|
||||
blk_mq_rq_ctx_init(data->q, data->ctx, rq, op, op_flags);
|
||||
return rq;
|
||||
}
|
||||
|
||||
@@ -246,7 +247,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
|
||||
hctx = q->mq_ops->map_queue(q, ctx->cpu);
|
||||
blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
|
||||
|
||||
rq = __blk_mq_alloc_request(&alloc_data, rw);
|
||||
rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
|
||||
if (!rq && !(flags & BLK_MQ_REQ_NOWAIT)) {
|
||||
__blk_mq_run_hw_queue(hctx);
|
||||
blk_mq_put_ctx(ctx);
|
||||
@@ -254,7 +255,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
|
||||
ctx = blk_mq_get_ctx(q);
|
||||
hctx = q->mq_ops->map_queue(q, ctx->cpu);
|
||||
blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
|
||||
rq = __blk_mq_alloc_request(&alloc_data, rw);
|
||||
rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
|
||||
ctx = alloc_data.ctx;
|
||||
}
|
||||
blk_mq_put_ctx(ctx);
|
||||
@@ -784,7 +785,7 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
|
||||
switch (ret) {
|
||||
case BLK_MQ_RQ_QUEUE_OK:
|
||||
queued++;
|
||||
continue;
|
||||
break;
|
||||
case BLK_MQ_RQ_QUEUE_BUSY:
|
||||
list_add(&rq->queuelist, &rq_list);
|
||||
__blk_mq_requeue_request(rq);
|
||||
@@ -1169,28 +1170,29 @@ static struct request *blk_mq_map_request(struct request_queue *q,
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
struct blk_mq_ctx *ctx;
|
||||
struct request *rq;
|
||||
int rw = bio_data_dir(bio);
|
||||
int op = bio_data_dir(bio);
|
||||
int op_flags = 0;
|
||||
struct blk_mq_alloc_data alloc_data;
|
||||
|
||||
blk_queue_enter_live(q);
|
||||
ctx = blk_mq_get_ctx(q);
|
||||
hctx = q->mq_ops->map_queue(q, ctx->cpu);
|
||||
|
||||
if (rw_is_sync(bio->bi_rw))
|
||||
rw |= REQ_SYNC;
|
||||
if (rw_is_sync(bio_op(bio), bio->bi_rw))
|
||||
op_flags |= REQ_SYNC;
|
||||
|
||||
trace_block_getrq(q, bio, rw);
|
||||
trace_block_getrq(q, bio, op);
|
||||
blk_mq_set_alloc_data(&alloc_data, q, BLK_MQ_REQ_NOWAIT, ctx, hctx);
|
||||
rq = __blk_mq_alloc_request(&alloc_data, rw);
|
||||
rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
|
||||
if (unlikely(!rq)) {
|
||||
__blk_mq_run_hw_queue(hctx);
|
||||
blk_mq_put_ctx(ctx);
|
||||
trace_block_sleeprq(q, bio, rw);
|
||||
trace_block_sleeprq(q, bio, op);
|
||||
|
||||
ctx = blk_mq_get_ctx(q);
|
||||
hctx = q->mq_ops->map_queue(q, ctx->cpu);
|
||||
blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx);
|
||||
rq = __blk_mq_alloc_request(&alloc_data, rw);
|
||||
rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
|
||||
ctx = alloc_data.ctx;
|
||||
hctx = alloc_data.hctx;
|
||||
}
|
||||
@@ -1244,8 +1246,8 @@ static int blk_mq_direct_issue_request(struct request *rq, blk_qc_t *cookie)
|
||||
*/
|
||||
static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
const int is_sync = rw_is_sync(bio->bi_rw);
|
||||
const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA);
|
||||
const int is_sync = rw_is_sync(bio_op(bio), bio->bi_rw);
|
||||
const int is_flush_fua = bio->bi_rw & (REQ_PREFLUSH | REQ_FUA);
|
||||
struct blk_map_ctx data;
|
||||
struct request *rq;
|
||||
unsigned int request_count = 0;
|
||||
@@ -1338,8 +1340,8 @@ done:
|
||||
*/
|
||||
static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
const int is_sync = rw_is_sync(bio->bi_rw);
|
||||
const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA);
|
||||
const int is_sync = rw_is_sync(bio_op(bio), bio->bi_rw);
|
||||
const int is_flush_fua = bio->bi_rw & (REQ_PREFLUSH | REQ_FUA);
|
||||
struct blk_plug *plug;
|
||||
unsigned int request_count = 0;
|
||||
struct blk_map_ctx data;
|
||||
|
||||
@@ -379,6 +379,11 @@ static ssize_t queue_wc_store(struct request_queue *q, const char *page,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t queue_dax_show(struct request_queue *q, char *page)
|
||||
{
|
||||
return queue_var_show(blk_queue_dax(q), page);
|
||||
}
|
||||
|
||||
static struct queue_sysfs_entry queue_requests_entry = {
|
||||
.attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
|
||||
.show = queue_requests_show,
|
||||
@@ -516,6 +521,11 @@ static struct queue_sysfs_entry queue_wc_entry = {
|
||||
.store = queue_wc_store,
|
||||
};
|
||||
|
||||
static struct queue_sysfs_entry queue_dax_entry = {
|
||||
.attr = {.name = "dax", .mode = S_IRUGO },
|
||||
.show = queue_dax_show,
|
||||
};
|
||||
|
||||
static struct attribute *default_attrs[] = {
|
||||
&queue_requests_entry.attr,
|
||||
&queue_ra_entry.attr,
|
||||
@@ -542,6 +552,7 @@ static struct attribute *default_attrs[] = {
|
||||
&queue_random_entry.attr,
|
||||
&queue_poll_entry.attr,
|
||||
&queue_wc_entry.attr,
|
||||
&queue_dax_entry.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
+260
-172
File diff suppressed because it is too large.
Load diff
@@ -137,7 +137,7 @@ deadline_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
||||
if (__rq) {
|
||||
BUG_ON(sector != blk_rq_pos(__rq));
|
||||
|
||||
if (elv_rq_merge_ok(__rq, bio)) {
|
||||
if (elv_bio_merge_ok(__rq, bio)) {
|
||||
ret = ELEVATOR_FRONT_MERGE;
|
||||
goto out;
|
||||
}
|
||||
@@ -173,7 +173,8 @@ deadline_merged_requests(struct request_queue *q, struct request *req,
|
||||
* and move into next position (next will be deleted) in fifo
|
||||
*/
|
||||
if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) {
|
||||
if (time_before(next->fifo_time, req->fifo_time)) {
|
||||
if (time_before((unsigned long)next->fifo_time,
|
||||
(unsigned long)req->fifo_time)) {
|
||||
list_move(&req->queuelist, &next->queuelist);
|
||||
req->fifo_time = next->fifo_time;
|
||||
}
|
||||
@@ -227,7 +228,7 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
|
||||
/*
|
||||
* rq is expired!
|
||||
*/
|
||||
if (time_after_eq(jiffies, rq->fifo_time))
|
||||
if (time_after_eq(jiffies, (unsigned long)rq->fifo_time))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
+14
-15
@@ -53,13 +53,13 @@ static LIST_HEAD(elv_list);
|
||||
* Query io scheduler to see if the current process issuing bio may be
|
||||
* merged with rq.
|
||||
*/
|
||||
static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
|
||||
static int elv_iosched_allow_bio_merge(struct request *rq, struct bio *bio)
|
||||
{
|
||||
struct request_queue *q = rq->q;
|
||||
struct elevator_queue *e = q->elevator;
|
||||
|
||||
if (e->type->ops.elevator_allow_merge_fn)
|
||||
return e->type->ops.elevator_allow_merge_fn(q, rq, bio);
|
||||
if (e->type->ops.elevator_allow_bio_merge_fn)
|
||||
return e->type->ops.elevator_allow_bio_merge_fn(q, rq, bio);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -67,17 +67,17 @@ static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
|
||||
/*
|
||||
* can we safely merge with this request?
|
||||
*/
|
||||
bool elv_rq_merge_ok(struct request *rq, struct bio *bio)
|
||||
bool elv_bio_merge_ok(struct request *rq, struct bio *bio)
|
||||
{
|
||||
if (!blk_rq_merge_ok(rq, bio))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (!elv_iosched_allow_merge(rq, bio))
|
||||
return 0;
|
||||
if (!elv_iosched_allow_bio_merge(rq, bio))
|
||||
return false;
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(elv_rq_merge_ok);
|
||||
EXPORT_SYMBOL(elv_bio_merge_ok);
|
||||
|
||||
static struct elevator_type *elevator_find(const char *name)
|
||||
{
|
||||
@@ -366,8 +366,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq)
|
||||
list_for_each_prev(entry, &q->queue_head) {
|
||||
struct request *pos = list_entry_rq(entry);
|
||||
|
||||
if ((rq->cmd_flags & REQ_DISCARD) !=
|
||||
(pos->cmd_flags & REQ_DISCARD))
|
||||
if ((req_op(rq) == REQ_OP_DISCARD) != (req_op(pos) == REQ_OP_DISCARD))
|
||||
break;
|
||||
if (rq_data_dir(rq) != rq_data_dir(pos))
|
||||
break;
|
||||
@@ -426,7 +425,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
||||
/*
|
||||
* First try one-hit cache.
|
||||
*/
|
||||
if (q->last_merge && elv_rq_merge_ok(q->last_merge, bio)) {
|
||||
if (q->last_merge && elv_bio_merge_ok(q->last_merge, bio)) {
|
||||
ret = blk_try_merge(q->last_merge, bio);
|
||||
if (ret != ELEVATOR_NO_MERGE) {
|
||||
*req = q->last_merge;
|
||||
@@ -441,7 +440,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
||||
* See if our hash lookup can find a potential backmerge.
|
||||
*/
|
||||
__rq = elv_rqhash_find(q, bio->bi_iter.bi_sector);
|
||||
if (__rq && elv_rq_merge_ok(__rq, bio)) {
|
||||
if (__rq && elv_bio_merge_ok(__rq, bio)) {
|
||||
*req = __rq;
|
||||
return ELEVATOR_BACK_MERGE;
|
||||
}
|
||||
@@ -717,12 +716,12 @@ void elv_put_request(struct request_queue *q, struct request *rq)
|
||||
e->type->ops.elevator_put_req_fn(rq);
|
||||
}
|
||||
|
||||
int elv_may_queue(struct request_queue *q, int rw)
|
||||
int elv_may_queue(struct request_queue *q, int op, int op_flags)
|
||||
{
|
||||
struct elevator_queue *e = q->elevator;
|
||||
|
||||
if (e->type->ops.elevator_may_queue_fn)
|
||||
return e->type->ops.elevator_may_queue_fn(q, rw);
|
||||
return e->type->ops.elevator_may_queue_fn(q, op, op_flags);
|
||||
|
||||
return ELV_MQUEUE_MAY;
|
||||
}
|
||||
|
||||
@@ -495,7 +495,6 @@ rescan:
|
||||
/* add partitions */
|
||||
for (p = 1; p < state->limit; p++) {
|
||||
sector_t size, from;
|
||||
struct partition_meta_info *info = NULL;
|
||||
|
||||
size = state->parts[p].size;
|
||||
if (!size)
|
||||
@@ -530,8 +529,6 @@ rescan:
|
||||
}
|
||||
}
|
||||
|
||||
if (state->parts[p].has_info)
|
||||
info = &state->parts[p].info;
|
||||
part = add_partition(disk, p, from, size,
|
||||
state->parts[p].flags,
|
||||
&state->parts[p].info);
|
||||
|
||||
@@ -42,6 +42,13 @@ int atari_partition(struct parsed_partitions *state)
|
||||
int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ATARI partition scheme supports 512 lba only. If this is not
|
||||
* the case, bail early to avoid miscalculating hd_size.
|
||||
*/
|
||||
if (bdev_logical_block_size(state->bdev) != 512)
|
||||
return 0;
|
||||
|
||||
rs = read_part_sector(state, 0, §);
|
||||
if (!rs)
|
||||
return -1;
|
||||
|
||||
Loaded 20 of 199 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user