* Re: [PATCH Linux 2.6.12-rc5-mm1 01/06] blk: add @uptodate to end_that_request_last() and @error to rq_end_io_fn()
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
@ 2005-05-29 4:23 ` Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 02/06] blk: make scsi use -EOPNOTSUPP instead of -EIO on ILLEGAL_REQUEST Tejun Heo
` (6 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2005-05-29 4:23 UTC (permalink / raw)
To: axboe, James.Bottomley, bzolnier, jgarzik; +Cc: linux-kernel
01_blk_add_uptodate_to_end_that_request_last.patch
Add @uptodate argument to end_that_request_last() and @error
to rq_end_io_fn(). There's no generic way to pass error code
to request completion function, making generic error handling
of non-fs request difficult (rq->errors is driver-specific and
each driver uses it differently). This patch adds @uptodate
to end_that_request_last() and @error to rq_end_io_fn().
For fs requests, this doesn't really matter, so just using the
same uptodate argument used in the last call to
end_that_request_first() should suffice. IMHO, this can also
help the generic command-carrying request Jens is working on.
One thing that bothers me is this change can be user-visible
in that additional error codes may be seen by some ioctls.
eg. -EOPNOTSUPP instead of -EIO can be seen with the following
two patches on direct-command ioctls.
Signed-off-by: Tejun Heo <htejun@gmail.com>
drivers/block/DAC960.c | 2 +-
drivers/block/cciss.c | 2 +-
drivers/block/cpqarray.c | 2 +-
drivers/block/elevator.c | 2 +-
drivers/block/floppy.c | 2 +-
drivers/block/ll_rw_blk.c | 20 ++++++++++++++------
drivers/block/nbd.c | 2 +-
drivers/block/sx8.c | 2 +-
drivers/block/ub.c | 2 +-
drivers/block/viodasd.c | 2 +-
drivers/cdrom/cdu31a.c | 2 +-
drivers/ide/ide-cd.c | 4 ++--
drivers/ide/ide-io.c | 6 +++---
drivers/message/i2o/i2o_block.c | 2 +-
drivers/mmc/mmc_block.c | 4 ++--
drivers/s390/block/dasd.c | 2 +-
drivers/s390/char/tape_block.c | 2 +-
drivers/scsi/ide-scsi.c | 4 ++--
drivers/scsi/scsi_lib.c | 8 ++++----
drivers/scsi/sd.c | 2 +-
include/linux/blkdev.h | 6 +++---
21 files changed, 44 insertions(+), 36 deletions(-)
Index: blk-fixes/drivers/block/DAC960.c
===================================================================
--- blk-fixes.orig/drivers/block/DAC960.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/DAC960.c 2005-05-29 13:20:30.000000000 +0900
@@ -3480,7 +3480,7 @@ static inline boolean DAC960_ProcessComp
if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) {
- end_that_request_last(Request);
+ end_that_request_last(Request, UpToDate);
if (Command->Completion) {
complete(Command->Completion);
Index: blk-fixes/drivers/block/cciss.c
===================================================================
--- blk-fixes.orig/drivers/block/cciss.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/cciss.c 2005-05-29 13:20:30.000000000 +0900
@@ -2072,7 +2072,7 @@ static inline void complete_command( ctl
printk("Done with %p\n", cmd->rq);
#endif /* CCISS_DEBUG */
- end_that_request_last(cmd->rq);
+ end_that_request_last(cmd->rq, status ? 1 : -EIO);
cmd_free(h,cmd,1);
}
Index: blk-fixes/drivers/block/cpqarray.c
===================================================================
--- blk-fixes.orig/drivers/block/cpqarray.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/cpqarray.c 2005-05-29 13:20:30.000000000 +0900
@@ -1036,7 +1036,7 @@ static inline void complete_command(cmdl
complete_buffers(cmd->rq->bio, ok);
DBGPX(printk("Done with %p\n", cmd->rq););
- end_that_request_last(cmd->rq);
+ end_that_request_last(cmd->rq, ok ? 1 : -EIO);
}
/*
Index: blk-fixes/drivers/block/elevator.c
===================================================================
--- blk-fixes.orig/drivers/block/elevator.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/elevator.c 2005-05-29 13:20:30.000000000 +0900
@@ -410,7 +410,7 @@ struct request *elv_next_request(request
blkdev_dequeue_request(rq);
rq->flags |= REQ_QUIET;
end_that_request_chunk(rq, 0, nr_bytes);
- end_that_request_last(rq);
+ end_that_request_last(rq, 0);
} else {
printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__,
ret);
Index: blk-fixes/drivers/block/floppy.c
===================================================================
--- blk-fixes.orig/drivers/block/floppy.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/floppy.c 2005-05-29 13:20:30.000000000 +0900
@@ -2299,7 +2299,7 @@ static void floppy_end_request(struct re
add_disk_randomness(req->rq_disk);
floppy_off((long)req->rq_disk->private_data);
blkdev_dequeue_request(req);
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
/* We're done with the request */
current_req = NULL;
Index: blk-fixes/drivers/block/ll_rw_blk.c
===================================================================
--- blk-fixes.orig/drivers/block/ll_rw_blk.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/ll_rw_blk.c 2005-05-29 13:20:30.000000000 +0900
@@ -347,7 +347,7 @@ EXPORT_SYMBOL(blk_queue_issue_flush_fn);
/*
* Cache flushing for ordered writes handling
*/
-static void blk_pre_flush_end_io(struct request *flush_rq)
+static void blk_pre_flush_end_io(struct request *flush_rq, int error)
{
struct request *rq = flush_rq->end_io_data;
request_queue_t *q = rq->q;
@@ -363,7 +363,7 @@ static void blk_pre_flush_end_io(struct
}
}
-static void blk_post_flush_end_io(struct request *flush_rq)
+static void blk_post_flush_end_io(struct request *flush_rq, int error)
{
struct request *rq = flush_rq->end_io_data;
request_queue_t *q = rq->q;
@@ -2386,7 +2386,7 @@ EXPORT_SYMBOL(blk_put_request);
* blk_end_sync_rq - executes a completion event on a request
* @rq: request to complete
*/
-void blk_end_sync_rq(struct request *rq)
+void blk_end_sync_rq(struct request *rq, int error)
{
struct completion *waiting = rq->waiting;
@@ -3141,9 +3141,17 @@ EXPORT_SYMBOL(end_that_request_chunk);
/*
* queue lock must be held
*/
-void end_that_request_last(struct request *req)
+void end_that_request_last(struct request *req, int uptodate)
{
struct gendisk *disk = req->rq_disk;
+ int error;
+
+ /*
+ * extend uptodate bool to allow < 0 value to be direct io error
+ */
+ error = 0;
+ if (end_io_error(uptodate))
+ error = !uptodate ? -EIO : uptodate;
if (unlikely(laptop_mode) && blk_fs_request(req))
laptop_io_completion();
@@ -3164,7 +3172,7 @@ void end_that_request_last(struct reques
disk->in_flight--;
}
if (req->end_io)
- req->end_io(req);
+ req->end_io(req, error);
else
__blk_put_request(req->q, req);
}
@@ -3176,7 +3184,7 @@ void end_request(struct request *req, in
if (!end_that_request_first(req, uptodate, req->hard_cur_sectors)) {
add_disk_randomness(req->rq_disk);
blkdev_dequeue_request(req);
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
}
}
Index: blk-fixes/drivers/block/nbd.c
===================================================================
--- blk-fixes.orig/drivers/block/nbd.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/nbd.c 2005-05-29 13:20:30.000000000 +0900
@@ -136,7 +136,7 @@ static void nbd_end_request(struct reque
spin_lock_irqsave(q->queue_lock, flags);
if (!end_that_request_first(req, uptodate, req->nr_sectors)) {
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
}
spin_unlock_irqrestore(q->queue_lock, flags);
}
Index: blk-fixes/drivers/block/sx8.c
===================================================================
--- blk-fixes.orig/drivers/block/sx8.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/sx8.c 2005-05-29 13:20:30.000000000 +0900
@@ -745,7 +745,7 @@ static inline void carm_end_request_queu
rc = end_that_request_first(req, uptodate, req->hard_nr_sectors);
assert(rc == 0);
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
rc = carm_put_request(host, crq);
assert(rc == 0);
Index: blk-fixes/drivers/block/ub.c
===================================================================
--- blk-fixes.orig/drivers/block/ub.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/ub.c 2005-05-29 13:20:30.000000000 +0900
@@ -875,7 +875,7 @@ static void ub_end_rq(struct request *rq
rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
// assert(rc == 0);
- end_that_request_last(rq);
+ end_that_request_last(rq, uptodate);
}
/*
Index: blk-fixes/drivers/block/viodasd.c
===================================================================
--- blk-fixes.orig/drivers/block/viodasd.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/block/viodasd.c 2005-05-29 13:20:30.000000000 +0900
@@ -305,7 +305,7 @@ static void viodasd_end_request(struct r
if (end_that_request_first(req, uptodate, num_sectors))
return;
add_disk_randomness(req->rq_disk);
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
}
/*
Index: blk-fixes/drivers/cdrom/cdu31a.c
===================================================================
--- blk-fixes.orig/drivers/cdrom/cdu31a.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/cdrom/cdu31a.c 2005-05-29 13:20:30.000000000 +0900
@@ -1402,7 +1402,7 @@ static void do_cdu31a_request(request_qu
if (!end_that_request_first(req, 1, nblock)) {
spin_lock_irq(q->queue_lock);
blkdev_dequeue_request(req);
- end_that_request_last(req);
+ end_that_request_last(req, 1);
spin_unlock_irq(q->queue_lock);
}
continue;
Index: blk-fixes/drivers/ide/ide-cd.c
===================================================================
--- blk-fixes.orig/drivers/ide/ide-cd.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/ide/ide-cd.c 2005-05-29 13:20:30.000000000 +0900
@@ -614,7 +614,7 @@ static void cdrom_end_request (ide_drive
*/
spin_lock_irqsave(&ide_lock, flags);
end_that_request_chunk(failed, 0, failed->data_len);
- end_that_request_last(failed);
+ end_that_request_last(failed, 0);
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -1739,7 +1739,7 @@ end_request:
spin_lock_irqsave(&ide_lock, flags);
blkdev_dequeue_request(rq);
- end_that_request_last(rq);
+ end_that_request_last(rq, 1);
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
Index: blk-fixes/drivers/ide/ide-io.c
===================================================================
--- blk-fixes.orig/drivers/ide/ide-io.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/ide/ide-io.c 2005-05-29 13:20:30.000000000 +0900
@@ -89,7 +89,7 @@ int __ide_end_request(ide_drive_t *drive
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq);
+ end_that_request_last(rq, uptodate);
ret = 0;
}
return ret;
@@ -247,7 +247,7 @@ static void ide_complete_pm_request (ide
}
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq);
+ end_that_request_last(rq, 1);
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -379,7 +379,7 @@ void ide_end_drive_cmd (ide_drive_t *dri
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
rq->errors = err;
- end_that_request_last(rq);
+ end_that_request_last(rq, !rq->errors);
spin_unlock_irqrestore(&ide_lock, flags);
}
Index: blk-fixes/drivers/message/i2o/i2o_block.c
===================================================================
--- blk-fixes.orig/drivers/message/i2o/i2o_block.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/message/i2o/i2o_block.c 2005-05-29 13:20:30.000000000 +0900
@@ -466,7 +466,7 @@ static void i2o_block_end_request(struct
spin_lock_irqsave(q->queue_lock, flags);
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
if (likely(dev)) {
dev->open_queue_depth--;
Index: blk-fixes/drivers/mmc/mmc_block.c
===================================================================
--- blk-fixes.orig/drivers/mmc/mmc_block.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/mmc/mmc_block.c 2005-05-29 13:20:30.000000000 +0900
@@ -254,7 +254,7 @@ static int mmc_blk_issue_rq(struct mmc_q
*/
add_disk_randomness(req->rq_disk);
blkdev_dequeue_request(req);
- end_that_request_last(req);
+ end_that_request_last(req, 1);
}
spin_unlock_irq(&md->lock);
} while (ret);
@@ -280,7 +280,7 @@ static int mmc_blk_issue_rq(struct mmc_q
add_disk_randomness(req->rq_disk);
blkdev_dequeue_request(req);
- end_that_request_last(req);
+ end_that_request_last(req, 0);
spin_unlock_irq(&md->lock);
return 0;
Index: blk-fixes/drivers/s390/block/dasd.c
===================================================================
--- blk-fixes.orig/drivers/s390/block/dasd.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/s390/block/dasd.c 2005-05-29 13:20:30.000000000 +0900
@@ -1039,7 +1039,7 @@ dasd_end_request(struct request *req, in
if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
BUG();
add_disk_randomness(req->rq_disk);
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
}
/*
Index: blk-fixes/drivers/s390/char/tape_block.c
===================================================================
--- blk-fixes.orig/drivers/s390/char/tape_block.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/s390/char/tape_block.c 2005-05-29 13:20:30.000000000 +0900
@@ -78,7 +78,7 @@ tapeblock_end_request(struct request *re
{
if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
BUG();
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
}
static void
Index: blk-fixes/drivers/scsi/ide-scsi.c
===================================================================
--- blk-fixes.orig/drivers/scsi/ide-scsi.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/ide-scsi.c 2005-05-29 13:20:30.000000000 +0900
@@ -1016,7 +1016,7 @@ static int idescsi_eh_reset (struct scsi
/* kill current request */
blkdev_dequeue_request(req);
- end_that_request_last(req);
+ end_that_request_last(req, 0);
if (req->flags & REQ_SENSE)
kfree(scsi->pc->buffer);
kfree(scsi->pc);
@@ -1026,7 +1026,7 @@ static int idescsi_eh_reset (struct scsi
/* now nuke the drive queue */
while ((req = elv_next_request(drive->queue))) {
blkdev_dequeue_request(req);
- end_that_request_last(req);
+ end_that_request_last(req, 0);
}
HWGROUP(drive)->rq = NULL;
Index: blk-fixes/drivers/scsi/scsi_lib.c
===================================================================
--- blk-fixes.orig/drivers/scsi/scsi_lib.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/scsi_lib.c 2005-05-29 13:20:30.000000000 +0900
@@ -258,7 +258,7 @@ static void scsi_wait_done(struct scsi_c
/* This is the end routine we get to if a command was never attached
* to the request. Simply complete the request without changing
* rq_status; this will cause a DRIVER_ERROR. */
-static void scsi_wait_req_end_io(struct request *req)
+static void scsi_wait_req_end_io(struct request *req, int error)
{
BUG_ON(!req->waiting);
@@ -574,7 +574,7 @@ static struct scsi_cmnd *scsi_end_reques
spin_lock_irqsave(q->queue_lock, flags);
if (blk_rq_tagged(req))
blk_queue_end_tag(q, req);
- end_that_request_last(req);
+ end_that_request_last(req, uptodate);
spin_unlock_irqrestore(q->queue_lock, flags);
/*
@@ -1259,7 +1259,7 @@ static void scsi_kill_requests(request_q
req->flags |= REQ_QUIET;
while (end_that_request_first(req, 0, req->nr_sectors))
;
- end_that_request_last(req);
+ end_that_request_last(req, 0);
}
}
@@ -1314,7 +1314,7 @@ static void scsi_request_fn(struct reque
req->flags |= REQ_QUIET;
while (end_that_request_first(req, 0, req->nr_sectors))
;
- end_that_request_last(req);
+ end_that_request_last(req, 0);
continue;
}
Index: blk-fixes/drivers/scsi/sd.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sd.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sd.c 2005-05-29 13:20:30.000000000 +0900
@@ -758,7 +758,7 @@ static void sd_end_flush(request_queue_t
* force journal abort of barriers
*/
end_that_request_first(rq, -EOPNOTSUPP, rq->hard_nr_sectors);
- end_that_request_last(rq);
+ end_that_request_last(rq, -EOPNOTSUPP);
}
}
Index: blk-fixes/include/linux/blkdev.h
===================================================================
--- blk-fixes.orig/include/linux/blkdev.h 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/include/linux/blkdev.h 2005-05-29 13:20:30.000000000 +0900
@@ -102,7 +102,7 @@ void copy_io_context(struct io_context *
void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
struct request;
-typedef void (rq_end_io_fn)(struct request *);
+typedef void (rq_end_io_fn)(struct request *, int);
struct request_list {
int count[2];
@@ -547,7 +547,7 @@ extern void blk_unregister_queue(struct
extern void register_disk(struct gendisk *dev);
extern void generic_make_request(struct bio *bio);
extern void blk_put_request(struct request *);
-extern void blk_end_sync_rq(struct request *rq);
+extern void blk_end_sync_rq(struct request *rq, int error);
extern void blk_attempt_remerge(request_queue_t *, struct request *);
extern struct request *blk_get_request(request_queue_t *, int, int);
extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
@@ -595,7 +595,7 @@ static inline void blk_run_address_space
*/
extern int end_that_request_first(struct request *, int, int);
extern int end_that_request_chunk(struct request *, int, int);
-extern void end_that_request_last(struct request *);
+extern void end_that_request_last(struct request *, int);
extern void end_request(struct request *req, int uptodate);
/*
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 02/06] blk: make scsi use -EOPNOTSUPP instead of -EIO on ILLEGAL_REQUEST
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 01/06] blk: add @uptodate to end_that_request_last() and @error to rq_end_io_fn() Tejun Heo
@ 2005-05-29 4:23 ` Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 03/06] blk: make ide use -EOPNOTSUPP instead of -EIO on ABRT_ERR Tejun Heo
` (5 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2005-05-29 4:23 UTC (permalink / raw)
To: axboe, James.Bottomley, bzolnier, jgarzik; +Cc: linux-kernel
02_blk_scsi_eopnotsupp.patch
Use -EOPNOTSUPP instead of -EIO on ILLEGAL_REQUEST.
Signed-off-by: Tejun Heo <htejun@gmail.com>
scsi_lib.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletion(-)
Index: blk-fixes/drivers/scsi/scsi_lib.c
===================================================================
--- blk-fixes.orig/drivers/scsi/scsi_lib.c 2005-05-29 13:20:30.000000000 +0900
+++ blk-fixes/drivers/scsi/scsi_lib.c 2005-05-29 13:20:31.000000000 +0900
@@ -849,7 +849,8 @@ void scsi_io_completion(struct scsi_cmnd
scsi_requeue_command(q, cmd);
result = 0;
} else {
- cmd = scsi_end_request(cmd, 0, this_count, 1);
+ cmd = scsi_end_request(cmd, -EOPNOTSUPP,
+ this_count, 1);
return;
}
break;
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 03/06] blk: make ide use -EOPNOTSUPP instead of -EIO on ABRT_ERR
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 01/06] blk: add @uptodate to end_that_request_last() and @error to rq_end_io_fn() Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 02/06] blk: make scsi use -EOPNOTSUPP instead of -EIO on ILLEGAL_REQUEST Tejun Heo
@ 2005-05-29 4:23 ` Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 04/06] blk: reimplement QUEUE_OREDERED_FLUSH Tejun Heo
` (4 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2005-05-29 4:23 UTC (permalink / raw)
To: axboe, James.Bottomley, bzolnier, jgarzik; +Cc: linux-kernel
03_blk_ide_eopnotsupp.patch
Use -EOPNOTSUPP instead of -EIO on ABRT_ERR.
Signed-off-by: Tejun Heo <htejun@gmail.com>
ide-io.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletion(-)
Index: blk-fixes/drivers/ide/ide-io.c
===================================================================
--- blk-fixes.orig/drivers/ide/ide-io.c 2005-05-29 13:20:30.000000000 +0900
+++ blk-fixes/drivers/ide/ide-io.c 2005-05-29 13:20:31.000000000 +0900
@@ -305,6 +305,7 @@ void ide_end_drive_cmd (ide_drive_t *dri
ide_hwif_t *hwif = HWIF(drive);
unsigned long flags;
struct request *rq;
+ int uptodate;
spin_lock_irqsave(&ide_lock, flags);
rq = HWGROUP(drive)->rq;
@@ -379,7 +380,10 @@ void ide_end_drive_cmd (ide_drive_t *dri
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
rq->errors = err;
- end_that_request_last(rq, !rq->errors);
+ uptodate = 1;
+ if (err)
+ uptodate = err & ABRT_ERR ? -EOPNOTSUPP : -EIO;
+ end_that_request_last(rq, uptodate);
spin_unlock_irqrestore(&ide_lock, flags);
}
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 04/06] blk: reimplement QUEUE_OREDERED_FLUSH
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
` (2 preceding siblings ...)
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 03/06] blk: make ide use -EOPNOTSUPP instead of -EIO on ABRT_ERR Tejun Heo
@ 2005-05-29 4:23 ` Tejun Heo
2005-05-29 9:54 ` Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 05/06] blk: turn on QUEUE_ORDERED_FLUSH by default if ordered tag isn't supported Tejun Heo
` (3 subsequent siblings)
7 siblings, 1 reply; 12+ messages in thread
From: Tejun Heo @ 2005-05-29 4:23 UTC (permalink / raw)
To: axboe, James.Bottomley, bzolnier, jgarzik; +Cc: linux-kernel
04_blk_flush_reimplementation.patch
Reimplement QUEUE_ORDERED_FLUSH.
* Implementation is contained inside blk layer. Only
prepare_flush_fn() is needed from individual drivers.
* Tagged queues which don't support ordered tag can use
flushing.
* Multi-bio barrier requests supported.
Signed-off-by: Tejun Heo <htejun@gmail.com>
drivers/block/elevator.c | 52 ++++----
drivers/block/ll_rw_blk.c | 279 +++++++++++++++++++++++++++------------------
drivers/ide/ide-disk.c | 39 ------
drivers/ide/ide-io.c | 5
drivers/scsi/scsi_lib.c | 21 ---
drivers/scsi/sd.c | 25 ----
include/linux/blkdev.h | 29 ++--
include/scsi/scsi_driver.h | 1
8 files changed, 210 insertions(+), 241 deletions(-)
Index: blk-fixes/drivers/block/elevator.c
===================================================================
--- blk-fixes.orig/drivers/block/elevator.c 2005-05-29 13:20:30.000000000 +0900
+++ blk-fixes/drivers/block/elevator.c 2005-05-29 13:20:31.000000000 +0900
@@ -40,6 +40,26 @@
static DEFINE_SPINLOCK(elv_list_lock);
static LIST_HEAD(elv_list);
+static inline void elv_inc_inflight(request_queue_t *q)
+{
+ q->in_flight++;
+}
+
+static inline void elv_dec_inflight(request_queue_t *q)
+{
+ q->in_flight--;
+
+ /*
+ * If the queue is waiting for all accounted requests to be
+ * drained to start flush sequence and we're the last one,
+ * kick the queue in the ass to start the flush sequence.
+ */
+ if (q->flush_seq == QUEUE_FLUSH_DRAIN && q->in_flight == 0) {
+ q->flush_seq = QUEUE_FLUSH_PRE;
+ q->request_fn(q);
+ }
+}
+
/*
* can we safely merge with this request?
*/
@@ -270,7 +290,7 @@ void elv_deactivate_request(request_queu
* in_flight count again
*/
if (blk_account_rq(rq))
- q->in_flight--;
+ elv_dec_inflight(q);
rq->flags &= ~REQ_STARTED;
@@ -283,14 +303,6 @@ void elv_requeue_request(request_queue_t
elv_deactivate_request(q, rq);
/*
- * if this is the flush, requeue the original instead and drop the flush
- */
- if (rq->flags & REQ_BAR_FLUSH) {
- clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
- rq = rq->end_io_data;
- }
-
- /*
* the request is prepped and may have some resources allocated.
* allowing unprepped requests to pass this one may cause resource
* deadlock. turn on softbarrier.
@@ -353,20 +365,10 @@ void elv_add_request(request_queue_t *q,
static inline struct request *__elv_next_request(request_queue_t *q)
{
- struct request *rq = q->elevator->ops->elevator_next_req_fn(q);
-
- /*
- * if this is a barrier write and the device has to issue a
- * flush sequence to support it, check how far we are
- */
- if (rq && blk_fs_request(rq) && blk_barrier_rq(rq)) {
- BUG_ON(q->ordered == QUEUE_ORDERED_NONE);
-
- if (q->ordered == QUEUE_ORDERED_FLUSH &&
- !blk_barrier_preflush(rq))
- rq = blk_start_pre_flush(q, rq);
- }
-
+ struct request *rq;
+ while ((rq = q->elevator->ops->elevator_next_req_fn(q)))
+ if (blk_do_barrier(q, &rq))
+ break;
return rq;
}
@@ -433,7 +435,7 @@ void elv_remove_request(request_queue_t
* for request-request merges
*/
if (blk_account_rq(rq))
- q->in_flight++;
+ elv_inc_inflight(q);
/*
* the main clearing point for q->last_merge is on retrieval of
@@ -529,7 +531,7 @@ void elv_completed_request(request_queue
* request is released from the driver, io must be done
*/
if (blk_account_rq(rq))
- q->in_flight--;
+ elv_dec_inflight(q);
if (e->ops->elevator_completed_req_fn)
e->ops->elevator_completed_req_fn(q, rq);
Index: blk-fixes/drivers/block/ll_rw_blk.c
===================================================================
--- blk-fixes.orig/drivers/block/ll_rw_blk.c 2005-05-29 13:20:30.000000000 +0900
+++ blk-fixes/drivers/block/ll_rw_blk.c 2005-05-29 13:20:31.000000000 +0900
@@ -347,165 +347,216 @@ EXPORT_SYMBOL(blk_queue_issue_flush_fn);
/*
* Cache flushing for ordered writes handling
*/
-static void blk_pre_flush_end_io(struct request *flush_rq, int error)
+static void blk_finish_flush(request_queue_t *q, int error)
{
- struct request *rq = flush_rq->end_io_data;
- request_queue_t *q = rq->q;
+ struct request *rq = q->bar_rq;
+ struct bio *bio = q->bar_bio;
- rq->flags |= REQ_BAR_PREFLUSH;
+ q->flush_seq = QUEUE_FLUSH_NONE;
+ q->bar_rq = NULL;
+ q->bar_bio = NULL;
- if (!flush_rq->errors)
- elv_requeue_request(q, rq);
- else {
- q->end_flush_fn(q, flush_rq);
- clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
- q->request_fn(q);
+ while (bio) {
+ bio_endio(bio, bio->bi_size, error);
+ bio = bio->bi_next;
}
+ end_that_request_last(rq, error ? error : 1);
+
+ q->request_fn(q); /* is this necessary? - tj */
}
-static void blk_post_flush_end_io(struct request *flush_rq, int error)
+static int blk_prep_flush(request_queue_t *q, struct request *flush_rq,
+ struct gendisk *disk)
{
- struct request *rq = flush_rq->end_io_data;
- request_queue_t *q = rq->q;
-
- rq->flags |= REQ_BAR_POSTFLUSH;
+ rq_init(q, flush_rq);
+ flush_rq->flags = 0;
+ flush_rq->elevator_private = NULL;
+ flush_rq->rq_disk = disk;
+ flush_rq->rl = NULL;
- q->end_flush_fn(q, flush_rq);
- clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
- q->request_fn(q);
+ return q->prepare_flush_fn(q, flush_rq);
}
-struct request *blk_start_pre_flush(request_queue_t *q, struct request *rq)
+static void blk_pre_flush_end_io(struct request *flush_rq, int error)
{
- struct request *flush_rq = q->flush_rq;
+ request_queue_t *q = flush_rq->q;
+ struct request *rq = q->bar_rq;
- BUG_ON(!blk_barrier_rq(rq));
+ switch (error) {
+ case 0:
+ q->flush_seq = QUEUE_FLUSH_BAR;
+ elv_requeue_request(q, rq);
+ break;
- if (test_and_set_bit(QUEUE_FLAG_FLUSH, &q->queue_flags))
- return NULL;
+ case -EOPNOTSUPP:
+ blk_queue_ordered(q, QUEUE_ORDERED_NONE);
+ /* fall through */
+ default:
+ blk_finish_flush(q, error);
+ break;
+ }
+}
- rq_init(q, flush_rq);
- flush_rq->elevator_private = NULL;
- flush_rq->flags = REQ_BAR_FLUSH;
- flush_rq->rq_disk = rq->rq_disk;
- flush_rq->rl = NULL;
+static void blk_post_flush_end_io(struct request *flush_rq, int error)
+{
+ blk_finish_flush(flush_rq->q, error);
+}
- /*
- * prepare_flush returns 0 if no flush is needed, just mark both
- * pre and post flush as done in that case
- */
- if (!q->prepare_flush_fn(q, flush_rq)) {
- rq->flags |= REQ_BAR_PREFLUSH | REQ_BAR_POSTFLUSH;
- clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
- return rq;
- }
+struct request *blk_start_pre_flush(request_queue_t *q, struct request *rq)
+{
+ struct request *flush_rq = q->flush_rq;
/*
- * some drivers dequeue requests right away, some only after io
- * completion. make sure the request is dequeued.
+ * prepare_flush returns 0 if no flush is needed, just perform
+ * the original barrier request in that case.
*/
- if (!list_empty(&rq->queuelist))
- blkdev_dequeue_request(rq);
+ if (!blk_prep_flush(q, flush_rq, rq->rq_disk))
+ return rq;
- elv_deactivate_request(q, rq);
+ blkdev_dequeue_request(rq);
+ q->bar_rq = rq;
+ q->bar_bio = rq->bio;
+ q->bi_size = 0;
+ q->flush_error = 0;
- flush_rq->end_io_data = rq;
flush_rq->end_io = blk_pre_flush_end_io;
__elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
- return flush_rq;
+
+ if (q->in_flight == 0) {
+ q->flush_seq = QUEUE_FLUSH_PRE;
+ return flush_rq;
+ } else {
+ q->flush_seq = QUEUE_FLUSH_DRAIN;
+ return NULL;
+ }
}
-static void blk_start_post_flush(request_queue_t *q, struct request *rq)
+static void blk_start_post_flush(request_queue_t *q)
{
struct request *flush_rq = q->flush_rq;
- BUG_ON(!blk_barrier_rq(rq));
+ if (blk_prep_flush(q, flush_rq, q->bar_rq->rq_disk)) {
+ flush_rq->end_io = blk_post_flush_end_io;
+ q->flush_seq = QUEUE_FLUSH_POST;
+ __elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
+ q->request_fn(q); /* is this necessary? - tj */
+ } else
+ blk_finish_flush(q, 0);
+}
- rq_init(q, flush_rq);
- flush_rq->elevator_private = NULL;
- flush_rq->flags = REQ_BAR_FLUSH;
- flush_rq->rq_disk = rq->rq_disk;
- flush_rq->rl = NULL;
+int blk_do_barrier(request_queue_t *q, struct request **rqp)
+{
+ struct request *rq = *rqp;
+ int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
- if (q->prepare_flush_fn(q, flush_rq)) {
- flush_rq->end_io_data = rq;
- flush_rq->end_io = blk_post_flush_end_io;
+ switch (q->ordered) {
+ case QUEUE_ORDERED_NONE:
+ if (is_barrier) {
+ /*
+ * This can happen when the queue switches to
+ * ORDERED_NONE while this request is on it.
+ */
+ end_that_request_first(rq, -EOPNOTSUPP,
+ rq->hard_nr_sectors);
+ end_that_request_last(rq, -EOPNOTSUPP);
+ *rqp = NULL;
+ return 0;
+ }
+ return 1;
- __elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
- q->request_fn(q);
+ case QUEUE_ORDERED_FLUSH:
+ switch (q->flush_seq) {
+ case QUEUE_FLUSH_NONE:
+ if (is_barrier)
+ *rqp = blk_start_pre_flush(q, rq);
+ break;
+ case QUEUE_FLUSH_DRAIN:
+ *rqp = NULL;
+ break;
+ default:
+ /*
+ * Don't allow any other requests while
+ * flushing is in progress.
+ */
+ if (rq != q->flush_rq && rq != q->bar_rq)
+ *rqp = NULL;
+ break;
+ }
+ return 1;
+
+ case QUEUE_ORDERED_TAG:
+ return 1;
+
+ default:
+ BUG();
+ return 1;
}
}
-static inline int blk_check_end_barrier(request_queue_t *q, struct request *rq,
- int sectors)
+static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error)
{
- if (sectors > rq->nr_sectors)
- sectors = rq->nr_sectors;
+ request_queue_t *q = bio->bi_private;
+
+ /*
+ * This is dry run, restore bio_sector and size. We'll finish
+ * this request again with the original bi_end_io after an
+ * error occurs or post flush is complete.
+ */
+ q->bi_size += bytes;
+
+ if (bio->bi_size)
+ return 1;
+
+ bio->bi_size = q->bi_size;
+ bio->bi_sector -= (q->bi_size >> 9);
+ q->bi_size = 0;
- rq->nr_sectors -= sectors;
- return rq->nr_sectors;
+ return 0;
}
-static int __blk_complete_barrier_rq(request_queue_t *q, struct request *rq,
- int sectors, int queue_locked)
+static inline int blk_flush_bio_endio(struct request *rq, struct bio *bio,
+ unsigned int nbytes, int error)
{
- if (q->ordered != QUEUE_ORDERED_FLUSH)
- return 0;
- if (!blk_fs_request(rq) || !blk_barrier_rq(rq))
- return 0;
- if (blk_barrier_postflush(rq))
+ request_queue_t *q = rq->q;
+ bio_end_io_t *endio;
+ void *private;
+
+ if (q->flush_seq != QUEUE_FLUSH_BAR || q->bar_rq != rq)
return 0;
- if (!blk_check_end_barrier(q, rq, sectors)) {
- unsigned long flags = 0;
+ /*
+ * Okay, this is the barrier request in progress, dry finish it.
+ */
+ if (error)
+ q->flush_error = error;
- if (!queue_locked)
- spin_lock_irqsave(q->queue_lock, flags);
+ endio = bio->bi_end_io;
+ private = bio->bi_private;
+ bio->bi_end_io = flush_dry_bio_endio;
+ bio->bi_private = q;
- blk_start_post_flush(q, rq);
+ bio_endio(bio, nbytes, error);
- if (!queue_locked)
- spin_unlock_irqrestore(q->queue_lock, flags);
- }
+ bio->bi_end_io = endio;
+ bio->bi_private = private;
return 1;
}
-/**
- * blk_complete_barrier_rq - complete possible barrier request
- * @q: the request queue for the device
- * @rq: the request
- * @sectors: number of sectors to complete
- *
- * Description:
- * Used in driver end_io handling to determine whether to postpone
- * completion of a barrier request until a post flush has been done. This
- * is the unlocked variant, used if the caller doesn't already hold the
- * queue lock.
- **/
-int blk_complete_barrier_rq(request_queue_t *q, struct request *rq, int sectors)
+static inline int blk_flush_end_request(struct request *rq)
{
- return __blk_complete_barrier_rq(q, rq, sectors, 0);
-}
-EXPORT_SYMBOL(blk_complete_barrier_rq);
+ request_queue_t *q = rq->q;
-/**
- * blk_complete_barrier_rq_locked - complete possible barrier request
- * @q: the request queue for the device
- * @rq: the request
- * @sectors: number of sectors to complete
- *
- * Description:
- * See blk_complete_barrier_rq(). This variant must be used if the caller
- * holds the queue lock.
- **/
-int blk_complete_barrier_rq_locked(request_queue_t *q, struct request *rq,
- int sectors)
-{
- return __blk_complete_barrier_rq(q, rq, sectors, 1);
+ if (q->flush_seq != QUEUE_FLUSH_BAR || q->bar_rq != rq)
+ return 0;
+
+ if (!q->flush_error)
+ blk_start_post_flush(q);
+ else
+ blk_finish_flush(q, q->flush_error);
+ return 1;
}
-EXPORT_SYMBOL(blk_complete_barrier_rq_locked);
/**
* blk_queue_bounce_limit - set bounce buffer limit for queue
@@ -3029,7 +3080,8 @@ static int __end_that_request_first(stru
if (nr_bytes >= bio->bi_size) {
req->bio = bio->bi_next;
nbytes = bio->bi_size;
- bio_endio(bio, nbytes, error);
+ if (!blk_flush_bio_endio(req, bio, nbytes, error))
+ bio_endio(bio, nbytes, error);
next_idx = 0;
bio_nbytes = 0;
} else {
@@ -3084,7 +3136,8 @@ static int __end_that_request_first(stru
* if the request wasn't completed, update state
*/
if (bio_nbytes) {
- bio_endio(bio, bio_nbytes, error);
+ if (!blk_flush_bio_endio(req, bio, bio_nbytes, error))
+ bio_endio(bio, bio_nbytes, error);
bio->bi_idx += next_idx;
bio_iovec(bio)->bv_offset += nr_bytes;
bio_iovec(bio)->bv_len -= nr_bytes;
@@ -3147,6 +3200,12 @@ void end_that_request_last(struct reques
int error;
/*
+ * Are we finishing the barrier request?
+ */
+ if (blk_flush_end_request(req))
+ return;
+
+ /*
* extend uptodate bool to allow < 0 value to be direct io error
*/
error = 0;
Index: blk-fixes/drivers/ide/ide-disk.c
===================================================================
--- blk-fixes.orig/drivers/ide/ide-disk.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/ide/ide-disk.c 2005-05-29 13:20:31.000000000 +0900
@@ -681,44 +681,6 @@ static ide_proc_entry_t idedisk_proc[] =
#endif /* CONFIG_PROC_FS */
-static void idedisk_end_flush(request_queue_t *q, struct request *flush_rq)
-{
- ide_drive_t *drive = q->queuedata;
- struct request *rq = flush_rq->end_io_data;
- int good_sectors = rq->hard_nr_sectors;
- int bad_sectors;
- sector_t sector;
-
- if (flush_rq->errors & ABRT_ERR) {
- printk(KERN_ERR "%s: barrier support doesn't work\n", drive->name);
- blk_queue_ordered(drive->queue, QUEUE_ORDERED_NONE);
- blk_queue_issue_flush_fn(drive->queue, NULL);
- good_sectors = 0;
- } else if (flush_rq->errors) {
- good_sectors = 0;
- if (blk_barrier_preflush(rq)) {
- sector = ide_get_error_location(drive,flush_rq->buffer);
- if ((sector >= rq->hard_sector) &&
- (sector < rq->hard_sector + rq->hard_nr_sectors))
- good_sectors = sector - rq->hard_sector;
- }
- }
-
- if (flush_rq->errors)
- printk(KERN_ERR "%s: failed barrier write: "
- "sector=%Lx(good=%d/bad=%d)\n",
- drive->name, (unsigned long long)rq->sector,
- good_sectors,
- (int) (rq->hard_nr_sectors-good_sectors));
-
- bad_sectors = rq->hard_nr_sectors - good_sectors;
-
- if (good_sectors)
- __ide_end_request(drive, rq, 1, good_sectors);
- if (bad_sectors)
- __ide_end_request(drive, rq, 0, bad_sectors);
-}
-
static int idedisk_prepare_flush(request_queue_t *q, struct request *rq)
{
ide_drive_t *drive = q->queuedata;
@@ -1016,7 +978,6 @@ static void idedisk_setup (ide_drive_t *
if (barrier) {
blk_queue_ordered(drive->queue, QUEUE_ORDERED_FLUSH);
drive->queue->prepare_flush_fn = idedisk_prepare_flush;
- drive->queue->end_flush_fn = idedisk_end_flush;
blk_queue_issue_flush_fn(drive->queue, idedisk_issue_flush);
}
}
Index: blk-fixes/drivers/ide/ide-io.c
===================================================================
--- blk-fixes.orig/drivers/ide/ide-io.c 2005-05-29 13:20:31.000000000 +0900
+++ blk-fixes/drivers/ide/ide-io.c 2005-05-29 13:20:31.000000000 +0900
@@ -119,10 +119,7 @@ int ide_end_request (ide_drive_t *drive,
if (!nr_sectors)
nr_sectors = rq->hard_cur_sectors;
- if (blk_complete_barrier_rq_locked(drive->queue, rq, nr_sectors))
- ret = rq->nr_sectors != 0;
- else
- ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
+ ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
spin_unlock_irqrestore(&ide_lock, flags);
return ret;
Index: blk-fixes/drivers/scsi/scsi_lib.c
===================================================================
--- blk-fixes.orig/drivers/scsi/scsi_lib.c 2005-05-29 13:20:31.000000000 +0900
+++ blk-fixes/drivers/scsi/scsi_lib.c 2005-05-29 13:20:31.000000000 +0900
@@ -717,9 +717,6 @@ void scsi_io_completion(struct scsi_cmnd
int sense_valid = 0;
int sense_deferred = 0;
- if (blk_complete_barrier_rq(q, req, good_bytes >> 9))
- return;
-
/*
* Free up any indirection buffers we allocated for DMA purposes.
* For the case of a READ, we need to copy the data out of the
@@ -999,23 +996,6 @@ static int scsi_prepare_flush_fn(request
return 0;
}
-static void scsi_end_flush_fn(request_queue_t *q, struct request *rq)
-{
- struct scsi_device *sdev = q->queuedata;
- struct request *flush_rq = rq->end_io_data;
- struct scsi_driver *drv;
-
- if (flush_rq->errors) {
- printk("scsi: barrier error, disabling flush support\n");
- blk_queue_ordered(q, QUEUE_ORDERED_NONE);
- }
-
- if (sdev->sdev_state == SDEV_RUNNING) {
- drv = *(struct scsi_driver **) rq->rq_disk->private_data;
- drv->end_flush(q, rq);
- }
-}
-
static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
sector_t *error_sector)
{
@@ -1451,7 +1431,6 @@ struct request_queue *scsi_alloc_queue(s
else if (shost->ordered_flush) {
blk_queue_ordered(q, QUEUE_ORDERED_FLUSH);
q->prepare_flush_fn = scsi_prepare_flush_fn;
- q->end_flush_fn = scsi_end_flush_fn;
}
if (!shost->use_clustering)
Index: blk-fixes/drivers/scsi/sd.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sd.c 2005-05-29 13:20:30.000000000 +0900
+++ blk-fixes/drivers/scsi/sd.c 2005-05-29 13:20:31.000000000 +0900
@@ -122,7 +122,6 @@ static void sd_shutdown(struct device *d
static void sd_rescan(struct device *);
static int sd_init_command(struct scsi_cmnd *);
static int sd_issue_flush(struct device *, sector_t *);
-static void sd_end_flush(request_queue_t *, struct request *);
static int sd_prepare_flush(request_queue_t *, struct request *);
static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer);
@@ -139,7 +138,6 @@ static struct scsi_driver sd_template =
.init_command = sd_init_command,
.issue_flush = sd_issue_flush,
.prepare_flush = sd_prepare_flush,
- .end_flush = sd_end_flush,
};
/*
@@ -739,29 +737,6 @@ static int sd_issue_flush(struct device
return sd_sync_cache(sdp);
}
-static void sd_end_flush(request_queue_t *q, struct request *flush_rq)
-{
- struct request *rq = flush_rq->end_io_data;
- struct scsi_cmnd *cmd = rq->special;
- unsigned int bytes = rq->hard_nr_sectors << 9;
-
- if (!flush_rq->errors) {
- spin_unlock(q->queue_lock);
- scsi_io_completion(cmd, bytes, 0);
- spin_lock(q->queue_lock);
- } else if (blk_barrier_postflush(rq)) {
- spin_unlock(q->queue_lock);
- scsi_io_completion(cmd, 0, bytes);
- spin_lock(q->queue_lock);
- } else {
- /*
- * force journal abort of barriers
- */
- end_that_request_first(rq, -EOPNOTSUPP, rq->hard_nr_sectors);
- end_that_request_last(rq, -EOPNOTSUPP);
- }
-}
-
static int sd_prepare_flush(request_queue_t *q, struct request *rq)
{
struct scsi_device *sdev = q->queuedata;
Index: blk-fixes/include/linux/blkdev.h
===================================================================
--- blk-fixes.orig/include/linux/blkdev.h 2005-05-29 13:20:30.000000000 +0900
+++ blk-fixes/include/linux/blkdev.h 2005-05-29 13:20:31.000000000 +0900
@@ -227,9 +227,6 @@ enum rq_flag_bits {
__REQ_PM_SUSPEND, /* suspend request */
__REQ_PM_RESUME, /* resume request */
__REQ_PM_SHUTDOWN, /* shutdown request */
- __REQ_BAR_PREFLUSH, /* barrier pre-flush done */
- __REQ_BAR_POSTFLUSH, /* barrier post-flush */
- __REQ_BAR_FLUSH, /* rq is the flush request */
__REQ_NR_BITS, /* stops here */
};
@@ -255,9 +252,6 @@ enum rq_flag_bits {
#define REQ_PM_SUSPEND (1 << __REQ_PM_SUSPEND)
#define REQ_PM_RESUME (1 << __REQ_PM_RESUME)
#define REQ_PM_SHUTDOWN (1 << __REQ_PM_SHUTDOWN)
-#define REQ_BAR_PREFLUSH (1 << __REQ_BAR_PREFLUSH)
-#define REQ_BAR_POSTFLUSH (1 << __REQ_BAR_POSTFLUSH)
-#define REQ_BAR_FLUSH (1 << __REQ_BAR_FLUSH)
/*
* State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME
@@ -288,7 +282,6 @@ typedef int (merge_bvec_fn) (request_que
typedef void (activity_fn) (void *data, int rw);
typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *);
typedef int (prepare_flush_fn) (request_queue_t *, struct request *);
-typedef void (end_flush_fn) (request_queue_t *, struct request *);
enum blk_queue_state {
Queue_down,
@@ -329,7 +322,6 @@ struct request_queue
activity_fn *activity_fn;
issue_flush_fn *issue_flush_fn;
prepare_flush_fn *prepare_flush_fn;
- end_flush_fn *end_flush_fn;
/*
* Auto-unplugging state
@@ -409,7 +401,11 @@ struct request_queue
/*
* reserved for flush operations
*/
- struct request *flush_rq;
+ int flush_seq; /* QUEUE_FLUSH_* */
+ int flush_error;
+ struct request *flush_rq, *bar_rq;
+ struct bio *bar_bio;
+ unsigned int bi_size;
unsigned char ordered;
};
@@ -434,12 +430,17 @@ enum {
#define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */
#define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */
#define QUEUE_FLAG_DRAIN 8 /* draining queue for sched switch */
-#define QUEUE_FLAG_FLUSH 9 /* doing barrier flush sequence */
+
+#define QUEUE_FLUSH_NONE 0 /* flushing isn't in progress */
+#define QUEUE_FLUSH_DRAIN 1 /* waiting for the queue to be drained */
+#define QUEUE_FLUSH_PRE 2 /* pre-flushing in progress */
+#define QUEUE_FLUSH_BAR 3 /* original barrier req in progress */
+#define QUEUE_FLUSH_POST 4 /* post-flushing in progress */
#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
#define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
-#define blk_queue_flushing(q) test_bit(QUEUE_FLAG_FLUSH, &(q)->queue_flags)
+#define blk_queue_flushing(q) ((q)->flush_seq != QUEUE_FLUSH_NONE)
#define blk_fs_request(rq) ((rq)->flags & REQ_CMD)
#define blk_pc_request(rq) ((rq)->flags & REQ_BLOCK_PC)
@@ -454,8 +455,6 @@ enum {
((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
#define blk_barrier_rq(rq) ((rq)->flags & REQ_HARDBARRIER)
-#define blk_barrier_preflush(rq) ((rq)->flags & REQ_BAR_PREFLUSH)
-#define blk_barrier_postflush(rq) ((rq)->flags & REQ_BAR_POSTFLUSH)
#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
@@ -638,9 +637,7 @@ extern void blk_queue_dma_alignment(requ
extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
extern void blk_queue_ordered(request_queue_t *, int);
extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *);
-extern struct request *blk_start_pre_flush(request_queue_t *,struct request *);
-extern int blk_complete_barrier_rq(request_queue_t *, struct request *, int);
-extern int blk_complete_barrier_rq_locked(request_queue_t *, struct request *, int);
+extern int blk_do_barrier(request_queue_t *, struct request **);
extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *);
extern void blk_dump_rq_flags(struct request *, char *);
Index: blk-fixes/include/scsi/scsi_driver.h
===================================================================
--- blk-fixes.orig/include/scsi/scsi_driver.h 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/include/scsi/scsi_driver.h 2005-05-29 13:20:31.000000000 +0900
@@ -15,7 +15,6 @@ struct scsi_driver {
void (*rescan)(struct device *);
int (*issue_flush)(struct device *, sector_t *);
int (*prepare_flush)(struct request_queue *, struct request *);
- void (*end_flush)(struct request_queue *, struct request *);
};
#define to_scsi_driver(drv) \
container_of((drv), struct scsi_driver, gendrv)
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 04/06] blk: reimplement QUEUE_OREDERED_FLUSH
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 04/06] blk: reimplement QUEUE_OREDERED_FLUSH Tejun Heo
@ 2005-05-29 9:54 ` Tejun Heo
0 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2005-05-29 9:54 UTC (permalink / raw)
To: axboe, James.Bottomley, bzolnier, jgarzik; +Cc: linux-kernel
On Sun, May 29, 2005 at 01:23:38PM +0900, Tejun Heo wrote:
> 04_blk_flush_reimplementation.patch
>
> Reimplement QUEUE_ORDERED_FLUSH.
>
> * Implementation is contained inside blk layer. Only
> prepare_flush_fn() is needed from individual drivers.
> * Tagged queues which don't support ordered tag can use
> flushing.
> * Multi-bio barrier requests supported.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
>
> drivers/block/elevator.c | 52 ++++----
> drivers/block/ll_rw_blk.c | 279 +++++++++++++++++++++++++++------------------
> drivers/ide/ide-disk.c | 39 ------
> drivers/ide/ide-io.c | 5
> drivers/scsi/scsi_lib.c | 21 ---
> drivers/scsi/sd.c | 25 ----
> include/linux/blkdev.h | 29 ++--
> include/scsi/scsi_driver.h | 1
> 8 files changed, 210 insertions(+), 241 deletions(-)
In blk_do_barrier() above patch implements, when a barrier request is
terminated w/ -EOPNOTSUPP, the request is not dequeued. The following
patch fixes this. The fixed path is a very rare error path, so, for
reviewing, this patch doesn't make much difference. I'll use properly
regenerated patch on the next posting of this patchset.
diff -u blk-fixes/drivers/block/ll_rw_blk.c blk-fixes/drivers/block/ll_rw_blk.c
--- blk-fixes/drivers/block/ll_rw_blk.c 2005-05-29 13:20:31.000000000 +0900
+++ blk-fixes/drivers/block/ll_rw_blk.c 2005-05-29 18:23:05.000000000 +0900
@@ -352,6 +352,8 @@
struct request *rq = q->bar_rq;
struct bio *bio = q->bar_bio;
+ BUG_ON(!list_empty(&rq->queuelist));
+
q->flush_seq = QUEUE_FLUSH_NONE;
q->bar_rq = NULL;
q->bar_bio = NULL;
@@ -457,6 +459,7 @@
* This can happen when the queue switches to
* ORDERED_NONE while this request is on it.
*/
+ blkdev_dequeue_request(rq);
end_that_request_first(rq, -EOPNOTSUPP,
rq->hard_nr_sectors);
end_that_request_last(rq, -EOPNOTSUPP);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH Linux 2.6.12-rc5-mm1 05/06] blk: turn on QUEUE_ORDERED_FLUSH by default if ordered tag isn't supported
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
` (3 preceding siblings ...)
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 04/06] blk: reimplement QUEUE_OREDERED_FLUSH Tejun Heo
@ 2005-05-29 4:23 ` Tejun Heo
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 06/06] blk: debug messages Tejun Heo
` (2 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2005-05-29 4:23 UTC (permalink / raw)
To: axboe, James.Bottomley, bzolnier, jgarzik; +Cc: linux-kernel
05_blk_scsi_turn_on_flushing_by_default.patch
As flushing can now be used by devices which only support
simple tags, there's no need to use
Scsi_Host_Template->ordered_flush to enable it selectively.
This patch removes ->ordered_flush and enables flushing
implicitly when ordered tag isn't supported. If the device
doesn't support flushing, it can just return -EOPNOTSUPP for
flush requests. blk layer will switch to QUEUE_OREDERED_NONE
automatically.
Signed-off-by: Tejun Heo <htejun@gmail.com>
drivers/scsi/ahci.c | 1 -
drivers/scsi/ata_piix.c | 1 -
drivers/scsi/hosts.c | 9 ---------
drivers/scsi/sata_nv.c | 1 -
drivers/scsi/sata_promise.c | 1 -
drivers/scsi/sata_sil.c | 1 -
drivers/scsi/sata_sis.c | 1 -
drivers/scsi/sata_svw.c | 1 -
drivers/scsi/sata_sx4.c | 1 -
drivers/scsi/sata_uli.c | 1 -
drivers/scsi/sata_via.c | 1 -
drivers/scsi/sata_vsc.c | 1 -
drivers/scsi/scsi_lib.c | 2 +-
include/scsi/scsi_host.h | 1 -
14 files changed, 1 insertion(+), 22 deletions(-)
Index: blk-fixes/drivers/scsi/ahci.c
===================================================================
--- blk-fixes.orig/drivers/scsi/ahci.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/ahci.c 2005-05-29 13:20:32.000000000 +0900
@@ -200,7 +200,6 @@ static Scsi_Host_Template ahci_sht = {
.dma_boundary = AHCI_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations ahci_ops = {
Index: blk-fixes/drivers/scsi/ata_piix.c
===================================================================
--- blk-fixes.orig/drivers/scsi/ata_piix.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/ata_piix.c 2005-05-29 13:20:32.000000000 +0900
@@ -123,7 +123,6 @@ static Scsi_Host_Template piix_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations piix_pata_ops = {
Index: blk-fixes/drivers/scsi/hosts.c
===================================================================
--- blk-fixes.orig/drivers/scsi/hosts.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/hosts.c 2005-05-29 13:20:32.000000000 +0900
@@ -264,17 +264,8 @@ struct Scsi_Host *scsi_host_alloc(struct
shost->cmd_per_lun = sht->cmd_per_lun;
shost->unchecked_isa_dma = sht->unchecked_isa_dma;
shost->use_clustering = sht->use_clustering;
- shost->ordered_flush = sht->ordered_flush;
shost->ordered_tag = sht->ordered_tag;
- /*
- * hosts/devices that do queueing must support ordered tags
- */
- if (shost->can_queue > 1 && shost->ordered_flush) {
- printk(KERN_ERR "scsi: ordered flushes don't support queueing\n");
- shost->ordered_flush = 0;
- }
-
if (sht->max_host_blocked)
shost->max_host_blocked = sht->max_host_blocked;
else
Index: blk-fixes/drivers/scsi/sata_nv.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_nv.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_nv.c 2005-05-29 13:20:32.000000000 +0900
@@ -206,7 +206,6 @@ static Scsi_Host_Template nv_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations nv_ops = {
Index: blk-fixes/drivers/scsi/sata_promise.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_promise.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_promise.c 2005-05-29 13:20:32.000000000 +0900
@@ -102,7 +102,6 @@ static Scsi_Host_Template pdc_ata_sht =
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations pdc_ata_ops = {
Index: blk-fixes/drivers/scsi/sata_sil.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_sil.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_sil.c 2005-05-29 13:20:32.000000000 +0900
@@ -134,7 +134,6 @@ static Scsi_Host_Template sil_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations sil_ops = {
Index: blk-fixes/drivers/scsi/sata_sis.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_sis.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_sis.c 2005-05-29 13:20:32.000000000 +0900
@@ -90,7 +90,6 @@ static Scsi_Host_Template sis_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations sis_ops = {
Index: blk-fixes/drivers/scsi/sata_svw.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_svw.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_svw.c 2005-05-29 13:20:32.000000000 +0900
@@ -288,7 +288,6 @@ static Scsi_Host_Template k2_sata_sht =
.proc_info = k2_sata_proc_info,
#endif
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
Index: blk-fixes/drivers/scsi/sata_sx4.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_sx4.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_sx4.c 2005-05-29 13:20:32.000000000 +0900
@@ -188,7 +188,6 @@ static Scsi_Host_Template pdc_sata_sht =
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations pdc_20621_ops = {
Index: blk-fixes/drivers/scsi/sata_uli.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_uli.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_uli.c 2005-05-29 13:20:32.000000000 +0900
@@ -82,7 +82,6 @@ static Scsi_Host_Template uli_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations uli_ops = {
Index: blk-fixes/drivers/scsi/sata_via.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_via.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_via.c 2005-05-29 13:20:32.000000000 +0900
@@ -102,7 +102,6 @@ static Scsi_Host_Template svia_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
static struct ata_port_operations svia_sata_ops = {
Index: blk-fixes/drivers/scsi/sata_vsc.c
===================================================================
--- blk-fixes.orig/drivers/scsi/sata_vsc.c 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/drivers/scsi/sata_vsc.c 2005-05-29 13:20:32.000000000 +0900
@@ -205,7 +205,6 @@ static Scsi_Host_Template vsc_sata_sht =
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
- .ordered_flush = 1,
};
Index: blk-fixes/drivers/scsi/scsi_lib.c
===================================================================
--- blk-fixes.orig/drivers/scsi/scsi_lib.c 2005-05-29 13:20:31.000000000 +0900
+++ blk-fixes/drivers/scsi/scsi_lib.c 2005-05-29 13:20:32.000000000 +0900
@@ -1428,7 +1428,7 @@ struct request_queue *scsi_alloc_queue(s
*/
if (shost->ordered_tag)
blk_queue_ordered(q, QUEUE_ORDERED_TAG);
- else if (shost->ordered_flush) {
+ else {
blk_queue_ordered(q, QUEUE_ORDERED_FLUSH);
q->prepare_flush_fn = scsi_prepare_flush_fn;
}
Index: blk-fixes/include/scsi/scsi_host.h
===================================================================
--- blk-fixes.orig/include/scsi/scsi_host.h 2005-05-29 13:20:29.000000000 +0900
+++ blk-fixes/include/scsi/scsi_host.h 2005-05-29 13:20:32.000000000 +0900
@@ -366,7 +366,6 @@ struct scsi_host_template {
/*
* ordered write support
*/
- unsigned ordered_flush:1;
unsigned ordered_tag:1;
/*
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 06/06] blk: debug messages
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
` (4 preceding siblings ...)
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 05/06] blk: turn on QUEUE_ORDERED_FLUSH by default if ordered tag isn't supported Tejun Heo
@ 2005-05-29 4:23 ` Tejun Heo
2005-05-29 17:37 ` [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Jeff Garzik
2005-05-29 19:14 ` Jens Axboe
7 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2005-05-29 4:23 UTC (permalink / raw)
To: axboe, James.Bottomley, bzolnier, jgarzik; +Cc: linux-kernel
06_blk_flush_reimplementation_debug_messages.patch
These are debug messages I've used. If you are interested how
it works...
Signed-off-by: Tejun Heo <htejun@gmail.com>
elevator.c | 3 +++
ll_rw_blk.c | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 37 insertions(+), 2 deletions(-)
Index: blk-fixes/drivers/block/elevator.c
===================================================================
--- blk-fixes.orig/drivers/block/elevator.c 2005-05-29 13:20:31.000000000 +0900
+++ blk-fixes/drivers/block/elevator.c 2005-05-29 13:20:32.000000000 +0900
@@ -37,6 +37,8 @@
#include <asm/uaccess.h>
+#define pd(fmt, args...) printk("[%-21s]: " fmt, __FUNCTION__ , ##args);
+
static DEFINE_SPINLOCK(elv_list_lock);
static LIST_HEAD(elv_list);
@@ -55,6 +57,7 @@ static inline void elv_dec_inflight(requ
* kick the queue in the ass to start the flush sequence.
*/
if (q->flush_seq == QUEUE_FLUSH_DRAIN && q->in_flight == 0) {
+ pd("-> FLUSH_PRE\n");
q->flush_seq = QUEUE_FLUSH_PRE;
q->request_fn(q);
}
Index: blk-fixes/drivers/block/ll_rw_blk.c
===================================================================
--- blk-fixes.orig/drivers/block/ll_rw_blk.c 2005-05-29 13:20:31.000000000 +0900
+++ blk-fixes/drivers/block/ll_rw_blk.c 2005-05-29 13:20:32.000000000 +0900
@@ -30,6 +30,8 @@
#include <linux/writeback.h>
#include <linux/blkdev.h>
+#define pd(fmt, args...) printk("[%-21s]: " fmt, __FUNCTION__ , ##args);
+
/*
* for max sense size
*/
@@ -352,6 +354,7 @@ static void blk_finish_flush(request_que
struct request *rq = q->bar_rq;
struct bio *bio = q->bar_bio;
+ pd("ENTER, -> FLUSH_NONE, error=%d\n", error);
q->flush_seq = QUEUE_FLUSH_NONE;
q->bar_rq = NULL;
q->bar_bio = NULL;
@@ -382,9 +385,11 @@ static void blk_pre_flush_end_io(struct
request_queue_t *q = flush_rq->q;
struct request *rq = q->bar_rq;
+ pd("ENTER\n");
switch (error) {
case 0:
q->flush_seq = QUEUE_FLUSH_BAR;
+ pd("-> FLUSH_BAR\n");
elv_requeue_request(q, rq);
break;
@@ -399,6 +404,7 @@ static void blk_pre_flush_end_io(struct
static void blk_post_flush_end_io(struct request *flush_rq, int error)
{
+ pd("ENTER\n");
blk_finish_flush(flush_rq->q, error);
}
@@ -406,12 +412,20 @@ struct request *blk_start_pre_flush(requ
{
struct request *flush_rq = q->flush_rq;
+ pd("ENTER\n");
+ struct bio *bio;
+ for (bio = rq->bio; bio; bio = bio->bi_next)
+ pd("BIO %p %llu %u\n",
+ bio, (unsigned long long)bio->bi_sector, bio->bi_size);
+
/*
* prepare_flush returns 0 if no flush is needed, just perform
* the original barrier request in that case.
*/
- if (!blk_prep_flush(q, flush_rq, rq->rq_disk))
+ if (!blk_prep_flush(q, flush_rq, rq->rq_disk)) {
+ pd("Oh well, prep says it's unnecessary\n");
return rq;
+ }
blkdev_dequeue_request(rq);
q->bar_rq = rq;
@@ -425,9 +439,11 @@ struct request *blk_start_pre_flush(requ
if (q->in_flight == 0) {
q->flush_seq = QUEUE_FLUSH_PRE;
+ pd("-> FLUSH_PRE\n");
return flush_rq;
} else {
q->flush_seq = QUEUE_FLUSH_DRAIN;
+ pd("-> FLUSH_DRAIN, in_flight=%d\n", q->in_flight);
return NULL;
}
}
@@ -436,13 +452,18 @@ static void blk_start_post_flush(request
{
struct request *flush_rq = q->flush_rq;
+ pd("ENTER\n");
+
if (blk_prep_flush(q, flush_rq, q->bar_rq->rq_disk)) {
+ pd("-> FLUSH_POST\n");
flush_rq->end_io = blk_post_flush_end_io;
q->flush_seq = QUEUE_FLUSH_POST;
__elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
q->request_fn(q); /* is this necessary? - tj */
- } else
+ } else {
+ pd("wow, unnecessary?\n");
blk_finish_flush(q, 0);
+ }
}
int blk_do_barrier(request_queue_t *q, struct request **rqp)
@@ -453,6 +474,7 @@ int blk_do_barrier(request_queue_t *q, s
switch (q->ordered) {
case QUEUE_ORDERED_NONE:
if (is_barrier) {
+ pd("ORDERED_NONE, seen barrier\n");
/*
* This can happen when the queue switches to
* ORDERED_NONE while this request is on it.
@@ -473,6 +495,7 @@ int blk_do_barrier(request_queue_t *q, s
break;
case QUEUE_FLUSH_DRAIN:
*rqp = NULL;
+ pd("draining... deferring %p\n", rq);
break;
default:
/*
@@ -481,11 +504,14 @@ int blk_do_barrier(request_queue_t *q, s
*/
if (rq != q->flush_rq && rq != q->bar_rq)
*rqp = NULL;
+ pd("flush_seq == %d, %p->%p\n", q->flush_seq, rq, *rqp);
break;
}
return 1;
case QUEUE_ORDERED_TAG:
+ if (is_barrier)
+ pd("ORDERED_TAG, seen barrier\n");
return 1;
default:
@@ -512,6 +538,9 @@ static int flush_dry_bio_endio(struct bi
bio->bi_sector -= (q->bi_size >> 9);
q->bi_size = 0;
+ pd("%p %llu %u\n",
+ bio, (unsigned long long)bio->bi_sector, bio->bi_size);
+
return 0;
}
@@ -525,6 +554,7 @@ static inline int blk_flush_bio_endio(st
if (q->flush_seq != QUEUE_FLUSH_BAR || q->bar_rq != rq)
return 0;
+ pd("q->flush_error=%d error=%d\n", q->flush_error, error);
/*
* Okay, this is the barrier request in progress, dry finish it.
*/
@@ -551,6 +581,7 @@ static inline int blk_flush_end_request(
if (q->flush_seq != QUEUE_FLUSH_BAR || q->bar_rq != rq)
return 0;
+ pd("q->flush_error=%d\n", q->flush_error);
if (!q->flush_error)
blk_start_post_flush(q);
else
@@ -2601,6 +2632,7 @@ static int __make_request(request_queue_
barrier = bio_barrier(bio);
if (unlikely(barrier) && (q->ordered == QUEUE_ORDERED_NONE)) {
+ pd("ORDERED_NONE, seen barrier\n");
err = -EOPNOTSUPP;
goto end_io;
}
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
` (5 preceding siblings ...)
2005-05-29 4:23 ` [PATCH Linux 2.6.12-rc5-mm1 06/06] blk: debug messages Tejun Heo
@ 2005-05-29 17:37 ` Jeff Garzik
2005-05-29 19:14 ` Jens Axboe
7 siblings, 0 replies; 12+ messages in thread
From: Jeff Garzik @ 2005-05-29 17:37 UTC (permalink / raw)
To: Tejun Heo; +Cc: axboe, James.Bottomley, bzolnier, linux-kernel
Tejun Heo wrote:
> 05_blk_scsi_turn_on_flushing_by_default.patch
> : turn on QUEUE_ORDERED_FLUSH by default if ordered tag isn't supported
>
> As flushing can now be used by devices which only support
> simple tags, there's no need to use
> Scsi_Host_Template->ordered_flush to enable it selectively.
> This patch removes ->ordered_flush and enables flushing
> implicitly when ordered tag isn't supported. If the device
> doesn't support flushing, it can just return -EOPNOTSUPP for
> flush requests. blk layer will switch to QUEUE_OREDERED_NONE
> automatically.
This is rather nice...
Jeff
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation
2005-05-29 4:23 [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Tejun Heo
` (6 preceding siblings ...)
2005-05-29 17:37 ` [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation Jeff Garzik
@ 2005-05-29 19:14 ` Jens Axboe
2005-05-30 11:31 ` Jens Axboe
7 siblings, 1 reply; 12+ messages in thread
From: Jens Axboe @ 2005-05-29 19:14 UTC (permalink / raw)
To: Tejun Heo; +Cc: James.Bottomley, bzolnier, jgarzik, linux-kernel
On Sun, May 29 2005, Tejun Heo wrote:
> Hello, guys.
>
> This patchset is reimplementation of QUEUE_ORDERED_FLUSH feature. It
> doens't update API docs yet. If it's determined that this patchset
> can go in, I'll regenerate this patchset with doc updates (sans the
> last debug message patch of course).
Awesome work, that's really the last step in getting the barrier code
fully unified and working with tags. I'll review your patchset tomorrow.
--
Jens Axboe
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation
2005-05-29 19:14 ` Jens Axboe
@ 2005-05-30 11:31 ` Jens Axboe
2005-05-30 19:38 ` Tejun Heo
0 siblings, 1 reply; 12+ messages in thread
From: Jens Axboe @ 2005-05-30 11:31 UTC (permalink / raw)
To: Tejun Heo; +Cc: James.Bottomley, bzolnier, jgarzik, linux-kernel
On Sun, May 29 2005, Jens Axboe wrote:
> On Sun, May 29 2005, Tejun Heo wrote:
> > Hello, guys.
> >
> > This patchset is reimplementation of QUEUE_ORDERED_FLUSH feature. It
> > doens't update API docs yet. If it's determined that this patchset
> > can go in, I'll regenerate this patchset with doc updates (sans the
> > last debug message patch of course).
>
> Awesome work, that's really the last step in getting the barrier code
> fully unified and working with tags. I'll review your patchset tomorrow.
Patches look nice, this is a good step forward. If you feel like doing a
little more work in this area, I would very much like to add
QUEUE_ORDERED_FUA as a third method for implementing barriers. Basically
it would use the FUA commands to put data safely on disk, instead of
using the post flushes.
For NCQ, we have a FUA bit in the FPDMA commands. For non-ncq, we have
the various WRITE_DMA_EXT_FUA (and similar). It would be identical to
ORDERED_FLUSH in that we let the queue drain, issue a pre-flush, and
then a write with FUA set. It would eliminate the need to issue an extra
flush at the end, cutting down the required commands for writing a
barrier from 3 to 2.
--
Jens Axboe
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH Linux 2.6.12-rc5-mm1 00/06] blk: barrier flushing reimplementation
2005-05-30 11:31 ` Jens Axboe
@ 2005-05-30 19:38 ` Tejun Heo
0 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2005-05-30 19:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: James.Bottomley, bzolnier, jgarzik, linux-kernel
Jens Axboe wrote:
> On Sun, May 29 2005, Jens Axboe wrote:
>
>>On Sun, May 29 2005, Tejun Heo wrote:
>>
>>> Hello, guys.
>>>
>>> This patchset is reimplementation of QUEUE_ORDERED_FLUSH feature. It
>>>doens't update API docs yet. If it's determined that this patchset
>>>can go in, I'll regenerate this patchset with doc updates (sans the
>>>last debug message patch of course).
>>
>>Awesome work, that's really the last step in getting the barrier code
>>fully unified and working with tags. I'll review your patchset tomorrow.
>
>
> Patches look nice, this is a good step forward. If you feel like doing a
> little more work in this area, I would very much like to add
> QUEUE_ORDERED_FUA as a third method for implementing barriers. Basically
> it would use the FUA commands to put data safely on disk, instead of
> using the post flushes.
>
> For NCQ, we have a FUA bit in the FPDMA commands. For non-ncq, we have
> the various WRITE_DMA_EXT_FUA (and similar). It would be identical to
> ORDERED_FLUSH in that we let the queue drain, issue a pre-flush, and
> then a write with FUA set. It would eliminate the need to issue an extra
> flush at the end, cutting down the required commands for writing a
> barrier from 3 to 2.
>
Hi, Jens.
I'm on it.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 12+ messages in thread