cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dasd_genhd.c (4641B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
      4 *		    Horst Hummel <Horst.Hummel@de.ibm.com>
      5 *		    Carsten Otte <Cotte@de.ibm.com>
      6 *		    Martin Schwidefsky <schwidefsky@de.ibm.com>
      7 * Bugreports.to..: <Linux390@de.ibm.com>
      8 * Copyright IBM Corp. 1999, 2001
      9 *
     10 * gendisk related functions for the dasd driver.
     11 *
     12 */
     13
     14#define KMSG_COMPONENT "dasd"
     15
     16#include <linux/interrupt.h>
     17#include <linux/major.h>
     18#include <linux/fs.h>
     19#include <linux/blkpg.h>
     20
     21#include <linux/uaccess.h>
     22
     23/* This is ugly... */
     24#define PRINTK_HEADER "dasd_gendisk:"
     25
     26#include "dasd_int.h"
     27
     28static struct lock_class_key dasd_bio_compl_lkclass;
     29
     30/*
     31 * Allocate and register gendisk structure for device.
     32 */
     33int dasd_gendisk_alloc(struct dasd_block *block)
     34{
     35	struct gendisk *gdp;
     36	struct dasd_device *base;
     37	int len, rc;
     38
     39	/* Make sure the minor for this device exists. */
     40	base = block->base;
     41	if (base->devindex >= DASD_PER_MAJOR)
     42		return -EBUSY;
     43
     44	gdp = __alloc_disk_node(block->request_queue, NUMA_NO_NODE,
     45				&dasd_bio_compl_lkclass);
     46	if (!gdp)
     47		return -ENOMEM;
     48
     49	/* Initialize gendisk structure. */
     50	gdp->major = DASD_MAJOR;
     51	gdp->first_minor = base->devindex << DASD_PARTN_BITS;
     52	gdp->minors = 1 << DASD_PARTN_BITS;
     53	gdp->fops = &dasd_device_operations;
     54
     55	/*
     56	 * Set device name.
     57	 *   dasda - dasdz : 26 devices
     58	 *   dasdaa - dasdzz : 676 devices, added up = 702
     59	 *   dasdaaa - dasdzzz : 17576 devices, added up = 18278
     60	 *   dasdaaaa - dasdzzzz : 456976 devices, added up = 475252
     61	 */
     62	len = sprintf(gdp->disk_name, "dasd");
     63	if (base->devindex > 25) {
     64		if (base->devindex > 701) {
     65			if (base->devindex > 18277)
     66			        len += sprintf(gdp->disk_name + len, "%c",
     67					       'a'+(((base->devindex-18278)
     68						     /17576)%26));
     69			len += sprintf(gdp->disk_name + len, "%c",
     70				       'a'+(((base->devindex-702)/676)%26));
     71		}
     72		len += sprintf(gdp->disk_name + len, "%c",
     73			       'a'+(((base->devindex-26)/26)%26));
     74	}
     75	len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26));
     76
     77	if (base->features & DASD_FEATURE_READONLY ||
     78	    test_bit(DASD_FLAG_DEVICE_RO, &base->flags))
     79		set_disk_ro(gdp, 1);
     80	dasd_add_link_to_gendisk(gdp, base);
     81	block->gdp = gdp;
     82	set_capacity(block->gdp, 0);
     83
     84	rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
     85	if (rc) {
     86		dasd_gendisk_free(block);
     87		return rc;
     88	}
     89
     90	return 0;
     91}
     92
     93/*
     94 * Unregister and free gendisk structure for device.
     95 */
     96void dasd_gendisk_free(struct dasd_block *block)
     97{
     98	if (block->gdp) {
     99		del_gendisk(block->gdp);
    100		block->gdp->private_data = NULL;
    101		put_disk(block->gdp);
    102		block->gdp = NULL;
    103	}
    104}
    105
    106/*
    107 * Trigger a partition detection.
    108 */
    109int dasd_scan_partitions(struct dasd_block *block)
    110{
    111	struct block_device *bdev;
    112	int rc;
    113
    114	bdev = blkdev_get_by_dev(disk_devt(block->gdp), FMODE_READ, NULL);
    115	if (IS_ERR(bdev)) {
    116		DBF_DEV_EVENT(DBF_ERR, block->base,
    117			      "scan partitions error, blkdev_get returned %ld",
    118			      PTR_ERR(bdev));
    119		return -ENODEV;
    120	}
    121
    122	mutex_lock(&block->gdp->open_mutex);
    123	rc = bdev_disk_changed(block->gdp, false);
    124	mutex_unlock(&block->gdp->open_mutex);
    125	if (rc)
    126		DBF_DEV_EVENT(DBF_ERR, block->base,
    127				"scan partitions error, rc %d", rc);
    128
    129	/*
    130	 * Since the matching blkdev_put call to the blkdev_get in
    131	 * this function is not called before dasd_destroy_partitions
    132	 * the offline open_count limit needs to be increased from
    133	 * 0 to 1. This is done by setting device->bdev (see
    134	 * dasd_generic_set_offline). As long as the partition
    135	 * detection is running no offline should be allowed. That
    136	 * is why the assignment to device->bdev is done AFTER
    137	 * the BLKRRPART ioctl.
    138	 */
    139	block->bdev = bdev;
    140	return 0;
    141}
    142
    143/*
    144 * Remove all inodes in the system for a device, delete the
    145 * partitions and make device unusable by setting its size to zero.
    146 */
    147void dasd_destroy_partitions(struct dasd_block *block)
    148{
    149	struct block_device *bdev;
    150
    151	/*
    152	 * Get the bdev pointer from the device structure and clear
    153	 * device->bdev to lower the offline open_count limit again.
    154	 */
    155	bdev = block->bdev;
    156	block->bdev = NULL;
    157
    158	mutex_lock(&bdev->bd_disk->open_mutex);
    159	bdev_disk_changed(bdev->bd_disk, true);
    160	mutex_unlock(&bdev->bd_disk->open_mutex);
    161
    162	/* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */
    163	blkdev_put(bdev, FMODE_READ);
    164}
    165
    166int dasd_gendisk_init(void)
    167{
    168	int rc;
    169
    170	/* Register to static dasd major 94 */
    171	rc = register_blkdev(DASD_MAJOR, "dasd");
    172	if (rc != 0) {
    173		pr_warn("Registering the device driver with major number %d failed\n",
    174			DASD_MAJOR);
    175		return rc;
    176	}
    177	return 0;
    178}
    179
    180void dasd_gendisk_exit(void)
    181{
    182	unregister_blkdev(DASD_MAJOR, "dasd");
    183}