forked from Minki/linux
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: block: don't delay blk_run_queue_async scsi: remove performance regression due to async queue run blk-throttle: Use task_subsys_state() to determine a task's blkio_cgroup block: rescan partitions on invalidated devices on -ENOMEDIA too cdrom: always check_disk_change() on open block: unexport DISK_EVENT_MEDIA_CHANGE for legacy/fringe drivers
This commit is contained in:
commit
a2b9c1f620
@ -114,6 +114,13 @@ struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cgroup_to_blkio_cgroup);
|
||||
|
||||
struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk)
|
||||
{
|
||||
return container_of(task_subsys_state(tsk, blkio_subsys_id),
|
||||
struct blkio_cgroup, css);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(task_blkio_cgroup);
|
||||
|
||||
static inline void
|
||||
blkio_update_group_weight(struct blkio_group *blkg, unsigned int weight)
|
||||
{
|
||||
|
@ -291,6 +291,7 @@ static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg) {}
|
||||
#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
|
||||
extern struct blkio_cgroup blkio_root_cgroup;
|
||||
extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
|
||||
extern struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk);
|
||||
extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
|
||||
struct blkio_group *blkg, void *key, dev_t dev,
|
||||
enum blkio_policy_id plid);
|
||||
@ -314,6 +315,8 @@ void blkiocg_update_io_remove_stats(struct blkio_group *blkg,
|
||||
struct cgroup;
|
||||
static inline struct blkio_cgroup *
|
||||
cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; }
|
||||
static inline struct blkio_cgroup *
|
||||
task_blkio_cgroup(struct task_struct *tsk) { return NULL; }
|
||||
|
||||
static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
|
||||
struct blkio_group *blkg, void *key, dev_t dev,
|
||||
|
@ -316,8 +316,10 @@ EXPORT_SYMBOL(__blk_run_queue);
|
||||
*/
|
||||
void blk_run_queue_async(struct request_queue *q)
|
||||
{
|
||||
if (likely(!blk_queue_stopped(q)))
|
||||
if (likely(!blk_queue_stopped(q))) {
|
||||
__cancel_delayed_work(&q->delay_work);
|
||||
queue_delayed_work(kblockd_workqueue, &q->delay_work, 0);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(blk_run_queue_async);
|
||||
|
||||
|
@ -160,9 +160,8 @@ static void throtl_put_tg(struct throtl_grp *tg)
|
||||
}
|
||||
|
||||
static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td,
|
||||
struct cgroup *cgroup)
|
||||
struct blkio_cgroup *blkcg)
|
||||
{
|
||||
struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
|
||||
struct throtl_grp *tg = NULL;
|
||||
void *key = td;
|
||||
struct backing_dev_info *bdi = &td->queue->backing_dev_info;
|
||||
@ -229,12 +228,12 @@ done:
|
||||
|
||||
static struct throtl_grp * throtl_get_tg(struct throtl_data *td)
|
||||
{
|
||||
struct cgroup *cgroup;
|
||||
struct throtl_grp *tg = NULL;
|
||||
struct blkio_cgroup *blkcg;
|
||||
|
||||
rcu_read_lock();
|
||||
cgroup = task_cgroup(current, blkio_subsys_id);
|
||||
tg = throtl_find_alloc_tg(td, cgroup);
|
||||
blkcg = task_blkio_cgroup(current);
|
||||
tg = throtl_find_alloc_tg(td, blkcg);
|
||||
if (!tg)
|
||||
tg = &td->root_tg;
|
||||
rcu_read_unlock();
|
||||
|
@ -1014,10 +1014,9 @@ void cfq_update_blkio_group_weight(void *key, struct blkio_group *blkg,
|
||||
cfqg->needs_update = true;
|
||||
}
|
||||
|
||||
static struct cfq_group *
|
||||
cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
|
||||
static struct cfq_group * cfq_find_alloc_cfqg(struct cfq_data *cfqd,
|
||||
struct blkio_cgroup *blkcg, int create)
|
||||
{
|
||||
struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
|
||||
struct cfq_group *cfqg = NULL;
|
||||
void *key = cfqd;
|
||||
int i, j;
|
||||
@ -1079,12 +1078,12 @@ done:
|
||||
*/
|
||||
static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
|
||||
{
|
||||
struct cgroup *cgroup;
|
||||
struct blkio_cgroup *blkcg;
|
||||
struct cfq_group *cfqg = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
cgroup = task_cgroup(current, blkio_subsys_id);
|
||||
cfqg = cfq_find_alloc_cfqg(cfqd, cgroup, create);
|
||||
blkcg = task_blkio_cgroup(current);
|
||||
cfqg = cfq_find_alloc_cfqg(cfqd, blkcg, create);
|
||||
if (!cfqg && create)
|
||||
cfqg = &cfqd->root_group;
|
||||
rcu_read_unlock();
|
||||
|
@ -2547,7 +2547,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
|
||||
disk->major = MajorNumber;
|
||||
disk->first_minor = n << DAC960_MaxPartitionsBits;
|
||||
disk->fops = &DAC960_BlockDeviceOperations;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
}
|
||||
/*
|
||||
Indicate the Block Device Registration completed successfully,
|
||||
|
@ -1736,7 +1736,6 @@ static int __init fd_probe_drives(void)
|
||||
disk->major = FLOPPY_MAJOR;
|
||||
disk->first_minor = drive;
|
||||
disk->fops = &floppy_fops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
sprintf(disk->disk_name, "fd%d", drive);
|
||||
disk->private_data = &unit[drive];
|
||||
set_capacity(disk, 880*2);
|
||||
|
@ -1964,7 +1964,6 @@ static int __init atari_floppy_init (void)
|
||||
unit[i].disk->first_minor = i;
|
||||
sprintf(unit[i].disk->disk_name, "fd%d", i);
|
||||
unit[i].disk->fops = &floppy_fops;
|
||||
unit[i].disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
unit[i].disk->private_data = &unit[i];
|
||||
unit[i].disk->queue = blk_init_queue(do_fd_request,
|
||||
&ataflop_lock);
|
||||
|
@ -4205,7 +4205,6 @@ static int __init floppy_init(void)
|
||||
disks[dr]->major = FLOPPY_MAJOR;
|
||||
disks[dr]->first_minor = TOMINOR(dr);
|
||||
disks[dr]->fops = &floppy_fops;
|
||||
disks[dr]->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
sprintf(disks[dr]->disk_name, "fd%d", dr);
|
||||
|
||||
init_timer(&motor_off_timer[dr]);
|
||||
|
@ -320,7 +320,6 @@ static void pcd_init_units(void)
|
||||
disk->first_minor = unit;
|
||||
strcpy(disk->disk_name, cd->name); /* umm... */
|
||||
disk->fops = &pcd_bdops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -837,7 +837,6 @@ static void pd_probe_drive(struct pd_unit *disk)
|
||||
p->fops = &pd_fops;
|
||||
p->major = major;
|
||||
p->first_minor = (disk - pd) << PD_BITS;
|
||||
p->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
disk->gd = p;
|
||||
p->private_data = disk;
|
||||
p->queue = pd_queue;
|
||||
|
@ -294,7 +294,6 @@ static void __init pf_init_units(void)
|
||||
disk->first_minor = unit;
|
||||
strcpy(disk->disk_name, pf->name);
|
||||
disk->fops = &pf_fops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
if (!(*drives[unit])[D_PRT])
|
||||
pf_drive_count++;
|
||||
}
|
||||
|
@ -858,7 +858,6 @@ static int __devinit swim_floppy_init(struct swim_priv *swd)
|
||||
swd->unit[drive].disk->first_minor = drive;
|
||||
sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
|
||||
swd->unit[drive].disk->fops = &floppy_fops;
|
||||
swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
swd->unit[drive].disk->private_data = &swd->unit[drive];
|
||||
swd->unit[drive].disk->queue = swd->queue;
|
||||
set_capacity(swd->unit[drive].disk, 2880);
|
||||
|
@ -1163,7 +1163,6 @@ static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device
|
||||
disk->major = FLOPPY_MAJOR;
|
||||
disk->first_minor = i;
|
||||
disk->fops = &floppy_fops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
disk->private_data = &floppy_states[i];
|
||||
disk->queue = swim3_queue;
|
||||
disk->flags |= GENHD_FL_REMOVABLE;
|
||||
|
@ -2334,7 +2334,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
|
||||
disk->major = UB_MAJOR;
|
||||
disk->first_minor = lun->id * UB_PARTS_PER_LUN;
|
||||
disk->fops = &ub_bd_fops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
disk->private_data = lun;
|
||||
disk->driverfs_dev = &sc->intf->dev;
|
||||
|
||||
|
@ -1005,7 +1005,6 @@ static int __devinit ace_setup(struct ace_device *ace)
|
||||
ace->gd->major = ace_major;
|
||||
ace->gd->first_minor = ace->id * ACE_NUM_MINORS;
|
||||
ace->gd->fops = &ace_fops;
|
||||
ace->gd->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
ace->gd->queue = ace->queue;
|
||||
ace->gd->private_data = ace;
|
||||
snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a');
|
||||
|
@ -986,6 +986,9 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t
|
||||
|
||||
cdinfo(CD_OPEN, "entering cdrom_open\n");
|
||||
|
||||
/* open is event synchronization point, check events first */
|
||||
check_disk_change(bdev);
|
||||
|
||||
/* if this was a O_NONBLOCK open and we should honor the flags,
|
||||
* do a quick open without drive/disc integrity checks. */
|
||||
cdi->use_count++;
|
||||
@ -1012,9 +1015,6 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t
|
||||
|
||||
cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n",
|
||||
cdi->name, cdi->use_count);
|
||||
/* Do this on open. Don't wait for mount, because they might
|
||||
not be mounting, but opening with O_NONBLOCK */
|
||||
check_disk_change(bdev);
|
||||
return 0;
|
||||
err_release:
|
||||
if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
|
||||
|
@ -803,7 +803,6 @@ static int __devinit probe_gdrom(struct platform_device *devptr)
|
||||
goto probe_fail_cdrom_register;
|
||||
}
|
||||
gd.disk->fops = &gdrom_bdops;
|
||||
gd.disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
/* latch on to the interrupt */
|
||||
err = gdrom_set_interrupt_handlers();
|
||||
if (err)
|
||||
|
@ -626,7 +626,6 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
|
||||
gendisk->queue = q;
|
||||
gendisk->fops = &viocd_fops;
|
||||
gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE;
|
||||
gendisk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
set_capacity(gendisk, 0);
|
||||
gendisk->private_data = d;
|
||||
d->viocd_disk = gendisk;
|
||||
|
@ -1000,7 +1000,6 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
|
||||
gd->major = I2O_MAJOR;
|
||||
gd->queue = queue;
|
||||
gd->fops = &i2o_block_fops;
|
||||
gd->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
gd->private_data = dev;
|
||||
|
||||
dev->gd = gd;
|
||||
|
@ -236,7 +236,6 @@ tapeblock_setup_device(struct tape_device * device)
|
||||
disk->major = tapeblock_major;
|
||||
disk->first_minor = device->first_minor;
|
||||
disk->fops = &tapeblock_fops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
disk->private_data = tape_get_device(device);
|
||||
disk->queue = blkdat->request_queue;
|
||||
set_capacity(disk, 0);
|
||||
|
@ -74,8 +74,6 @@ struct kmem_cache *scsi_sdb_cache;
|
||||
*/
|
||||
#define SCSI_QUEUE_DELAY 3
|
||||
|
||||
static void scsi_run_queue(struct request_queue *q);
|
||||
|
||||
/*
|
||||
* Function: scsi_unprep_request()
|
||||
*
|
||||
@ -161,7 +159,7 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
|
||||
blk_requeue_request(q, cmd->request);
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
||||
scsi_run_queue(q);
|
||||
kblockd_schedule_work(q, &device->requeue_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -438,7 +436,11 @@ static void scsi_run_queue(struct request_queue *q)
|
||||
continue;
|
||||
}
|
||||
|
||||
blk_run_queue_async(sdev->request_queue);
|
||||
spin_unlock(shost->host_lock);
|
||||
spin_lock(sdev->request_queue->queue_lock);
|
||||
__blk_run_queue(sdev->request_queue);
|
||||
spin_unlock(sdev->request_queue->queue_lock);
|
||||
spin_lock(shost->host_lock);
|
||||
}
|
||||
/* put any unprocessed entries back */
|
||||
list_splice(&starved_list, &shost->starved_list);
|
||||
@ -447,6 +449,16 @@ static void scsi_run_queue(struct request_queue *q)
|
||||
blk_run_queue(q);
|
||||
}
|
||||
|
||||
void scsi_requeue_run_queue(struct work_struct *work)
|
||||
{
|
||||
struct scsi_device *sdev;
|
||||
struct request_queue *q;
|
||||
|
||||
sdev = container_of(work, struct scsi_device, requeue_work);
|
||||
q = sdev->request_queue;
|
||||
scsi_run_queue(q);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: scsi_requeue_command()
|
||||
*
|
||||
|
@ -242,6 +242,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
|
||||
int display_failure_msg = 1, ret;
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
extern void scsi_evt_thread(struct work_struct *work);
|
||||
extern void scsi_requeue_run_queue(struct work_struct *work);
|
||||
|
||||
sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size,
|
||||
GFP_ATOMIC);
|
||||
@ -264,6 +265,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
|
||||
INIT_LIST_HEAD(&sdev->event_list);
|
||||
spin_lock_init(&sdev->list_lock);
|
||||
INIT_WORK(&sdev->event_work, scsi_evt_thread);
|
||||
INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue);
|
||||
|
||||
sdev->sdev_gendev.parent = get_device(&starget->dev);
|
||||
sdev->sdev_target = starget;
|
||||
|
@ -1102,6 +1102,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
||||
if (!bdev->bd_part)
|
||||
goto out_clear;
|
||||
|
||||
ret = 0;
|
||||
if (disk->fops->open) {
|
||||
ret = disk->fops->open(bdev, mode);
|
||||
if (ret == -ERESTARTSYS) {
|
||||
@ -1118,9 +1119,18 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
||||
put_disk(disk);
|
||||
goto restart;
|
||||
}
|
||||
if (ret)
|
||||
goto out_clear;
|
||||
}
|
||||
/*
|
||||
* If the device is invalidated, rescan partition
|
||||
* if open succeeded or failed with -ENOMEDIUM.
|
||||
* The latter is necessary to prevent ghost
|
||||
* partitions on a removed medium.
|
||||
*/
|
||||
if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
|
||||
rescan_partitions(disk, bdev);
|
||||
if (ret)
|
||||
goto out_clear;
|
||||
|
||||
if (!bdev->bd_openers) {
|
||||
bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
|
||||
bdi = blk_get_backing_dev_info(bdev);
|
||||
@ -1128,8 +1138,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
||||
bdi = &default_backing_dev_info;
|
||||
bdev_inode_switch_bdi(bdev->bd_inode, bdi);
|
||||
}
|
||||
if (bdev->bd_invalidated)
|
||||
rescan_partitions(disk, bdev);
|
||||
} else {
|
||||
struct block_device *whole;
|
||||
whole = bdget_disk(disk, 0);
|
||||
@ -1153,13 +1161,14 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
||||
}
|
||||
} else {
|
||||
if (bdev->bd_contains == bdev) {
|
||||
if (bdev->bd_disk->fops->open) {
|
||||
ret = 0;
|
||||
if (bdev->bd_disk->fops->open)
|
||||
ret = bdev->bd_disk->fops->open(bdev, mode);
|
||||
if (ret)
|
||||
goto out_unlock_bdev;
|
||||
}
|
||||
if (bdev->bd_invalidated)
|
||||
/* the same as first opener case, read comment there */
|
||||
if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
|
||||
rescan_partitions(bdev->bd_disk, bdev);
|
||||
if (ret)
|
||||
goto out_unlock_bdev;
|
||||
}
|
||||
/* only one opener holds refs to the module and disk */
|
||||
module_put(disk->fops->owner);
|
||||
|
@ -169,6 +169,7 @@ struct scsi_device {
|
||||
sdev_dev;
|
||||
|
||||
struct execute_work ew; /* used to get process context on put */
|
||||
struct work_struct requeue_work;
|
||||
|
||||
struct scsi_dh_data *scsi_dh_data;
|
||||
enum scsi_device_state sdev_state;
|
||||
|
Loading…
Reference in New Issue
Block a user