Skip to content

Commit 7ab78e3

Browse files
yocalebobugclerk
authored andcommitted
fix stale sysfs symlinks
(cherry picked from commit e51d428) (cherry picked from commit dcbc7bf)
1 parent 987c44a commit 7ab78e3

1 file changed

Lines changed: 34 additions & 2 deletions

File tree

drivers/scsi/ses.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,27 @@ static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
591591

592592
#define INIT_ALLOC_SIZE 32
593593

594+
/*
595+
* After a fresh SES read updates every component's scomp->addr, any slot
596+
* whose address went back to zero is now empty. Drop the stale binding so
597+
* sysfs (/sys/class/enclosure/.../<slot>/device/...) reflects reality. The
598+
* add path in ses_enclosure_find_by_addr is the only place bindings are
599+
* created during polling; without this symmetric teardown a hot relocation
600+
* leaves the source slot permanently pointing at the moved disk.
601+
*/
602+
static void ses_remove_stale_components(struct enclosure_device *edev)
603+
{
604+
int i;
605+
606+
for (i = 0; i < edev->components; i++) {
607+
struct enclosure_component *ecomp = &edev->component[i];
608+
struct ses_component *scomp = ecomp->scratch;
609+
610+
if (ecomp->dev && scomp->addr == 0)
611+
enclosure_remove_device(edev, ecomp->dev);
612+
}
613+
}
614+
594615
static void ses_enclosure_data_process(struct enclosure_device *edev,
595616
struct scsi_device *sdev,
596617
int create)
@@ -601,13 +622,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
601622
struct ses_device *ses_dev = edev->scratch;
602623
int types = ses_dev->page1_num_types;
603624
unsigned char *hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
625+
bool addr_refreshed = false;
604626

605627
if (!hdr_buf)
606628
goto simple_populate;
607629

608630
/* re-read page 10 */
609-
if (ses_dev->page10)
610-
ses_recv_diag(sdev, 10, ses_dev->page10, ses_dev->page10_len);
631+
if (ses_dev->page10 &&
632+
!ses_recv_diag(sdev, 10, ses_dev->page10, ses_dev->page10_len))
633+
addr_refreshed = true;
611634
/* Page 7 for the descriptors is optional */
612635
result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE);
613636
if (result)
@@ -710,6 +733,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
710733
spin_unlock(&edev->enc_lock);
711734
kfree(buf);
712735
kfree(hdr_buf);
736+
737+
/*
738+
* Only prune bindings when we actually got a fresh page 10 read on
739+
* a refresh call. Skip it on create (no bindings exist yet) and when
740+
* SES was unreachable (scomp->addr values would be stale and could
741+
* cause us to unbind a slot that is still occupied).
742+
*/
743+
if (!create && addr_refreshed)
744+
ses_remove_stale_components(edev);
713745
}
714746

715747
static int ses_get_enclosure_pci_domain(struct enclosure_device *edev)

0 commit comments

Comments
 (0)