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 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
"Six minor fixes to device drivers and one to the multipath alua
handler.

The most extensive fix is the zfcp port remove prevention one, but
it's impact is only s390"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: libsas: delete sas port if expander discover failed
scsi: libsas: only clear phy->in_shutdown after shutdown event done
scsi: scsi_dh_alua: Fix possible null-ptr-deref
scsi: smartpqi: properly set both the DMA mask and the coherent DMA mask
scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs)
scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove
scsi: libcxgbi: add a check for NULL pointer in cxgbi_check_route()

+76 -14
+1
drivers/s390/scsi/zfcp_ext.h
··· 167 167 extern struct mutex zfcp_sysfs_port_units_mutex; 168 168 extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; 169 169 extern struct device_attribute *zfcp_sysfs_shost_attrs[]; 170 + bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port); 170 171 171 172 /* zfcp_unit.c */ 172 173 extern int zfcp_unit_add(struct zfcp_port *, u64);
+9
drivers/s390/scsi/zfcp_scsi.c
··· 129 129 130 130 zfcp_sdev->erp_action.port = port; 131 131 132 + mutex_lock(&zfcp_sysfs_port_units_mutex); 133 + if (zfcp_sysfs_port_is_removing(port)) { 134 + /* port is already gone */ 135 + mutex_unlock(&zfcp_sysfs_port_units_mutex); 136 + put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */ 137 + return -ENXIO; 138 + } 139 + mutex_unlock(&zfcp_sysfs_port_units_mutex); 140 + 132 141 unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); 133 142 if (unit) 134 143 put_device(&unit->dev);
+49 -6
drivers/s390/scsi/zfcp_sysfs.c
··· 235 235 236 236 DEFINE_MUTEX(zfcp_sysfs_port_units_mutex); 237 237 238 + static void zfcp_sysfs_port_set_removing(struct zfcp_port *const port) 239 + { 240 + lockdep_assert_held(&zfcp_sysfs_port_units_mutex); 241 + atomic_set(&port->units, -1); 242 + } 243 + 244 + bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port) 245 + { 246 + lockdep_assert_held(&zfcp_sysfs_port_units_mutex); 247 + return atomic_read(&port->units) == -1; 248 + } 249 + 250 + static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port) 251 + { 252 + struct zfcp_adapter *const adapter = port->adapter; 253 + unsigned long flags; 254 + struct scsi_device *sdev; 255 + bool in_use = true; 256 + 257 + mutex_lock(&zfcp_sysfs_port_units_mutex); 258 + if (atomic_read(&port->units) > 0) 259 + goto unlock_port_units_mutex; /* zfcp_unit(s) under port */ 260 + 261 + spin_lock_irqsave(adapter->scsi_host->host_lock, flags); 262 + __shost_for_each_device(sdev, adapter->scsi_host) { 263 + const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev); 264 + 265 + if (sdev->sdev_state == SDEV_DEL || 266 + sdev->sdev_state == SDEV_CANCEL) 267 + continue; 268 + if (zsdev->port != port) 269 + continue; 270 + /* alive scsi_device under port of interest */ 271 + goto unlock_host_lock; 272 + } 273 + 274 + /* port is about to be removed, so no more unit_add or slave_alloc */ 275 + zfcp_sysfs_port_set_removing(port); 276 + in_use = false; 277 + 278 + unlock_host_lock: 279 + spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); 280 + unlock_port_units_mutex: 281 + mutex_unlock(&zfcp_sysfs_port_units_mutex); 282 + return in_use; 283 + } 284 + 238 285 static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, 239 286 struct device_attribute *attr, 240 287 const char *buf, size_t count) ··· 304 257 else 305 258 retval = 0; 306 259 307 - mutex_lock(&zfcp_sysfs_port_units_mutex); 308 - if (atomic_read(&port->units) > 0) { 260 + if (zfcp_sysfs_port_in_use(port)) { 309 261 retval = -EBUSY; 310 - mutex_unlock(&zfcp_sysfs_port_units_mutex); 262 + put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */ 311 263 goto out; 312 264 } 313 - /* port is about to be removed, so no more unit_add */ 314 - atomic_set(&port->units, -1); 315 - mutex_unlock(&zfcp_sysfs_port_units_mutex); 316 265 317 266 write_lock_irq(&adapter->port_list_lock); 318 267 list_del(&port->list);
+7 -1
drivers/s390/scsi/zfcp_unit.c
··· 124 124 int retval = 0; 125 125 126 126 mutex_lock(&zfcp_sysfs_port_units_mutex); 127 - if (atomic_read(&port->units) == -1) { 127 + if (zfcp_sysfs_port_is_removing(port)) { 128 128 /* port is already gone */ 129 129 retval = -ENODEV; 130 130 goto out; ··· 168 168 write_lock_irq(&port->unit_list_lock); 169 169 list_add_tail(&unit->list, &port->unit_list); 170 170 write_unlock_irq(&port->unit_list_lock); 171 + /* 172 + * lock order: shost->scan_mutex before zfcp_sysfs_port_units_mutex 173 + * due to zfcp_unit_scsi_scan() => zfcp_scsi_slave_alloc() 174 + */ 175 + mutex_unlock(&zfcp_sysfs_port_units_mutex); 171 176 172 177 zfcp_unit_scsi_scan(unit); 178 + return retval; 173 179 174 180 out: 175 181 mutex_unlock(&zfcp_sysfs_port_units_mutex);
+4
drivers/scsi/cxgbi/libcxgbi.c
··· 639 639 640 640 if (ndev->flags & IFF_LOOPBACK) { 641 641 ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr); 642 + if (!ndev) { 643 + err = -ENETUNREACH; 644 + goto rel_neigh; 645 + } 642 646 mtu = ndev->mtu; 643 647 pr_info("rt dev %s, loopback -> %s, mtu %u.\n", 644 648 n->dev->name, ndev->name, mtu);
+2 -4
drivers/scsi/device_handler/scsi_dh_alua.c
··· 1160 1160 int r; 1161 1161 1162 1162 kaluad_wq = alloc_workqueue("kaluad", WQ_MEM_RECLAIM, 0); 1163 - if (!kaluad_wq) { 1164 - /* Temporary failure, bypass */ 1165 - return SCSI_DH_DEV_TEMP_BUSY; 1166 - } 1163 + if (!kaluad_wq) 1164 + return -ENOMEM; 1167 1165 1168 1166 r = scsi_register_device_handler(&alua_dh); 1169 1167 if (r != 0) {
+2
drivers/scsi/libsas/sas_expander.c
··· 1019 1019 list_del(&child->dev_list_node); 1020 1020 spin_unlock_irq(&parent->port->dev_list_lock); 1021 1021 sas_put_device(child); 1022 + sas_port_delete(phy->port); 1023 + phy->port = NULL; 1022 1024 return NULL; 1023 1025 } 1024 1026 list_add_tail(&child->siblings, &parent->ex_dev.children);
+1 -2
drivers/scsi/libsas/sas_phy.c
··· 35 35 struct asd_sas_event *ev = to_asd_sas_event(work); 36 36 struct asd_sas_phy *phy = ev->phy; 37 37 38 - phy->in_shutdown = 0; 39 38 phy->error = 0; 40 39 sas_deform_port(phy, 1); 41 40 } ··· 44 45 struct asd_sas_event *ev = to_asd_sas_event(work); 45 46 struct asd_sas_phy *phy = ev->phy; 46 47 47 - phy->in_shutdown = 0; 48 48 phy->error = 0; 49 49 } 50 50 ··· 124 126 ret); 125 127 } else 126 128 pr_notice("phy%d is not enabled, cannot shutdown\n", phy->id); 129 + phy->in_shutdown = 0; 127 130 } 128 131 129 132 /* ---------- Phy class registration ---------- */
+1 -1
drivers/scsi/smartpqi/smartpqi_init.c
··· 7291 7291 else 7292 7292 mask = DMA_BIT_MASK(32); 7293 7293 7294 - rc = dma_set_mask(&ctrl_info->pci_dev->dev, mask); 7294 + rc = dma_set_mask_and_coherent(&ctrl_info->pci_dev->dev, mask); 7295 7295 if (rc) { 7296 7296 dev_err(&ctrl_info->pci_dev->dev, "failed to set DMA mask\n"); 7297 7297 goto disable_device;