mirror of
https://github.com/torvalds/linux
synced 2024-09-06 09:51:23 +00:00
block-5.9-2020-08-14
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAl83DGUQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgplTYEACs5kPPpSVdzVsOeHj0LkfQXiSlli8dbPBo NB2+TIyr9NxJgxn8B4x+5/4DZgJaCoHOeyyzOocXQmvWGwWOTkrfX/OSyQOlRB5z dpzqF0Huhw31MSQEiwA/8lo3omBmat9cMzMa5PJYPghMGfqyQDzVJk1lIX51a1th oE01eBpNNsDK0OTwKrl6Rx2/OuFZnA0P3lQwgPZSLnDM6Hq+xeHTdx2LNSyE2QFv GzYl4dFoXg3NReLv9D57b7hE6Dc95NcCDDeU7Y3cE7XPksKMA/TkVYOD20ysJ31l 9uzscvvcm2UugN2r0d/B35lf6NWmOG24SmkLMKTtExPGHOCQIbDAlSP/QQ4zz9pQ 2yA+eImpQnRsCzPbGcnBzwEF3yX5+lQYmFWac+0AHDiWEWkb8e3MzNSWPZrsN+cD 7U7c5Zw6zDEtl/naJccuZZPgQGbZgFJ/P6Wo6l5ywIPtE7wzv4MUe4eUxZhitL9M 0ZP6WIQd8oNQdNoCYVQDwPdYJYMq7uUQFUo40vaSfntZxVKZQao7cvUHwmzVzNlZ v5UazETAx+4Eg6MNwfjKp+kt3rr6Xul7K9Nzn6R/cVacIU349FovUshm7WieoAUu niZ40gXltxj7NDwHj3p/dqesW5Nhv/qk6hlVWoi9vdmh8vAVBy/fedQfocvKrFJy prCI1h1UOQ== =10Pr -----END PGP SIGNATURE----- Merge tag 'block-5.9-2020-08-14' of git://git.kernel.dk/linux-block Pull block fixes from Jens Axboe: "A few fixes on the block side of things: - Discard granularity fix (Coly) - rnbd cleanups (Guoqing) - md error handling fix (Dan) - md sysfs fix (Junxiao) - Fix flush request accounting, which caused an IO slowdown for some configurations (Ming) - Properly propagate loop flag for partition scanning (Lennart)" * tag 'block-5.9-2020-08-14' of git://git.kernel.dk/linux-block: block: fix double account of flush request's driver tag loop: unset GENHD_FL_NO_PART_SCAN on LOOP_CONFIGURE rnbd: no need to set bi_end_io in rnbd_bio_map_kern rnbd: remove rnbd_dev_submit_io md-cluster: Fix potential error pointer dereference in resize_bitmaps() block: check queue's limits.discard_granularity in __blkdev_issue_discard() md: get sysfs entry after redundancy attr group create
This commit is contained in:
commit
4b6c093e21
|
@ -308,9 +308,16 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
|
|||
flush_rq->mq_ctx = first_rq->mq_ctx;
|
||||
flush_rq->mq_hctx = first_rq->mq_hctx;
|
||||
|
||||
if (!q->elevator)
|
||||
if (!q->elevator) {
|
||||
flush_rq->tag = first_rq->tag;
|
||||
else
|
||||
|
||||
/*
|
||||
* We borrow data request's driver tag, so have to mark
|
||||
* this flush request as INFLIGHT for avoiding double
|
||||
* account of this driver tag
|
||||
*/
|
||||
flush_rq->rq_flags |= RQF_MQ_INFLIGHT;
|
||||
} else
|
||||
flush_rq->internal_tag = first_rq->internal_tag;
|
||||
|
||||
flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
|
||||
|
|
|
@ -47,6 +47,15 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
|||
op = REQ_OP_DISCARD;
|
||||
}
|
||||
|
||||
/* In case the discard granularity isn't set by buggy device driver */
|
||||
if (WARN_ON_ONCE(!q->limits.discard_granularity)) {
|
||||
char dev_name[BDEVNAME_SIZE];
|
||||
|
||||
bdevname(bdev, dev_name);
|
||||
pr_err_ratelimited("%s: Error: discard_granularity is 0.\n", dev_name);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
|
||||
if ((sector | nr_sects) & bs_mask)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -1171,6 +1171,8 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
|
|||
if (part_shift)
|
||||
lo->lo_flags |= LO_FLAGS_PARTSCAN;
|
||||
partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
|
||||
if (partscan)
|
||||
lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
|
||||
|
||||
/* Grab the block_device to prevent its destruction after we
|
||||
* put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev).
|
||||
|
|
|
@ -45,7 +45,7 @@ void rnbd_dev_close(struct rnbd_dev *dev)
|
|||
kfree(dev);
|
||||
}
|
||||
|
||||
static void rnbd_dev_bi_end_io(struct bio *bio)
|
||||
void rnbd_dev_bi_end_io(struct bio *bio)
|
||||
{
|
||||
struct rnbd_dev_blk_io *io = bio->bi_private;
|
||||
|
||||
|
@ -63,8 +63,8 @@ static void rnbd_dev_bi_end_io(struct bio *bio)
|
|||
* Map the kernel address into a bio suitable for io to a block
|
||||
* device. Returns an error pointer in case of error.
|
||||
*/
|
||||
static struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
|
||||
unsigned int len, gfp_t gfp_mask)
|
||||
struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
|
||||
unsigned int len, gfp_t gfp_mask)
|
||||
{
|
||||
unsigned long kaddr = (unsigned long)data;
|
||||
unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
|
@ -99,36 +99,5 @@ static struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
|
|||
offset = 0;
|
||||
}
|
||||
|
||||
bio->bi_end_io = bio_put;
|
||||
return bio;
|
||||
}
|
||||
|
||||
int rnbd_dev_submit_io(struct rnbd_dev *dev, sector_t sector, void *data,
|
||||
size_t len, u32 bi_size, enum rnbd_io_flags flags,
|
||||
short prio, void *priv)
|
||||
{
|
||||
struct rnbd_dev_blk_io *io;
|
||||
struct bio *bio;
|
||||
|
||||
/* Generate bio with pages pointing to the rdma buffer */
|
||||
bio = rnbd_bio_map_kern(data, dev->ibd_bio_set, len, GFP_KERNEL);
|
||||
if (IS_ERR(bio))
|
||||
return PTR_ERR(bio);
|
||||
|
||||
io = container_of(bio, struct rnbd_dev_blk_io, bio);
|
||||
|
||||
io->dev = dev;
|
||||
io->priv = priv;
|
||||
|
||||
bio->bi_end_io = rnbd_dev_bi_end_io;
|
||||
bio->bi_private = io;
|
||||
bio->bi_opf = rnbd_to_bio_flags(flags);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
bio->bi_iter.bi_size = bi_size;
|
||||
bio_set_prio(bio, prio);
|
||||
bio_set_dev(bio, dev->bdev);
|
||||
|
||||
submit_bio(bio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,11 @@ void rnbd_dev_close(struct rnbd_dev *dev);
|
|||
|
||||
void rnbd_endio(void *priv, int error);
|
||||
|
||||
void rnbd_dev_bi_end_io(struct bio *bio);
|
||||
|
||||
struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
|
||||
unsigned int len, gfp_t gfp_mask);
|
||||
|
||||
static inline int rnbd_dev_get_max_segs(const struct rnbd_dev *dev)
|
||||
{
|
||||
return queue_max_segments(bdev_get_queue(dev->bdev));
|
||||
|
@ -75,18 +80,4 @@ static inline int rnbd_dev_get_discard_alignment(const struct rnbd_dev *dev)
|
|||
return bdev_get_queue(dev->bdev)->limits.discard_alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* rnbd_dev_submit_io() - Submit an I/O to the disk
|
||||
* @dev: device to that the I/O is submitted
|
||||
* @sector: address to read/write data to
|
||||
* @data: I/O data to write or buffer to read I/O date into
|
||||
* @len: length of @data
|
||||
* @bi_size: Amount of data that will be read/written
|
||||
* @prio: IO priority
|
||||
* @priv: private data passed to @io_fn
|
||||
*/
|
||||
int rnbd_dev_submit_io(struct rnbd_dev *dev, sector_t sector, void *data,
|
||||
size_t len, u32 bi_size, enum rnbd_io_flags flags,
|
||||
short prio, void *priv);
|
||||
|
||||
#endif /* RNBD_SRV_DEV_H */
|
||||
|
|
|
@ -124,6 +124,9 @@ static int process_rdma(struct rtrs_srv *sess,
|
|||
struct rnbd_srv_sess_dev *sess_dev;
|
||||
u32 dev_id;
|
||||
int err;
|
||||
struct rnbd_dev_blk_io *io;
|
||||
struct bio *bio;
|
||||
short prio;
|
||||
|
||||
priv = kmalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
|
@ -142,18 +145,29 @@ static int process_rdma(struct rtrs_srv *sess,
|
|||
priv->sess_dev = sess_dev;
|
||||
priv->id = id;
|
||||
|
||||
err = rnbd_dev_submit_io(sess_dev->rnbd_dev, le64_to_cpu(msg->sector),
|
||||
data, datalen, le32_to_cpu(msg->bi_size),
|
||||
le32_to_cpu(msg->rw),
|
||||
srv_sess->ver < RNBD_PROTO_VER_MAJOR ||
|
||||
usrlen < sizeof(*msg) ?
|
||||
0 : le16_to_cpu(msg->prio), priv);
|
||||
if (unlikely(err)) {
|
||||
rnbd_srv_err(sess_dev, "Submitting I/O to device failed, err: %d\n",
|
||||
err);
|
||||
/* Generate bio with pages pointing to the rdma buffer */
|
||||
bio = rnbd_bio_map_kern(data, sess_dev->rnbd_dev->ibd_bio_set, datalen, GFP_KERNEL);
|
||||
if (IS_ERR(bio)) {
|
||||
rnbd_srv_err(sess_dev, "Failed to generate bio, err: %ld\n", PTR_ERR(bio));
|
||||
goto sess_dev_put;
|
||||
}
|
||||
|
||||
io = container_of(bio, struct rnbd_dev_blk_io, bio);
|
||||
io->dev = sess_dev->rnbd_dev;
|
||||
io->priv = priv;
|
||||
|
||||
bio->bi_end_io = rnbd_dev_bi_end_io;
|
||||
bio->bi_private = io;
|
||||
bio->bi_opf = rnbd_to_bio_flags(le32_to_cpu(msg->rw));
|
||||
bio->bi_iter.bi_sector = le64_to_cpu(msg->sector);
|
||||
bio->bi_iter.bi_size = le32_to_cpu(msg->bi_size);
|
||||
prio = srv_sess->ver < RNBD_PROTO_VER_MAJOR ||
|
||||
usrlen < sizeof(*msg) ? 0 : le16_to_cpu(msg->prio);
|
||||
bio_set_prio(bio, prio);
|
||||
bio_set_dev(bio, sess_dev->rnbd_dev->bdev);
|
||||
|
||||
submit_bio(bio);
|
||||
|
||||
return 0;
|
||||
|
||||
sess_dev_put:
|
||||
|
|
|
@ -1139,6 +1139,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz
|
|||
bitmap = get_bitmap_from_slot(mddev, i);
|
||||
if (IS_ERR(bitmap)) {
|
||||
pr_err("can't get bitmap from slot %d\n", i);
|
||||
bitmap = NULL;
|
||||
goto out;
|
||||
}
|
||||
counts = &bitmap->counts;
|
||||
|
|
|
@ -850,7 +850,13 @@ void mddev_unlock(struct mddev *mddev)
|
|||
sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
|
||||
if (mddev->sysfs_action)
|
||||
sysfs_put(mddev->sysfs_action);
|
||||
if (mddev->sysfs_completed)
|
||||
sysfs_put(mddev->sysfs_completed);
|
||||
if (mddev->sysfs_degraded)
|
||||
sysfs_put(mddev->sysfs_degraded);
|
||||
mddev->sysfs_action = NULL;
|
||||
mddev->sysfs_completed = NULL;
|
||||
mddev->sysfs_degraded = NULL;
|
||||
}
|
||||
}
|
||||
mddev->sysfs_active = 0;
|
||||
|
@ -4068,6 +4074,8 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
|
|||
pr_warn("md: cannot register extra attributes for %s\n",
|
||||
mdname(mddev));
|
||||
mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action");
|
||||
mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed");
|
||||
mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");
|
||||
}
|
||||
if (oldpers->sync_request != NULL &&
|
||||
pers->sync_request == NULL) {
|
||||
|
@ -5582,14 +5590,9 @@ static void md_free(struct kobject *ko)
|
|||
|
||||
if (mddev->sysfs_state)
|
||||
sysfs_put(mddev->sysfs_state);
|
||||
if (mddev->sysfs_completed)
|
||||
sysfs_put(mddev->sysfs_completed);
|
||||
if (mddev->sysfs_degraded)
|
||||
sysfs_put(mddev->sysfs_degraded);
|
||||
if (mddev->sysfs_level)
|
||||
sysfs_put(mddev->sysfs_level);
|
||||
|
||||
|
||||
if (mddev->gendisk)
|
||||
del_gendisk(mddev->gendisk);
|
||||
if (mddev->queue)
|
||||
|
@ -5757,8 +5760,6 @@ static int md_alloc(dev_t dev, char *name)
|
|||
if (!error && mddev->kobj.sd) {
|
||||
kobject_uevent(&mddev->kobj, KOBJ_ADD);
|
||||
mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
|
||||
mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed");
|
||||
mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");
|
||||
mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");
|
||||
}
|
||||
mddev_put(mddev);
|
||||
|
@ -6036,6 +6037,8 @@ int md_run(struct mddev *mddev)
|
|||
pr_warn("md: cannot register extra attributes for %s\n",
|
||||
mdname(mddev));
|
||||
mddev->sysfs_action = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_action");
|
||||
mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed");
|
||||
mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");
|
||||
} else if (mddev->ro == 2) /* auto-readonly not meaningful */
|
||||
mddev->ro = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue