Commit cec8546638dc634824b629e33968d6c68f8b07d6
Committed by
Martin Schwidefsky
1 parent
aa92b33c6b
Exists in
master
and in
20 other branches
s390/css: stop stsch loop after cc 3
Receiving cc=3 from store subchannel means 2 things: * the subchannel is not provided * there are no further subchannels in this subchannel set With this patch we abort the store subchannel loop after cc=3 (or an exception) and clear the subsequent bits in the subchannel id set. Reported-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Acked-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Showing 3 changed files with 16 additions and 2 deletions Side-by-side Diff
drivers/s390/cio/css.c
... | ... | @@ -377,7 +377,11 @@ |
377 | 377 | /* Will be done on the slow path. */ |
378 | 378 | return -EAGAIN; |
379 | 379 | } |
380 | - if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) { | |
380 | + if (stsch_err(schid, &schib)) { | |
381 | + /* Subchannel is not provided. */ | |
382 | + return -ENXIO; | |
383 | + } | |
384 | + if (!css_sch_is_valid(&schib)) { | |
381 | 385 | /* Unusable - ignore. */ |
382 | 386 | return 0; |
383 | 387 | } |
... | ... | @@ -536,6 +540,7 @@ |
536 | 540 | case -ENOMEM: |
537 | 541 | case -EIO: |
538 | 542 | /* These should abort looping */ |
543 | + idset_sch_del_subseq(slow_subchannel_set, schid); | |
539 | 544 | break; |
540 | 545 | default: |
541 | 546 | rc = 0; |
drivers/s390/cio/idset.c
... | ... | @@ -90,6 +90,14 @@ |
90 | 90 | idset_del(set, schid.ssid, schid.sch_no); |
91 | 91 | } |
92 | 92 | |
93 | +/* Clear ids starting from @schid up to end of subchannel set. */ | |
94 | +void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid) | |
95 | +{ | |
96 | + int pos = schid.ssid * set->num_id + schid.sch_no; | |
97 | + | |
98 | + bitmap_clear(set->bitmap, pos, set->num_id - schid.sch_no); | |
99 | +} | |
100 | + | |
93 | 101 | int idset_sch_contains(struct idset *set, struct subchannel_id schid) |
94 | 102 | { |
95 | 103 | return idset_contains(set, schid.ssid, schid.sch_no); |
drivers/s390/cio/idset.h
1 | 1 | /* |
2 | - * Copyright IBM Corp. 2007 | |
2 | + * Copyright IBM Corp. 2007, 2012 | |
3 | 3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
4 | 4 | */ |
5 | 5 | |
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | struct idset *idset_sch_new(void); |
18 | 18 | void idset_sch_add(struct idset *set, struct subchannel_id id); |
19 | 19 | void idset_sch_del(struct idset *set, struct subchannel_id id); |
20 | +void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); | |
20 | 21 | int idset_sch_contains(struct idset *set, struct subchannel_id id); |
21 | 22 | int idset_sch_get_first(struct idset *set, struct subchannel_id *id); |
22 | 23 | int idset_is_empty(struct idset *set); |