diff options
| author | Jens Axboe <axboe@suse.de> | 2005-03-07 17:49:17 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-03-07 17:49:17 -0800 |
| commit | e18e923a3cbae899248430b52fc761ce6e7f6ef0 (patch) | |
| tree | 75c120e08902c756a4866ed9e0492739b3b701ea /include | |
| parent | e8be9091faa43e75879ec238d0171b6f3484d61c (diff) | |
[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 <axboe@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/blkdev.h | 24 | ||||
| -rw-r--r-- | include/linux/ide.h | 2 | ||||
| -rw-r--r-- | include/scsi/scsi_driver.h | 2 | ||||
| -rw-r--r-- | include/scsi/scsi_host.h | 12 |
4 files changed, 37 insertions, 3 deletions
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 @@ -363,6 +363,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 */ unsigned int max_host_blocked; @@ -502,6 +508,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. */ unsigned int host_blocked; |
