Skip to content

Commit 5fc6b07

Browse files
committed
Merge tag 'block-5.10-2020-10-30' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: - null_blk zone fixes (Damien, Kanchan) - NVMe pull request from Christoph: - improve zone revalidation (Keith Busch) - gracefully handle zero length messages in nvme-rdma (zhenwei pi) - nvme-fc error handling fixes (James Smart) - nvmet tracing NULL pointer dereference fix (Chaitanya Kulkarni)" - xsysace platform fixes (Andy) - scatterlist type cleanup (David) - blk-cgroup memory fixes (Gabriel) - nbd block size update fix (Ming) - Flush completion state fix (Ming) - bio_add_hw_page() iteration fix (Naohiro) * tag 'block-5.10-2020-10-30' of git://git.kernel.dk/linux-block: blk-mq: mark flush request as IDLE in flush_end_io() lib/scatterlist: use consistent sg_copy_buffer() return type xsysace: use platform_get_resource() and platform_get_irq_optional() null_blk: Fix locking in zoned mode null_blk: Fix zone reset all tracing nbd: don't update block size after device is started block: advance iov_iter on bio_add_hw_page failure null_blk: synchronization fix for zoned device nvmet: fix a NULL pointer dereference when tracing the flush command nvme-fc: remove nvme_fc_terminate_io() nvme-fc: eliminate terminate_io use by nvme_fc_error_recovery nvme-fc: remove err_work work item nvme-fc: track error_recovery while connecting nvme-rdma: handle unexpected nvme completion data length nvme: ignore zone validate errors on subsequent scans blk-cgroup: Pre-allocate tree node on blkg_conf_prep blk-cgroup: Fix memleak on error path
2 parents cf9446c + 65ff5cd commit 5fc6b07

13 files changed

Lines changed: 281 additions & 236 deletions

File tree

block/bio.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter)
10441044
ssize_t size, left;
10451045
unsigned len, i;
10461046
size_t offset;
1047+
int ret = 0;
10471048

10481049
if (WARN_ON_ONCE(!max_append_sectors))
10491050
return 0;
@@ -1066,15 +1067,17 @@ static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter)
10661067

10671068
len = min_t(size_t, PAGE_SIZE - offset, left);
10681069
if (bio_add_hw_page(q, bio, page, len, offset,
1069-
max_append_sectors, &same_page) != len)
1070-
return -EINVAL;
1070+
max_append_sectors, &same_page) != len) {
1071+
ret = -EINVAL;
1072+
break;
1073+
}
10711074
if (same_page)
10721075
put_page(page);
10731076
offset = 0;
10741077
}
10751078

1076-
iov_iter_advance(iter, size);
1077-
return 0;
1079+
iov_iter_advance(iter, size - left);
1080+
return ret;
10781081
}
10791082

10801083
/**

block/blk-cgroup.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,13 +657,20 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
657657
goto fail;
658658
}
659659

660+
if (radix_tree_preload(GFP_KERNEL)) {
661+
blkg_free(new_blkg);
662+
ret = -ENOMEM;
663+
goto fail;
664+
}
665+
660666
rcu_read_lock();
661667
spin_lock_irq(&q->queue_lock);
662668

663669
blkg = blkg_lookup_check(pos, pol, q);
664670
if (IS_ERR(blkg)) {
665671
ret = PTR_ERR(blkg);
666-
goto fail_unlock;
672+
blkg_free(new_blkg);
673+
goto fail_preloaded;
667674
}
668675

669676
if (blkg) {
@@ -672,10 +679,12 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
672679
blkg = blkg_create(pos, q, new_blkg);
673680
if (IS_ERR(blkg)) {
674681
ret = PTR_ERR(blkg);
675-
goto fail_unlock;
682+
goto fail_preloaded;
676683
}
677684
}
678685

686+
radix_tree_preload_end();
687+
679688
if (pos == blkcg)
680689
goto success;
681690
}
@@ -685,6 +694,8 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
685694
ctx->body = input;
686695
return 0;
687696

697+
fail_preloaded:
698+
radix_tree_preload_end();
688699
fail_unlock:
689700
spin_unlock_irq(&q->queue_lock);
690701
rcu_read_unlock();

block/blk-flush.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
225225
/* release the tag's ownership to the req cloned from */
226226
spin_lock_irqsave(&fq->mq_flush_lock, flags);
227227

228+
WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE);
228229
if (!refcount_dec_and_test(&flush_rq->ref)) {
229230
fq->rq_status = error;
230231
spin_unlock_irqrestore(&fq->mq_flush_lock, flags);

drivers/block/nbd.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ static void nbd_size_clear(struct nbd_device *nbd)
296296
}
297297
}
298298

299-
static void nbd_size_update(struct nbd_device *nbd)
299+
static void nbd_size_update(struct nbd_device *nbd, bool start)
300300
{
301301
struct nbd_config *config = nbd->config;
302302
struct block_device *bdev = bdget_disk(nbd->disk, 0);
@@ -313,7 +313,8 @@ static void nbd_size_update(struct nbd_device *nbd)
313313
if (bdev) {
314314
if (bdev->bd_disk) {
315315
bd_set_nr_sectors(bdev, nr_sectors);
316-
set_blocksize(bdev, config->blksize);
316+
if (start)
317+
set_blocksize(bdev, config->blksize);
317318
} else
318319
set_bit(GD_NEED_PART_SCAN, &nbd->disk->state);
319320
bdput(bdev);
@@ -328,7 +329,7 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize,
328329
config->blksize = blocksize;
329330
config->bytesize = blocksize * nr_blocks;
330331
if (nbd->task_recv != NULL)
331-
nbd_size_update(nbd);
332+
nbd_size_update(nbd, false);
332333
}
333334

334335
static void nbd_complete_rq(struct request *req)
@@ -1308,7 +1309,7 @@ static int nbd_start_device(struct nbd_device *nbd)
13081309
args->index = i;
13091310
queue_work(nbd->recv_workq, &args->work);
13101311
}
1311-
nbd_size_update(nbd);
1312+
nbd_size_update(nbd, true);
13121313
return error;
13131314
}
13141315

drivers/block/null_blk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ struct nullb_device {
4747
unsigned int nr_zones_closed;
4848
struct blk_zone *zones;
4949
sector_t zone_size_sects;
50+
spinlock_t zone_dev_lock;
51+
unsigned long *zone_locks;
5052

5153
unsigned long size; /* device size in MB */
5254
unsigned long completion_nsec; /* time in ns to complete a request */

drivers/block/null_blk_zoned.c

Lines changed: 99 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0
22
#include <linux/vmalloc.h>
3+
#include <linux/bitmap.h>
34
#include "null_blk.h"
45

56
#define CREATE_TRACE_POINTS
@@ -45,6 +46,13 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
4546
if (!dev->zones)
4647
return -ENOMEM;
4748

49+
spin_lock_init(&dev->zone_dev_lock);
50+
dev->zone_locks = bitmap_zalloc(dev->nr_zones, GFP_KERNEL);
51+
if (!dev->zone_locks) {
52+
kvfree(dev->zones);
53+
return -ENOMEM;
54+
}
55+
4856
if (dev->zone_nr_conv >= dev->nr_zones) {
4957
dev->zone_nr_conv = dev->nr_zones - 1;
5058
pr_info("changed the number of conventional zones to %u",
@@ -123,15 +131,26 @@ int null_register_zoned_dev(struct nullb *nullb)
123131

124132
void null_free_zoned_dev(struct nullb_device *dev)
125133
{
134+
bitmap_free(dev->zone_locks);
126135
kvfree(dev->zones);
127136
}
128137

138+
static inline void null_lock_zone(struct nullb_device *dev, unsigned int zno)
139+
{
140+
wait_on_bit_lock_io(dev->zone_locks, zno, TASK_UNINTERRUPTIBLE);
141+
}
142+
143+
static inline void null_unlock_zone(struct nullb_device *dev, unsigned int zno)
144+
{
145+
clear_and_wake_up_bit(zno, dev->zone_locks);
146+
}
147+
129148
int null_report_zones(struct gendisk *disk, sector_t sector,
130149
unsigned int nr_zones, report_zones_cb cb, void *data)
131150
{
132151
struct nullb *nullb = disk->private_data;
133152
struct nullb_device *dev = nullb->dev;
134-
unsigned int first_zone, i;
153+
unsigned int first_zone, i, zno;
135154
struct blk_zone zone;
136155
int error;
137156

@@ -142,15 +161,18 @@ int null_report_zones(struct gendisk *disk, sector_t sector,
142161
nr_zones = min(nr_zones, dev->nr_zones - first_zone);
143162
trace_nullb_report_zones(nullb, nr_zones);
144163

145-
for (i = 0; i < nr_zones; i++) {
164+
zno = first_zone;
165+
for (i = 0; i < nr_zones; i++, zno++) {
146166
/*
147167
* Stacked DM target drivers will remap the zone information by
148168
* modifying the zone information passed to the report callback.
149169
* So use a local copy to avoid corruption of the device zone
150170
* array.
151171
*/
152-
memcpy(&zone, &dev->zones[first_zone + i],
153-
sizeof(struct blk_zone));
172+
null_lock_zone(dev, zno);
173+
memcpy(&zone, &dev->zones[zno], sizeof(struct blk_zone));
174+
null_unlock_zone(dev, zno);
175+
154176
error = cb(&zone, i, data);
155177
if (error)
156178
return error;
@@ -159,6 +181,10 @@ int null_report_zones(struct gendisk *disk, sector_t sector,
159181
return nr_zones;
160182
}
161183

184+
/*
185+
* This is called in the case of memory backing from null_process_cmd()
186+
* with the target zone already locked.
187+
*/
162188
size_t null_zone_valid_read_len(struct nullb *nullb,
163189
sector_t sector, unsigned int len)
164190
{
@@ -295,22 +321,27 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
295321
if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
296322
return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
297323

324+
null_lock_zone(dev, zno);
325+
spin_lock(&dev->zone_dev_lock);
326+
298327
switch (zone->cond) {
299328
case BLK_ZONE_COND_FULL:
300329
/* Cannot write to a full zone */
301-
return BLK_STS_IOERR;
330+
ret = BLK_STS_IOERR;
331+
goto unlock;
302332
case BLK_ZONE_COND_EMPTY:
303333
case BLK_ZONE_COND_CLOSED:
304334
ret = null_check_zone_resources(dev, zone);
305335
if (ret != BLK_STS_OK)
306-
return ret;
336+
goto unlock;
307337
break;
308338
case BLK_ZONE_COND_IMP_OPEN:
309339
case BLK_ZONE_COND_EXP_OPEN:
310340
break;
311341
default:
312342
/* Invalid zone condition */
313-
return BLK_STS_IOERR;
343+
ret = BLK_STS_IOERR;
344+
goto unlock;
314345
}
315346

316347
/*
@@ -326,11 +357,14 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
326357
else
327358
cmd->rq->__sector = sector;
328359
} else if (sector != zone->wp) {
329-
return BLK_STS_IOERR;
360+
ret = BLK_STS_IOERR;
361+
goto unlock;
330362
}
331363

332-
if (zone->wp + nr_sectors > zone->start + zone->capacity)
333-
return BLK_STS_IOERR;
364+
if (zone->wp + nr_sectors > zone->start + zone->capacity) {
365+
ret = BLK_STS_IOERR;
366+
goto unlock;
367+
}
334368

335369
if (zone->cond == BLK_ZONE_COND_CLOSED) {
336370
dev->nr_zones_closed--;
@@ -341,9 +375,11 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
341375
if (zone->cond != BLK_ZONE_COND_EXP_OPEN)
342376
zone->cond = BLK_ZONE_COND_IMP_OPEN;
343377

378+
spin_unlock(&dev->zone_dev_lock);
344379
ret = null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
380+
spin_lock(&dev->zone_dev_lock);
345381
if (ret != BLK_STS_OK)
346-
return ret;
382+
goto unlock;
347383

348384
zone->wp += nr_sectors;
349385
if (zone->wp == zone->start + zone->capacity) {
@@ -353,7 +389,13 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
353389
dev->nr_zones_imp_open--;
354390
zone->cond = BLK_ZONE_COND_FULL;
355391
}
356-
return BLK_STS_OK;
392+
ret = BLK_STS_OK;
393+
394+
unlock:
395+
spin_unlock(&dev->zone_dev_lock);
396+
null_unlock_zone(dev, zno);
397+
398+
return ret;
357399
}
358400

359401
static blk_status_t null_open_zone(struct nullb_device *dev, struct blk_zone *zone)
@@ -464,16 +506,33 @@ static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op,
464506
sector_t sector)
465507
{
466508
struct nullb_device *dev = cmd->nq->dev;
467-
unsigned int zone_no = null_zone_no(dev, sector);
468-
struct blk_zone *zone = &dev->zones[zone_no];
469-
blk_status_t ret = BLK_STS_OK;
509+
unsigned int zone_no;
510+
struct blk_zone *zone;
511+
blk_status_t ret;
470512
size_t i;
471513

514+
if (op == REQ_OP_ZONE_RESET_ALL) {
515+
for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) {
516+
null_lock_zone(dev, i);
517+
zone = &dev->zones[i];
518+
if (zone->cond != BLK_ZONE_COND_EMPTY) {
519+
spin_lock(&dev->zone_dev_lock);
520+
null_reset_zone(dev, zone);
521+
spin_unlock(&dev->zone_dev_lock);
522+
trace_nullb_zone_op(cmd, i, zone->cond);
523+
}
524+
null_unlock_zone(dev, i);
525+
}
526+
return BLK_STS_OK;
527+
}
528+
529+
zone_no = null_zone_no(dev, sector);
530+
zone = &dev->zones[zone_no];
531+
532+
null_lock_zone(dev, zone_no);
533+
spin_lock(&dev->zone_dev_lock);
534+
472535
switch (op) {
473-
case REQ_OP_ZONE_RESET_ALL:
474-
for (i = dev->zone_nr_conv; i < dev->nr_zones; i++)
475-
null_reset_zone(dev, &dev->zones[i]);
476-
break;
477536
case REQ_OP_ZONE_RESET:
478537
ret = null_reset_zone(dev, zone);
479538
break;
@@ -487,30 +546,46 @@ static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op,
487546
ret = null_finish_zone(dev, zone);
488547
break;
489548
default:
490-
return BLK_STS_NOTSUPP;
549+
ret = BLK_STS_NOTSUPP;
550+
break;
491551
}
492552

553+
spin_unlock(&dev->zone_dev_lock);
554+
493555
if (ret == BLK_STS_OK)
494556
trace_nullb_zone_op(cmd, zone_no, zone->cond);
495557

558+
null_unlock_zone(dev, zone_no);
559+
496560
return ret;
497561
}
498562

499563
blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_opf op,
500564
sector_t sector, sector_t nr_sectors)
501565
{
566+
struct nullb_device *dev = cmd->nq->dev;
567+
unsigned int zno = null_zone_no(dev, sector);
568+
blk_status_t sts;
569+
502570
switch (op) {
503571
case REQ_OP_WRITE:
504-
return null_zone_write(cmd, sector, nr_sectors, false);
572+
sts = null_zone_write(cmd, sector, nr_sectors, false);
573+
break;
505574
case REQ_OP_ZONE_APPEND:
506-
return null_zone_write(cmd, sector, nr_sectors, true);
575+
sts = null_zone_write(cmd, sector, nr_sectors, true);
576+
break;
507577
case REQ_OP_ZONE_RESET:
508578
case REQ_OP_ZONE_RESET_ALL:
509579
case REQ_OP_ZONE_OPEN:
510580
case REQ_OP_ZONE_CLOSE:
511581
case REQ_OP_ZONE_FINISH:
512-
return null_zone_mgmt(cmd, op, sector);
582+
sts = null_zone_mgmt(cmd, op, sector);
583+
break;
513584
default:
514-
return null_process_cmd(cmd, op, sector, nr_sectors);
585+
null_lock_zone(dev, zno);
586+
sts = null_process_cmd(cmd, op, sector, nr_sectors);
587+
null_unlock_zone(dev, zno);
515588
}
589+
590+
return sts;
516591
}

0 commit comments

Comments
 (0)