| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * iSCSI over TCP/IP Data-Path lib |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Copyright (C) 2005 - 2006 Mike Christie |
|---|
| 7 | 8 | * Copyright (C) 2006 Red Hat, Inc. All rights reserved. |
|---|
| 8 | 9 | * maintained by open-iscsi@googlegroups.com |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License as published |
|---|
| 12 | | - * by the Free Software Foundation; either version 2 of the License, or |
|---|
| 13 | | - * (at your option) any later version. |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 16 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 18 | | - * General Public License for more details. |
|---|
| 19 | | - * |
|---|
| 20 | | - * See the file COPYING included with this distribution for more details. |
|---|
| 21 | 10 | * |
|---|
| 22 | 11 | * Credits: |
|---|
| 23 | 12 | * Christoph Hellwig |
|---|
| .. | .. |
|---|
| 43 | 32 | #include <scsi/scsi_host.h> |
|---|
| 44 | 33 | #include <scsi/scsi.h> |
|---|
| 45 | 34 | #include <scsi/scsi_transport_iscsi.h> |
|---|
| 35 | +#include <trace/events/iscsi.h> |
|---|
| 46 | 36 | |
|---|
| 47 | 37 | #include "iscsi_tcp.h" |
|---|
| 48 | 38 | |
|---|
| .. | .. |
|---|
| 65 | 55 | iscsi_conn_printk(KERN_INFO, _conn, \ |
|---|
| 66 | 56 | "%s " dbg_fmt, \ |
|---|
| 67 | 57 | __func__, ##arg); \ |
|---|
| 58 | + iscsi_dbg_trace(trace_iscsi_dbg_tcp, \ |
|---|
| 59 | + &(_conn)->cls_conn->dev, \ |
|---|
| 60 | + "%s " dbg_fmt, __func__, ##arg);\ |
|---|
| 68 | 61 | } while (0); |
|---|
| 69 | 62 | |
|---|
| 70 | 63 | static int iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn, |
|---|
| .. | .. |
|---|
| 125 | 118 | BUG_ON(sg->length == 0); |
|---|
| 126 | 119 | |
|---|
| 127 | 120 | /* |
|---|
| 121 | + * We always map for the recv path. |
|---|
| 122 | + * |
|---|
| 128 | 123 | * If the page count is greater than one it is ok to send |
|---|
| 129 | 124 | * to the network layer's zero copy send path. If not we |
|---|
| 130 | | - * have to go the slow sendmsg path. We always map for the |
|---|
| 131 | | - * recv path. |
|---|
| 125 | + * have to go the slow sendmsg path. |
|---|
| 126 | + * |
|---|
| 127 | + * Same goes for slab pages: skb_can_coalesce() allows |
|---|
| 128 | + * coalescing neighboring slab objects into a single frag which |
|---|
| 129 | + * triggers one of hardened usercopy checks. |
|---|
| 132 | 130 | */ |
|---|
| 133 | | - if (page_count(sg_page(sg)) >= 1 && !recv) |
|---|
| 131 | + if (!recv && sendpage_ok(sg_page(sg))) |
|---|
| 134 | 132 | return; |
|---|
| 135 | 133 | |
|---|
| 136 | 134 | if (recv) { |
|---|
| .. | .. |
|---|
| 491 | 489 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
|---|
| 492 | 490 | struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr; |
|---|
| 493 | 491 | int datasn = be32_to_cpu(rhdr->datasn); |
|---|
| 494 | | - unsigned total_in_length = scsi_in(task->sc)->length; |
|---|
| 492 | + unsigned total_in_length = task->sc->sdb.length; |
|---|
| 495 | 493 | |
|---|
| 496 | 494 | /* |
|---|
| 497 | 495 | * lib iscsi will update this in the completion handling if there |
|---|
| .. | .. |
|---|
| 576 | 574 | data_length, session->max_burst); |
|---|
| 577 | 575 | |
|---|
| 578 | 576 | data_offset = be32_to_cpu(rhdr->data_offset); |
|---|
| 579 | | - if (data_offset + data_length > scsi_out(task->sc)->length) { |
|---|
| 577 | + if (data_offset + data_length > task->sc->sdb.length) { |
|---|
| 580 | 578 | iscsi_conn_printk(KERN_ERR, conn, |
|---|
| 581 | 579 | "invalid R2T with data len %u at offset %u " |
|---|
| 582 | 580 | "and total length %d\n", data_length, |
|---|
| 583 | | - data_offset, scsi_out(task->sc)->length); |
|---|
| 581 | + data_offset, task->sc->sdb.length); |
|---|
| 584 | 582 | return ISCSI_ERR_DATALEN; |
|---|
| 585 | 583 | } |
|---|
| 586 | 584 | |
|---|
| .. | .. |
|---|
| 692 | 690 | if (tcp_conn->in.datalen) { |
|---|
| 693 | 691 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
|---|
| 694 | 692 | struct ahash_request *rx_hash = NULL; |
|---|
| 695 | | - struct scsi_data_buffer *sdb = scsi_in(task->sc); |
|---|
| 693 | + struct scsi_data_buffer *sdb = &task->sc->sdb; |
|---|
| 696 | 694 | |
|---|
| 697 | 695 | /* |
|---|
| 698 | 696 | * Setup copy of Data-In into the struct scsi_cmnd |
|---|
| .. | .. |
|---|
| 774 | 772 | iscsi_tcp_data_recv_prep(tcp_conn); |
|---|
| 775 | 773 | return 0; |
|---|
| 776 | 774 | } |
|---|
| 777 | | - /* fall through */ |
|---|
| 775 | + fallthrough; |
|---|
| 778 | 776 | case ISCSI_OP_LOGOUT_RSP: |
|---|
| 779 | 777 | case ISCSI_OP_NOOP_IN: |
|---|
| 780 | 778 | case ISCSI_OP_SCSI_TMFUNC_RSP: |
|---|