Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block driver update from Jens Axboe:
 "Distilled down variant, the rest will pass over to 3.8.  I pulled it
  into the for-linus branch I had waiting for a pull request as well, in
  case you are wondering why there are new entries in here too.  This
  also got rid of two reverts and the ones of the mtip32xx patches that
  went in later in the 3.6 cycle, so the series looks a bit cleaner."

* 'for-linus' of git://git.kernel.dk/linux-block:
  loop: Make explicit loop device destruction lazy
  mtip32xx:Added appropriate timeout value for secure erase
  xen/blkback: Change xen_vbd's flush_support and discard_secure to have type unsigned int, rather than bool
  cciss: select CONFIG_CHECK_SIGNATURE
  cciss: remove unneeded memset()
  xen/blkback: use kmem_cache_zalloc instead of kmem_cache_alloc/memset
  pktcdvd: update MAINTAINERS
  floppy: remove dr, reuse drive on do_floppy_init
  floppy: use common function to check if floppies can be registered
  floppy: properly handle failure on add_disk loop
  floppy: do put_disk on current dr if blk_init_queue fails
  floppy: don't call alloc_ordered_workqueue inside the alloc_disk loop
  xen/blkback: Fix compile warning
  block: Add blk_rq_pos(rq) to sort rq when plushing
  drivers/block: remove CONFIG_EXPERIMENTAL
  block: remove CONFIG_EXPERIMENTAL
  vfs: fix: don't increase bio_slab_max if krealloc() fails
  blkcg: stop iteration early if root_rl is the only request list
  blkcg: Fix use-after-free of q->root_blkg and q->root_rl.blkg
This commit is contained in:
Linus Torvalds 2012-10-30 15:34:09 -07:00
commit 4476c0eead
13 changed files with 113 additions and 68 deletions

View File

@ -5647,7 +5647,7 @@ S: Maintained
F: drivers/pinctrl/spear/ F: drivers/pinctrl/spear/
PKTCDVD DRIVER PKTCDVD DRIVER
M: Peter Osterlund <petero2@telia.com> M: Jiri Kosina <jkosina@suse.cz>
S: Maintained S: Maintained
F: drivers/block/pktcdvd.c F: drivers/block/pktcdvd.c
F: include/linux/pktcdvd.h F: include/linux/pktcdvd.h

View File

@ -89,7 +89,7 @@ config BLK_DEV_INTEGRITY
config BLK_DEV_THROTTLING config BLK_DEV_THROTTLING
bool "Block layer bio throttling support" bool "Block layer bio throttling support"
depends on BLK_CGROUP=y && EXPERIMENTAL depends on BLK_CGROUP=y
default n default n
---help--- ---help---
Block layer bio throttling support. It can be used to limit Block layer bio throttling support. It can be used to limit

View File

@ -285,6 +285,13 @@ static void blkg_destroy_all(struct request_queue *q)
blkg_destroy(blkg); blkg_destroy(blkg);
spin_unlock(&blkcg->lock); spin_unlock(&blkcg->lock);
} }
/*
* root blkg is destroyed. Just clear the pointer since
* root_rl does not take reference on root blkg.
*/
q->root_blkg = NULL;
q->root_rl.blkg = NULL;
} }
static void blkg_rcu_free(struct rcu_head *rcu_head) static void blkg_rcu_free(struct rcu_head *rcu_head)
@ -326,6 +333,9 @@ struct request_list *__blk_queue_next_rl(struct request_list *rl,
*/ */
if (rl == &q->root_rl) { if (rl == &q->root_rl) {
ent = &q->blkg_list; ent = &q->blkg_list;
/* There are no more block groups, hence no request lists */
if (list_empty(ent))
return NULL;
} else { } else {
blkg = container_of(rl, struct blkcg_gq, rl); blkg = container_of(rl, struct blkcg_gq, rl);
ent = &blkg->q_node; ent = &blkg->q_node;

View File

@ -2868,7 +2868,8 @@ static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b)
struct request *rqa = container_of(a, struct request, queuelist); struct request *rqa = container_of(a, struct request, queuelist);
struct request *rqb = container_of(b, struct request, queuelist); struct request *rqb = container_of(b, struct request, queuelist);
return !(rqa->q <= rqb->q); return !(rqa->q < rqb->q ||
(rqa->q == rqb->q && blk_rq_pos(rqa) < blk_rq_pos(rqb)));
} }
/* /*

View File

@ -131,6 +131,7 @@ config BLK_CPQ_DA
config BLK_CPQ_CISS_DA config BLK_CPQ_CISS_DA
tristate "Compaq Smart Array 5xxx support" tristate "Compaq Smart Array 5xxx support"
depends on PCI depends on PCI
select CHECK_SIGNATURE
help help
This is the driver for Compaq Smart Array 5xxx controllers. This is the driver for Compaq Smart Array 5xxx controllers.
Everyone using these boards should say Y here. Everyone using these boards should say Y here.
@ -166,8 +167,8 @@ config BLK_DEV_DAC960
module will be called DAC960. module will be called DAC960.
config BLK_DEV_UMEM config BLK_DEV_UMEM
tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)" tristate "Micro Memory MM5415 Battery Backed RAM support"
depends on PCI && EXPERIMENTAL depends on PCI
---help--- ---help---
Saying Y here will include support for the MM5415 family of Saying Y here will include support for the MM5415 family of
battery backed (Non-volatile) RAM cards. battery backed (Non-volatile) RAM cards.
@ -430,8 +431,8 @@ config CDROM_PKTCDVD_BUFFERS
a disc is opened for writing. a disc is opened for writing.
config CDROM_PKTCDVD_WCACHE config CDROM_PKTCDVD_WCACHE
bool "Enable write caching (EXPERIMENTAL)" bool "Enable write caching"
depends on CDROM_PKTCDVD && EXPERIMENTAL depends on CDROM_PKTCDVD
help help
If enabled, write caching will be set for the CD-R/W device. For now If enabled, write caching will be set for the CD-R/W device. For now
this option is dangerous unless the CD-RW media is known good, as we this option is dangerous unless the CD-RW media is known good, as we
@ -508,8 +509,8 @@ config XEN_BLKDEV_BACKEND
config VIRTIO_BLK config VIRTIO_BLK
tristate "Virtio block driver (EXPERIMENTAL)" tristate "Virtio block driver"
depends on EXPERIMENTAL && VIRTIO depends on VIRTIO
---help--- ---help---
This is the virtual block driver for virtio. It can be used with This is the virtual block driver for virtio. It can be used with
lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
@ -528,7 +529,7 @@ config BLK_DEV_HD
config BLK_DEV_RBD config BLK_DEV_RBD
tristate "Rados block device (RBD)" tristate "Rados block device (RBD)"
depends on INET && EXPERIMENTAL && BLOCK depends on INET && BLOCK
select CEPH_LIB select CEPH_LIB
select LIBCRC32C select LIBCRC32C
select CRYPTO_AES select CRYPTO_AES

View File

@ -5205,7 +5205,6 @@ static void cciss_shutdown(struct pci_dev *pdev)
return; return;
} }
/* write all data in the battery backed cache to disk */ /* write all data in the battery backed cache to disk */
memset(flush_buf, 0, 4);
return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf,
4, 0, CTLR_LUNID, TYPE_CMD); 4, 0, CTLR_LUNID, TYPE_CMD);
kfree(flush_buf); kfree(flush_buf);

View File

@ -4109,12 +4109,19 @@ static struct platform_driver floppy_driver = {
static struct platform_device floppy_device[N_DRIVE]; static struct platform_device floppy_device[N_DRIVE];
static bool floppy_available(int drive)
{
if (!(allowed_drive_mask & (1 << drive)))
return false;
if (fdc_state[FDC(drive)].version == FDC_NONE)
return false;
return true;
}
static struct kobject *floppy_find(dev_t dev, int *part, void *data) static struct kobject *floppy_find(dev_t dev, int *part, void *data)
{ {
int drive = (*part & 3) | ((*part & 0x80) >> 5); int drive = (*part & 3) | ((*part & 0x80) >> 5);
if (drive >= N_DRIVE || if (drive >= N_DRIVE || !floppy_available(drive))
!(allowed_drive_mask & (1 << drive)) ||
fdc_state[FDC(drive)].version == FDC_NONE)
return NULL; return NULL;
if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
return NULL; return NULL;
@ -4124,8 +4131,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
static int __init do_floppy_init(void) static int __init do_floppy_init(void)
{ {
int i, unit, drive; int i, unit, drive, err;
int err, dr;
set_debugt(); set_debugt();
interruptjiffies = resultjiffies = jiffies; interruptjiffies = resultjiffies = jiffies;
@ -4137,34 +4143,32 @@ static int __init do_floppy_init(void)
raw_cmd = NULL; raw_cmd = NULL;
for (dr = 0; dr < N_DRIVE; dr++) { floppy_wq = alloc_ordered_workqueue("floppy", 0);
disks[dr] = alloc_disk(1); if (!floppy_wq)
if (!disks[dr]) { return -ENOMEM;
for (drive = 0; drive < N_DRIVE; drive++) {
disks[drive] = alloc_disk(1);
if (!disks[drive]) {
err = -ENOMEM; err = -ENOMEM;
goto out_put_disk; goto out_put_disk;
} }
floppy_wq = alloc_ordered_workqueue("floppy", 0); disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock);
if (!floppy_wq) { if (!disks[drive]->queue) {
err = -ENOMEM; err = -ENOMEM;
goto out_put_disk; goto out_put_disk;
} }
disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); blk_queue_max_hw_sectors(disks[drive]->queue, 64);
if (!disks[dr]->queue) { disks[drive]->major = FLOPPY_MAJOR;
err = -ENOMEM; disks[drive]->first_minor = TOMINOR(drive);
goto out_destroy_workq; disks[drive]->fops = &floppy_fops;
} sprintf(disks[drive]->disk_name, "fd%d", drive);
blk_queue_max_hw_sectors(disks[dr]->queue, 64); init_timer(&motor_off_timer[drive]);
disks[dr]->major = FLOPPY_MAJOR; motor_off_timer[drive].data = drive;
disks[dr]->first_minor = TOMINOR(dr); motor_off_timer[drive].function = motor_off_callback;
disks[dr]->fops = &floppy_fops;
sprintf(disks[dr]->disk_name, "fd%d", dr);
init_timer(&motor_off_timer[dr]);
motor_off_timer[dr].data = dr;
motor_off_timer[dr].function = motor_off_callback;
} }
err = register_blkdev(FLOPPY_MAJOR, "fd"); err = register_blkdev(FLOPPY_MAJOR, "fd");
@ -4282,9 +4286,7 @@ static int __init do_floppy_init(void)
} }
for (drive = 0; drive < N_DRIVE; drive++) { for (drive = 0; drive < N_DRIVE; drive++) {
if (!(allowed_drive_mask & (1 << drive))) if (!floppy_available(drive))
continue;
if (fdc_state[FDC(drive)].version == FDC_NONE)
continue; continue;
floppy_device[drive].name = floppy_device_name; floppy_device[drive].name = floppy_device_name;
@ -4293,7 +4295,7 @@ static int __init do_floppy_init(void)
err = platform_device_register(&floppy_device[drive]); err = platform_device_register(&floppy_device[drive]);
if (err) if (err)
goto out_release_dma; goto out_remove_drives;
err = device_create_file(&floppy_device[drive].dev, err = device_create_file(&floppy_device[drive].dev,
&dev_attr_cmos); &dev_attr_cmos);
@ -4311,29 +4313,34 @@ static int __init do_floppy_init(void)
out_unreg_platform_dev: out_unreg_platform_dev:
platform_device_unregister(&floppy_device[drive]); platform_device_unregister(&floppy_device[drive]);
out_remove_drives:
while (drive--) {
if (floppy_available(drive)) {
del_gendisk(disks[drive]);
device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
platform_device_unregister(&floppy_device[drive]);
}
}
out_release_dma: out_release_dma:
if (atomic_read(&usage_count)) if (atomic_read(&usage_count))
floppy_release_irq_and_dma(); floppy_release_irq_and_dma();
out_unreg_region: out_unreg_region:
blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
platform_driver_unregister(&floppy_driver); platform_driver_unregister(&floppy_driver);
out_destroy_workq:
destroy_workqueue(floppy_wq);
out_unreg_blkdev: out_unreg_blkdev:
unregister_blkdev(FLOPPY_MAJOR, "fd"); unregister_blkdev(FLOPPY_MAJOR, "fd");
out_put_disk: out_put_disk:
while (dr--) { for (drive = 0; drive < N_DRIVE; drive++) {
del_timer_sync(&motor_off_timer[dr]); if (!disks[drive])
if (disks[dr]->queue) { break;
blk_cleanup_queue(disks[dr]->queue); if (disks[drive]->queue) {
/* del_timer_sync(&motor_off_timer[drive]);
* put_disk() is not paired with add_disk() and blk_cleanup_queue(disks[drive]->queue);
* will put queue reference one extra time. fix it. disks[drive]->queue = NULL;
*/
disks[dr]->queue = NULL;
} }
put_disk(disks[dr]); put_disk(disks[drive]);
} }
destroy_workqueue(floppy_wq);
return err; return err;
} }
@ -4551,8 +4558,7 @@ static void __exit floppy_module_exit(void)
for (drive = 0; drive < N_DRIVE; drive++) { for (drive = 0; drive < N_DRIVE; drive++) {
del_timer_sync(&motor_off_timer[drive]); del_timer_sync(&motor_off_timer[drive]);
if ((allowed_drive_mask & (1 << drive)) && if (floppy_available(drive)) {
fdc_state[FDC(drive)].version != FDC_NONE) {
del_gendisk(disks[drive]); del_gendisk(disks[drive]);
device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
platform_device_unregister(&floppy_device[drive]); platform_device_unregister(&floppy_device[drive]);

View File

@ -976,8 +976,21 @@ static int loop_clr_fd(struct loop_device *lo)
if (lo->lo_state != Lo_bound) if (lo->lo_state != Lo_bound)
return -ENXIO; return -ENXIO;
if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ /*
return -EBUSY; * If we've explicitly asked to tear down the loop device,
* and it has an elevated reference count, set it for auto-teardown when
* the last reference goes away. This stops $!~#$@ udev from
* preventing teardown because it decided that it needs to run blkid on
* the loopback device whenever they appear. xfstests is notorious for
* failing tests because blkid via udev races with a losetup
* <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d
* command to fail with EBUSY.
*/
if (lo->lo_refcnt > 1) {
lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
mutex_unlock(&lo->lo_ctl_mutex);
return 0;
}
if (filp == NULL) if (filp == NULL)
return -EINVAL; return -EINVAL;

View File

@ -2035,8 +2035,9 @@ static unsigned int implicit_sector(unsigned char command,
} }
return rv; return rv;
} }
static void mtip_set_timeout(struct driver_data *dd,
static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) struct host_to_dev_fis *fis,
unsigned int *timeout, u8 erasemode)
{ {
switch (fis->command) { switch (fis->command) {
case ATA_CMD_DOWNLOAD_MICRO: case ATA_CMD_DOWNLOAD_MICRO:
@ -2044,7 +2045,10 @@ static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout)
break; break;
case ATA_CMD_SEC_ERASE_UNIT: case ATA_CMD_SEC_ERASE_UNIT:
case 0xFC: case 0xFC:
*timeout = 240000; /* 4 minutes */ if (erasemode)
*timeout = ((*(dd->port->identify + 90) * 2) * 60000);
else
*timeout = ((*(dd->port->identify + 89) * 2) * 60000);
break; break;
case ATA_CMD_STANDBYNOW1: case ATA_CMD_STANDBYNOW1:
*timeout = 120000; /* 2 minutes */ *timeout = 120000; /* 2 minutes */
@ -2087,6 +2091,7 @@ static int exec_drive_taskfile(struct driver_data *dd,
unsigned int transfer_size; unsigned int transfer_size;
unsigned long task_file_data; unsigned long task_file_data;
int intotal = outtotal + req_task->out_size; int intotal = outtotal + req_task->out_size;
int erasemode = 0;
taskout = req_task->out_size; taskout = req_task->out_size;
taskin = req_task->in_size; taskin = req_task->in_size;
@ -2212,7 +2217,13 @@ static int exec_drive_taskfile(struct driver_data *dd,
fis.lba_hi, fis.lba_hi,
fis.device); fis.device);
mtip_set_timeout(&fis, &timeout); /* check for erase mode support during secure erase.*/
if ((fis.command == ATA_CMD_SEC_ERASE_UNIT)
&& (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
erasemode = 1;
}
mtip_set_timeout(dd, &fis, &timeout, erasemode);
/* Determine the correct transfer size.*/ /* Determine the correct transfer size.*/
if (force_single_sector) if (force_single_sector)

View File

@ -33,6 +33,9 @@
/* offset of Device Control register in PCIe extended capabilites space */ /* offset of Device Control register in PCIe extended capabilites space */
#define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48
/* check for erase mode support during secure erase */
#define MTIP_SEC_ERASE_MODE 0x3
/* # of times to retry timed out/failed IOs */ /* # of times to retry timed out/failed IOs */
#define MTIP_MAX_RETRIES 2 #define MTIP_MAX_RETRIES 2

View File

@ -158,8 +158,8 @@ struct xen_vbd {
struct block_device *bdev; struct block_device *bdev;
/* Cached size parameter. */ /* Cached size parameter. */
sector_t size; sector_t size;
bool flush_support; unsigned int flush_support:1;
bool discard_secure; unsigned int discard_secure:1;
}; };
struct backend_info; struct backend_info;

View File

@ -105,11 +105,10 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
{ {
struct xen_blkif *blkif; struct xen_blkif *blkif;
blkif = kmem_cache_alloc(xen_blkif_cachep, GFP_KERNEL); blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL);
if (!blkif) if (!blkif)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
memset(blkif, 0, sizeof(*blkif));
blkif->domid = domid; blkif->domid = domid;
spin_lock_init(&blkif->blk_ring_lock); spin_lock_init(&blkif->blk_ring_lock);
atomic_set(&blkif->refcnt, 1); atomic_set(&blkif->refcnt, 1);
@ -196,7 +195,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif)
} }
} }
void xen_blkif_free(struct xen_blkif *blkif) static void xen_blkif_free(struct xen_blkif *blkif)
{ {
if (!atomic_dec_and_test(&blkif->refcnt)) if (!atomic_dec_and_test(&blkif->refcnt))
BUG(); BUG();
@ -257,7 +256,7 @@ static struct attribute_group xen_vbdstat_group = {
VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
VBD_SHOW(mode, "%s\n", be->mode); VBD_SHOW(mode, "%s\n", be->mode);
int xenvbd_sysfs_addif(struct xenbus_device *dev) static int xenvbd_sysfs_addif(struct xenbus_device *dev)
{ {
int error; int error;
@ -281,7 +280,7 @@ fail1: device_remove_file(&dev->dev, &dev_attr_physical_device);
return error; return error;
} }
void xenvbd_sysfs_delif(struct xenbus_device *dev) static void xenvbd_sysfs_delif(struct xenbus_device *dev)
{ {
sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group);
device_remove_file(&dev->dev, &dev_attr_mode); device_remove_file(&dev->dev, &dev_attr_mode);

View File

@ -75,6 +75,7 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)
unsigned int sz = sizeof(struct bio) + extra_size; unsigned int sz = sizeof(struct bio) + extra_size;
struct kmem_cache *slab = NULL; struct kmem_cache *slab = NULL;
struct bio_slab *bslab, *new_bio_slabs; struct bio_slab *bslab, *new_bio_slabs;
unsigned int new_bio_slab_max;
unsigned int i, entry = -1; unsigned int i, entry = -1;
mutex_lock(&bio_slab_lock); mutex_lock(&bio_slab_lock);
@ -97,12 +98,13 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)
goto out_unlock; goto out_unlock;
if (bio_slab_nr == bio_slab_max && entry == -1) { if (bio_slab_nr == bio_slab_max && entry == -1) {
bio_slab_max <<= 1; new_bio_slab_max = bio_slab_max << 1;
new_bio_slabs = krealloc(bio_slabs, new_bio_slabs = krealloc(bio_slabs,
bio_slab_max * sizeof(struct bio_slab), new_bio_slab_max * sizeof(struct bio_slab),
GFP_KERNEL); GFP_KERNEL);
if (!new_bio_slabs) if (!new_bio_slabs)
goto out_unlock; goto out_unlock;
bio_slab_max = new_bio_slab_max;
bio_slabs = new_bio_slabs; bio_slabs = new_bio_slabs;
} }
if (entry == -1) if (entry == -1)