Skip to content

Commit

Permalink
[BLOCK] update SCSI to use new blk_ordered for barriers
Browse files Browse the repository at this point in the history
All ordered request related stuff delegated to HLD.  Midlayer
now doens't deal with ordered setting or prepare_flush
callback.  sd.c updated to deal with blk_queue_ordered
setting.  Currently, ordered tag isn't used as SCSI midlayer
cannot guarantee request ordering.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jens Axboe <axboe@suse.de>
  • Loading branch information
Tejun Heo authored and Jens Axboe committed Jan 6, 2006
1 parent 797e7db commit 461d4e9
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 95 deletions.
9 changes: 0 additions & 9 deletions drivers/scsi/hosts.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,17 +347,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
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
Expand Down
46 changes: 0 additions & 46 deletions drivers/scsi/scsi_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -932,9 +932,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
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
Expand Down Expand Up @@ -1199,38 +1196,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
return BLKPREP_KILL;
}

static int scsi_prepare_flush_fn(request_queue_t *q, struct request *rq)
{
struct scsi_device *sdev = q->queuedata;
struct scsi_driver *drv;

if (sdev->sdev_state == SDEV_RUNNING) {
drv = *(struct scsi_driver **) rq->rq_disk->private_data;

if (drv->prepare_flush)
return drv->prepare_flush(q, rq);
}

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)
{
Expand Down Expand Up @@ -1703,17 +1668,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
blk_queue_segment_boundary(q, shost->dma_boundary);
blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);

/*
* ordered tags are superior to flush ordering
*/
if (shost->ordered_tag)
blk_queue_ordered(q, QUEUE_ORDERED_TAG);
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)
clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
return q;
Expand Down
58 changes: 20 additions & 38 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ static void sd_shutdown(struct device *dev);
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_prepare_flush(request_queue_t *, struct request *);
static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
unsigned char *buffer);

Expand All @@ -137,8 +136,6 @@ static struct scsi_driver sd_template = {
.rescan = sd_rescan,
.init_command = sd_init_command,
.issue_flush = sd_issue_flush,
.prepare_flush = sd_prepare_flush,
.end_flush = sd_end_flush,
};

/*
Expand Down Expand Up @@ -729,42 +726,13 @@ static int sd_issue_flush(struct device *dev, sector_t *error_sector)
return ret;
}

static void sd_end_flush(request_queue_t *q, struct request *flush_rq)
static void sd_prepare_flush(request_queue_t *q, struct request *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;
struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev);

if (!sdkp || !sdkp->WCE)
return 0;

memset(rq->cmd, 0, sizeof(rq->cmd));
rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
rq->flags |= REQ_BLOCK_PC;
rq->timeout = SD_TIMEOUT;
rq->cmd[0] = SYNCHRONIZE_CACHE;
return 1;
rq->cmd_len = 10;
}

static void sd_rescan(struct device *dev)
Expand Down Expand Up @@ -1462,6 +1430,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device;
unsigned char *buffer;
unsigned ordered;

SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));

Expand Down Expand Up @@ -1498,7 +1467,20 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_write_protect_flag(sdkp, disk->disk_name, buffer);
sd_read_cache_type(sdkp, disk->disk_name, buffer);
}


/*
* We now have all cache related info, determine how we deal
* with ordered requests. Note that as the current SCSI
* dispatch function can alter request order, we cannot use
* QUEUE_ORDERED_TAG_* even when ordered tag is supported.
*/
if (sdkp->WCE)
ordered = QUEUE_ORDERED_DRAIN_FLUSH;
else
ordered = QUEUE_ORDERED_DRAIN;

blk_queue_ordered(sdkp->disk->queue, ordered, sd_prepare_flush);

set_capacity(disk, sdkp->capacity);
kfree(buffer);

Expand Down Expand Up @@ -1598,14 +1580,14 @@ static int sd_probe(struct device *dev)
strcpy(gd->devfs_name, sdp->devfs_name);

gd->private_data = &sdkp->driver;
gd->queue = sdkp->device->request_queue;

sd_revalidate_disk(gd);

gd->driverfs_dev = &sdp->sdev_gendev;
gd->flags = GENHD_FL_DRIVERFS;
if (sdp->removable)
gd->flags |= GENHD_FL_REMOVABLE;
gd->queue = sdkp->device->request_queue;

dev_set_drvdata(dev, sdkp);
add_disk(gd);
Expand Down
1 change: 0 additions & 1 deletion include/scsi/scsi_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion include/scsi/scsi_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ struct scsi_host_template {
/*
* ordered write support
*/
unsigned ordered_flush:1;
unsigned ordered_tag:1;

/*
Expand Down

0 comments on commit 461d4e9

Please sign in to comment.