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 patch series "scsi: st: scsi_error: More reset patches"

Kai Mäkisara <Kai.Makisara@kolumbus.fi> says:

The first patch re-applies after device reset some settings changed
by the user (partition, density, block size).

The second and third patch address the case where more than one ULD
access the same device. The Unit Attention (UA) sense data is sent only
to one ULD and the others miss it. The st driver needs to find out
if device reset or media change has happened.

The second patch adds counters for New Media and Power On/Reset (POR)
Unit Attentions to the scsi_device struct. The third one changes st
so that these are used: if the value in the scsi_device struct does
not match the one stored locally, the corresponding UA has happened.
Use of the was_reset flag has been removed.

The fourth patch adds a file to sysfs to tell the user if reads/writes
to a tape are blocked following a device reset.

Link: https://lore.kernel.org/r/20250120194925.44432-1-Kai.Makisara@kolumbus.fi
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+97 -8
+5
Documentation/scsi/st.rst
··· 157 157 bit definitions are the same as those used with MTSETDRVBUFFER in setting the 158 158 options. 159 159 160 + Each directory contains the entry 'position_lost_in_reset'. If this value is 161 + one, reading and writing to the device is blocked after device reset. Most 162 + devices rewind the tape after reset and the writes/read don't access the 163 + tape position the user expects. 164 + 160 165 A link named 'tape' is made from the SCSI device directory to the class 161 166 directory corresponding to the mode 0 auto-rewind device (e.g., st0). 162 167
+12
drivers/scsi/scsi_error.c
··· 547 547 548 548 scsi_report_sense(sdev, &sshdr); 549 549 550 + if (sshdr.sense_key == UNIT_ATTENTION) { 551 + /* 552 + * Increment the counters for Power on/Reset or New Media so 553 + * that all ULDs interested in these can see that those have 554 + * happened, even if someone else gets the sense data. 555 + */ 556 + if (sshdr.asc == 0x28) 557 + scmd->device->ua_new_media_ctr++; 558 + else if (sshdr.asc == 0x29) 559 + scmd->device->ua_por_ctr++; 560 + } 561 + 550 562 if (scsi_sense_is_deferred(&sshdr)) 551 563 return NEEDS_RETRY; 552 564
+65 -8
drivers/scsi/st.c
··· 163 163 164 164 static int debugging = DEBUG; 165 165 166 + /* Setting these non-zero may risk recognizing resets */ 166 167 #define MAX_RETRIES 0 167 168 #define MAX_WRITE_RETRIES 0 168 169 #define MAX_READY_RETRIES 0 170 + 169 171 #define NO_TAPE NOT_READY 170 172 171 173 #define ST_TIMEOUT (900 * HZ) ··· 359 357 { 360 358 int result = SRpnt->result; 361 359 u8 scode; 360 + unsigned int ctr; 362 361 DEB(const char *stp;) 363 362 char *name = STp->name; 364 363 struct st_cmdstatus *cmdstatp; 364 + 365 + ctr = scsi_get_ua_por_ctr(STp->device); 366 + if (ctr != STp->por_ctr) { 367 + STp->por_ctr = ctr; 368 + STp->pos_unknown = 1; /* ASC => power on / reset */ 369 + st_printk(KERN_WARNING, STp, "Power on/reset recognized."); 370 + } 365 371 366 372 if (!result) 367 373 return 0; ··· 423 413 if (cmdstatp->have_sense && 424 414 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17) 425 415 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */ 426 - if (cmdstatp->have_sense && scode == UNIT_ATTENTION && cmdstatp->sense_hdr.asc == 0x29) 416 + if (cmdstatp->have_sense && scode == UNIT_ATTENTION && 417 + cmdstatp->sense_hdr.asc == 0x29 && !STp->pos_unknown) { 427 418 STp->pos_unknown = 1; /* ASC => power on / reset */ 428 - 429 - STp->pos_unknown |= STp->device->was_reset; 419 + st_printk(KERN_WARNING, STp, "Power on/reset recognized."); 420 + } 430 421 431 422 if (cmdstatp->have_sense && 432 423 scode == RECOVERED_ERROR ··· 963 952 STp->partition = find_partition(STp); 964 953 if (STp->partition < 0) 965 954 STp->partition = 0; 966 - STp->new_partition = STp->partition; 967 955 } 968 956 } 969 957 ··· 979 969 { 980 970 int attentions, waits, max_wait, scode; 981 971 int retval = CHKRES_READY, new_session = 0; 972 + unsigned int ctr; 982 973 unsigned char cmd[MAX_COMMAND_SIZE]; 983 974 struct st_request *SRpnt = NULL; 984 975 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; ··· 1034 1023 break; 1035 1024 } 1036 1025 } 1026 + } 1027 + 1028 + ctr = scsi_get_ua_new_media_ctr(STp->device); 1029 + if (ctr != STp->new_media_ctr) { 1030 + STp->new_media_ctr = ctr; 1031 + new_session = 1; 1032 + DEBC_printk(STp, "New tape session."); 1037 1033 } 1038 1034 1039 1035 retval = (STp->buffer)->syscall_result; ··· 2948 2930 if (cmd_in == MTSETDENSITY) { 2949 2931 (STp->buffer)->b_data[4] = arg; 2950 2932 STp->density_changed = 1; /* At least we tried ;-) */ 2933 + STp->changed_density = arg; 2951 2934 } else if (cmd_in == SET_DENS_AND_BLK) 2952 2935 (STp->buffer)->b_data[4] = arg >> 24; 2953 2936 else 2954 2937 (STp->buffer)->b_data[4] = STp->density; 2955 2938 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) { 2956 2939 ltmp = arg & MT_ST_BLKSIZE_MASK; 2957 - if (cmd_in == MTSETBLK) 2940 + if (cmd_in == MTSETBLK) { 2958 2941 STp->blksize_changed = 1; /* At least we tried ;-) */ 2942 + STp->changed_blksize = arg; 2943 + } 2959 2944 } else 2960 2945 ltmp = STp->block_size; 2961 2946 (STp->buffer)->b_data[9] = (ltmp >> 16); ··· 3657 3636 retval = (-EIO); 3658 3637 goto out; 3659 3638 } 3660 - reset_state(STp); 3661 - /* remove this when the midlevel properly clears was_reset */ 3662 - STp->device->was_reset = 0; 3639 + reset_state(STp); /* Clears pos_unknown */ 3640 + 3641 + /* Fix the device settings after reset, ignore errors */ 3642 + if (mtc.mt_op == MTREW || mtc.mt_op == MTSEEK || 3643 + mtc.mt_op == MTEOM) { 3644 + if (STp->can_partitions) { 3645 + /* STp->new_partition contains the 3646 + * latest partition set 3647 + */ 3648 + STp->partition = 0; 3649 + switch_partition(STp); 3650 + } 3651 + if (STp->density_changed) 3652 + st_int_ioctl(STp, MTSETDENSITY, STp->changed_density); 3653 + if (STp->blksize_changed) 3654 + st_int_ioctl(STp, MTSETBLK, STp->changed_blksize); 3655 + } 3663 3656 } 3664 3657 3665 3658 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && ··· 4419 4384 goto out_idr_remove; 4420 4385 } 4421 4386 4387 + tpnt->new_media_ctr = scsi_get_ua_new_media_ctr(SDp); 4388 + tpnt->por_ctr = scsi_get_ua_por_ctr(SDp); 4389 + 4422 4390 dev_set_drvdata(dev, tpnt); 4423 4391 4424 4392 ··· 4703 4665 } 4704 4666 static DEVICE_ATTR_RO(options); 4705 4667 4668 + /** 4669 + * position_lost_in_reset_show - Value 1 indicates that reads, writes, etc. 4670 + * are blocked because a device reset has occurred and no operation positioning 4671 + * the tape has been issued. 4672 + * @dev: struct device 4673 + * @attr: attribute structure 4674 + * @buf: buffer to return formatted data in 4675 + */ 4676 + static ssize_t position_lost_in_reset_show(struct device *dev, 4677 + struct device_attribute *attr, char *buf) 4678 + { 4679 + struct st_modedef *STm = dev_get_drvdata(dev); 4680 + struct scsi_tape *STp = STm->tape; 4681 + 4682 + return sprintf(buf, "%d", STp->pos_unknown); 4683 + } 4684 + static DEVICE_ATTR_RO(position_lost_in_reset); 4685 + 4706 4686 /* Support for tape stats */ 4707 4687 4708 4688 /** ··· 4905 4849 &dev_attr_default_density.attr, 4906 4850 &dev_attr_default_compression.attr, 4907 4851 &dev_attr_options.attr, 4852 + &dev_attr_position_lost_in_reset.attr, 4908 4853 NULL, 4909 4854 }; 4910 4855
+6
drivers/scsi/st.h
··· 165 165 unsigned char compression_changed; 166 166 unsigned char drv_buffer; 167 167 unsigned char density; 168 + unsigned char changed_density; 168 169 unsigned char door_locked; 169 170 unsigned char autorew_dev; /* auto-rewind device */ 170 171 unsigned char rew_at_close; /* rewind necessary at close */ ··· 173 172 unsigned char cleaning_req; /* cleaning requested? */ 174 173 unsigned char first_tur; /* first TEST UNIT READY */ 175 174 int block_size; 175 + int changed_blksize; 176 176 int min_block; 177 177 int max_block; 178 178 int recover_count; /* From tape opening */ 179 179 int recover_reg; /* From last status call */ 180 + 181 + /* The saved values of midlevel counters */ 182 + unsigned int new_media_ctr; 183 + unsigned int por_ctr; 180 184 181 185 #if DEBUG 182 186 unsigned char write_pending;
+9
include/scsi/scsi_device.h
··· 247 247 unsigned int queue_stopped; /* request queue is quiesced */ 248 248 bool offline_already; /* Device offline message logged */ 249 249 250 + unsigned int ua_new_media_ctr; /* Counter for New Media UNIT ATTENTIONs */ 251 + unsigned int ua_por_ctr; /* Counter for Power On / Reset UAs */ 252 + 250 253 atomic_t disk_events_disable_depth; /* disable depth for disk events */ 251 254 252 255 DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ ··· 686 683 { 687 684 return sbitmap_weight(&sdev->budget_map); 688 685 } 686 + 687 + /* Macros to access the UNIT ATTENTION counters */ 688 + #define scsi_get_ua_new_media_ctr(sdev) \ 689 + ((const unsigned int)(sdev->ua_new_media_ctr)) 690 + #define scsi_get_ua_por_ctr(sdev) \ 691 + ((const unsigned int)(sdev->ua_por_ctr)) 689 692 690 693 #define MODULE_ALIAS_SCSI_DEVICE(type) \ 691 694 MODULE_ALIAS("scsi:t-" __stringify(type) "*")