diff options
| -rw-r--r-- | block/blk-settings.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 8 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 19 | ||||
| -rw-r--r-- | drivers/scsi/libiscsi.c | 25 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 6 |
5 files changed, 28 insertions, 34 deletions
diff --git a/block/blk-settings.c b/block/blk-settings.c index 12600bfffca9..e0057d035200 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
| @@ -241,8 +241,8 @@ EXPORT_SYMBOL(blk_queue_bounce_limit); | |||
| 241 | * Description: | 241 | * Description: |
| 242 | * Enables a low level driver to set a hard upper limit, | 242 | * Enables a low level driver to set a hard upper limit, |
| 243 | * max_hw_sectors, on the size of requests. max_hw_sectors is set by | 243 | * max_hw_sectors, on the size of requests. max_hw_sectors is set by |
| 244 | * the device driver based upon the combined capabilities of I/O | 244 | * the device driver based upon the capabilities of the I/O |
| 245 | * controller and storage device. | 245 | * controller. |
| 246 | * | 246 | * |
| 247 | * max_sectors is a soft limit imposed by the block layer for | 247 | * max_sectors is a soft limit imposed by the block layer for |
| 248 | * filesystem type requests. This value can be overridden on a | 248 | * filesystem type requests. This value can be overridden on a |
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 1b3a09473452..30f9ef0c0d4f 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
| @@ -733,8 +733,6 @@ static bool fc_invoke_resp(struct fc_exch *ep, struct fc_seq *sp, | |||
| 733 | if (resp) { | 733 | if (resp) { |
| 734 | resp(sp, fp, arg); | 734 | resp(sp, fp, arg); |
| 735 | res = true; | 735 | res = true; |
| 736 | } else if (!IS_ERR(fp)) { | ||
| 737 | fc_frame_free(fp); | ||
| 738 | } | 736 | } |
| 739 | 737 | ||
| 740 | spin_lock_bh(&ep->ex_lock); | 738 | spin_lock_bh(&ep->ex_lock); |
| @@ -1596,7 +1594,8 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
| 1596 | * If new exch resp handler is valid then call that | 1594 | * If new exch resp handler is valid then call that |
| 1597 | * first. | 1595 | * first. |
| 1598 | */ | 1596 | */ |
| 1599 | fc_invoke_resp(ep, sp, fp); | 1597 | if (!fc_invoke_resp(ep, sp, fp)) |
| 1598 | fc_frame_free(fp); | ||
| 1600 | 1599 | ||
| 1601 | fc_exch_release(ep); | 1600 | fc_exch_release(ep); |
| 1602 | return; | 1601 | return; |
| @@ -1695,7 +1694,8 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) | |||
| 1695 | fc_exch_hold(ep); | 1694 | fc_exch_hold(ep); |
| 1696 | if (!rc) | 1695 | if (!rc) |
| 1697 | fc_exch_delete(ep); | 1696 | fc_exch_delete(ep); |
| 1698 | fc_invoke_resp(ep, sp, fp); | 1697 | if (!fc_invoke_resp(ep, sp, fp)) |
| 1698 | fc_frame_free(fp); | ||
| 1699 | if (has_rec) | 1699 | if (has_rec) |
| 1700 | fc_exch_timer_set(ep, ep->r_a_tov); | 1700 | fc_exch_timer_set(ep, ep->r_a_tov); |
| 1701 | fc_exch_release(ep); | 1701 | fc_exch_release(ep); |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index c6795941b45d..2d5909c4685c 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
| @@ -1039,11 +1039,26 @@ restart: | |||
| 1039 | fc_fcp_pkt_hold(fsp); | 1039 | fc_fcp_pkt_hold(fsp); |
| 1040 | spin_unlock_irqrestore(&si->scsi_queue_lock, flags); | 1040 | spin_unlock_irqrestore(&si->scsi_queue_lock, flags); |
| 1041 | 1041 | ||
| 1042 | if (!fc_fcp_lock_pkt(fsp)) { | 1042 | spin_lock_bh(&fsp->scsi_pkt_lock); |
| 1043 | if (!(fsp->state & FC_SRB_COMPL)) { | ||
| 1044 | fsp->state |= FC_SRB_COMPL; | ||
| 1045 | /* | ||
| 1046 | * TODO: dropping scsi_pkt_lock and then reacquiring | ||
| 1047 | * again around fc_fcp_cleanup_cmd() is required, | ||
| 1048 | * since fc_fcp_cleanup_cmd() calls into | ||
| 1049 | * fc_seq_set_resp() and that func preempts cpu using | ||
| 1050 | * schedule. May be schedule and related code should be | ||
| 1051 | * removed instead of unlocking here to avoid scheduling | ||
| 1052 | * while atomic bug. | ||
| 1053 | */ | ||
| 1054 | spin_unlock_bh(&fsp->scsi_pkt_lock); | ||
| 1055 | |||
| 1043 | fc_fcp_cleanup_cmd(fsp, error); | 1056 | fc_fcp_cleanup_cmd(fsp, error); |
| 1057 | |||
| 1058 | spin_lock_bh(&fsp->scsi_pkt_lock); | ||
| 1044 | fc_io_compl(fsp); | 1059 | fc_io_compl(fsp); |
| 1045 | fc_fcp_unlock_pkt(fsp); | ||
| 1046 | } | 1060 | } |
| 1061 | spin_unlock_bh(&fsp->scsi_pkt_lock); | ||
| 1047 | 1062 | ||
| 1048 | fc_fcp_pkt_release(fsp); | 1063 | fc_fcp_pkt_release(fsp); |
| 1049 | spin_lock_irqsave(&si->scsi_queue_lock, flags); | 1064 | spin_lock_irqsave(&si->scsi_queue_lock, flags); |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 8053f24f0349..98d9bb6ff725 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -2941,10 +2941,10 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
| 2941 | { | 2941 | { |
| 2942 | struct iscsi_conn *conn = cls_conn->dd_data; | 2942 | struct iscsi_conn *conn = cls_conn->dd_data; |
| 2943 | struct iscsi_session *session = conn->session; | 2943 | struct iscsi_session *session = conn->session; |
| 2944 | unsigned long flags; | ||
| 2945 | 2944 | ||
| 2946 | del_timer_sync(&conn->transport_timer); | 2945 | del_timer_sync(&conn->transport_timer); |
| 2947 | 2946 | ||
| 2947 | mutex_lock(&session->eh_mutex); | ||
| 2948 | spin_lock_bh(&session->frwd_lock); | 2948 | spin_lock_bh(&session->frwd_lock); |
| 2949 | conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; | 2949 | conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; |
| 2950 | if (session->leadconn == conn) { | 2950 | if (session->leadconn == conn) { |
| @@ -2956,28 +2956,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
| 2956 | } | 2956 | } |
| 2957 | spin_unlock_bh(&session->frwd_lock); | 2957 | spin_unlock_bh(&session->frwd_lock); |
| 2958 | 2958 | ||
| 2959 | /* | ||
| 2960 | * Block until all in-progress commands for this connection | ||
| 2961 | * time out or fail. | ||
| 2962 | */ | ||
| 2963 | for (;;) { | ||
| 2964 | spin_lock_irqsave(session->host->host_lock, flags); | ||
| 2965 | if (!atomic_read(&session->host->host_busy)) { /* OK for ERL == 0 */ | ||
| 2966 | spin_unlock_irqrestore(session->host->host_lock, flags); | ||
| 2967 | break; | ||
| 2968 | } | ||
| 2969 | spin_unlock_irqrestore(session->host->host_lock, flags); | ||
| 2970 | msleep_interruptible(500); | ||
| 2971 | iscsi_conn_printk(KERN_INFO, conn, "iscsi conn_destroy(): " | ||
| 2972 | "host_busy %d host_failed %d\n", | ||
| 2973 | atomic_read(&session->host->host_busy), | ||
| 2974 | session->host->host_failed); | ||
| 2975 | /* | ||
| 2976 | * force eh_abort() to unblock | ||
| 2977 | */ | ||
| 2978 | wake_up(&conn->ehwait); | ||
| 2979 | } | ||
| 2980 | |||
| 2981 | /* flush queued up work because we free the connection below */ | 2959 | /* flush queued up work because we free the connection below */ |
| 2982 | iscsi_suspend_tx(conn); | 2960 | iscsi_suspend_tx(conn); |
| 2983 | 2961 | ||
| @@ -2994,6 +2972,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
| 2994 | if (session->leadconn == conn) | 2972 | if (session->leadconn == conn) |
| 2995 | session->leadconn = NULL; | 2973 | session->leadconn = NULL; |
| 2996 | spin_unlock_bh(&session->frwd_lock); | 2974 | spin_unlock_bh(&session->frwd_lock); |
| 2975 | mutex_unlock(&session->eh_mutex); | ||
| 2997 | 2976 | ||
| 2998 | iscsi_destroy_conn(cls_conn); | 2977 | iscsi_destroy_conn(cls_conn); |
| 2999 | } | 2978 | } |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3b2fcb4fada0..a20da8c25b4f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -2770,9 +2770,9 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
| 2770 | max_xfer = sdkp->max_xfer_blocks; | 2770 | max_xfer = sdkp->max_xfer_blocks; |
| 2771 | max_xfer <<= ilog2(sdp->sector_size) - 9; | 2771 | max_xfer <<= ilog2(sdp->sector_size) - 9; |
| 2772 | 2772 | ||
| 2773 | max_xfer = min_not_zero(queue_max_hw_sectors(sdkp->disk->queue), | 2773 | sdkp->disk->queue->limits.max_sectors = |
| 2774 | max_xfer); | 2774 | min_not_zero(queue_max_hw_sectors(sdkp->disk->queue), max_xfer); |
| 2775 | blk_queue_max_hw_sectors(sdkp->disk->queue, max_xfer); | 2775 | |
| 2776 | set_capacity(disk, sdkp->capacity); | 2776 | set_capacity(disk, sdkp->capacity); |
| 2777 | sd_config_write_same(sdkp); | 2777 | sd_config_write_same(sdkp); |
| 2778 | kfree(buffer); | 2778 | kfree(buffer); |
