Skip to content

Commit

Permalink
Merge branch 'for-2.6.26' of git://git.kernel.dk/linux-2.6-block
Browse files Browse the repository at this point in the history
* '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
  • Loading branch information
Linus Torvalds committed Apr 21, 2008
2 parents 9fd9121 + fb19974 commit 548453f
Show file tree
Hide file tree
Showing 18 changed files with 462 additions and 239 deletions.
2 changes: 1 addition & 1 deletion Documentation/cdrom/cdrom-standard.tex
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ \subsection{$Int\ register_cdrom( struct\ cdrom_device_info\ * cdi)$}
it may have as many structures $<device>_info$ as there are minor devices
active. $Register_cdrom()$ builds a linked list from these.

\subsection{$Int\ unregister_cdrom(struct\ cdrom_device_info * cdi)$}
\subsection{$Void\ unregister_cdrom(struct\ cdrom_device_info * cdi)$}

Unregistering device $cdi$ with minor number $MINOR(cdi\to dev)$ removes
the minor device from the list. If it was the last registered minor for
Expand Down
65 changes: 42 additions & 23 deletions block/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ menuconfig BLOCK
bool "Enable the block layer" if EMBEDDED
default y
help
This permits the block layer to be removed from the kernel if it's not
needed (on some embedded devices for example). If this option is
disabled, then blockdev files will become unusable and some
filesystems (such as ext3) will become unavailable.
Provide block layer support for the kernel.

This option will also disable SCSI character devices and USB storage
since they make use of various block layer definitions and
facilities.
Disable this option to remove the block layer support from the
kernel. This may be useful for embedded devices.

If this option is disabled:

- block device files will become unusable
- some filesystems (such as ext3) will become unavailable.

Also, SCSI character devices and USB storage will be disabled since
they make use of various block layer definitions and facilities.

Say Y here unless you know you really don't want to mount disks and
suchlike.
Expand All @@ -23,44 +27,59 @@ config LBD
bool "Support for Large Block Devices"
depends on !64BIT
help
Say Y here if you want to attach large (bigger than 2TB) discs to
your machine, or if you want to have a raid or loopback device
bigger than 2TB. Otherwise say N.
Enable block devices of size 2TB and larger.

This option is required to support the full capacity of large
(2TB+) block devices, including RAID, disk, Network Block Device,
Logical Volume Manager (LVM) and loopback.

For example, RAID devices are frequently bigger than the capacity
of the largest individual hard drive.

This option is not required if you have individual disk drives
which total 2TB+ and you are not aggregating the capacity into
a large block device (e.g. using RAID or LVM).

If unsure, say N.

config BLK_DEV_IO_TRACE
bool "Support for tracing block io actions"
depends on SYSFS
select RELAY
select DEBUG_FS
help
Say Y here, if you want to be able to trace the block layer actions
Say Y here if you want to be able to trace the block layer actions
on a given queue. Tracing allows you to see any traffic happening
on a block device queue. For more information (and the user space
support tools needed), fetch the blktrace app from:
on a block device queue. For more information (and the userspace
support tools needed), fetch the blktrace tools from:

git://git.kernel.dk/blktrace.git

If unsure, say N.

config LSF
bool "Support for Large Single Files"
depends on !64BIT
help
Say Y here if you want to be able to handle very large files (bigger
than 2TB), otherwise say N.
Say Y here if you want to be able to handle very large files (2TB
and larger), otherwise say N.

If unsure, say Y.

config BLK_DEV_BSG
bool "Block layer SG support v4 (EXPERIMENTAL)"
depends on EXPERIMENTAL
---help---
Saying Y here will enable generic SG (SCSI generic) v4 support
for any block device.

Unlike SG v3 (aka block/scsi_ioctl.c drivers/scsi/sg.c), SG v4
can handle complicated SCSI commands: tagged variable length cdbs
with bidirectional data transfers and generic request/response
protocols (e.g. Task Management Functions and SMP in Serial
Attached SCSI).
Saying Y here will enable generic SG (SCSI generic) v4 support
for any block device.

Unlike SG v3 (aka block/scsi_ioctl.c drivers/scsi/sg.c), SG v4
can handle complicated SCSI commands: tagged variable length cdbs
with bidirectional data transfers and generic request/response
protocols (e.g. Task Management Functions and SMP in Serial
Attached SCSI).

If unsure, say N.

endif # BLOCK

Expand Down
46 changes: 22 additions & 24 deletions block/blk-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <scsi/sg.h> /* for struct sg_iovec */

#include "blk.h"

Expand Down Expand Up @@ -140,25 +141,8 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
ubuf += ret;
}

/*
* __blk_rq_map_user() copies the buffers if starting address
* or length isn't aligned to dma_pad_mask. As the copied
* buffer is always page aligned, we know that there's enough
* room for padding. Extend the last bio and update
* rq->data_len accordingly.
*
* On unmap, bio_uncopy_user() will use unmodified
* bio_map_data pointed to by bio->bi_private.
*/
if (len & q->dma_pad_mask) {
unsigned int pad_len = (q->dma_pad_mask & ~len) + 1;
struct bio *tail = rq->biotail;

tail->bi_io_vec[tail->bi_vcnt - 1].bv_len += pad_len;
tail->bi_size += pad_len;

rq->extra_len += pad_len;
}
if (!bio_flagged(bio, BIO_USER_MAPPED))
rq->cmd_flags |= REQ_COPY_USER;

rq->buffer = rq->data = NULL;
return 0;
Expand Down Expand Up @@ -194,15 +178,26 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
struct sg_iovec *iov, int iov_count, unsigned int len)
{
struct bio *bio;
int i, read = rq_data_dir(rq) == READ;
int unaligned = 0;

if (!iov || iov_count <= 0)
return -EINVAL;

/* we don't allow misaligned data like bio_map_user() does. If the
* user is using sg, they're expected to know the alignment constraints
* and respect them accordingly */
bio = bio_map_user_iov(q, NULL, iov, iov_count,
rq_data_dir(rq) == READ);
for (i = 0; i < iov_count; i++) {
unsigned long uaddr = (unsigned long)iov[i].iov_base;

if (uaddr & queue_dma_alignment(q)) {
unaligned = 1;
break;
}
}

if (unaligned || (q->dma_pad_mask & len))
bio = bio_copy_user_iov(q, iov, iov_count, read);
else
bio = bio_map_user_iov(q, NULL, iov, iov_count, read);

if (IS_ERR(bio))
return PTR_ERR(bio);

Expand All @@ -212,6 +207,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
return -EINVAL;
}

if (!bio_flagged(bio, BIO_USER_MAPPED))
rq->cmd_flags |= REQ_COPY_USER;

bio_get(bio);
blk_rq_bio_prep(q, rq, bio);
rq->buffer = rq->data = NULL;
Expand Down
9 changes: 9 additions & 0 deletions block/blk-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
bvprv = bvec;
} /* segments in rq */


if (unlikely(rq->cmd_flags & REQ_COPY_USER) &&
(rq->data_len & q->dma_pad_mask)) {
unsigned int pad_len = (q->dma_pad_mask & ~rq->data_len) + 1;

sg->length += pad_len;
rq->extra_len += pad_len;
}

if (q->dma_drain_size && q->dma_drain_needed(rq)) {
if (rq->cmd_flags & REQ_RW)
memset(q->dma_drain_buffer, 0, q->dma_drain_size);
Expand Down
10 changes: 8 additions & 2 deletions block/blk-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,12 @@ int blk_register_queue(struct gendisk *disk)

struct request_queue *q = disk->queue;

if (!q || !q->request_fn)
if (WARN_ON(!q))
return -ENXIO;

if (!q->request_fn)
return 0;

ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj),
"%s", "queue");
if (ret < 0)
Expand All @@ -300,7 +303,10 @@ void blk_unregister_queue(struct gendisk *disk)
{
struct request_queue *q = disk->queue;

if (q && q->request_fn) {
if (WARN_ON(!q))
return;

if (q->request_fn) {
elv_unregister_queue(q);

kobject_uevent(&q->kobj, KOBJ_REMOVE);
Expand Down
17 changes: 16 additions & 1 deletion drivers/block/cciss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1419,6 +1423,10 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
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);
}
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/cciss_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 21 additions & 5 deletions drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -1502,15 +1513,20 @@ 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) {
nr = max_loop;
range = max_loop;
} else {
nr = 8;
range = 1UL << MINORBITS;
range = 1UL << (MINORBITS - part_shift);
}

if (register_blkdev(LOOP_MAJOR, "loop"))
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions drivers/block/sx8.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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

Expand Down
Loading

0 comments on commit 548453f

Please sign in to comment.