Skip to content

Commit 5ea34a0

Browse files
hreineckeMartin Schwidefsky
authored and
Martin Schwidefsky
committed
s390/dasd: Fail all requests when DASD_FLAG_ABORTIO is set
Whenever a DASD request encounters a timeout we might need to abort all outstanding requests on this or even other devices. This is especially useful if one wants to fail all devices on one side of a RAID10 configuration, even though only one device exhibited an error. To handle this I've introduced a new device flag DASD_FLAG_ABORTIO. This flag is evaluated in __dasd_process_request_queue() and will invoke blk_abort_request() for all outstanding requests with DASD_CQR_FLAGS_FAILFAST set. This will cause any of these requests to be aborted immediately if the blk_timeout function is activated. The DASD_FLAG_ABORTIO is also evaluated in __dasd_process_request_queue to abort all new request which would have the DASD_CQR_FLAGS_FAILFAST bit set. The flag can be set with the new ioctls 'BIODASDABORTIO' and removed with 'BIODASDALLOWIO'. Signed-off-by: Hannes Reinecke <[email protected]> Signed-off-by: Stefan Weinhuber <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 3d71ad3 commit 5ea34a0

File tree

4 files changed

+76
-3
lines changed

4 files changed

+76
-3
lines changed

arch/s390/include/uapi/asm/dasd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ struct dasd_snid_ioctl_data {
261261
#define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6)
262262
/* Resume IO on device */
263263
#define BIODASDRESUME _IO(DASD_IOCTL_LETTER,7)
264+
/* Abort all I/O on a device */
265+
#define BIODASDABORTIO _IO(DASD_IOCTL_LETTER, 240)
266+
/* Allow I/O on a device */
267+
#define BIODASDALLOWIO _IO(DASD_IOCTL_LETTER, 241)
264268

265269

266270
/* retrieve API version number */

drivers/s390/block/dasd.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@
3838
*/
3939
#define DASD_CHANQ_MAX_SIZE 4
4040

41-
#define DASD_SLEEPON_START_TAG (void *) 1
42-
#define DASD_SLEEPON_END_TAG (void *) 2
43-
4441
/*
4542
* SECTION: exported variables of dasd.c
4643
*/
@@ -2535,6 +2532,16 @@ static void __dasd_process_request_queue(struct dasd_block *block)
25352532
__blk_end_request_all(req, -EIO);
25362533
continue;
25372534
}
2535+
if (test_bit(DASD_FLAG_ABORTALL, &basedev->flags) &&
2536+
(basedev->features & DASD_FEATURE_FAILFAST ||
2537+
blk_noretry_request(req))) {
2538+
DBF_DEV_EVENT(DBF_ERR, basedev,
2539+
"Rejecting failfast request %p",
2540+
req);
2541+
blk_start_request(req);
2542+
__blk_end_request_all(req, -ETIMEDOUT);
2543+
continue;
2544+
}
25382545
cqr = basedev->discipline->build_cp(basedev, block, req);
25392546
if (IS_ERR(cqr)) {
25402547
if (PTR_ERR(cqr) == -EBUSY)

drivers/s390/block/dasd_int.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,10 @@ struct dasd_block {
524524
#define DASD_FLAG_SUSPENDED 9 /* The device was suspended */
525525
#define DASD_FLAG_SAFE_OFFLINE 10 /* safe offline processing requested*/
526526
#define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */
527+
#define DASD_FLAG_ABORTALL 12 /* Abort all noretry requests */
527528

529+
#define DASD_SLEEPON_START_TAG ((void *) 1)
530+
#define DASD_SLEEPON_END_TAG ((void *) 2)
528531

529532
void dasd_put_device_wake(struct dasd_device *);
530533

drivers/s390/block/dasd_ioctl.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,59 @@ static int dasd_ioctl_resume(struct dasd_block *block)
140140
return 0;
141141
}
142142

143+
/*
144+
* Abort all failfast I/O on a device.
145+
*/
146+
static int dasd_ioctl_abortio(struct dasd_block *block)
147+
{
148+
unsigned long flags;
149+
struct dasd_device *base;
150+
struct dasd_ccw_req *cqr, *n;
151+
152+
base = block->base;
153+
if (!capable(CAP_SYS_ADMIN))
154+
return -EACCES;
155+
156+
if (test_and_set_bit(DASD_FLAG_ABORTALL, &base->flags))
157+
return 0;
158+
DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag set");
159+
160+
spin_lock_irqsave(&block->request_queue_lock, flags);
161+
spin_lock(&block->queue_lock);
162+
list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) {
163+
if (test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
164+
cqr->callback_data &&
165+
cqr->callback_data != DASD_SLEEPON_START_TAG &&
166+
cqr->callback_data != DASD_SLEEPON_END_TAG) {
167+
spin_unlock(&block->queue_lock);
168+
blk_abort_request(cqr->callback_data);
169+
spin_lock(&block->queue_lock);
170+
}
171+
}
172+
spin_unlock(&block->queue_lock);
173+
spin_unlock_irqrestore(&block->request_queue_lock, flags);
174+
175+
dasd_schedule_block_bh(block);
176+
return 0;
177+
}
178+
179+
/*
180+
* Allow I/O on a device
181+
*/
182+
static int dasd_ioctl_allowio(struct dasd_block *block)
183+
{
184+
struct dasd_device *base;
185+
186+
base = block->base;
187+
if (!capable(CAP_SYS_ADMIN))
188+
return -EACCES;
189+
190+
if (test_and_clear_bit(DASD_FLAG_ABORTALL, &base->flags))
191+
DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag unset");
192+
193+
return 0;
194+
}
195+
143196
/*
144197
* performs formatting of _device_ according to _fdata_
145198
* Note: The discipline's format_function is assumed to deliver formatting
@@ -458,6 +511,12 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode,
458511
case BIODASDRESUME:
459512
rc = dasd_ioctl_resume(block);
460513
break;
514+
case BIODASDABORTIO:
515+
rc = dasd_ioctl_abortio(block);
516+
break;
517+
case BIODASDALLOWIO:
518+
rc = dasd_ioctl_allowio(block);
519+
break;
461520
case BIODASDFMT:
462521
rc = dasd_ioctl_format(bdev, argp);
463522
break;

0 commit comments

Comments
 (0)