block-6.11-20240824
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAma/oVEQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgpg1AD/wJFx5MaHVNGtgtl6av6G8oJKTnFiaPGilY 1+oQGd0JwokWhXNzs9AqhSiusgvS3cYj5hU/cvecI4d90bZ0Rl/w1h01zPmivWYt ndB3PjHKcGD4JM+gdSDbWOSG00b7jymCW977A5Kw5DYR9CNzCJNs1vVed6FDKVr3 Hke0YsXu37a2jEb63ofqR+DesmZyBlucKGqQ8J5W+PYB1PR21KV7COsKwOvp8M3x asMq2QWLVibQ2BdrINqOzdHmQMYeaG51K7mjtZENErOxxDKEkeMdcuTM4SMjyQtQ mF3YsmxfhWtqakrMqoHc+W3k8kZ7qd/qqDPOlrDLRgoPs+uGVDr7kuyyTDQJZWPK sNlPI2RtRfsPfcTPuvZQbn2ev/UoiJbjGlKiqeabg0FllsnjGz+m3MsufVGA3a2v OoXgQQVvSKdJW9Z2Nq/TBFunsnB60q5QwRUXzl/ozttPanPsw7mKTxHuzXlFFGlj s5IL63GYxWE6xSh0TElF9cMxAiaRAmNuAeK9279ULPj69UNWlnJKw8wyVmBgmTXy kYn5AtHKsdj+kJFGinWQ9U0os5PZxgP2ikPOjFVigReOLY7noU4OWfcK/SgUtXMk wo0y4ROmm+/bKtOBnG+SnBkpwjOUI4kfVRXfOYQAl5IOxFIHUwFIhxGcNjTvSW4P KgY/8TQvog== =lbw7 -----END PGP SIGNATURE----- Merge tag 'block-6.11-20240824' of git://git.kernel.dk/linux Pull block fixes from Jens Axboe: - Fix corruption issues with s390/dasd (Eric, Stefan) - Fix a misuse of non irq locking grab of a lock (Li) - MD pull request with a single data corruption fix for raid1 (Yu) * tag 'block-6.11-20240824' of git://git.kernel.dk/linux: block: Fix lockdep warning in blk_mq_mark_tag_wait md/raid1: Fix data corruption for degraded array with slow disk s390/dasd: fix error recovery leading to data corruption on ESE devices s390/dasd: Remove DMA alignment
This commit is contained in:
commit
85652baa89
@ -38,6 +38,7 @@ static void blk_mq_update_wake_batch(struct blk_mq_tags *tags,
|
||||
void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
|
||||
{
|
||||
unsigned int users;
|
||||
unsigned long flags;
|
||||
struct blk_mq_tags *tags = hctx->tags;
|
||||
|
||||
/*
|
||||
@ -56,11 +57,11 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irq(&tags->lock);
|
||||
spin_lock_irqsave(&tags->lock, flags);
|
||||
users = tags->active_queues + 1;
|
||||
WRITE_ONCE(tags->active_queues, users);
|
||||
blk_mq_update_wake_batch(tags, users);
|
||||
spin_unlock_irq(&tags->lock);
|
||||
spin_unlock_irqrestore(&tags->lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -617,6 +617,12 @@ static int choose_first_rdev(struct r1conf *conf, struct r1bio *r1_bio,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool rdev_in_recovery(struct md_rdev *rdev, struct r1bio *r1_bio)
|
||||
{
|
||||
return !test_bit(In_sync, &rdev->flags) &&
|
||||
rdev->recovery_offset < r1_bio->sector + r1_bio->sectors;
|
||||
}
|
||||
|
||||
static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio,
|
||||
int *max_sectors)
|
||||
{
|
||||
@ -635,6 +641,7 @@ static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio,
|
||||
|
||||
rdev = conf->mirrors[disk].rdev;
|
||||
if (!rdev || test_bit(Faulty, &rdev->flags) ||
|
||||
rdev_in_recovery(rdev, r1_bio) ||
|
||||
test_bit(WriteMostly, &rdev->flags))
|
||||
continue;
|
||||
|
||||
@ -673,7 +680,8 @@ static int choose_slow_rdev(struct r1conf *conf, struct r1bio *r1_bio,
|
||||
|
||||
rdev = conf->mirrors[disk].rdev;
|
||||
if (!rdev || test_bit(Faulty, &rdev->flags) ||
|
||||
!test_bit(WriteMostly, &rdev->flags))
|
||||
!test_bit(WriteMostly, &rdev->flags) ||
|
||||
rdev_in_recovery(rdev, r1_bio))
|
||||
continue;
|
||||
|
||||
/* there are no bad blocks, we can use this disk */
|
||||
@ -733,9 +741,7 @@ static bool rdev_readable(struct md_rdev *rdev, struct r1bio *r1_bio)
|
||||
if (!rdev || test_bit(Faulty, &rdev->flags))
|
||||
return false;
|
||||
|
||||
/* still in recovery */
|
||||
if (!test_bit(In_sync, &rdev->flags) &&
|
||||
rdev->recovery_offset < r1_bio->sector + r1_bio->sectors)
|
||||
if (rdev_in_recovery(rdev, r1_bio))
|
||||
return false;
|
||||
|
||||
/* don't read from slow disk unless have to */
|
||||
|
@ -1601,9 +1601,15 @@ static int dasd_ese_needs_format(struct dasd_block *block, struct irb *irb)
|
||||
if (!sense)
|
||||
return 0;
|
||||
|
||||
return !!(sense[1] & SNS1_NO_REC_FOUND) ||
|
||||
!!(sense[1] & SNS1_FILE_PROTECTED) ||
|
||||
scsw_cstat(&irb->scsw) == SCHN_STAT_INCORR_LEN;
|
||||
if (sense[1] & SNS1_NO_REC_FOUND)
|
||||
return 1;
|
||||
|
||||
if ((sense[1] & SNS1_INV_TRACK_FORMAT) &&
|
||||
scsw_is_tm(&irb->scsw) &&
|
||||
!(sense[2] & SNS2_ENV_DATA_PRESENT))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dasd_ese_oos_cond(u8 *sense)
|
||||
@ -1624,7 +1630,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
struct dasd_device *device;
|
||||
unsigned long now;
|
||||
int nrf_suppressed = 0;
|
||||
int fp_suppressed = 0;
|
||||
int it_suppressed = 0;
|
||||
struct request *req;
|
||||
u8 *sense = NULL;
|
||||
int expires;
|
||||
@ -1679,8 +1685,9 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
*/
|
||||
sense = dasd_get_sense(irb);
|
||||
if (sense) {
|
||||
fp_suppressed = (sense[1] & SNS1_FILE_PROTECTED) &&
|
||||
test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
|
||||
it_suppressed = (sense[1] & SNS1_INV_TRACK_FORMAT) &&
|
||||
!(sense[2] & SNS2_ENV_DATA_PRESENT) &&
|
||||
test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
|
||||
nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) &&
|
||||
test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
|
||||
|
||||
@ -1695,7 +1702,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!(fp_suppressed || nrf_suppressed))
|
||||
if (!(it_suppressed || nrf_suppressed))
|
||||
device->discipline->dump_sense_dbf(device, irb, "int");
|
||||
|
||||
if (device->features & DASD_FEATURE_ERPLOG)
|
||||
@ -2459,14 +2466,17 @@ retry:
|
||||
rc = 0;
|
||||
list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) {
|
||||
/*
|
||||
* In some cases the 'File Protected' or 'Incorrect Length'
|
||||
* error might be expected and error recovery would be
|
||||
* unnecessary in these cases. Check if the according suppress
|
||||
* bit is set.
|
||||
* In some cases certain errors might be expected and
|
||||
* error recovery would be unnecessary in these cases.
|
||||
* Check if the according suppress bit is set.
|
||||
*/
|
||||
sense = dasd_get_sense(&cqr->irb);
|
||||
if (sense && sense[1] & SNS1_FILE_PROTECTED &&
|
||||
test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags))
|
||||
if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) &&
|
||||
!(sense[2] & SNS2_ENV_DATA_PRESENT) &&
|
||||
test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags))
|
||||
continue;
|
||||
if (sense && (sense[1] & SNS1_NO_REC_FOUND) &&
|
||||
test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags))
|
||||
continue;
|
||||
if (scsw_cstat(&cqr->irb.scsw) == 0x40 &&
|
||||
test_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags))
|
||||
|
@ -1386,14 +1386,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
|
||||
|
||||
struct dasd_device *device = erp->startdev;
|
||||
|
||||
/*
|
||||
* In some cases the 'File Protected' error might be expected and
|
||||
* log messages shouldn't be written then.
|
||||
* Check if the according suppress bit is set.
|
||||
*/
|
||||
if (!test_bit(DASD_CQR_SUPPRESS_FP, &erp->flags))
|
||||
dev_err(&device->cdev->dev,
|
||||
"Accessing the DASD failed because of a hardware error\n");
|
||||
dev_err(&device->cdev->dev,
|
||||
"Accessing the DASD failed because of a hardware error\n");
|
||||
|
||||
return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
|
||||
|
||||
|
@ -2275,6 +2275,7 @@ dasd_eckd_analysis_ccw(struct dasd_device *device)
|
||||
cqr->status = DASD_CQR_FILLED;
|
||||
/* Set flags to suppress output for expected errors */
|
||||
set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
|
||||
set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
|
||||
|
||||
return cqr;
|
||||
}
|
||||
@ -2556,7 +2557,6 @@ dasd_eckd_build_check_tcw(struct dasd_device *base, struct format_data_t *fdata,
|
||||
cqr->buildclk = get_tod_clock();
|
||||
cqr->status = DASD_CQR_FILLED;
|
||||
/* Set flags to suppress output for expected errors */
|
||||
set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
|
||||
set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
|
||||
|
||||
return cqr;
|
||||
@ -4130,8 +4130,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
|
||||
|
||||
/* Set flags to suppress output for expected errors */
|
||||
if (dasd_eckd_is_ese(basedev)) {
|
||||
set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
|
||||
set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
|
||||
set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
|
||||
}
|
||||
|
||||
@ -4633,9 +4631,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
|
||||
|
||||
/* Set flags to suppress output for expected errors */
|
||||
if (dasd_eckd_is_ese(basedev)) {
|
||||
set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
|
||||
set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
|
||||
set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
|
||||
set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
|
||||
}
|
||||
|
||||
return cqr;
|
||||
@ -5780,36 +5777,32 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
|
||||
{
|
||||
u8 *sense = dasd_get_sense(irb);
|
||||
|
||||
if (scsw_is_tm(&irb->scsw)) {
|
||||
/*
|
||||
* In some cases the 'File Protected' or 'Incorrect Length'
|
||||
* error might be expected and log messages shouldn't be written
|
||||
* then. Check if the according suppress bit is set.
|
||||
*/
|
||||
if (sense && (sense[1] & SNS1_FILE_PROTECTED) &&
|
||||
test_bit(DASD_CQR_SUPPRESS_FP, &req->flags))
|
||||
return;
|
||||
if (scsw_cstat(&irb->scsw) == 0x40 &&
|
||||
test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))
|
||||
return;
|
||||
/*
|
||||
* In some cases certain errors might be expected and
|
||||
* log messages shouldn't be written then.
|
||||
* Check if the according suppress bit is set.
|
||||
*/
|
||||
if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) &&
|
||||
!(sense[2] & SNS2_ENV_DATA_PRESENT) &&
|
||||
test_bit(DASD_CQR_SUPPRESS_IT, &req->flags))
|
||||
return;
|
||||
|
||||
if (sense && sense[0] & SNS0_CMD_REJECT &&
|
||||
test_bit(DASD_CQR_SUPPRESS_CR, &req->flags))
|
||||
return;
|
||||
|
||||
if (sense && sense[1] & SNS1_NO_REC_FOUND &&
|
||||
test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags))
|
||||
return;
|
||||
|
||||
if (scsw_cstat(&irb->scsw) == 0x40 &&
|
||||
test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))
|
||||
return;
|
||||
|
||||
if (scsw_is_tm(&irb->scsw))
|
||||
dasd_eckd_dump_sense_tcw(device, req, irb);
|
||||
} else {
|
||||
/*
|
||||
* In some cases the 'Command Reject' or 'No Record Found'
|
||||
* error might be expected and log messages shouldn't be
|
||||
* written then. Check if the according suppress bit is set.
|
||||
*/
|
||||
if (sense && sense[0] & SNS0_CMD_REJECT &&
|
||||
test_bit(DASD_CQR_SUPPRESS_CR, &req->flags))
|
||||
return;
|
||||
|
||||
if (sense && sense[1] & SNS1_NO_REC_FOUND &&
|
||||
test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags))
|
||||
return;
|
||||
|
||||
else
|
||||
dasd_eckd_dump_sense_ccw(device, req, irb);
|
||||
}
|
||||
}
|
||||
|
||||
static int dasd_eckd_reload_device(struct dasd_device *device)
|
||||
|
@ -41,7 +41,6 @@ int dasd_gendisk_alloc(struct dasd_block *block)
|
||||
*/
|
||||
.max_segment_size = PAGE_SIZE,
|
||||
.seg_boundary_mask = PAGE_SIZE - 1,
|
||||
.dma_alignment = PAGE_SIZE - 1,
|
||||
.max_segments = USHRT_MAX,
|
||||
};
|
||||
struct gendisk *gdp;
|
||||
|
@ -196,7 +196,7 @@ struct dasd_ccw_req {
|
||||
* The following flags are used to suppress output of certain errors.
|
||||
*/
|
||||
#define DASD_CQR_SUPPRESS_NRF 4 /* Suppress 'No Record Found' error */
|
||||
#define DASD_CQR_SUPPRESS_FP 5 /* Suppress 'File Protected' error*/
|
||||
#define DASD_CQR_SUPPRESS_IT 5 /* Suppress 'Invalid Track' error*/
|
||||
#define DASD_CQR_SUPPRESS_IL 6 /* Suppress 'Incorrect Length' error */
|
||||
#define DASD_CQR_SUPPRESS_CR 7 /* Suppress 'Command Reject' error */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user