Skip to content

Commit

Permalink
[S390] tape390: Fix request queue handling in block driver
Browse files Browse the repository at this point in the history
When setting a channel attached tape online under Linux 2.6.31, the

"vol_id" process from udev hangs in sync_page():
 2 sync_page+144 [0x1dfaac]
 3 __wait_on_bit_lock+194 [0x58c23e]
 4 __lock_page+116 [0x1df9dc]
 5 truncate_inode_pages_range+728 [0x1ed7cc]
 6 __blkdev_put+244 [0x25f738]
 7 __fput+300 [0x229c4c]
 8 filp_close+122 [0x225a3a]

The reason for that is an error in the request queue handling. It can
happen that we fetch a request, but do not process it further because
the number of queued requests exceeds TAPEBLOCK_MIN_REQUEUE.
To fix this, we should call blk_peek_request() instead of
blk_fetch_request() in the while condition and fetch the request in
the loop body afterwards.

This bug was introduced with the patch "block: implement and enforce
request peek/start/fetch" (9934c8c)

Signed-off-by: Michael Holzheu <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
  • Loading branch information
Michael Holzheu authored and Martin Schwidefsky committed Oct 14, 2009
1 parent 7874b1b commit 03cadd3
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion drivers/s390/char/tape_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,10 @@ tapeblock_requeue(struct work_struct *work) {
spin_lock_irq(&device->blk_data.request_queue_lock);
while (
!blk_queue_plugged(queue) &&
(req = blk_fetch_request(queue)) &&
blk_peek_request(queue) &&
nr_queued < TAPEBLOCK_MIN_REQUEUE
) {
req = blk_fetch_request(queue);
if (rq_data_dir(req) == WRITE) {
DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
spin_unlock_irq(&device->blk_data.request_queue_lock);
Expand Down

0 comments on commit 03cadd3

Please sign in to comment.