diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-22 01:03:40 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-22 01:03:40 +0200 |
commit | 548453fd107f789f5f1bc2dc13cc432ceb3b5efd (patch) | |
tree | dc5a62d49260d66b7390ef110113134e3bef9152 /drivers/block | |
parent | frv: unexport kmap_atomic_to_page (diff) | |
parent | block: fix blk_register_queue() return value (diff) | |
download | linux-548453fd107f789f5f1bc2dc13cc432ceb3b5efd.tar.xz linux-548453fd107f789f5f1bc2dc13cc432ceb3b5efd.zip |
Merge branch 'for-2.6.26' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.26' of git://git.kernel.dk/linux-2.6-block:
block: fix blk_register_queue() return value
block: fix memory hotplug and bouncing in block layer
block: replace remaining __FUNCTION__ occurrences
Kconfig: clean up block/Kconfig help descriptions
cciss: fix warning oops on rmmod of driver
cciss: Fix race between disk-adding code and interrupt handler
block: move the padding adjustment to blk_rq_map_sg
block: add bio_copy_user_iov support to blk_rq_map_user_iov
block: convert bio_copy_user to bio_copy_user_iov
loop: manage partitions in disk image
cdrom: use kmalloced buffers instead of buffers on stack
cdrom: make unregister_cdrom() return void
cdrom: use list_head for cdrom_device_info list
cdrom: protect cdrom_device_info list by mutex
cdrom: cleanup hardcoded error-code
cdrom: remove ifdef CONFIG_SYSCTL
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/cciss.c | 17 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 2 | ||||
-rw-r--r-- | drivers/block/loop.c | 26 | ||||
-rw-r--r-- | drivers/block/sx8.c | 6 |
4 files changed, 41 insertions, 10 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 9c9627e8e334..cf6083a1f928 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1349,6 +1349,10 @@ static void cciss_update_drive_info(int ctlr, int drv_index) spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); h->drv[drv_index].busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + + /* deregister_disk sets h->drv[drv_index].queue = NULL */ + /* which keeps the interrupt handler from starting */ + /* the queue. */ ret = deregister_disk(h->gendisk[drv_index], &h->drv[drv_index], 0); h->drv[drv_index].busy_configuring = 0; @@ -1419,6 +1423,10 @@ geo_inq: blk_queue_hardsect_size(disk->queue, hba[ctlr]->drv[drv_index].block_size); + /* Make sure all queue data is written out before */ + /* setting h->drv[drv_index].queue, as setting this */ + /* allows the interrupt handler to start the queue */ + wmb(); h->drv[drv_index].queue = disk->queue; add_disk(disk); } @@ -3520,10 +3528,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, continue; blk_queue_hardsect_size(q, drv->block_size); set_capacity(disk, drv->nr_blocks); - add_disk(disk); j++; } while (j <= hba[i]->highest_lun); + /* Make sure all queue data is written out before */ + /* interrupt handler, triggered by add_disk, */ + /* is allowed to start them. */ + wmb(); + + for (j = 0; j <= hba[i]->highest_lun; j++) + add_disk(hba[i]->gendisk[j]); + return 1; clean4: diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 45ac09300eb3..e4bf9a11ca0d 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1349,9 +1349,9 @@ cciss_unregister_scsi(int ctlr) /* set scsi_host to NULL so our detect routine will find us on register */ sa->scsi_host = NULL; + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); scsi_cmd_stack_free(ctlr); kfree(sa); - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); } static int diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 91ebb007416c..f7f163557aa0 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -82,6 +82,9 @@ static LIST_HEAD(loop_devices); static DEFINE_MUTEX(loop_devices_mutex); +static int max_part; +static int part_shift; + /* * Transfer functions */ @@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file, goto out_putf; fput(old_file); + if (max_part > 0) + ioctl_by_bdev(bdev, BLKRRPART, 0); return 0; out_putf: @@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, } lo->lo_state = Lo_bound; wake_up_process(lo->lo_thread); + if (max_part > 0) + ioctl_by_bdev(bdev, BLKRRPART, 0); return 0; out_clr: @@ -919,6 +926,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) fput(filp); /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); + if (max_part > 0) + ioctl_by_bdev(bdev, BLKRRPART, 0); return 0; } @@ -1360,6 +1369,8 @@ static struct block_device_operations lo_fops = { static int max_loop; module_param(max_loop, int, 0); MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); +module_param(max_part, int, 0); +MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); @@ -1412,7 +1423,7 @@ static struct loop_device *loop_alloc(int i) if (!lo->lo_queue) goto out_free_dev; - disk = lo->lo_disk = alloc_disk(1); + disk = lo->lo_disk = alloc_disk(1 << part_shift); if (!disk) goto out_free_queue; @@ -1422,7 +1433,7 @@ static struct loop_device *loop_alloc(int i) init_waitqueue_head(&lo->lo_event); spin_lock_init(&lo->lo_lock); disk->major = LOOP_MAJOR; - disk->first_minor = i; + disk->first_minor = i << part_shift; disk->fops = &lo_fops; disk->private_data = lo; disk->queue = lo->lo_queue; @@ -1502,7 +1513,12 @@ static int __init loop_init(void) * themselves and have kernel automatically instantiate actual * device on-demand. */ - if (max_loop > 1UL << MINORBITS) + + part_shift = 0; + if (max_part > 0) + part_shift = fls(max_part); + + if (max_loop > 1UL << (MINORBITS - part_shift)) return -EINVAL; if (max_loop) { @@ -1510,7 +1526,7 @@ static int __init loop_init(void) range = max_loop; } else { nr = 8; - range = 1UL << MINORBITS; + range = 1UL << (MINORBITS - part_shift); } if (register_blkdev(LOOP_MAJOR, "loop")) @@ -1549,7 +1565,7 @@ static void __exit loop_exit(void) unsigned long range; struct loop_device *lo, *next; - range = max_loop ? max_loop : 1UL << MINORBITS; + range = max_loop ? max_loop : 1UL << (MINORBITS - part_shift); list_for_each_entry_safe(lo, next, &loop_devices, lo_list) loop_del_one(lo); diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index cd5674b63faf..a18e1ca0f761 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -79,9 +79,9 @@ MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30 /* note: prints function name for you */ #ifdef CARM_DEBUG -#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) +#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) #ifdef CARM_VERBOSE_DEBUG -#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) +#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) #else #define VPRINTK(fmt, args...) #endif /* CARM_VERBOSE_DEBUG */ @@ -96,7 +96,7 @@ MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30 #define assert(expr) \ if(unlikely(!(expr))) { \ printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr,__FILE__,__FUNCTION__,__LINE__); \ + #expr, __FILE__, __func__, __LINE__); \ } #endif |