summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-16 12:57:51 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-16 12:57:51 -0800
commitac7ac4618cf25e0d5cd8eba83d5f600084b65b9a (patch)
treee5d28907ff72690a0463a2238b96202d751a535c /drivers/block
parent48aba79bcf6ea05148dc82ad9c40713960b00396 (diff)
parentfa94ba8a7b22890e6a17b39b9359e114fe18cd59 (diff)
downloadlinux-ac7ac4618cf25e0d5cd8eba83d5f600084b65b9a.tar.bz2
Merge tag 'for-5.11/block-2020-12-14' of git://git.kernel.dk/linux-block
Pull block updates from Jens Axboe: "Another series of killing more code than what is being added, again thanks to Christoph's relentless cleanups and tech debt tackling. This contains: - blk-iocost improvements (Baolin Wang) - part0 iostat fix (Jeffle Xu) - Disable iopoll for split bios (Jeffle Xu) - block tracepoint cleanups (Christoph Hellwig) - Merging of struct block_device and hd_struct (Christoph Hellwig) - Rework/cleanup of how block device sizes are updated (Christoph Hellwig) - Simplification of gendisk lookup and removal of block device aliasing (Christoph Hellwig) - Block device ioctl cleanups (Christoph Hellwig) - Removal of bdget()/blkdev_get() as exported API (Christoph Hellwig) - Disk change rework, avoid ->revalidate_disk() (Christoph Hellwig) - sbitmap improvements (Pavel Begunkov) - Hybrid polling fix (Pavel Begunkov) - bvec iteration improvements (Pavel Begunkov) - Zone revalidation fixes (Damien Le Moal) - blk-throttle limit fix (Yu Kuai) - Various little fixes" * tag 'for-5.11/block-2020-12-14' of git://git.kernel.dk/linux-block: (126 commits) blk-mq: fix msec comment from micro to milli seconds blk-mq: update arg in comment of blk_mq_map_queue blk-mq: add helper allocating tagset->tags Revert "block: Fix a lockdep complaint triggered by request queue flushing" nvme-loop: use blk_mq_hctx_set_fq_lock_class to set loop's lock class blk-mq: add new API of blk_mq_hctx_set_fq_lock_class block: disable iopoll for split bio block: Improve blk_revalidate_disk_zones() checks sbitmap: simplify wrap check sbitmap: replace CAS with atomic and sbitmap: remove swap_lock sbitmap: optimise sbitmap_deferred_clear() blk-mq: skip hybrid polling if iopoll doesn't spin blk-iocost: Factor out the base vrate change into a separate function blk-iocost: Factor out the active iocgs' state check into a separate function blk-iocost: Move the usage ratio calculation to the correct place blk-iocost: Remove unnecessary advance declaration blk-iocost: Fix some typos in comments blktrace: fix up a kerneldoc comment block: remove the request_queue to argument request based tracepoints ...
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/amiflop.c98
-rw-r--r--drivers/block/aoe/aoecmd.c15
-rw-r--r--drivers/block/ataflop.c135
-rw-r--r--drivers/block/brd.c39
-rw-r--r--drivers/block/drbd/drbd_main.c6
-rw-r--r--drivers/block/drbd/drbd_receiver.c2
-rw-r--r--drivers/block/drbd/drbd_worker.c3
-rw-r--r--drivers/block/floppy.c154
-rw-r--r--drivers/block/loop.c64
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c15
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h2
-rw-r--r--drivers/block/nbd.c94
-rw-r--r--drivers/block/pktcdvd.c9
-rw-r--r--drivers/block/rbd.c43
-rw-r--r--drivers/block/rnbd/rnbd-clt.c3
-rw-r--r--drivers/block/swim.c17
-rw-r--r--drivers/block/virtio_blk.c3
-rw-r--r--drivers/block/xen-blkback/common.h4
-rw-r--r--drivers/block/xen-blkfront.c22
-rw-r--r--drivers/block/z2ram.c547
-rw-r--r--drivers/block/zram/zram_drv.c34
-rw-r--r--drivers/block/zram/zram_drv.h1
22 files changed, 603 insertions, 707 deletions
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 71c2b1564558..9e2d0c6a3877 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -201,7 +201,7 @@ struct amiga_floppy_struct {
int busy; /* true when drive is active */
int dirty; /* true when trackbuf is not on disk */
int status; /* current error code for unit */
- struct gendisk *gendisk;
+ struct gendisk *gendisk[2];
struct blk_mq_tag_set tag_set;
};
@@ -1669,6 +1669,11 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
return -EBUSY;
}
+ if (unit[drive].type->code == FD_NODRIVE) {
+ mutex_unlock(&amiflop_mutex);
+ return -ENXIO;
+ }
+
if (mode & (FMODE_READ|FMODE_WRITE)) {
bdev_check_media_change(bdev);
if (mode & FMODE_WRITE) {
@@ -1695,7 +1700,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
unit[drive].dtype=&data_types[system];
unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
data_types[system].sects*unit[drive].type->sect_mult;
- set_capacity(unit[drive].gendisk, unit[drive].blocks);
+ set_capacity(unit[drive].gendisk[system], unit[drive].blocks);
printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,
unit[drive].type->name, data_types[system].name);
@@ -1772,36 +1777,68 @@ static const struct blk_mq_ops amiflop_mq_ops = {
.queue_rq = amiflop_queue_rq,
};
-static struct gendisk *fd_alloc_disk(int drive)
+static int fd_alloc_disk(int drive, int system)
{
struct gendisk *disk;
disk = alloc_disk(1);
if (!disk)
goto out;
-
- disk->queue = blk_mq_init_sq_queue(&unit[drive].tag_set, &amiflop_mq_ops,
- 2, BLK_MQ_F_SHOULD_MERGE);
- if (IS_ERR(disk->queue)) {
- disk->queue = NULL;
+ disk->queue = blk_mq_init_queue(&unit[drive].tag_set);
+ if (IS_ERR(disk->queue))
goto out_put_disk;
- }
+ disk->major = FLOPPY_MAJOR;
+ disk->first_minor = drive + system;
+ disk->fops = &floppy_fops;
+ disk->events = DISK_EVENT_MEDIA_CHANGE;
+ if (system)
+ sprintf(disk->disk_name, "fd%d_msdos", drive);
+ else
+ sprintf(disk->disk_name, "fd%d", drive);
+ disk->private_data = &unit[drive];
+ set_capacity(disk, 880 * 2);
+
+ unit[drive].gendisk[system] = disk;
+ add_disk(disk);
+ return 0;
+
+out_put_disk:
+ disk->queue = NULL;
+ put_disk(disk);
+out:
+ return -ENOMEM;
+}
+
+static int fd_alloc_drive(int drive)
+{
unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL);
if (!unit[drive].trackbuf)
- goto out_cleanup_queue;
+ goto out;
- return disk;
+ memset(&unit[drive].tag_set, 0, sizeof(unit[drive].tag_set));
+ unit[drive].tag_set.ops = &amiflop_mq_ops;
+ unit[drive].tag_set.nr_hw_queues = 1;
+ unit[drive].tag_set.nr_maps = 1;
+ unit[drive].tag_set.queue_depth = 2;
+ unit[drive].tag_set.numa_node = NUMA_NO_NODE;
+ unit[drive].tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
+ if (blk_mq_alloc_tag_set(&unit[drive].tag_set))
+ goto out_cleanup_trackbuf;
-out_cleanup_queue:
- blk_cleanup_queue(disk->queue);
- disk->queue = NULL;
+ pr_cont(" fd%d", drive);
+
+ if (fd_alloc_disk(drive, 0) || fd_alloc_disk(drive, 1))
+ goto out_cleanup_tagset;
+ return 0;
+
+out_cleanup_tagset:
blk_mq_free_tag_set(&unit[drive].tag_set);
-out_put_disk:
- put_disk(disk);
+out_cleanup_trackbuf:
+ kfree(unit[drive].trackbuf);
out:
unit[drive].type->code = FD_NODRIVE;
- return NULL;
+ return -ENOMEM;
}
static int __init fd_probe_drives(void)
@@ -1812,29 +1849,16 @@ static int __init fd_probe_drives(void)
drives=0;
nomem=0;
for(drive=0;drive<FD_MAX_UNITS;drive++) {
- struct gendisk *disk;
fd_probe(drive);
if (unit[drive].type->code == FD_NODRIVE)
continue;
- disk = fd_alloc_disk(drive);
- if (!disk) {
+ if (fd_alloc_drive(drive) < 0) {
pr_cont(" no mem for fd%d", drive);
nomem = 1;
continue;
}
- unit[drive].gendisk = disk;
drives++;
-
- pr_cont(" fd%d",drive);
- 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);
- add_disk(disk);
}
if ((drives > 0) || (nomem == 0)) {
if (drives == 0)
@@ -1846,15 +1870,6 @@ static int __init fd_probe_drives(void)
return -ENOMEM;
}
-static struct kobject *floppy_find(dev_t dev, int *part, void *data)
-{
- int drive = *part & 3;
- if (unit[drive].type->code == FD_NODRIVE)
- return NULL;
- *part = 0;
- return get_disk_and_module(unit[drive].gendisk);
-}
-
static int __init amiga_floppy_probe(struct platform_device *pdev)
{
int i, ret;
@@ -1884,9 +1899,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev)
if (fd_probe_drives() < 1) /* No usable drives */
goto out_probe;
- blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
- floppy_find, NULL, NULL);
-
/* initialize variables */
timer_setup(&motor_on_timer, motor_on_callback, 0);
motor_on_timer.expires = 0;
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 313f0b946fe2..ac720bdcd983 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -890,19 +890,13 @@ void
aoecmd_sleepwork(struct work_struct *work)
{
struct aoedev *d = container_of(work, struct aoedev, work);
- struct block_device *bd;
- u64 ssize;
if (d->flags & DEVFL_GDALLOC)
aoeblk_gdalloc(d);
if (d->flags & DEVFL_NEWSIZE) {
- ssize = get_capacity(d->gd);
- bd = bdget_disk(d->gd, 0);
- if (bd) {
- bd_set_nr_sectors(bd, ssize);
- bdput(bd);
- }
+ set_capacity_and_notify(d->gd, d->ssize);
+
spin_lock_irq(&d->lock);
d->flags |= DEVFL_UP;
d->flags &= ~DEVFL_NEWSIZE;
@@ -971,10 +965,9 @@ ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
d->geo.start = 0;
if (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
return;
- if (d->gd != NULL) {
- set_capacity(d->gd, ssize);
+ if (d->gd != NULL)
d->flags |= DEVFL_NEWSIZE;
- } else
+ else
d->flags |= DEVFL_GDALLOC;
schedule_work(&d->work);
}
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 3e881fdb06e0..104b713f4055 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -297,7 +297,7 @@ static struct atari_floppy_struct {
unsigned int wpstat; /* current state of WP signal (for
disk change detection) */
int flags; /* flags */
- struct gendisk *disk;
+ struct gendisk *disk[NUM_DISK_MINORS];
int ref;
int type;
struct blk_mq_tag_set tag_set;
@@ -723,12 +723,16 @@ static void fd_error( void )
static int do_format(int drive, int type, struct atari_format_descr *desc)
{
- struct request_queue *q = unit[drive].disk->queue;
+ struct request_queue *q;
unsigned char *p;
int sect, nsect;
unsigned long flags;
int ret;
+ if (type)
+ type--;
+
+ q = unit[drive].disk[type]->queue;
blk_mq_freeze_queue(q);
blk_mq_quiesce_queue(q);
@@ -738,7 +742,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
local_irq_restore(flags);
if (type) {
- if (--type >= NUM_DISK_MINORS ||
+ if (type >= NUM_DISK_MINORS ||
minor2disktype[type].drive_types > DriveType) {
ret = -EINVAL;
goto out;
@@ -1154,7 +1158,7 @@ static void fd_rwsec_done1(int status)
if (SUDT[-1].blocks > ReqBlock) {
/* try another disk type */
SUDT--;
- set_capacity(unit[SelectedDrive].disk,
+ set_capacity(unit[SelectedDrive].disk[0],
SUDT->blocks);
} else
Probing = 0;
@@ -1169,7 +1173,7 @@ static void fd_rwsec_done1(int status)
/* record not found, but not probing. Maybe stretch wrong ? Restart probing */
if (SUD.autoprobe) {
SUDT = atari_disk_type + StartDiskType[DriveType];
- set_capacity(unit[SelectedDrive].disk,
+ set_capacity(unit[SelectedDrive].disk[0],
SUDT->blocks);
Probing = 1;
}
@@ -1515,7 +1519,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
if (!UDT) {
Probing = 1;
UDT = atari_disk_type + StartDiskType[DriveType];
- set_capacity(floppy->disk, UDT->blocks);
+ set_capacity(bd->rq->rq_disk, UDT->blocks);
UD.autoprobe = 1;
}
}
@@ -1533,7 +1537,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
}
type = minor2disktype[type].index;
UDT = &atari_disk_type[type];
- set_capacity(floppy->disk, UDT->blocks);
+ set_capacity(bd->rq->rq_disk, UDT->blocks);
UD.autoprobe = 0;
}
@@ -1658,7 +1662,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
printk (KERN_INFO "floppy%d: setting %s %p!\n",
drive, dtp->name, dtp);
UDT = dtp;
- set_capacity(floppy->disk, UDT->blocks);
+ set_capacity(disk, UDT->blocks);
if (cmd == FDDEFPRM) {
/* save settings as permanent default type */
@@ -1702,7 +1706,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
return -EINVAL;
UDT = dtp;
- set_capacity(floppy->disk, UDT->blocks);
+ set_capacity(disk, UDT->blocks);
return 0;
case FDMSGON:
@@ -1725,7 +1729,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
UDT = NULL;
/* MSch: invalidate default_params */
default_params[drive].blocks = 0;
- set_capacity(floppy->disk, MAX_DISK_SIZE * 2);
+ set_capacity(disk, MAX_DISK_SIZE * 2);
fallthrough;
case FDFMTEND:
case FDFLUSH:
@@ -1962,14 +1966,50 @@ static const struct blk_mq_ops ataflop_mq_ops = {
.commit_rqs = ataflop_commit_rqs,
};
-static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+static int ataflop_alloc_disk(unsigned int drive, unsigned int type)
{
- int drive = *part & 3;
- int type = *part >> 2;
+ struct gendisk *disk;
+ int ret;
+
+ disk = alloc_disk(1);
+ if (!disk)
+ return -ENOMEM;
+
+ disk->queue = blk_mq_init_queue(&unit[drive].tag_set);
+ if (IS_ERR(disk->queue)) {
+ ret = PTR_ERR(disk->queue);
+ disk->queue = NULL;
+ put_disk(disk);
+ return ret;
+ }
+
+ disk->major = FLOPPY_MAJOR;
+ disk->first_minor = drive + (type << 2);
+ sprintf(disk->disk_name, "fd%d", drive);
+ disk->fops = &floppy_fops;
+ disk->events = DISK_EVENT_MEDIA_CHANGE;
+ disk->private_data = &unit[drive];
+ set_capacity(disk, MAX_DISK_SIZE * 2);
+
+ unit[drive].disk[type] = disk;
+ return 0;
+}
+
+static DEFINE_MUTEX(ataflop_probe_lock);
+
+static void ataflop_probe(dev_t dev)
+{
+ int drive = MINOR(dev) & 3;
+ int type = MINOR(dev) >> 2;
+
if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
- return NULL;
- *part = 0;
- return get_disk_and_module(unit[drive].disk);
+ return;
+ mutex_lock(&ataflop_probe_lock);
+ if (!unit[drive].disk[type]) {
+ if (ataflop_alloc_disk(drive, type) == 0)
+ add_disk(unit[drive].disk[type]);
+ }
+ mutex_unlock(&ataflop_probe_lock);
}
static int __init atari_floppy_init (void)
@@ -1981,23 +2021,26 @@ static int __init atari_floppy_init (void)
/* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
return -ENODEV;
- if (register_blkdev(FLOPPY_MAJOR,"fd"))
- return -EBUSY;
+ mutex_lock(&ataflop_probe_lock);
+ ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe);
+ if (ret)
+ goto out_unlock;
for (i = 0; i < FD_MAX_UNITS; i++) {
- unit[i].disk = alloc_disk(1);
- if (!unit[i].disk) {
- ret = -ENOMEM;
+ memset(&unit[i].tag_set, 0, sizeof(unit[i].tag_set));
+ unit[i].tag_set.ops = &ataflop_mq_ops;
+ unit[i].tag_set.nr_hw_queues = 1;
+ unit[i].tag_set.nr_maps = 1;
+ unit[i].tag_set.queue_depth = 2;
+ unit[i].tag_set.numa_node = NUMA_NO_NODE;
+ unit[i].tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
+ ret = blk_mq_alloc_tag_set(&unit[i].tag_set);
+ if (ret)
goto err;
- }
- unit[i].disk->queue = blk_mq_init_sq_queue(&unit[i].tag_set,
- &ataflop_mq_ops, 2,
- BLK_MQ_F_SHOULD_MERGE);
- if (IS_ERR(unit[i].disk->queue)) {
- put_disk(unit[i].disk);
- ret = PTR_ERR(unit[i].disk->queue);
- unit[i].disk->queue = NULL;
+ ret = ataflop_alloc_disk(i, 0);
+ if (ret) {
+ blk_mq_free_tag_set(&unit[i].tag_set);
goto err;
}
}
@@ -2027,19 +2070,9 @@ static int __init atari_floppy_init (void)
for (i = 0; i < FD_MAX_UNITS; i++) {
unit[i].track = -1;
unit[i].flags = 0;
- unit[i].disk->major = FLOPPY_MAJOR;
- 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];
- set_capacity(unit[i].disk, MAX_DISK_SIZE * 2);
- add_disk(unit[i].disk);
+ add_disk(unit[i].disk[0]);
}
- blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
- floppy_find, NULL, NULL);
-
printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n",
DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E',
UseTrackbuffer ? "" : "no ");
@@ -2049,14 +2082,14 @@ static int __init atari_floppy_init (void)
err:
while (--i >= 0) {
- struct gendisk *disk = unit[i].disk;
-
- blk_cleanup_queue(disk->queue);
+ blk_cleanup_queue(unit[i].disk[0]->queue);
+ put_disk(unit[i].disk[0]);
blk_mq_free_tag_set(&unit[i].tag_set);
- put_disk(unit[i].disk);
}
unregister_blkdev(FLOPPY_MAJOR, "fd");
+out_unlock:
+ mutex_unlock(&ataflop_probe_lock);
return ret;
}
@@ -2101,13 +2134,17 @@ __setup("floppy=", atari_floppy_setup);
static void __exit atari_floppy_exit(void)
{
- int i;
- blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+ int i, type;
+
for (i = 0; i < FD_MAX_UNITS; i++) {
- del_gendisk(unit[i].disk);
- blk_cleanup_queue(unit[i].disk->queue);
+ for (type = 0; type < NUM_DISK_MINORS; type++) {
+ if (!unit[i].disk[type])
+ continue;
+ del_gendisk(unit[i].disk[type]);
+ blk_cleanup_queue(unit[i].disk[type]->queue);
+ put_disk(unit[i].disk[type]);
+ }
blk_mq_free_tag_set(&unit[i].tag_set);
- put_disk(unit[i].disk);
}
unregister_blkdev(FLOPPY_MAJOR, "fd");
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index cc49a921339f..c43a6ab4b1f3 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -426,14 +426,15 @@ static void brd_free(struct brd_device *brd)
kfree(brd);
}
-static struct brd_device *brd_init_one(int i, bool *new)
+static void brd_probe(dev_t dev)
{
struct brd_device *brd;
+ int i = MINOR(dev) / max_part;
- *new = false;
+ mutex_lock(&brd_devices_mutex);
list_for_each_entry(brd, &brd_devices, brd_list) {
if (brd->brd_number == i)
- goto out;
+ goto out_unlock;
}
brd = brd_alloc(i);
@@ -442,9 +443,9 @@ static struct brd_device *brd_init_one(int i, bool *new)
add_disk(brd->brd_disk);
list_add_tail(&brd->brd_list, &brd_devices);
}
- *new = true;
-out:
- return brd;
+
+out_unlock:
+ mutex_unlock(&brd_devices_mutex);
}
static void brd_del_one(struct brd_device *brd)
@@ -454,23 +455,6 @@ static void brd_del_one(struct brd_device *brd)
brd_free(brd);
}
-static struct kobject *brd_probe(dev_t dev, int *part, void *data)
-{
- struct brd_device *brd;
- struct kobject *kobj;
- bool new;
-
- mutex_lock(&brd_devices_mutex);
- brd = brd_init_one(MINOR(dev) / max_part, &new);
- kobj = brd ? get_disk_and_module(brd->brd_disk) : NULL;
- mutex_unlock(&brd_devices_mutex);
-
- if (new)
- *part = 0;
-
- return kobj;
-}
-
static inline void brd_check_and_reset_par(void)
{
if (unlikely(!max_part))
@@ -510,11 +494,12 @@ static int __init brd_init(void)
* dynamically.
*/
- if (register_blkdev(RAMDISK_MAJOR, "ramdisk"))
+ if (__register_blkdev(RAMDISK_MAJOR, "ramdisk", brd_probe))
return -EIO;
brd_check_and_reset_par();
+ mutex_lock(&brd_devices_mutex);
for (i = 0; i < rd_nr; i++) {
brd = brd_alloc(i);
if (!brd)
@@ -532,9 +517,7 @@ static int __init brd_init(void)
brd->brd_disk->queue = brd->brd_queue;
add_disk(brd->brd_disk);
}
-
- blk_register_region(MKDEV(RAMDISK_MAJOR, 0), 1UL << MINORBITS,
- THIS_MODULE, brd_probe, NULL, NULL);
+ mutex_unlock(&brd_devices_mutex);
pr_info("brd: module loaded\n");
return 0;
@@ -544,6 +527,7 @@ out_free:
list_del(&brd->brd_list);
brd_free(brd);
}
+ mutex_unlock(&brd_devices_mutex);
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
pr_info("brd: module NOT loaded !!!\n");
@@ -557,7 +541,6 @@ static void __exit brd_exit(void)
list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
brd_del_one(brd);
- blk_unregister_region(MKDEV(RAMDISK_MAJOR, 0), 1UL << MINORBITS);
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
pr_info("brd: module unloaded\n");
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 65b95aef8dbc..1c8c18b2a25f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2036,8 +2036,7 @@ void drbd_set_my_capacity(struct drbd_device *device, sector_t size)
{
char ppb[10];
- set_capacity(device->vdisk, size);
- revalidate_disk_size(device->vdisk, false);
+ set_capacity_and_notify(device->vdisk, size);
drbd_info(device, "size = %s (%llu KB)\n",
ppsize(ppb, size>>1), (unsigned long long)size>>1);
@@ -2068,8 +2067,7 @@ void drbd_device_cleanup(struct drbd_device *device)
}
D_ASSERT(device, first_peer_device(device)->connection->net_conf == NULL);
- set_capacity(device->vdisk, 0);
- revalidate_disk_size(device->vdisk, false);
+ set_capacity_and_notify(device->vdisk, 0);
if (device->bitmap) {
/* maybe never allocated. */
drbd_bm_resize(device, 0, 1);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index dc333dbe5232..09c86ef3f0fd 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2802,7 +2802,7 @@ bool drbd_rs_c_min_rate_throttle(struct drbd_device *device)
if (c_min_rate == 0)
return false;
- curr_events = (int)part_stat_read_accum(&disk->part0, sectors) -
+ curr_events = (int)part_stat_read_accum(disk->part0, sectors) -
atomic_read(&device->rs_sect_ev);
if (atomic_read(&device->ap_actlog_cnt)
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index ba56f3f05312..02044ab7f767 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1678,7 +1678,8 @@ void drbd_rs_controller_reset(struct drbd_device *device)
atomic_set(&device->rs_sect_in, 0);
atomic_set(&device->rs_sect_ev, 0);
device->rs_in_flight = 0;
- device->rs_last_events = (int)part_stat_read_accum(&disk->part0, sectors);
+ device->rs_last_events =
+ (int)part_stat_read_accum(disk->part0, sectors);
/* Updating the RCU protected object in place is necessary since
this function gets called from atomic context.
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 7df79ae6b0a1..dfe1dfc901cc 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -402,7 +402,6 @@ static struct floppy_drive_params drive_params[N_DRIVE];
static struct floppy_drive_struct drive_state[N_DRIVE];
static struct floppy_write_errors write_errors[N_DRIVE];
static struct timer_list motor_off_timer[N_DRIVE];
-static struct gendisk *disks[N_DRIVE];
static struct blk_mq_tag_set tag_sets[N_DRIVE];
static struct block_device *opened_bdev[N_DRIVE];
static DEFINE_MUTEX(open_lock);
@@ -477,6 +476,8 @@ static struct floppy_struct floppy_type[32] = {
{ 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */
};
+static struct gendisk *disks[N_DRIVE][ARRAY_SIZE(floppy_type)];
+
#define SECTSIZE (_FD_SECTSIZE(*floppy))
/* Auto-detection: Disk type used until the next media change occurs. */
@@ -4111,7 +4112,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
new_dev = MINOR(bdev->bd_dev);
drive_state[drive].fd_device = new_dev;
- set_capacity(disks[drive], floppy_sizes[new_dev]);
+ set_capacity(disks[drive][ITYPE(new_dev)], floppy_sizes[new_dev]);
if (old_dev != -1 && old_dev != new_dev) {
if (buffer_drive == drive)
buffer_track = -1;
@@ -4579,15 +4580,58 @@ static bool floppy_available(int drive)
return true;
}
-static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+static int floppy_alloc_disk(unsigned int drive, unsigned int type)
{
- int drive = (*part & 3) | ((*part & 0x80) >> 5);
- if (drive >= N_DRIVE || !floppy_available(drive))
- return NULL;
- if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
- return NULL;
- *part = 0;
- return get_disk_and_module(disks[drive]);
+ struct gendisk *disk;
+ int err;
+
+ disk = alloc_disk(1);
+ if (!disk)
+ return -ENOMEM;
+
+ disk->queue = blk_mq_init_queue(&tag_sets[drive]);
+ if (IS_ERR(disk->queue)) {
+ err = PTR_ERR(disk->queue);
+ disk->queue = NULL;
+ put_disk(disk);
+ return err;
+ }
+
+ blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
+ blk_queue_max_hw_sectors(disk->queue, 64);
+ disk->major = FLOPPY_MAJOR;
+ disk->first_minor = TOMINOR(drive) | (type << 2);
+ disk->fops = &floppy_fops;
+ disk->events = DISK_EVENT_MEDIA_CHANGE;
+ if (type)
+ sprintf(disk->disk_name, "fd%d_type%d", drive, type);
+ else
+ sprintf(disk->disk_name, "fd%d", drive);
+ /* to be cleaned up... */
+ disk->private_data = (void *)(long)drive;
+ disk->flags |= GENHD_FL_REMOVABLE;
+
+ disks[drive][type] = disk;
+ return 0;
+}
+
+static DEFINE_MUTEX(floppy_probe_lock);
+
+static void floppy_probe(dev_t dev)
+{
+ unsigned int drive = (MINOR(dev) & 3) | ((MINOR(dev) & 0x80) >> 5);
+ unsigned int type = (MINOR(dev) >> 2) & 0x1f;
+
+ if (drive >= N_DRIVE || !floppy_available(drive) ||
+ type >= ARRAY_SIZE(floppy_type))
+ return;
+
+ mutex_lock(&floppy_probe_lock);
+ if (!disks[drive][type]) {
+ if (floppy_alloc_disk(drive, type) == 0)
+ add_disk(disks[drive][type]);
+ }
+ mutex_unlock(&floppy_probe_lock);
}
static int __init do_floppy_init(void)
@@ -4609,33 +4653,25 @@ static int __init do_floppy_init(void)
return -ENOMEM;
for (drive = 0; drive < N_DRIVE; drive++) {
- disks[drive] = alloc_disk(1);
- if (!disks[drive]) {
- err = -ENOMEM;
+ memset(&tag_sets[drive], 0, sizeof(tag_sets[drive]));
+ tag_sets[drive].ops = &floppy_mq_ops;
+ tag_sets[drive].nr_hw_queues = 1;
+ tag_sets[drive].nr_maps = 1;
+ tag_sets[drive].queue_depth = 2;
+ tag_sets[drive].numa_node = NUMA_NO_NODE;
+ tag_sets[drive].flags = BLK_MQ_F_SHOULD_MERGE;
+ err = blk_mq_alloc_tag_set(&tag_sets[drive]);
+ if (err)
goto out_put_disk;
- }
- disks[drive]->queue = blk_mq_init_sq_queue(&tag_sets[drive],
- &floppy_mq_ops, 2,
- BLK_MQ_F_SHOULD_MERGE);
- if (IS_ERR(disks[drive]->queue)) {
- err = PTR_ERR(disks[drive]->queue);
- disks[drive]->queue = NULL;
+ err = floppy_alloc_disk(drive, 0);
+ if (err)
goto out_put_disk;
- }
-
- blk_queue_bounce_limit(disks[drive]->queue, BLK_BOUNCE_HIGH);
- blk_queue_max_hw_sectors(disks[drive]->queue, 64);
- disks[drive]->major = FLOPPY_MAJOR;
- disks[drive]->first_minor = TOMINOR(drive);
- disks[drive]->fops = &floppy_fops;
- disks[drive]->events = DISK_EVENT_MEDIA_CHANGE;
- sprintf(disks[drive]->disk_name, "fd%d", drive);
timer_setup(&motor_off_timer[drive], motor_off_callback, 0);
}
- err = register_blkdev(FLOPPY_MAJOR, "fd");
+ err = __register_blkdev(FLOPPY_MAJOR, "fd", floppy_probe);
if (err)
goto out_put_disk;
@@ -4643,9 +4679,6 @@ static int __init do_floppy_init(void)
if (err)
goto out_unreg_blkdev;
- blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
- floppy_find, NULL, NULL);
-
for (i = 0; i < 256; i++)
if (ITYPE(i))
floppy_sizes[i] = floppy_type[ITYPE(i)].size;
@@ -4673,7 +4706,7 @@ static int __init do_floppy_init(void)
if (fdc_state[0].address == -1) {
cancel_delayed_work(&fd_timeout);
err = -ENODEV;
- goto out_unreg_region;
+ goto out_unreg_driver;
}
#if N_FDC > 1
fdc_state[1].address = FDC2;
@@ -4684,7 +4717,7 @@ static int __init do_floppy_init(void)
if (err) {
cancel_delayed_work(&fd_timeout);
err = -EBUSY;
- goto out_unreg_region;
+ goto out_unreg_driver;
}
/* initialise drive state */
@@ -4761,10 +4794,8 @@ static int __init do_floppy_init(void)
if (err)
goto out_remove_drives;
- /* to be cleaned up... */
- disks[drive]->private_data = (void *)(long)drive;
- disks[drive]->flags |= GENHD_FL_REMOVABLE;
- device_add_disk(&floppy_device[drive].dev, disks[drive], NULL);
+ device_add_disk(&floppy_device[drive].dev, disks[drive][0],
+ NULL);
}
return 0;
@@ -4772,30 +4803,27 @@ static int __init do_floppy_init(void)
out_remove_drives:
while (drive--) {
if (floppy_available(drive)) {
- del_gendisk(disks[drive]);
+ del_gendisk(disks[drive][0]);
platform_device_unregister(&floppy_device[drive]);
}
}
out_release_dma:
if (atomic_read(&usage_count))
floppy_release_irq_and_dma();
-out_unreg_region:
- blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+out_unreg_driver:
platform_driver_unregister(&floppy_driver);
out_unreg_blkdev:
unregister_blkdev(FLOPPY_MAJOR, "fd");
out_put_disk:
destroy_workqueue(floppy_wq);
for (drive = 0; drive < N_DRIVE; drive++) {
- if (!disks[drive])
+ if (!disks[drive][0])
break;
- if (disks[drive]->queue) {
- del_timer_sync(&motor_off_timer[drive]);
- blk_cleanup_queue(disks[drive]->queue);
- disks[drive]->queue = NULL;
- blk_mq_free_tag_set(&tag_sets[drive]);
- }
- put_disk(disks[drive]);
+ del_timer_sync(&motor_off_timer[drive]);
+ blk_cleanup_queue(disks[drive][0]->queue);
+ disks[drive][0]->queue = NULL;
+ blk_mq_free_tag_set(&tag_sets[drive]);
+ put_disk(disks[drive][0]);
}
return err;
}
@@ -5006,9 +5034,8 @@ module_init(floppy_module_init);
static void __exit floppy_module_exit(void)
{
- int drive;
+ int drive, i;
- blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
unregister_blkdev(FLOPPY_MAJOR, "fd");
platform_driver_unregister(&floppy_driver);
@@ -5018,10 +5045,16 @@ static void __exit floppy_module_exit(void)
del_timer_sync(&motor_off_timer[drive]);
if (floppy_available(drive)) {
- del_gendisk(disks[drive]);
+ for (i = 0; i < ARRAY_SIZE(floppy_type); i++) {
+ if (disks[drive][i])
+ del_gendisk(disks[drive][i]);
+ }
platform_device_unregister(&floppy_device[drive]);
}
- blk_cleanup_queue(disks[drive]->queue);
+ for (i = 0; i < ARRAY_SIZE(floppy_type); i++) {
+ if (disks[drive][i])
+ blk_cleanup_queue(disks[drive][i]->queue);
+ }
blk_mq_free_tag_set(&tag_sets[drive]);
/*
@@ -5029,10 +5062,17 @@ static void __exit floppy_module_exit(void)
* queue reference in put_disk().
*/
if (!(allowed_drive_mask & (1 << drive)) ||
- fdc_state[FDC(drive)].version == FDC_NONE)
- disks[drive]->queue = NULL;
+ fdc_state[FDC(drive)].version == FDC_NONE) {
+ for (i = 0; i < ARRAY_SIZE(floppy_type); i++) {
+ if (disks[drive][i])
+ disks[drive][i]->queue = NULL;
+ }
+ }
- put_disk(disks[drive]);
+ for (i = 0; i < ARRAY_SIZE(floppy_type); i++) {
+ if (disks[drive][i])
+ put_disk(disks[drive][i]);
+ }
}
cancel_delayed_work_sync(&fd_timeout);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index a58084c2ed7c..d2ce1ddc192d 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -251,12 +251,8 @@ loop_validate_block_size(unsigned short bsize)
*/
static void loop_set_size(struct loop_device *lo, loff_t size)
{
- struct block_device *bdev = lo->lo_device;
-
- bd_set_nr_sectors(bdev, size);
-
- if (!set_capacity_revalidate_and_notify(lo->lo_disk, size, false))
- kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
+ if (!set_capacity_and_notify(lo->lo_disk, size))
+ kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE);
}
static inline int
@@ -679,10 +675,10 @@ static int loop_validate_file(struct file *file, struct block_device *bdev)
while (is_loop_device(f)) {
struct loop_device *l;
- if (f->f_mapping->host->i_bdev == bdev)
+ if (f->f_mapping->host->i_rdev == bdev->bd_dev)
return -EBADF;
- l = f->f_mapping->host->i_bdev->bd_disk->private_data;
+ l = I_BDEV(f->f_mapping->host)->bd_disk->private_data;
if (l->lo_state != Lo_bound) {
return -EINVAL;
}
@@ -889,9 +885,7 @@ static void loop_config_discard(struct loop_device *lo)
* file-backed loop devices: discarded regions read back as zero.
*/
if (S_ISBLK(inode->i_mode) && !lo->lo_encrypt_key_size) {
- struct request_queue *backingq;
-
- backingq = bdev_get_queue(inode->i_bdev);
+ struct request_queue *backingq = bdev_get_queue(I_BDEV(inode));
max_discard_sectors = backingq->limits.max_write_zeroes_sectors;
granularity = backingq->limits.discard_granularity ?:
@@ -1075,7 +1069,6 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
struct file *file;
struct inode *inode;
struct address_space *mapping;
- struct block_device *claimed_bdev = NULL;
int error;
loff_t size;
bool partscan;
@@ -1094,8 +1087,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
* here to avoid changing device under exclusive owner.
*/
if (!(mode & FMODE_EXCL)) {
- claimed_bdev = bdev->bd_contains;
- error = bd_prepare_to_claim(bdev, claimed_bdev, loop_configure);
+ error = bd_prepare_to_claim(bdev, loop_configure);
if (error)
goto out_putf;
}
@@ -1138,7 +1130,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
if (error)
goto out_unlock;
- set_device_ro(bdev, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0);
+ set_disk_ro(lo->lo_disk, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0);
lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO;
lo->lo_device = bdev;
@@ -1168,9 +1160,6 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
size = get_loop_size(lo, file);
loop_set_size(lo, size);
- set_blocksize(bdev, S_ISBLK(inode->i_mode) ?
- block_size(inode->i_bdev) : PAGE_SIZE);
-
lo->lo_state = Lo_bound;
if (part_shift)
lo->lo_flags |= LO_FLAGS_PARTSCAN;
@@ -1185,15 +1174,15 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
mutex_unlock(&loop_ctl_mutex);
if (partscan)
loop_reread_partitions(lo, bdev);
- if (claimed_bdev)
- bd_abort_claiming(bdev, claimed_bdev, loop_configure);
+ if (!(mode & FMODE_EXCL))
+ bd_abort_claiming(bdev, loop_configure);
return 0;
out_unlock:
mutex_unlock(&loop_ctl_mutex);
out_bdev:
- if (claimed_bdev)
- bd_abort_claiming(bdev, claimed_bdev, loop_configure);
+ if (!(mode & FMODE_EXCL))
+ bd_abort_claiming(bdev, loop_configure);
out_putf:
fput(file);
out:
@@ -1252,7 +1241,6 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
set_capacity(lo->lo_disk, 0);
loop_sysfs_exit(lo);
if (bdev) {
- bd_set_nr_sectors(bdev, 0);
/* let user-space know about this change */
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
}
@@ -2235,24 +2223,18 @@ out:
return ret;
}
-static struct kobject *loop_probe(dev_t dev, int *part, void *data)
+static void loop_probe(dev_t dev)
{
+ int idx = MINOR(dev) >> part_shift;
struct loop_device *lo;
- struct kobject *kobj;
- int err;
+
+ if (max_loop && idx >= max_loop)
+ return;
mutex_lock(&loop_ctl_mutex);
- err = loop_lookup(&lo, MINOR(dev) >> part_shift);
- if (err < 0)
- err = loop_add(&lo, MINOR(dev) >> part_shift);
- if (err < 0)
- kobj = NULL;
- else
- kobj = get_disk_and_module(lo->lo_disk);
+ if (loop_lookup(&lo, idx) < 0)
+ loop_add(&lo, idx);
mutex_unlock(&loop_ctl_mutex);
-
- *part = 0;
- return kobj;
}
static long loop_control_ioctl(struct file *file, unsigned int cmd,
@@ -2372,14 +2354,11 @@ static int __init loop_init(void)
goto err_out;
- if (register_blkdev(LOOP_MAJOR, "loop")) {
+ if (__register_blkdev(LOOP_MAJOR, "loop", loop_probe)) {
err = -EIO;
goto misc_out;
}
- blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
- THIS_MODULE, loop_probe, NULL, NULL);
-
/* pre-create number of devices given by config or max_loop */
mutex_lock(&loop_ctl_mutex);
for (i = 0; i < nr; i++)
@@ -2405,16 +2384,11 @@ static int loop_exit_cb(int id, void *ptr, void *data)
static void __exit loop_exit(void)
{
- unsigned long range;
-
- range = max_loop ? max_loop << part_shift : 1UL << MINORBITS;
-
mutex_lock(&loop_ctl_mutex);
idr_for_each(&loop_index_idr, &loop_exit_cb, NULL);
idr_destroy(&loop_index_idr);
- blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range);
unregister_blkdev(LOOP_MAJOR, "loop");
misc_deregister(&loop_misc);
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 153e2cdecb4d..53ac59d19ae5 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3687,7 +3687,6 @@ skip_create_disk:
/* Enable the block device and add it to /dev */
device_add_disk(&dd->pdev->dev, dd->disk, NULL);
- dd->bdev = bdget_disk(dd->disk, 0);
/*
* Now that the disk is active, initialize any sysfs attributes
* managed by the protocol layer.
@@ -3721,9 +3720,6 @@ start_service_thread:
return rv;
kthread_run_error:
- bdput(dd->bdev);
- dd->bdev = NULL;
-
/* Delete our gendisk. This also removes the device from /dev */
del_gendisk(dd->disk);
@@ -3804,14 +3800,6 @@ static int mtip_block_remove(struct driver_data *dd)
blk_mq_tagset_busy_iter(&dd->tags, mtip_no_dev_cleanup, dd);
blk_mq_unquiesce_queue(dd->queue);
- /*
- * Delete our gendisk structure. This also removes the device
- * from /dev
- */
- if (dd->bdev) {
- bdput(dd->bdev);
- dd->bdev = NULL;
- }
if (dd->disk) {
if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
del_gendisk(dd->disk);
@@ -4206,9 +4194,6 @@ static void mtip_pci_remove(struct pci_dev *pdev)
} while (atomic_read(&dd->irq_workers_active) != 0 &&
time_before(jiffies, to));
- if (!dd->sr)
- fsync_bdev(dd->bdev);
-
if (atomic_read(&dd->irq_workers_active) != 0) {
dev_warn(&dd->pdev->dev,
"Completion workers still active!\n");
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index e22a7f0523bf..88f4206310e4 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -463,8 +463,6 @@ struct driver_data {
int isr_binding;
- struct block_device *bdev;
-
struct list_head online_list; /* linkage for online list */
struct list_head remove_list; /* linkage for removing list */
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index aaae9220f3a0..92f84ed0ba9e 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -296,40 +296,32 @@ static void nbd_size_clear(struct nbd_device *nbd)
}
}
-static void nbd_size_update(struct nbd_device *nbd, bool start)
+static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
+ loff_t blksize)
{
- struct nbd_config *config = nbd->config;
- struct block_device *bdev = bdget_disk(nbd->disk, 0);
- sector_t nr_sectors = config->bytesize >> 9;
+ if (!blksize)
+ blksize = NBD_DEF_BLKSIZE;
+ if (blksize < 512 || blksize > PAGE_SIZE || !is_power_of_2(blksize))
+ return -EINVAL;
+
+ nbd->config->bytesize = bytesize;
+ nbd->config->blksize = blksize;
- if (config->flags & NBD_FLAG_SEND_TRIM) {
- nbd->disk->queue->limits.discard_granularity = config->blksize;
- nbd->disk->queue->limits.discard_alignment = config->blksize;
+ if (!nbd->task_recv)
+ return 0;
+
+ if (nbd->config->flags & NBD_FLAG_SEND_TRIM) {
+ nbd->disk->queue->limits.discard_granularity = blksize;
+ nbd->disk->queue->limits.discard_alignment = blksize;
blk_queue_max_discard_sectors(nbd->disk->queue, UINT_MAX);
}
- blk_queue_logical_block_size(nbd->disk->queue, config->blksize);
- blk_queue_physical_block_size(nbd->disk->queue, config->blksize);
- set_capacity(nbd->disk, nr_sectors);
- if (bdev) {
- if (bdev->bd_disk) {
- bd_set_nr_sectors(bdev, nr_sectors);
- if (start)
- set_blocksize(bdev, config->blksize);
- } else
- set_bit(GD_NEED_PART_SCAN, &nbd->disk->state);
- bdput(bdev);
- }
- kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
-}
+ blk_queue_logical_block_size(nbd->disk->queue, blksize);
+ blk_queue_physical_block_size(nbd->disk->queue, blksize);
-static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize,
- loff_t nr_blocks)
-{
- struct nbd_config *config = nbd->config;
- config->blksize = blocksize;
- config->bytesize = blocksize * nr_blocks;
- if (nbd->task_recv != NULL)
- nbd_size_update(nbd, false);
+ set_bit(GD_NEED_PART_SCAN, &nbd->disk->state);
+ if (!set_capacity_and_notify(nbd->disk, bytesize >> 9))
+ kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
+ return 0;
}
static void nbd_complete_rq(struct request *req)
@@ -1140,7 +1132,7 @@ static void nbd_bdev_reset(struct block_device *bdev)
{
if (bdev->bd_openers > 1)
return;
- bd_set_nr_sectors(bdev, 0);
+ set_capacity(bdev->bd_disk, 0);
}
static void nbd_parse_flags(struct nbd_device *nbd)
@@ -1309,8 +1301,7 @@ static int nbd_start_device(struct nbd_device *nbd)
args->index = i;
queue_work(nbd->recv_workq, &args->work);
}
- nbd_size_update(nbd, true);
- return error;
+ return nbd_set_size(nbd, config->bytesize, config->blksize);
}
static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *bdev)
@@ -1352,14 +1343,6 @@ static void nbd_clear_sock_ioctl(struct nbd_device *nbd,
nbd_config_put(nbd);
}
-static bool nbd_is_valid_blksize(unsigned long blksize)
-{
- if (!blksize || !is_power_of_2(blksize) || blksize < 512 ||
- blksize > PAGE_SIZE)
- return false;
- return true;
-}
-
static void nbd_set_cmd_timeout(struct nbd_device *nbd, u64 timeout)
{
nbd->tag_set.timeout = timeout * HZ;
@@ -1384,20 +1367,12 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
case NBD_SET_SOCK:
return nbd_add_socket(nbd, arg, false);
case NBD_SET_BLKSIZE:
- if (!arg)
- arg = NBD_DEF_BLKSIZE;
- if (!nbd_is_valid_blksize(arg))
- return -EINVAL;
- nbd_size_set(nbd, arg,
- div_s64(config->bytesize, arg));
- return 0;
+ return nbd_set_size(nbd, config->bytesize, arg);
case NBD_SET_SIZE:
- nbd_size_set(nbd, config->blksize,
- div_s64(arg, config->blksize));
- return 0;
+ return nbd_set_size(nbd, arg, config->blksize);
case NBD_SET_SIZE_BLOCKS:
- nbd_size_set(nbd, config->blksize, arg);
- return 0;
+ return nbd_set_size(nbd, arg * config->blksize,
+ config->blksize);
case NBD_SET_TIMEOUT:
nbd_set_cmd_timeout(nbd, arg);
return 0;
@@ -1513,12 +1488,10 @@ out:
static void nbd_release(struct gendisk *disk, fmode_t mode)
{
struct nbd_device *nbd = disk->private_data;
- struct block_device *bdev = bdget_disk(disk, 0);
if (test_bit(NBD_RT_DISCONNECT_ON_CLOSE, &nbd->config->runtime_flags) &&
- bdev->bd_openers == 0)
+ disk->part0->bd_openers == 0)
nbd_disconnect_and_put(nbd);
- bdput(bdev);
nbd_config_put(nbd);
nbd_put(nbd);
@@ -1815,18 +1788,11 @@ static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd)
if (info->attrs[NBD_ATTR_SIZE_BYTES])
bytes = nla_get_u64(info->attrs[NBD_ATTR_SIZE_BYTES]);
- if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]) {
+ if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES])
bsize = nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]);
- if (!bsize)
- bsize = NBD_DEF_BLKSIZE;
- if (!nbd_is_valid_blksize(bsize)) {
- printk(KERN_ERR "Invalid block size %llu\n", bsize);
- return -EINVAL;
- }
- }
if (bytes != config->bytesize || bsize != config->blksize)
- nbd_size_set(nbd, bsize, div64_u64(bytes, bsize));
+ return nbd_set_size(nbd, bytes, bsize);
return 0;
}
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 467dbd06b7cd..b8bb8ec7538d 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2130,8 +2130,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
}
set_capacity(pd->disk, lba << 2);
- set_capacity(pd->bdev->bd_disk, lba << 2);
- bd_set_nr_sectors(pd->bdev, lba << 2);
+ set_capacity_and_notify(pd->bdev->bd_disk, lba << 2);
q = bdev_get_queue(pd->bdev);
if (write) {
@@ -2584,9 +2583,11 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
case CDROM_LAST_WRITTEN:
case CDROM_SEND_PACKET:
case SCSI_IOCTL_SEND_COMMAND:
- ret = __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg);
+ if (!bdev->bd_disk->fops->ioctl)
+ ret = -ENOTTY;
+ else
+ ret = bdev->bd_disk->fops->ioctl(bdev, mode, cmd, arg);
break;
-
default:
pkt_dbg(2, pd, "Unknown ioctl (%x)\n", cmd);
ret = -ENOTTY;
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index f84128abade3..2ed79b09439a 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -692,12 +692,9 @@ static void rbd_release(struct gendisk *disk, fmode_t mode)
put_device(&rbd_dev->dev);
}
-static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg)
+static int rbd_set_read_only(struct block_device *bdev, bool ro)
{
- int ro;
-
- if (get_user(ro, (int __user *)arg))
- return -EFAULT;
+ struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
/*
* Both images mapped read-only and snapshots can't be marked
@@ -710,43 +707,14 @@ static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg)
rbd_assert(!rbd_is_snap(rbd_dev));
}
- /* Let blkdev_roset() handle it */
- return -ENOTTY;
-}
-
-static int rbd_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
-{
- struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
- int ret;
-
- switch (cmd) {
- case BLKROSET:
- ret = rbd_ioctl_set_ro(rbd_dev, arg);
- break;
- default:
- ret = -ENOTTY;
- }
-
- return ret;
-}
-
-#ifdef CONFIG_COMPAT
-static int rbd_compat_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
-{
- return rbd_ioctl(bdev, mode, cmd, arg);
+ return 0;
}
-#endif /* CONFIG_COMPAT */
static const struct block_device_operations rbd_bd_ops = {
.owner = THIS_MODULE,
.open = rbd_open,
.release = rbd_release,
- .ioctl = rbd_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = rbd_compat_ioctl,
-#endif
+ .set_read_only = rbd_set_read_only,
};
/*
@@ -4920,8 +4888,7 @@ static void rbd_dev_update_size(struct rbd_device *rbd_dev)
!test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) {
size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE;
dout("setting size to %llu sectors", (unsigned long long)size);
- set_capacity(rbd_dev->disk, size);
- revalidate_disk_size(rbd_dev->disk, true);
+ set_capacity_and_notify(rbd_dev->disk, size);
}
}
diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
index 8b2411ccbda9..bb13d7dd195a 100644
--- a/drivers/block/rnbd/rnbd-clt.c
+++ b/drivers/block/rnbd/rnbd-clt.c
@@ -100,8 +100,7 @@ static int rnbd_clt_change_capacity(struct rnbd_clt_dev *dev,
rnbd_clt_info(dev, "Device size changed from %zu to %zu sectors\n",
dev->nsectors, new_nsectors);
dev->nsectors = new_nsectors;
- set_capacity(dev->gd, dev->nsectors);
- revalidate_disk_size(dev->gd, true);
+ set_capacity_and_notify(dev->gd, dev->nsectors);
return 0;
}
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index 52dd1efa00f9..cc6a0bc6c005 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -745,18 +745,6 @@ static const struct block_device_operations floppy_fops = {
.check_events = floppy_check_events,
};
-static struct kobject *floppy_find(dev_t dev, int *part, void *data)
-{
- struct swim_priv *swd = data;
- int drive = (*part & 3);
-
- if (drive >= swd->floppy_count)
- return NULL;
-
- *part = 0;
- return get_disk_and_module(swd->unit[drive].disk);
-}
-
static int swim_add_floppy(struct swim_priv *swd, enum drive_location location)
{
struct floppy_state *fs = &swd->unit[swd->floppy_count];
@@ -846,9 +834,6 @@ static int swim_floppy_init(struct swim_priv *swd)
add_disk(swd->unit[drive].disk);
}
- blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
- floppy_find, NULL, swd);
-
return 0;
exit_put_disks:
@@ -932,8 +917,6 @@ static int swim_remove(struct platform_device *dev)
int drive;
struct resource *res;
- blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
-
for (drive = 0; drive < swd->floppy_count; drive++) {
del_gendisk(swd->unit[drive].disk);
blk_cleanup_queue(swd->unit[drive].disk->queue);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index a314b9382442..145606dc52db 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -470,7 +470,7 @@ static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize)
cap_str_10,
cap_str_2);
- set_capacity_revalidate_and_notify(vblk->disk, capacity, true);
+ set_capacity_and_notify(vblk->disk, capacity);
}
static void virtblk_config_changed_work(struct work_struct *work)
@@ -598,7 +598,6 @@ static void virtblk_update_cache_mode(struct virtio_device *vdev)
struct virtio_blk *vblk = vdev->priv;
blk_queue_write_cache(vblk->disk->queue, writeback, false);
- revalidate_disk_size(vblk->disk, true);
}
static const char *const virtblk_cache_types[] = {
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index a1b9df2c4ef1..b0c71d3a81a0 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -356,9 +356,7 @@ struct pending_req {
};
-#define vbd_sz(_v) ((_v)->bdev->bd_part ? \
- (_v)->bdev->bd_part->nr_sects : \
- get_capacity((_v)->bdev->bd_disk))
+#define vbd_sz(_v) bdev_nr_sectors((_v)->bdev)
#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
#define xen_blkif_put(_b) \
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 48629d3433b4..188e0b47534b 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -2153,7 +2153,7 @@ static void blkfront_closing(struct blkfront_info *info)
}
if (info->gd)
- bdev = bdget_disk(info->gd, 0);
+ bdev = bdgrab(info->gd->part0);
mutex_unlock(&info->mutex);
@@ -2370,7 +2370,7 @@ static void blkfront_connect(struct blkfront_info *info)
return;
printk(KERN_INFO "Setting capacity to %Lu\n",
sectors);
- set_capacity_revalidate_and_notify(info->gd, sectors, true);
+ set_capacity_and_notify(info->gd, sectors);
return;
case BLKIF_STATE_SUSPENDED:
@@ -2518,7 +2518,7 @@ static int blkfront_remove(struct xenbus_device *xbdev)
disk = info->gd;
if (disk)
- bdev = bdget_disk(disk, 0);
+ bdev = bdgrab(disk->part0);
info->xbdev = NULL;
mutex_unlock(&info->mutex);
@@ -2595,19 +2595,11 @@ out:
static void blkif_release(struct gendisk *disk, fmode_t mode)
{
struct blkfront_info *info = disk->private_data;
- struct block_device *bdev;
struct xenbus_device *xbdev;
mutex_lock(&blkfront_mutex);
-
- bdev = bdget_disk(disk, 0);
-
- if (!bdev) {
- WARN(1, "Block device %s yanked out from us!\n", disk->disk_name);
+ if (disk->part0->bd_openers)
goto out_mutex;
- }
- if (bdev->bd_openers)
- goto out;
/*
* Check if we have been instructed to close. We will have
@@ -2619,7 +2611,7 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)
if (xbdev && xbdev->state == XenbusStateClosing) {
/* pending switch to state closed */
- dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n");
+ dev_info(disk_to_dev(disk), "releasing disk\n");
xlvbd_release_gendisk(info);
xenbus_frontend_closed(info->xbdev);
}
@@ -2628,14 +2620,12 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)
if (!xbdev) {
/* sudden device removal */
- dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n");
+ dev_info(disk_to_dev(disk), "releasing disk\n");
xlvbd_release_gendisk(info);
disk->private_data = NULL;
free_info(info);
}
-out:
- bdput(bdev);
out_mutex:
mutex_unlock(&blkfront_mutex);
}
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 0e734802ee7c..c1d20818e649 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -42,7 +42,6 @@
#include <linux/zorro.h>
-
#define Z2MINOR_COMBINED (0)
#define Z2MINOR_Z2ONLY (1)
#define Z2MINOR_CHIPONLY (2)
@@ -50,28 +49,28 @@
#define Z2MINOR_MEMLIST2 (5)
#define Z2MINOR_MEMLIST3 (6)
#define Z2MINOR_MEMLIST4 (7)
-#define Z2MINOR_COUNT (8) /* Move this down when adding a new minor */
+#define Z2MINOR_COUNT (8) /* Move this down when adding a new minor */
#define Z2RAM_CHUNK1024 ( Z2RAM_CHUNKSIZE >> 10 )
static DEFINE_MUTEX(z2ram_mutex);
-static u_long *z2ram_map = NULL;
-static u_long z2ram_size = 0;
-static int z2_count = 0;
-static int chip_count = 0;
-static int list_count = 0;
-static int current_device = -1;
+static u_long *z2ram_map = NULL;
+static u_long z2ram_size = 0;
+static int z2_count = 0;
+static int chip_count = 0;
+static int list_count = 0;
+static int current_device = -1;
static DEFINE_SPINLOCK(z2ram_lock);
-static struct gendisk *z2ram_gendisk;
+static struct gendisk *z2ram_gendisk[Z2MINOR_COUNT];
static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{
struct request *req = bd->rq;
unsigned long start = blk_rq_pos(req) << 9;
- unsigned long len = blk_rq_cur_bytes(req);
+ unsigned long len = blk_rq_cur_bytes(req);
blk_mq_start_request(req);
@@ -92,7 +91,7 @@ static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx,
if (len < size)
size = len;
- addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ];
+ addr += z2ram_map[start >> Z2RAM_CHUNKSHIFT];
if (rq_data_dir(req) == READ)
memcpy(buffer, (char *)addr, size);
else
@@ -106,323 +105,319 @@ static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx,
return BLK_STS_OK;
}
-static void
-get_z2ram( void )
+static void get_z2ram(void)
{
- int i;
-
- for ( i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++ )
- {
- if ( test_bit( i, zorro_unused_z2ram ) )
- {
- z2_count++;
- z2ram_map[z2ram_size++] = (unsigned long)ZTWO_VADDR(Z2RAM_START) +
- (i << Z2RAM_CHUNKSHIFT);
- clear_bit( i, zorro_unused_z2ram );
+ int i;
+
+ for (i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++) {
+ if (test_bit(i, zorro_unused_z2ram)) {
+ z2_count++;
+ z2ram_map[z2ram_size++] =
+ (unsigned long)ZTWO_VADDR(Z2RAM_START) +
+ (i << Z2RAM_CHUNKSHIFT);
+ clear_bit(i, zorro_unused_z2ram);
+ }
}
- }
- return;
+ return;
}
-static void
-get_chipram( void )
+static void get_chipram(void)
{
- while ( amiga_chip_avail() > ( Z2RAM_CHUNKSIZE * 4 ) )
- {
- chip_count++;
- z2ram_map[ z2ram_size ] =
- (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE, "z2ram" );
+ while (amiga_chip_avail() > (Z2RAM_CHUNKSIZE * 4)) {
+ chip_count++;
+ z2ram_map[z2ram_size] =
+ (u_long) amiga_chip_alloc(Z2RAM_CHUNKSIZE, "z2ram");
+
+ if (z2ram_map[z2ram_size] == 0) {
+ break;
+ }
- if ( z2ram_map[ z2ram_size ] == 0 )
- {
- break;
+ z2ram_size++;
}
- z2ram_size++;
- }
-
- return;
+ return;
}
static int z2_open(struct block_device *bdev, fmode_t mode)
{
- int device;
- int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
- sizeof( z2ram_map[0] );
- int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) *
- sizeof( z2ram_map[0] );
- int rc = -ENOMEM;
-
- device = MINOR(bdev->bd_dev);
-
- mutex_lock(&z2ram_mutex);
- if ( current_device != -1 && current_device != device )
- {
- rc = -EBUSY;
- goto err_out;
- }
-
- if ( current_device == -1 )
- {
- z2_count = 0;
- chip_count = 0;
- list_count = 0;
- z2ram_size = 0;
-
- /* Use a specific list entry. */
- if (device >= Z2MINOR_MEMLIST1 && device <= Z2MINOR_MEMLIST4) {
- int index = device - Z2MINOR_MEMLIST1 + 1;
- unsigned long size, paddr, vaddr;
-
- if (index >= m68k_realnum_memory) {
- printk( KERN_ERR DEVICE_NAME
- ": no such entry in z2ram_map\n" );
- goto err_out;
- }
+ int device;
+ int max_z2_map = (Z2RAM_SIZE / Z2RAM_CHUNKSIZE) * sizeof(z2ram_map[0]);
+ int max_chip_map = (amiga_chip_size / Z2RAM_CHUNKSIZE) *
+ sizeof(z2ram_map[0]);
+ int rc = -ENOMEM;
- paddr = m68k_memory[index].addr;
- size = m68k_memory[index].size & ~(Z2RAM_CHUNKSIZE-1);
+ device = MINOR(bdev->bd_dev);
-#ifdef __powerpc__
- /* FIXME: ioremap doesn't build correct memory tables. */
- {
- vfree(vmalloc (size));
- }
-
- vaddr = (unsigned long)ioremap_wt(paddr, size);
-
-#else
- vaddr = (unsigned long)z_remap_nocache_nonser(paddr, size);
-#endif
- z2ram_map =
- kmalloc_array(size / Z2RAM_CHUNKSIZE,
- sizeof(z2ram_map[0]),
- GFP_KERNEL);
- if ( z2ram_map == NULL )
- {
- printk( KERN_ERR DEVICE_NAME
- ": cannot get mem for z2ram_map\n" );
- goto err_out;
- }
+ mutex_lock(&z2ram_mutex);
+ if (current_device != -1 && current_device != device) {
+ rc = -EBUSY;
+ goto err_out;
+ }
- while (size) {
- z2ram_map[ z2ram_size++ ] = vaddr;
- size -= Z2RAM_CHUNKSIZE;
- vaddr += Z2RAM_CHUNKSIZE;
- list_count++;
- }
+ if (current_device == -1) {
+ z2_count = 0;
+ chip_count = 0;
+ list_count = 0;
+ z2ram_size = 0;
- if ( z2ram_size != 0 )
- printk( KERN_INFO DEVICE_NAME
- ": using %iK List Entry %d Memory\n",
- list_count * Z2RAM_CHUNK1024, index );
- } else
-
- switch ( device )
- {
- case Z2MINOR_COMBINED:
-
- z2ram_map = kmalloc( max_z2_map + max_chip_map, GFP_KERNEL );
- if ( z2ram_map == NULL )
- {
- printk( KERN_ERR DEVICE_NAME
- ": cannot get mem for z2ram_map\n" );
- goto err_out;
- }
+ /* Use a specific list entry. */
+ if (device >= Z2MINOR_MEMLIST1 && device <= Z2MINOR_MEMLIST4) {
+ int index = device - Z2MINOR_MEMLIST1 + 1;
+ unsigned long size, paddr, vaddr;
- get_z2ram();
- get_chipram();
-
- if ( z2ram_size != 0 )
- printk( KERN_INFO DEVICE_NAME
- ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)\n",
- z2_count * Z2RAM_CHUNK1024,
- chip_count * Z2RAM_CHUNK1024,
- ( z2_count + chip_count ) * Z2RAM_CHUNK1024 );
-
- break;
-
- case Z2MINOR_Z2ONLY:
- z2ram_map = kmalloc( max_z2_map, GFP_KERNEL );
- if ( z2ram_map == NULL )
- {
- printk( KERN_ERR DEVICE_NAME
- ": cannot get mem for z2ram_map\n" );
- goto err_out;
- }
+ if (index >= m68k_realnum_memory) {
+ printk(KERN_ERR DEVICE_NAME
+ ": no such entry in z2ram_map\n");
+ goto err_out;
+ }
- get_z2ram();
+ paddr = m68k_memory[index].addr;
+ size = m68k_memory[index].size & ~(Z2RAM_CHUNKSIZE - 1);
- if ( z2ram_size != 0 )
- printk( KERN_INFO DEVICE_NAME
- ": using %iK of Zorro II RAM\n",
- z2_count * Z2RAM_CHUNK1024 );
+#ifdef __powerpc__
+ /* FIXME: ioremap doesn't build correct memory tables. */
+ {
+ vfree(vmalloc(size));
+ }
- break;
+ vaddr = (unsigned long)ioremap_wt(paddr, size);
- case Z2MINOR_CHIPONLY:
- z2ram_map = kmalloc( max_chip_map, GFP_KERNEL );
- if ( z2ram_map == NULL )
- {
- printk( KERN_ERR DEVICE_NAME
- ": cannot get mem for z2ram_map\n" );
- goto err_out;
+#else
+ vaddr =
+ (unsigned long)z_remap_nocache_nonser(paddr, size);
+#endif
+ z2ram_map =
+ kmalloc_array(size / Z2RAM_CHUNKSIZE,
+ sizeof(z2ram_map[0]), GFP_KERNEL);
+ if (z2ram_map == NULL) {
+ printk(KERN_ERR DEVICE_NAME
+ ": cannot get mem for z2ram_map\n");
+ goto err_out;
+ }
+
+ while (size) {
+ z2ram_map[z2ram_size++] = vaddr;
+ size -= Z2RAM_CHUNKSIZE;
+ vaddr += Z2RAM_CHUNKSIZE;
+ list_count++;
+ }
+
+ if (z2ram_size != 0)
+ printk(KERN_INFO DEVICE_NAME
+ ": using %iK List Entry %d Memory\n",
+ list_count * Z2RAM_CHUNK1024, index);
+ } else
+ switch (device) {
+ case Z2MINOR_COMBINED:
+
+ z2ram_map =
+ kmalloc(max_z2_map + max_chip_map,
+ GFP_KERNEL);
+ if (z2ram_map == NULL) {
+ printk(KERN_ERR DEVICE_NAME
+ ": cannot get mem for z2ram_map\n");
+ goto err_out;
+ }
+
+ get_z2ram();
+ get_chipram();
+
+ if (z2ram_size != 0)
+ printk(KERN_INFO DEVICE_NAME
+ ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)\n",
+ z2_count * Z2RAM_CHUNK1024,
+ chip_count * Z2RAM_CHUNK1024,
+ (z2_count +
+ chip_count) * Z2RAM_CHUNK1024);
+
+ break;
+
+ case Z2MINOR_Z2ONLY:
+ z2ram_map = kmalloc(max_z2_map, GFP_KERNEL);
+ if (z2ram_map == NULL) {
+ printk(KERN_ERR DEVICE_NAME
+ ": cannot get mem for z2ram_map\n");
+ goto err_out;
+ }
+
+ get_z2ram();
+
+ if (z2ram_size != 0)
+ printk(KERN_INFO DEVICE_NAME
+ ": using %iK of Zorro II RAM\n",
+ z2_count * Z2RAM_CHUNK1024);
+
+ break;
+
+ case Z2MINOR_CHIPONLY:
+ z2ram_map = kmalloc(max_chip_map, GFP_KERNEL);
+ if (z2ram_map == NULL) {
+ printk(KERN_ERR DEVICE_NAME
+ ": cannot get mem for z2ram_map\n");
+ goto err_out;
+ }
+
+ get_chipram();
+
+ if (z2ram_size != 0)
+ printk(KERN_INFO DEVICE_NAME
+ ": using %iK Chip RAM\n",
+ chip_count * Z2RAM_CHUNK1024);
+
+ break;
+
+ default:
+ rc = -ENODEV;
+ goto err_out;
+
+ break;
+ }
+
+ if (z2ram_size == 0) {
+ printk(KERN_NOTICE DEVICE_NAME
+ ": no unused ZII/Chip RAM found\n");
+ goto err_out_kfree;
}
- get_chipram();
-
- if ( z2ram_size != 0 )
- printk( KERN_INFO DEVICE_NAME
- ": using %iK Chip RAM\n",
- chip_count * Z2RAM_CHUNK1024 );
-
- break;
-
- default:
- rc = -ENODEV;
- goto err_out;
-
- break;
- }
-
- if ( z2ram_size == 0 )
- {
- printk( KERN_NOTICE DEVICE_NAME
- ": no unused ZII/Chip RAM found\n" );
- goto err_out_kfree;
+ current_device = device;
+ z2ram_size <<= Z2RAM_CHUNKSHIFT;
+ set_capacity(z2ram_gendisk[device], z2ram_size >> 9);
}
- current_device = device;
- z2ram_size <<= Z2RAM_CHUNKSHIFT;
- set_capacity(z2ram_gendisk, z2ram_size >> 9);
- }
-
- mutex_unlock(&z2ram_mutex);
- return 0;
+ mutex_unlock(&z2ram_mutex);
+ return 0;
err_out_kfree:
- kfree(z2ram_map);
+ kfree(z2ram_map);
err_out:
- mutex_unlock(&z2ram_mutex);
- return rc;
+ mutex_unlock(&z2ram_mutex);
+ return rc;
}
-static void
-z2_release(struct gendisk *disk, fmode_t mode)
+static void z2_release(struct gendisk *disk, fmode_t mode)
{
- mutex_lock(&z2ram_mutex);
- if ( current_device == -1 ) {
- mutex_unlock(&z2ram_mutex);
- return;
- }
- mutex_unlock(&z2ram_mutex);
- /*
- * FIXME: unmap memory
- */
+ mutex_lock(&z2ram_mutex);
+ if (current_device == -1) {
+ mutex_unlock(&z2ram_mutex);
+ return;
+ }
+ mutex_unlock(&z2ram_mutex);
+ /*
+ * FIXME: unmap memory
+ */
}
-static const struct block_device_operations z2_fops =
-{
- .owner = THIS_MODULE,
- .open = z2_open,
- .release = z2_release,
+static const struct block_device_operations z2_fops = {
+ .owner = THIS_MODULE,
+ .open = z2_open,
+ .release = z2_release,
};
-static struct kobject *z2_find(dev_t dev, int *part, void *data)
-{
- *part = 0;
- return get_disk_and_module(z2ram_gendisk);
-}
-
-static struct request_queue *z2_queue;
static struct blk_mq_tag_set tag_set;
static const struct blk_mq_ops z2_mq_ops = {
- .queue_rq = z2_queue_rq,
+ .queue_rq = z2_queue_rq,
};
-static int __init
-z2_init(void)
+static int z2ram_register_disk(int minor)
{
- int ret;
-
- if (!MACH_IS_AMIGA)
- return -ENODEV;
-
- ret = -EBUSY;
- if (register_blkdev(Z2RAM_MAJOR, DEVICE_NAME))
- goto err;
-
- ret = -ENOMEM;
- z2ram_gendisk = alloc_disk(1);
- if (!z2ram_gendisk)
- goto out_disk;
-
- z2_queue = blk_mq_init_sq_queue(&tag_set, &z2_mq_ops, 16,
- BLK_MQ_F_SHOULD_MERGE);
- if (IS_ERR(z2_queue)) {
- ret = PTR_ERR(z2_queue);
- z2_queue = NULL;
- goto out_queue;
- }
-
- z2ram_gendisk->major = Z2RAM_MAJOR;
- z2ram_gendisk->first_minor = 0;
- z2ram_gendisk->fops = &z2_fops;
- sprintf(z2ram_gendisk->disk_name, "z2ram");
-
- z2ram_gendisk->queue = z2_queue;
- add_disk(z2ram_gendisk);
- blk_register_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT, THIS_MODULE,
- z2_find, NULL, NULL);
-
- return 0;
-
-out_queue:
- put_disk(z2ram_gendisk);
-out_disk:
- unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME);
-err:
- return ret;
+ struct request_queue *q;
+ struct gendisk *disk;
+
+ disk = alloc_disk(1);
+ if (!disk)
+ return -ENOMEM;
+
+ q = blk_mq_init_queue(&tag_set);
+ if (IS_ERR(q)) {
+ put_disk(disk);
+ return PTR_ERR(q);
+ }
+
+ disk->major = Z2RAM_MAJOR;
+ disk->first_minor = minor;
+ disk->fops = &z2_fops;
+ if (minor)
+ sprintf(disk->disk_name, "z2ram%d", minor);
+ else
+ sprintf(disk->disk_name, "z2ram");
+ disk->queue = q;
+
+ z2ram_gendisk[minor] = disk;
+ add_disk(disk);
+ return 0;
}
-static void __exit z2_exit(void)
+static int __init z2_init(void)
{
- int i, j;
- blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT);
- unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME);
- del_gendisk(z2ram_gendisk);
- put_disk(z2ram_gendisk);
- blk_cleanup_queue(z2_queue);
- blk_mq_free_tag_set(&tag_set);
-
- if ( current_device != -1 )
- {
- i = 0;
-
- for ( j = 0 ; j < z2_count; j++ )
- {
- set_bit( i++, zorro_unused_z2ram );
+ int ret, i;
+
+ if (!MACH_IS_AMIGA)
+ return -ENODEV;
+
+ if (register_blkdev(Z2RAM_MAJOR, DEVICE_NAME))
+ return -EBUSY;
+
+ tag_set.ops = &z2_mq_ops;
+ tag_set.nr_hw_queues = 1;
+ tag_set.nr_maps = 1;
+ tag_set.queue_depth = 16;
+ tag_set.numa_node = NUMA_NO_NODE;
+ tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
+ ret = blk_mq_alloc_tag_set(&tag_set);
+ if (ret)
+ goto out_unregister_blkdev;
+
+ for (i = 0; i < Z2MINOR_COUNT; i++) {
+ ret = z2ram_register_disk(i);
+ if (ret && i == 0)
+ goto out_free_tagset;
}
- for ( j = 0 ; j < chip_count; j++ )
- {
- if ( z2ram_map[ i ] )
- {
- amiga_chip_free( (void *) z2ram_map[ i++ ] );
- }
+ return 0;
+
+out_free_tagset:
+ blk_mq_free_tag_set(&tag_set);
+out_unregister_blkdev:
+ unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME);
+ return ret;
+}
+
+static void __exit z2_exit(void)
+{
+ int i, j;
+
+ unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME);
+
+ for (i = 0; i < Z2MINOR_COUNT; i++) {
+ del_gendisk(z2ram_gendisk[i]);
+ blk_cleanup_queue(z2ram_gendisk[i]->queue);
+ put_disk(z2ram_gendisk[i]);
}
+ blk_mq_free_tag_set(&tag_set);
+
+ if (current_device != -1) {
+ i = 0;
- if ( z2ram_map != NULL )
- {
- kfree( z2ram_map );
+ for (j = 0; j < z2_count; j++) {
+ set_bit(i++, zorro_unused_z2ram);
+ }
+
+ for (j = 0; j < chip_count; j++) {
+ if (z2ram_map[i]) {
+ amiga_chip_free((void *)z2ram_map[i++]);
+ }
+ }
+
+ if (z2ram_map != NULL) {
+ kfree(z2ram_map);
+ }
}
- }
- return;
-}
+ return;
+}
module_init(z2_init);
module_exit(z2_exit);
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 66a33e418940..e2933cb7a82a 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -403,13 +403,10 @@ static void reset_bdev(struct zram *zram)
return;
bdev = zram->bdev;
- if (zram->old_block_size)
- set_blocksize(bdev, zram->old_block_size);
blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
/* hope filp_close flush all of IO */
filp_close(zram->backing_dev, NULL);
zram->backing_dev = NULL;
- zram->old_block_size = 0;
zram->bdev = NULL;
zram->disk->fops = &zram_devops;
kvfree(zram->bitmap);
@@ -454,7 +451,7 @@ static ssize_t backing_dev_store(struct device *dev,
struct file *backing_dev = NULL;
struct inode *inode;
struct address_space *mapping;
- unsigned int bitmap_sz, old_block_size = 0;
+ unsigned int bitmap_sz;
unsigned long nr_pages, *bitmap = NULL;
struct block_device *bdev = NULL;
int err;
@@ -509,14 +506,8 @@ static ssize_t backing_dev_store(struct device *dev,
goto out;
}
- old_block_size = block_size(bdev);
- err = set_blocksize(bdev, PAGE_SIZE);
- if (err)
- goto out;
-
reset_bdev(zram);
- zram->old_block_size = old_block_size;
zram->bdev = bdev;
zram->backing_dev = backing_dev;
zram->bitmap = bitmap;
@@ -1710,8 +1701,8 @@ static void zram_reset_device(struct zram *zram)
disksize = zram->disksize;
zram->disksize = 0;
- set_capacity(zram->disk, 0);
- part_stat_set_all(&zram->disk->part0, 0);
+ set_capacity_and_notify(zram->disk, 0);
+ part_stat_set_all(zram->disk->part0, 0);
up_write(&zram->init_lock);
/* I/O operation under all of CPU are done so let's free */
@@ -1756,9 +1747,7 @@ static ssize_t disksize_store(struct device *dev,
zram->comp = comp;
zram->disksize = disksize;
- set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
-
- revalidate_disk_size(zram->disk, true);
+ set_capacity_and_notify(zram->disk, zram->disksize >> SECTOR_SHIFT);
up_write(&zram->init_lock);
return len;
@@ -1786,15 +1775,12 @@ static ssize_t reset_store(struct device *dev,
return -EINVAL;
zram = dev_to_zram(dev);
- bdev = bdget_disk(zram->disk, 0);
- if (!bdev)
- return -ENOMEM;
+ bdev = zram->disk->part0;
mutex_lock(&bdev->bd_mutex);
/* Do not reset an active device or claimed device */
if (bdev->bd_openers || zram->claim) {
mutex_unlock(&bdev->bd_mutex);
- bdput(bdev);
return -EBUSY;
}
@@ -1805,8 +1791,6 @@ static ssize_t reset_store(struct device *dev,
/* Make sure all the pending I/O are finished */
fsync_bdev(bdev);
zram_reset_device(zram);
- revalidate_disk_size(zram->disk, true);
- bdput(bdev);
mutex_lock(&bdev->bd_mutex);
zram->claim = false;
@@ -1992,16 +1976,11 @@ out_free_dev:
static int zram_remove(struct zram *zram)
{
- struct block_device *bdev;
-
- bdev = bdget_disk(zram->disk, 0);
- if (!bdev)
- return -ENOMEM;
+ struct block_device *bdev = zram->disk->part0;
mutex_lock(&bdev->bd_mutex);
if (bdev->bd_openers || zram->claim) {
mutex_unlock(&bdev->bd_mutex);
- bdput(bdev);
return -EBUSY;
}
@@ -2013,7 +1992,6 @@ static int zram_remove(struct zram *zram)
/* Make sure all the pending I/O are finished */
fsync_bdev(bdev);
zram_reset_device(zram);
- bdput(bdev);
pr_info("Removed device: %s\n", zram->disk->disk_name);
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 9cabcbb13fd9..419a7e8281ee 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -119,7 +119,6 @@ struct zram {
bool wb_limit_enable;
u64 bd_wb_limit;
struct block_device *bdev;
- unsigned int old_block_size;
unsigned long *bitmap;
unsigned long nr_pages;
#endif