From e18e923a3cbae899248430b52fc761ce6e7f6ef0 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 7 Mar 2005 17:49:17 -0800 Subject: [PATCH] rework core barrier support This reworks the core barrier support to be a lot nicer, so that all the nasty code resides outside of drivers/ide. It requires minimal changes to support in a driver, I've added SCSI support as an example. The ide code is adapted to the new code. With this patch, we support full barriers on sata now. Bart has acked the addition to -mm, I would like for this to be submitted as soon as 2.6.12 opens. Signed-off-by: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/blkdev.h | 24 ++++++++++++++++++++++-- include/linux/ide.h | 2 +- include/scsi/scsi_driver.h | 2 ++ include/scsi/scsi_host.h | 12 ++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c7553066b917..83eef4fde873 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -275,6 +275,8 @@ struct bio_vec; typedef int (merge_bvec_fn) (request_queue_t *, struct bio *, struct bio_vec *); 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, @@ -318,6 +320,8 @@ struct request_queue merge_bvec_fn *merge_bvec_fn; 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 @@ -389,6 +393,18 @@ struct request_queue unsigned int sg_reserved_size; struct list_head drain_list; + + /* + * reserved for flush operations + */ + struct request *flush_rq; + unsigned char ordered; +}; + +enum { + QUEUE_ORDERED_NONE, + QUEUE_ORDERED_TAG, + QUEUE_ORDERED_FLUSH, }; #define RQ_INACTIVE (-1) @@ -405,12 +421,13 @@ struct request_queue #define QUEUE_FLAG_DEAD 5 /* queue being torn down */ #define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */ #define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */ -#define QUEUE_FLAG_ORDERED 8 /* supports ordered writes */ -#define QUEUE_FLAG_DRAIN 9 /* draining queue for sched switch */ +#define QUEUE_FLAG_DRAIN 8 /* draining queue for sched switch */ +#define QUEUE_FLAG_FLUSH 9 /* doing barrier flush sequence */ #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_fs_request(rq) ((rq)->flags & REQ_CMD) #define blk_pc_request(rq) ((rq)->flags & REQ_BLOCK_PC) @@ -611,6 +628,9 @@ extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bd extern void blk_queue_ordered(request_queue_t *, int); extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *); extern int blkdev_scsi_issue_flush_fn(request_queue_t *, struct gendisk *, sector_t *); +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_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *); extern void blk_dump_rq_flags(struct request *, char *); diff --git a/include/linux/ide.h b/include/linux/ide.h index 28f35bc8ba7e..9c25adc6c28d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -740,7 +740,6 @@ typedef struct ide_drive_s { u8 sect; /* "real" sectors per track */ u8 bios_head; /* BIOS/fdisk/LILO number of heads */ u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */ - u8 doing_barrier; /* state, 1=currently doing flush */ unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned int cyl; /* "real" number of cyls */ @@ -1130,6 +1129,7 @@ extern ide_hwif_t ide_hwifs[]; /* master data repository */ extern int noautodma; extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); +extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs); /* * This is used on exit from the driver to designate the next irq handler diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 98c2e33f6159..850dfa877fda 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -14,6 +14,8 @@ struct scsi_driver { int (*init_command)(struct scsi_cmnd *); 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) diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 191b8fced8ac..1d3e91542fa9 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -362,6 +362,12 @@ struct scsi_host_template { */ unsigned skip_settle_delay:1; + /* + * ordered write support + */ + unsigned ordered_flush:1; + unsigned ordered_tag:1; + /* * Countdown for host blocking with no commands outstanding */ @@ -501,6 +507,12 @@ struct Scsi_Host { */ unsigned reverse_ordering:1; + /* + * ordered write support + */ + unsigned ordered_flush:1; + unsigned ordered_tag:1; + /* * Host has rejected a command because it was busy. */ -- cgit v1.2.3