Contributors: 15
Author |
Tokens |
Token Proportion |
Commits |
Commit Proportion |
Martin Schwidefsky |
262 |
40.18% |
6 |
17.65% |
Andrew Morton |
180 |
27.61% |
2 |
5.88% |
Stefan Haberland |
69 |
10.58% |
3 |
8.82% |
Stefan Weinhuber |
60 |
9.20% |
3 |
8.82% |
Christoph Hellwig |
28 |
4.29% |
2 |
5.88% |
Al Viro |
21 |
3.22% |
7 |
20.59% |
Horst Hummel |
11 |
1.69% |
2 |
5.88% |
Dan J Williams |
8 |
1.23% |
1 |
2.94% |
Heiko Carstens |
3 |
0.46% |
2 |
5.88% |
Hannes Reinecke |
2 |
0.31% |
1 |
2.94% |
Jarod Wilson |
2 |
0.31% |
1 |
2.94% |
Tejun Heo |
2 |
0.31% |
1 |
2.94% |
Joe Perches |
2 |
0.31% |
1 |
2.94% |
Linus Torvalds |
1 |
0.15% |
1 |
2.94% |
Greg Kroah-Hartman |
1 |
0.15% |
1 |
2.94% |
Total |
652 |
|
34 |
|
// SPDX-License-Identifier: GPL-2.0
/*
* Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
* Horst Hummel <Horst.Hummel@de.ibm.com>
* Carsten Otte <Cotte@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
* Bugreports.to..: <Linux390@de.ibm.com>
* Copyright IBM Corp. 1999, 2001
*
* gendisk related functions for the dasd driver.
*
*/
#define KMSG_COMPONENT "dasd"
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
#include <linux/uaccess.h>
/* This is ugly... */
#define PRINTK_HEADER "dasd_gendisk:"
#include "dasd_int.h"
/*
* Allocate and register gendisk structure for device.
*/
int dasd_gendisk_alloc(struct dasd_block *block)
{
struct gendisk *gdp;
struct dasd_device *base;
int len;
/* Make sure the minor for this device exists. */
base = block->base;
if (base->devindex >= DASD_PER_MAJOR)
return -EBUSY;
gdp = alloc_disk(1 << DASD_PARTN_BITS);
if (!gdp)
return -ENOMEM;
/* Initialize gendisk structure. */
gdp->major = DASD_MAJOR;
gdp->first_minor = base->devindex << DASD_PARTN_BITS;
gdp->fops = &dasd_device_operations;
/*
* Set device name.
* dasda - dasdz : 26 devices
* dasdaa - dasdzz : 676 devices, added up = 702
* dasdaaa - dasdzzz : 17576 devices, added up = 18278
* dasdaaaa - dasdzzzz : 456976 devices, added up = 475252
*/
len = sprintf(gdp->disk_name, "dasd");
if (base->devindex > 25) {
if (base->devindex > 701) {
if (base->devindex > 18277)
len += sprintf(gdp->disk_name + len, "%c",
'a'+(((base->devindex-18278)
/17576)%26));
len += sprintf(gdp->disk_name + len, "%c",
'a'+(((base->devindex-702)/676)%26));
}
len += sprintf(gdp->disk_name + len, "%c",
'a'+(((base->devindex-26)/26)%26));
}
len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26));
if (base->features & DASD_FEATURE_READONLY ||
test_bit(DASD_FLAG_DEVICE_RO, &base->flags))
set_disk_ro(gdp, 1);
dasd_add_link_to_gendisk(gdp, base);
gdp->queue = block->request_queue;
block->gdp = gdp;
set_capacity(block->gdp, 0);
device_add_disk(&base->cdev->dev, block->gdp, NULL);
return 0;
}
/*
* Unregister and free gendisk structure for device.
*/
void dasd_gendisk_free(struct dasd_block *block)
{
if (block->gdp) {
del_gendisk(block->gdp);
block->gdp->private_data = NULL;
put_disk(block->gdp);
block->gdp = NULL;
}
}
/*
* Trigger a partition detection.
*/
int dasd_scan_partitions(struct dasd_block *block)
{
struct block_device *bdev;
int rc;
bdev = bdget_disk(block->gdp, 0);
if (!bdev) {
DBF_DEV_EVENT(DBF_ERR, block->base, "%s",
"scan partitions error, bdget returned NULL");
return -ENODEV;
}
rc = blkdev_get(bdev, FMODE_READ, NULL);
if (rc < 0) {
DBF_DEV_EVENT(DBF_ERR, block->base,
"scan partitions error, blkdev_get returned %d",
rc);
return -ENODEV;
}
mutex_lock(&bdev->bd_mutex);
rc = bdev_disk_changed(bdev, false);
mutex_unlock(&bdev->bd_mutex);
if (rc)
DBF_DEV_EVENT(DBF_ERR, block->base,
"scan partitions error, rc %d", rc);
/*
* Since the matching blkdev_put call to the blkdev_get in
* this function is not called before dasd_destroy_partitions
* the offline open_count limit needs to be increased from
* 0 to 1. This is done by setting device->bdev (see
* dasd_generic_set_offline). As long as the partition
* detection is running no offline should be allowed. That
* is why the assignment to device->bdev is done AFTER
* the BLKRRPART ioctl.
*/
block->bdev = bdev;
return 0;
}
/*
* Remove all inodes in the system for a device, delete the
* partitions and make device unusable by setting its size to zero.
*/
void dasd_destroy_partitions(struct dasd_block *block)
{
struct block_device *bdev;
/*
* Get the bdev pointer from the device structure and clear
* device->bdev to lower the offline open_count limit again.
*/
bdev = block->bdev;
block->bdev = NULL;
mutex_lock(&bdev->bd_mutex);
blk_drop_partitions(bdev);
mutex_unlock(&bdev->bd_mutex);
/* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */
blkdev_put(bdev, FMODE_READ);
set_capacity(block->gdp, 0);
}
int dasd_gendisk_init(void)
{
int rc;
/* Register to static dasd major 94 */
rc = register_blkdev(DASD_MAJOR, "dasd");
if (rc != 0) {
pr_warn("Registering the device driver with major number %d failed\n",
DASD_MAJOR);
return rc;
}
return 0;
}
void dasd_gendisk_exit(void)
{
unregister_blkdev(DASD_MAJOR, "dasd");
}