Release 4.18 block/genhd.c
/*
* gendisk handling
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/genhd.h>
#include <linux/kdev_t.h>
#include <linux/kernel.h>
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/kobj_map.h>
#include <linux/mutex.h>
#include <linux/idr.h>
#include <linux/log2.h>
#include <linux/pm_runtime.h>
#include <linux/badblocks.h>
#include "blk.h"
static DEFINE_MUTEX(block_class_lock);
struct kobject *block_depr;
/* for extended dynamic devt allocation, currently only one major is used */
#define NR_EXT_DEVT (1 << MINORBITS)
/* For extended devt allocation. ext_devt_lock prevents look up
* results from going away underneath its user.
*/
static DEFINE_SPINLOCK(ext_devt_lock);
static DEFINE_IDR(ext_devt_idr);
static const struct device_type disk_type;
static void disk_check_events(struct disk_events *ev,
unsigned int *clearing_ptr);
static void disk_alloc_events(struct gendisk *disk);
static void disk_add_events(struct gendisk *disk);
static void disk_del_events(struct gendisk *disk);
static void disk_release_events(struct gendisk *disk);
void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
{
if (q->mq_ops)
return;
atomic_inc(&part->in_flight[rw]);
if (part->partno)
atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jens Axboe | 50 | 86.21% | 1 | 50.00% |
Tejun Heo | 8 | 13.79% | 1 | 50.00% |
Total | 58 | 100.00% | 2 | 100.00% |
void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
{
if (q->mq_ops)
return;
atomic_dec(&part->in_flight[rw]);
if (part->partno)
atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jens Axboe | 54 | 93.10% | 1 | 50.00% |
Tejun Heo | 4 | 6.90% | 1 | 50.00% |
Total | 58 | 100.00% | 2 | 100.00% |
void part_in_flight(struct request_queue *q, struct hd_struct *part,
unsigned int inflight[2])
{
if (q->mq_ops) {
blk_mq_in_flight(q, part, inflight);
return;
}
inflight[0] = atomic_read(&part->in_flight[0]) +
atomic_read(&part->in_flight[1]);
if (part->partno) {
part = &part_to_disk(part)->part0;
inflight[1] = atomic_read(&part->in_flight[0]) +
atomic_read(&part->in_flight[1]);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jens Axboe | 102 | 91.07% | 1 | 25.00% |
Tejun Heo | 10 | 8.93% | 3 | 75.00% |
Total | 112 | 100.00% | 4 | 100.00% |
void part_in_flight_rw(struct request_queue *q, struct hd_struct *part,
unsigned int inflight[2])
{
if (q->mq_ops) {
blk_mq_in_flight_rw(q, part, inflight);
return;
}
inflight[0] = atomic_read(&part->in_flight[0]);
inflight[1] = atomic_read(&part->in_flight[1]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Omar Sandoval | 72 | 100.00% | 1 | 100.00% |
Total | 72 | 100.00% | 1 | 100.00% |
struct hd_struct *__disk_get_part(struct gendisk *disk, int partno)
{
struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl);
if (unlikely(partno < 0 || partno >= ptbl->len))
return NULL;
return rcu_dereference(ptbl->part[partno]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 42 | 75.00% | 2 | 66.67% |
Christoph Hellwig | 14 | 25.00% | 1 | 33.33% |
Total | 56 | 100.00% | 3 | 100.00% |
/**
* disk_get_part - get partition
* @disk: disk to look partition from
* @partno: partition number
*
* Look for partition @partno from @disk. If found, increment
* reference count and return it.
*
* CONTEXT:
* Don't care.
*
* RETURNS:
* Pointer to the found partition on success, NULL if not found.
*/
struct hd_struct *disk_get_part(struct gendisk *disk, int partno)
{
struct hd_struct *part;
rcu_read_lock();
part = __disk_get_part(disk, partno);
if (part)
get_device(part_to_dev(part));
rcu_read_unlock();
return part;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Christoph Hellwig | 30 | 60.00% | 1 | 33.33% |
Tejun Heo | 20 | 40.00% | 2 | 66.67% |
Total | 50 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(disk_get_part);
/**
* disk_part_iter_init - initialize partition iterator
* @piter: iterator to initialize
* @disk: disk to iterate over
* @flags: DISK_PITER_* flags
*
* Initialize @piter so that it iterates over partitions of @disk.
*
* CONTEXT:
* Don't care.
*/
void disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
unsigned int flags)
{
struct disk_part_tbl *ptbl;
rcu_read_lock();
ptbl = rcu_dereference(disk->part_tbl);
piter->disk = disk;
piter->part = NULL;
if (flags & DISK_PITER_REVERSE)
piter->idx = ptbl->len - 1;
else if (flags & (DISK_PITER_INCL_PART0 | DISK_PITER_INCL_EMPTY_PART0))
piter->idx = 0;
else
piter->idx = 1;
piter->flags = flags;
rcu_read_unlock();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 97 | 100.00% | 4 | 100.00% |
Total | 97 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(disk_part_iter_init);
/**
* disk_part_iter_next - proceed iterator to the next partition and return it
* @piter: iterator of interest
*
* Proceed @piter to the next partition and return it.
*
* CONTEXT:
* Don't care.
*/
struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter)
{
struct disk_part_tbl *ptbl;
int inc, end;
/* put the last partition */
disk_put_part(piter->part);
piter->part = NULL;
/* get part_tbl */
rcu_read_lock();
ptbl = rcu_dereference(piter->disk->part_tbl);
/* determine iteration parameters */
if (piter->flags & DISK_PITER_REVERSE) {
inc = -1;
if (piter->flags & (DISK_PITER_INCL_PART0 |
DISK_PITER_INCL_EMPTY_PART0))
end = -1;
else
end = 0;
} else {
inc = 1;
end = ptbl->len;
}
/* iterate to the next partition */
for (; piter->idx != end; piter->idx += inc) {
struct hd_struct *part;
part = rcu_dereference(ptbl->part[piter->idx]);
if (!part)
continue;
if (!part_nr_sects_read(part) &&
!(piter->flags & DISK_PITER_INCL_EMPTY) &&
!(piter->flags & DISK_PITER_INCL_EMPTY_PART0 &&
piter->idx == 0))
continue;
get_device(part_to_dev(part));
piter->part = part;
piter->idx += inc;
break;
}
rcu_read_unlock();
return piter->part;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 204 | 98.55% | 5 | 83.33% |
Vivek Goyal | 3 | 1.45% | 1 | 16.67% |
Total | 207 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(disk_part_iter_next);
/**
* disk_part_iter_exit - finish up partition iteration
* @piter: iter of interest
*
* Called when iteration is over. Cleans up @piter.
*
* CONTEXT:
* Don't care.
*/
void disk_part_iter_exit(struct disk_part_iter *piter)
{
disk_put_part(piter->part);
piter->part = NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 23 | 100.00% | 1 | 100.00% |
Total | 23 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(disk_part_iter_exit);
static inline int sector_in_part(struct hd_struct *part, sector_t sector)
{
return part->start_sect <= sector &&
sector < part->start_sect + part_nr_sects_read(part);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jens Axboe | 30 | 90.91% | 1 | 50.00% |
Vivek Goyal | 3 | 9.09% | 1 | 50.00% |
Total | 33 | 100.00% | 2 | 100.00% |
/**
* disk_map_sector_rcu - map sector to partition
* @disk: gendisk of interest
* @sector: sector to map
*
* Find out which partition @sector maps to on @disk. This is
* primarily used for stats accounting.
*
* CONTEXT:
* RCU read locked. The returned partition pointer is valid only
* while preemption is disabled.
*
* RETURNS:
* Found partition on success, part0 is returned if no partition matches
*/
struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
{
struct disk_part_tbl *ptbl;
struct hd_struct *part;
int i;
ptbl = rcu_dereference(disk->part_tbl);
part = rcu_dereference(ptbl->last_lookup);
if (part && sector_in_part(part, sector))
return part;
for (i = 1; i < ptbl->len; i++) {
part = rcu_dereference(ptbl->part[i]);
if (part && sector_in_part(part, sector)) {
rcu_assign_pointer(ptbl->last_lookup, part);
return part;
}
}
return &disk->part0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 76 | 63.33% | 4 | 80.00% |
Jens Axboe | 44 | 36.67% | 1 | 20.00% |
Total | 120 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(disk_map_sector_rcu);
/*
* Can be deleted altogether. Later.
*
*/
#define BLKDEV_MAJOR_HASH_SIZE 255
static struct blk_major_name {
struct blk_major_name *next;
int major;
char name[16];
} *major_names[BLKDEV_MAJOR_HASH_SIZE];
/* index in the above - for now: assume no multimajor ranges */
static inline int major_to_index(unsigned major)
{
return major % BLKDEV_MAJOR_HASH_SIZE;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 13 | 86.67% | 1 | 33.33% |
Yang Zhang | 1 | 6.67% | 1 | 33.33% |
Joe Korty | 1 | 6.67% | 1 | 33.33% |
Total | 15 | 100.00% | 3 | 100.00% |
#ifdef CONFIG_PROC_FS
void blkdev_show(struct seq_file *seqf, off_t offset)
{
struct blk_major_name *dp;
mutex_lock(&block_class_lock);
for (dp = major_names[major_to_index(offset)]; dp; dp = dp->next)
if (dp->major == offset)
seq_printf(seqf, "%3d %s\n", dp->major, dp->name);
mutex_unlock(&block_class_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Joe Korty | 29 | 39.73% | 1 | 12.50% |
Neil Horman | 19 | 26.03% | 1 | 12.50% |
Logan Gunthorpe | 11 | 15.07% | 1 | 12.50% |
Andrew Morton | 6 | 8.22% | 1 | 12.50% |
Al Viro | 3 | 4.11% | 1 | 12.50% |
Tejun Heo | 2 | 2.74% | 1 | 12.50% |
Kay Sievers | 2 | 2.74% | 1 | 12.50% |
Jes Sorensen | 1 | 1.37% | 1 | 12.50% |
Total | 73 | 100.00% | 8 | 100.00% |
#endif /* CONFIG_PROC_FS */
/**
* register_blkdev - register a new block device
*
* @major: the requested major device number [1..BLKDEV_MAJOR_MAX-1]. If
* @major = 0, try to allocate any unused major number.
* @name: the name of the new block device as a zero terminated string
*
* The @name must be unique within the system.
*
* The return value depends on the @major input parameter:
*
* - if a major device number was requested in range [1..BLKDEV_MAJOR_MAX-1]
* then the function returns zero on success, or a negative error code
* - if any unused major number was requested with @major = 0 parameter
* then the return value is the allocated major number in range
* [1..BLKDEV_MAJOR_MAX-1] or a negative error code otherwise
*
* See Documentation/admin-guide/devices.txt for the list of allocated
* major numbers.
*/
int register_blkdev(unsigned int major, const char *name)
{
struct blk_major_name **n, *p;
int index, ret = 0;
mutex_lock(&block_class_lock);
/* temporary */
if (major == 0) {
for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {
if (major_names[index] == NULL)
break;
}
if (index == 0) {
printk("register_blkdev: failed to get major for %s\n",
name);
ret = -EBUSY;
goto out;
}
major = index;
ret = major;
}
if (major >= BLKDEV_MAJOR_MAX) {
pr_err("register_blkdev: major requested (%u) is greater than the maximum (%u) for %s\n",
major, BLKDEV_MAJOR_MAX-1, name);
ret = -EINVAL;
goto out;
}
p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL);
if (p == NULL) {
ret = -ENOMEM;
goto out;
}
p->major = major;
strlcpy(p->name, name, sizeof(p->name));
p->next = NULL;
index = major_to_index(major);
for (n = &major_names[index]; *n; n = &(*n)->next) {
if ((*n)->major == major)
break;
}
if (!*n)
*n = p;
else
ret = -EBUSY;
if (ret < 0) {
printk("register_blkdev: cannot get major %u for %s\n",
major, name);
kfree(p);
}
out:
mutex_unlock(&block_class_lock);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 250 | 87.41% | 3 | 33.33% |
Logan Gunthorpe | 26 | 9.09% | 1 | 11.11% |
Srivatsa S. Bhat | 4 | 1.40% | 1 | 11.11% |
Jes Sorensen | 2 | 0.70% | 1 | 11.11% |
Kay Sievers | 2 | 0.70% | 1 | 11.11% |
Benjamin Collins | 1 | 0.35% | 1 | 11.11% |
Mika Kukkonen | 1 | 0.35% | 1 | 11.11% |
Total | 286 | 100.00% | 9 | 100.00% |
EXPORT_SYMBOL(register_blkdev);
void unregister_blkdev(unsigned int major, const char *name)
{
struct blk_major_name **n;
struct blk_major_name *p = NULL;
int index = major_to_index(major);
mutex_lock(&block_class_lock);
for (n = &major_names[index]; *n; n = &(*n)->next)
if ((*n)->major == major)
break;
if (!*n || strcmp((*n)->name, name)) {
WARN_ON(1);
} else {
p = *n;
*n = p->next;
}
mutex_unlock(&block_class_lock);
kfree(p);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 110 | 86.61% | 2 | 28.57% |
Akinobu Mita | 8 | 6.30% | 2 | 28.57% |
Christoph Hellwig | 5 | 3.94% | 1 | 14.29% |
Jes Sorensen | 2 | 1.57% | 1 | 14.29% |
Kay Sievers | 2 | 1.57% | 1 | 14.29% |
Total | 127 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL(unregister_blkdev);
static struct kobj_map *bdev_map;
/**
* blk_mangle_minor - scatter minor numbers apart
* @minor: minor number to mangle
*
* Scatter consecutively allocated @minor number apart if MANGLE_DEVT
* is enabled. Mangling twice gives the original value.
*
* RETURNS:
* Mangled value.
*
* CONTEXT:
* Don't care.
*/
static int blk_mangle_minor(int minor)
{
#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
int i;
for (i = 0; i < MINORBITS / 2; i++) {
int low = minor & (1 << i);
int high = minor & (1 << (MINORBITS - 1 - i));
int distance = MINORBITS - 1 - 2 * i;
minor ^= low | high; /* clear both bits */
low <<= distance; /* swap the positions */
high >>= distance;
minor |= low | high; /* and set */
}
#endif
return minor;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 99 | 100.00% | 1 | 100.00% |
Total | 99 | 100.00% | 1 | 100.00% |
/**
* blk_alloc_devt - allocate a dev_t for a partition
* @part: partition to allocate dev_t for
* @devt: out parameter for resulting dev_t
*
* Allocate a dev_t for block device.
*
* RETURNS:
* 0 on success, allocated dev_t is returned in *@devt. -errno on
* failure.
*
* CONTEXT:
* Might sleep.
*/
int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
{
struct gendisk *disk = part_to_disk(part);
int idx;
/* in consecutive minor range? */
if (part->partno < disk->minors) {
*devt = MKDEV(disk->major, disk->first_minor + part->partno);
return 0;
}
/* allocate ext devt */
idr_preload(GFP_KERNEL);
spin_lock_bh(&ext_devt_lock);
idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT);
spin_unlock_bh(&ext_devt_lock);
idr_preload_end();
if (idx < 0)
return idx == -ENOSPC ? -EBUSY : idx;
*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 110 | 83.97% | 4 | 57.14% |
Keith Busch | 11 | 8.40% | 1 | 14.29% |
Tomas Henzl | 8 | 6.11% | 1 | 14.29% |
Dan J Williams | 2 | 1.53% | 1 | 14.29% |
Total | 131 | 100.00% | 7 | 100.00% |
/**
* blk_free_devt - free a dev_t
* @devt: dev_t to free
*
* Free @devt which was allocated using blk_alloc_devt().
*
* CONTEXT:
* Might sleep.
*/
void blk_free_devt(dev_t devt)
{
if (devt == MKDEV(0, 0))
return;
if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
spin_lock_bh(&ext_devt_lock);
idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
spin_unlock_bh(&ext_devt_lock);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 53 | 92.98% | 2 | 50.00% |
Keith Busch | 2 | 3.51% | 1 | 25.00% |
Dan J Williams | 2 | 3.51% | 1 | 25.00% |
Total | 57 | 100.00% | 4 | 100.00% |
static char *bdevt_str(dev_t devt, char *buf)
{
if (MAJOR(devt) <= 0xff && MINOR(devt) <= 0xff) {
char tbuf[BDEVT_SIZE];
snprintf(tbuf, BDEVT_SIZE, "%02x%02x", MAJOR(devt), MINOR(devt));
snprintf(buf, BDEVT_SIZE, "%-9s", tbuf);
} else
snprintf(buf, BDEVT_SIZE, "%03x:%05x", MAJOR(devt), MINOR(devt));
return buf;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 91 | 100.00% | 1 | 100.00% |
Total | 91 | 100.00% | 1 | 100.00% |
/*
* Register device numbers dev..(dev+range-1)
* range must be nonzero
* The hash chain is sorted on range, so that subranges can override.
*/
void blk_register_region(dev_t devt, unsigned long range, struct module *module,
struct kobject *(*probe)(dev_t, int *, void *),
int (*lock)(dev_t, void *), void *data)
{
kobj_map(bdev_map, devt, range, module, probe, lock, data);
}
EXPORT_SYMBOL(blk_register_region);
void blk_unregister_region(dev_t devt, unsigned long range)
{
kobj_unmap(bdev_map, devt, range);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Al Viro | 19 | 90.48% | 2 | 66.67% |
Kay Sievers | 2 | 9.52% | 1 | 33.33% |
Total | 21 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(blk_unregister_region);
static struct kobject *exact_match(dev_t devt, int *partno, void *data)
{
struct gendisk *p = data;
return &disk_to_dev(p)->kobj;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Al Viro | 30 | 85.71% | 3 | 50.00% |
Tejun Heo | 4 | 11.43% | 2 | 33.33% |
Kay Sievers | 1 | 2.86% | 1 | 16.67% |
Total | 35 | 100.00% | 6 | 100.00% |
static int exact_lock(dev_t devt, void *data)
{
struct gendisk *p = data;
if (!get_disk_and_module(p))
return -1;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Al Viro | 33 | 94.29% | 2 | 50.00% |
Jan Kara | 1 | 2.86% | 1 | 25.00% |
Kay Sievers | 1 | 2.86% | 1 | 25.00% |
Total | 35 | 100.00% | 4 | 100.00% |
static void register_disk(struct device *parent, struct gendisk *disk)
{
struct device *ddev = disk_to_dev(disk);
struct block_device *bdev;
struct disk_part_iter piter;
struct hd_struct *part;
int err;
ddev->parent = parent;
dev_set_name(ddev, "%s", disk->disk_name);
/* delay uevents, until we scanned partition table */
dev_set_uevent_suppress(ddev, 1);
if (device_add(ddev))
return;
if (!sysfs_deprecated) {
err = sysfs_create_link(block_depr, &ddev->kobj,
kobject_name(&ddev->kobj));
if (err) {
device_del(ddev);
return;
}
}
/*
* avoid probable deadlock caused by allocating memory with
* GFP_KERNEL in runtime_resume callback of its all ancestor
* devices
*/
pm_runtime_set_memalloc_noio(ddev, true);
disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
if (disk->flags & GENHD_FL_HIDDEN) {
dev_set_uevent_suppress(ddev, 0);
return;
}
/* No minors to use for partitions */
if (!disk_part_scan_enabled(disk))
goto exit;
/* No such device (e.g., media were just removed) */
if (!get_capacity(disk))
goto exit;
bdev = bdget_disk(disk, 0);
if (!bdev)
goto exit;
bdev->bd_invalidated = 1;
err = blkdev_get(bdev, FMODE_READ, NULL);
if (err < 0)
goto exit;
blkdev_put(bdev, FMODE_READ);
exit:
/* announce disk after possible partitions are created */
dev_set_uevent_suppress(ddev, 0);
kobject_uevent(&ddev->kobj, KOBJ_ADD);
/* announce possible partitions */
disk_part_iter_init(&piter, disk, 0);
while ((part = disk_part_iter_next(&piter)))
kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
disk_part_iter_exit(&piter);
err = sysfs_create_link(&ddev->kobj,
&disk->queue->backing_dev_info->dev->kobj,
"bdi");
WARN_ON(err);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 221 | 65.97% | 5 | 23.81% |
Christoph Hellwig | 28 | 8.36% | 1 | 4.76% |
Al Viro | 20 | 5.97% | 5 | 23.81% |
Hannes Reinecke | 18 | 5.37% | 1 | 4.76% |
Linus Torvalds | 9 | 2.69% | 2 | 9.52% |
Peter Zijlstra | 9 | 2.69% | 1 | 4.76% |
Ming Lei | 8 | 2.39% | 1 | 4.76% |
Dan J Williams | 6 | 1.79% | 1 | 4.76% |
Jan Kara | 6 | 1.79% | 1 | 4.76% |
Greg Kroah-Hartman | 5 | 1.49% | 1 | 4.76% |
Jens Axboe | 3 | 0.90% | 1 | 4.76% |
Kees Cook | 2 | 0.60% | 1 | 4.76% |
Total | 335 | 100.00% | 21 | 100.00% |
/**
* __device_add_disk - add disk information to kernel list
* @parent: parent device for the disk
* @disk: per-device partitioning information
* @register_queue: register the queue if set to true
*
* This function registers the partitioning information in @disk
* with the kernel.
*
* FIXME: error handling
*/
static void __device_add_disk(struct device *parent, struct gendisk *disk,
bool register_queue)
{
dev_t devt;
int retval;
/* minors == 0 indicates to use ext devt from part0 and should
* be accompanied with EXT_DEVT flag. Make sure all
* parameters make sense.
*/
WARN_ON(disk->minors && !(disk->major || disk->first_minor));
WARN_ON(!disk->minors &&
!(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));
disk->flags |= GENHD_FL_UP;
retval = blk_alloc_devt(&disk->part0, &devt);
if (retval) {
WARN_ON(1);
return;
}
disk->major = MAJOR(devt);
disk->first_minor = MINOR(devt);
disk_alloc_events(disk);
if (disk->flags & GENHD_FL_HIDDEN) {
/*
* Don't let hidden disks show up in /proc/partitions,
* and don't bother scanning for partitions either.
*/
disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
disk->flags |= GENHD_FL_NO_PART_SCAN;
} else {
int ret;
/* Register BDI before referencing it from bdev */
disk_to_dev(disk)->devt = devt;
ret = bdi_register_owner(disk->queue->backing_dev_info,
disk_to_dev(disk));
WARN_ON(ret);
blk_register_region(disk_devt(disk), disk->minors, NULL,
exact_match, exact_lock, disk);
}
register_disk(parent, disk);
if (register_queue)
blk_register_queue(disk);
/*
* Take an extra ref on queue which will be put on disk_release()
* so that it sticks around as long as @disk is there.
*/
WARN_ON_ONCE(!blk_get_queue(disk->queue));
disk_add_events(disk);
blk_integrity_add(disk);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tejun Heo | 87 | 36.71% | 5 | 21.74% |
Christoph Hellwig | 40 | 16.88% | 1 | 4.35% |
Al Viro | 36 | 15.19% | 4 | 17.39% |
Linus Torvalds | 11 | 4.64% | 2 | 8.70% |
Peter Zijlstra | 10 | 4.22% | 1 | 4.35% |
weiping zhang | 10 | 4.22% | 1 | 4.35% |
Mike Snitzer | 9 | 3.80% | 1 | 4.35% |
Jens Axboe | 8 | 3.38% | 1 | 4.35% |
Dan J Williams | 8 | 3.38% | 2 | 8.70% |
Stanislaw Gruszka | 5 | 2.11% | 1 | 4.35% |
Martin K. Petersen | 5 | 2.11% | 1 | 4.35% |
Jan Kara | 4 | 1.69% | 1 | 4.35% |
Greg Kroah-Hartman | 3 | 1.27% | 1 | 4.35% |
Andrew Morton | 1 | 0.42% | 1 | 4.35% |
Total | 237 | 100.00% | 23 | 100.00% |
void device_add_disk(struct device *parent, struct gendisk *disk)
{
__device_add_disk(parent, disk, true);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Mike Snitzer | 24 | 100.00% | 1 | 100.00% |
Total | 24 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(device_add_disk);
void device_add_disk_no_queue_reg(struct device *parent, struct gendisk *disk)
{
__device_add_disk(parent, disk, false);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Mike Snitzer | 24 | 100.00% | 1 | 100.00% |
Total | 24 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(device_add_disk_no_queue_reg);
void del_gendisk(struct gendisk *disk)