Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'block-6.1-2022-11-25' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

- A few fixes for s390 sads (Stefan, Colin)

- Ensure that ublk doesn't reorder requests, as that can be problematic
on devices that need specific ordering (Ming)

- Fix a queue reference leak in disk allocation handling (Christoph)

* tag 'block-6.1-2022-11-25' of git://git.kernel.dk/linux:
ublk_drv: don't forward io commands in reserve order
s390/dasd: fix possible buffer overflow in copy_pair_show
s390/dasd: fix no record found for raw_track_access
s390/dasd: increase printing of debug data payload
s390/dasd: Fix spelling mistake "Ivalid" -> "Invalid"
blk-mq: fix queue reference leak on blk_mq_alloc_disk_for_queue failure

+67 -69
+6 -1
block/blk-mq.c
··· 4045 4045 struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q, 4046 4046 struct lock_class_key *lkclass) 4047 4047 { 4048 + struct gendisk *disk; 4049 + 4048 4050 if (!blk_get_queue(q)) 4049 4051 return NULL; 4050 - return __alloc_disk_node(q, NUMA_NO_NODE, lkclass); 4052 + disk = __alloc_disk_node(q, NUMA_NO_NODE, lkclass); 4053 + if (!disk) 4054 + blk_put_queue(q); 4055 + return disk; 4051 4056 } 4052 4057 EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue); 4053 4058
+38 -44
drivers/block/ublk_drv.c
··· 57 57 #define UBLK_PARAM_TYPE_ALL (UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD) 58 58 59 59 struct ublk_rq_data { 60 - union { 61 - struct callback_head work; 62 - struct llist_node node; 63 - }; 60 + struct llist_node node; 61 + struct callback_head work; 64 62 }; 65 63 66 64 struct ublk_uring_cmd_pdu { ··· 764 766 ubq_complete_io_cmd(io, UBLK_IO_RES_OK); 765 767 } 766 768 769 + static inline void ublk_forward_io_cmds(struct ublk_queue *ubq) 770 + { 771 + struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); 772 + struct ublk_rq_data *data, *tmp; 773 + 774 + io_cmds = llist_reverse_order(io_cmds); 775 + llist_for_each_entry_safe(data, tmp, io_cmds, node) 776 + __ublk_rq_task_work(blk_mq_rq_from_pdu(data)); 777 + } 778 + 779 + static inline void ublk_abort_io_cmds(struct ublk_queue *ubq) 780 + { 781 + struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); 782 + struct ublk_rq_data *data, *tmp; 783 + 784 + llist_for_each_entry_safe(data, tmp, io_cmds, node) 785 + __ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data)); 786 + } 787 + 767 788 static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd) 768 789 { 769 790 struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); 770 791 struct ublk_queue *ubq = pdu->ubq; 771 - struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); 772 - struct ublk_rq_data *data; 773 792 774 - llist_for_each_entry(data, io_cmds, node) 775 - __ublk_rq_task_work(blk_mq_rq_from_pdu(data)); 793 + ublk_forward_io_cmds(ubq); 776 794 } 777 795 778 796 static void ublk_rq_task_work_fn(struct callback_head *work) ··· 796 782 struct ublk_rq_data *data = container_of(work, 797 783 struct ublk_rq_data, work); 798 784 struct request *req = blk_mq_rq_from_pdu(data); 785 + struct ublk_queue *ubq = req->mq_hctx->driver_data; 799 786 800 - __ublk_rq_task_work(req); 787 + ublk_forward_io_cmds(ubq); 801 788 } 802 789 803 - static void ublk_submit_cmd(struct ublk_queue *ubq, const struct request *rq) 790 + static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) 804 791 { 805 - struct ublk_io *io = &ubq->ios[rq->tag]; 792 + struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq); 793 + struct ublk_io *io; 806 794 795 + if (!llist_add(&data->node, &ubq->io_cmds)) 796 + return; 797 + 798 + io = &ubq->ios[rq->tag]; 807 799 /* 808 800 * If the check pass, we know that this is a re-issued request aborted 809 801 * previously in monitor_work because the ubq_daemon(cmd's task) is ··· 823 803 * guarantees that here is a re-issued request aborted previously. 824 804 */ 825 805 if (unlikely(io->flags & UBLK_IO_FLAG_ABORTED)) { 826 - struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); 827 - struct ublk_rq_data *data; 828 - 829 - llist_for_each_entry(data, io_cmds, node) 830 - __ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data)); 806 + ublk_abort_io_cmds(ubq); 807 + } else if (ublk_can_use_task_work(ubq)) { 808 + if (task_work_add(ubq->ubq_daemon, &data->work, 809 + TWA_SIGNAL_NO_IPI)) 810 + ublk_abort_io_cmds(ubq); 831 811 } else { 832 812 struct io_uring_cmd *cmd = io->cmd; 833 813 struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); 834 814 835 815 pdu->ubq = ubq; 836 816 io_uring_cmd_complete_in_task(cmd, ublk_rq_task_work_cb); 837 - } 838 - } 839 - 840 - static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq, 841 - bool last) 842 - { 843 - struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq); 844 - 845 - if (ublk_can_use_task_work(ubq)) { 846 - enum task_work_notify_mode notify_mode = last ? 847 - TWA_SIGNAL_NO_IPI : TWA_NONE; 848 - 849 - if (task_work_add(ubq->ubq_daemon, &data->work, notify_mode)) 850 - __ublk_abort_rq(ubq, rq); 851 - } else { 852 - if (llist_add(&data->node, &ubq->io_cmds)) 853 - ublk_submit_cmd(ubq, rq); 854 817 } 855 818 } 856 819 ··· 868 865 return BLK_STS_OK; 869 866 } 870 867 871 - ublk_queue_cmd(ubq, rq, bd->last); 868 + ublk_queue_cmd(ubq, rq); 872 869 873 870 return BLK_STS_OK; 874 - } 875 - 876 - static void ublk_commit_rqs(struct blk_mq_hw_ctx *hctx) 877 - { 878 - struct ublk_queue *ubq = hctx->driver_data; 879 - 880 - if (ublk_can_use_task_work(ubq)) 881 - __set_notify_signal(ubq->ubq_daemon); 882 871 } 883 872 884 873 static int ublk_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data, ··· 894 899 895 900 static const struct blk_mq_ops ublk_mq_ops = { 896 901 .queue_rq = ublk_queue_rq, 897 - .commit_rqs = ublk_commit_rqs, 898 902 .init_hctx = ublk_init_hctx, 899 903 .init_request = ublk_init_rq, 900 904 }; ··· 1191 1197 struct ublk_queue *ubq = ublk_get_queue(ub, q_id); 1192 1198 struct request *req = blk_mq_tag_to_rq(ub->tag_set.tags[q_id], tag); 1193 1199 1194 - ublk_queue_cmd(ubq, req, true); 1200 + ublk_queue_cmd(ubq, req); 1195 1201 } 1196 1202 1197 1203 static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
+1 -1
drivers/s390/block/dasd_devmap.c
··· 1954 1954 break; 1955 1955 } 1956 1956 } 1957 - if (!copy->entry[i].primary) 1957 + if (i == DASD_CP_ENTRIES) 1958 1958 goto out; 1959 1959 1960 1960 /* print all secondary */
+21 -22
drivers/s390/block/dasd_eckd.c
··· 4722 4722 struct dasd_device *basedev; 4723 4723 struct req_iterator iter; 4724 4724 struct dasd_ccw_req *cqr; 4725 - unsigned int first_offs; 4726 4725 unsigned int trkcount; 4727 4726 unsigned long *idaws; 4728 4727 unsigned int size; ··· 4755 4756 last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) / 4756 4757 DASD_RAW_SECTORS_PER_TRACK; 4757 4758 trkcount = last_trk - first_trk + 1; 4758 - first_offs = 0; 4759 4759 4760 4760 if (rq_data_dir(req) == READ) 4761 4761 cmd = DASD_ECKD_CCW_READ_TRACK; ··· 4798 4800 4799 4801 if (use_prefix) { 4800 4802 prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev, 4801 - startdev, 1, first_offs + 1, trkcount, 0, 0); 4803 + startdev, 1, 0, trkcount, 0, 0); 4802 4804 } else { 4803 4805 define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0); 4804 4806 ccw[-1].flags |= CCW_FLAG_CC; 4805 4807 4806 4808 data += sizeof(struct DE_eckd_data); 4807 - locate_record_ext(ccw++, data, first_trk, first_offs + 1, 4809 + locate_record_ext(ccw++, data, first_trk, 0, 4808 4810 trkcount, cmd, basedev, 0, 0); 4809 4811 } 4810 4812 ··· 5498 5500 * Dump the range of CCWs into 'page' buffer 5499 5501 * and return number of printed chars. 5500 5502 */ 5501 - static int 5503 + static void 5502 5504 dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) 5503 5505 { 5504 5506 int len, count; ··· 5516 5518 else 5517 5519 datap = (char *) ((addr_t) from->cda); 5518 5520 5519 - /* dump data (max 32 bytes) */ 5520 - for (count = 0; count < from->count && count < 32; count++) { 5521 - if (count % 8 == 0) len += sprintf(page + len, " "); 5522 - if (count % 4 == 0) len += sprintf(page + len, " "); 5521 + /* dump data (max 128 bytes) */ 5522 + for (count = 0; count < from->count && count < 128; count++) { 5523 + if (count % 32 == 0) 5524 + len += sprintf(page + len, "\n"); 5525 + if (count % 8 == 0) 5526 + len += sprintf(page + len, " "); 5527 + if (count % 4 == 0) 5528 + len += sprintf(page + len, " "); 5523 5529 len += sprintf(page + len, "%02x", datap[count]); 5524 5530 } 5525 5531 len += sprintf(page + len, "\n"); 5526 5532 from++; 5527 5533 } 5528 - return len; 5534 + if (len > 0) 5535 + printk(KERN_ERR "%s", page); 5529 5536 } 5530 5537 5531 5538 static void ··· 5622 5619 if (req) { 5623 5620 /* req == NULL for unsolicited interrupts */ 5624 5621 /* dump the Channel Program (max 140 Bytes per line) */ 5625 - /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */ 5622 + /* Count CCW and print first CCWs (maximum 7) */ 5626 5623 first = req->cpaddr; 5627 5624 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 5628 5625 to = min(first + 6, last); 5629 - len = sprintf(page, PRINTK_HEADER 5630 - " Related CP in req: %p\n", req); 5631 - dasd_eckd_dump_ccw_range(first, to, page + len); 5632 - printk(KERN_ERR "%s", page); 5626 + printk(KERN_ERR PRINTK_HEADER " Related CP in req: %p\n", req); 5627 + dasd_eckd_dump_ccw_range(first, to, page); 5633 5628 5634 5629 /* print failing CCW area (maximum 4) */ 5635 5630 /* scsw->cda is either valid or zero */ 5636 - len = 0; 5637 5631 from = ++to; 5638 5632 fail = (struct ccw1 *)(addr_t) 5639 5633 irb->scsw.cmd.cpa; /* failing CCW */ 5640 5634 if (from < fail - 2) { 5641 5635 from = fail - 2; /* there is a gap - print header */ 5642 - len += sprintf(page, PRINTK_HEADER "......\n"); 5636 + printk(KERN_ERR PRINTK_HEADER "......\n"); 5643 5637 } 5644 5638 to = min(fail + 1, last); 5645 - len += dasd_eckd_dump_ccw_range(from, to, page + len); 5639 + dasd_eckd_dump_ccw_range(from, to, page + len); 5646 5640 5647 5641 /* print last CCWs (maximum 2) */ 5642 + len = 0; 5648 5643 from = max(from, ++to); 5649 5644 if (from < last - 1) { 5650 5645 from = last - 1; /* there is a gap - print header */ 5651 - len += sprintf(page + len, PRINTK_HEADER "......\n"); 5646 + printk(KERN_ERR PRINTK_HEADER "......\n"); 5652 5647 } 5653 - len += dasd_eckd_dump_ccw_range(from, last, page + len); 5654 - if (len > 0) 5655 - printk(KERN_ERR "%s", page); 5648 + dasd_eckd_dump_ccw_range(from, last, page + len); 5656 5649 } 5657 5650 free_page((unsigned long) page); 5658 5651 }
+1 -1
drivers/s390/block/dasd_ioctl.c
··· 401 401 return -EFAULT; 402 402 } 403 403 if (memchr_inv(data.reserved, 0, sizeof(data.reserved))) { 404 - pr_warn("%s: Ivalid swap data specified.\n", 404 + pr_warn("%s: Invalid swap data specified\n", 405 405 dev_name(&device->cdev->dev)); 406 406 dasd_put_device(device); 407 407 return DASD_COPYPAIRSWAP_INVALID;