^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * gendisk handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/genhd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kdev_t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/backing-dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kmod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/kobj_map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/badblocks.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "blk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static DEFINE_MUTEX(block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct kobject *block_depr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* for extended dynamic devt allocation, currently only one major is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define NR_EXT_DEVT (1 << MINORBITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* For extended devt allocation. ext_devt_lock prevents look up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * results from going away underneath its user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static DEFINE_SPINLOCK(ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static DEFINE_IDR(ext_devt_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static void disk_check_events(struct disk_events *ev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned int *clearing_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static void disk_alloc_events(struct gendisk *disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static void disk_add_events(struct gendisk *disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static void disk_del_events(struct gendisk *disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static void disk_release_events(struct gendisk *disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Set disk capacity and notify if the size is not currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * zero and will not be set to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) bool set_capacity_revalidate_and_notify(struct gendisk *disk, sector_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) bool update_bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) sector_t capacity = get_capacity(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) set_capacity(disk, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (update_bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) revalidate_disk_size(disk, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (capacity != size && capacity != 0 && size != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) char *envp[] = { "RESIZE=1", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) kobject_uevent_env(&disk_to_dev(disk)->kobj, KOBJ_CHANGE, envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) EXPORT_SYMBOL_GPL(set_capacity_revalidate_and_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Format the device name of the indicated disk into the supplied buffer and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * return a pointer to that same buffer for convenience.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) char *disk_name(struct gendisk *hd, int partno, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) snprintf(buf, BDEVNAME_SIZE, "%s", hd->disk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else if (isdigit(hd->disk_name[strlen(hd->disk_name)-1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) snprintf(buf, BDEVNAME_SIZE, "%sp%d", hd->disk_name, partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) snprintf(buf, BDEVNAME_SIZE, "%s%d", hd->disk_name, partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) const char *bdevname(struct block_device *bdev, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return disk_name(bdev->bd_disk, bdev->bd_partno, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) EXPORT_SYMBOL(bdevname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) memset(stat, 0, sizeof(struct disk_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct disk_stats *ptr = per_cpu_ptr(part->dkstats, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) for (group = 0; group < NR_STAT_GROUPS; group++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) stat->nsecs[group] += ptr->nsecs[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) stat->sectors[group] += ptr->sectors[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) stat->ios[group] += ptr->ios[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) stat->merges[group] += ptr->merges[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) stat->io_ticks += ptr->io_ticks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static unsigned int part_in_flight(struct hd_struct *part)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int inflight = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) inflight += part_stat_local_read_cpu(part, in_flight[0], cpu) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) part_stat_local_read_cpu(part, in_flight[1], cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if ((int)inflight < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) inflight = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return inflight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void part_in_flight_rw(struct hd_struct *part, unsigned int inflight[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) inflight[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) inflight[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) inflight[0] += part_stat_local_read_cpu(part, in_flight[0], cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) inflight[1] += part_stat_local_read_cpu(part, in_flight[1], cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if ((int)inflight[0] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) inflight[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if ((int)inflight[1] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) inflight[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct hd_struct *__disk_get_part(struct gendisk *disk, int partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (unlikely(partno < 0 || partno >= ptbl->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return rcu_dereference(ptbl->part[partno]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * disk_get_part - get partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @disk: disk to look partition from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @partno: partition number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Look for partition @partno from @disk. If found, increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * reference count and return it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Pointer to the found partition on success, NULL if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct hd_struct *disk_get_part(struct gendisk *disk, int partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) part = __disk_get_part(disk, partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (part)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) get_device(part_to_dev(part));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * disk_part_iter_init - initialize partition iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * @piter: iterator to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * @disk: disk to iterate over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * @flags: DISK_PITER_* flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * Initialize @piter so that it iterates over partitions of @disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * Don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct disk_part_tbl *ptbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ptbl = rcu_dereference(disk->part_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) piter->disk = disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) piter->part = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (flags & DISK_PITER_REVERSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) piter->idx = ptbl->len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) else if (flags & (DISK_PITER_INCL_PART0 | DISK_PITER_INCL_EMPTY_PART0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) piter->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) piter->idx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) piter->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) EXPORT_SYMBOL_GPL(disk_part_iter_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * disk_part_iter_next - proceed iterator to the next partition and return it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * @piter: iterator of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Proceed @piter to the next partition and return it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * Don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct disk_part_tbl *ptbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int inc, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* put the last partition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) disk_put_part(piter->part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) piter->part = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* get part_tbl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ptbl = rcu_dereference(piter->disk->part_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* determine iteration parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (piter->flags & DISK_PITER_REVERSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) inc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (piter->flags & (DISK_PITER_INCL_PART0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) DISK_PITER_INCL_EMPTY_PART0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) end = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) inc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) end = ptbl->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* iterate to the next partition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) for (; piter->idx != end; piter->idx += inc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) part = rcu_dereference(ptbl->part[piter->idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!part)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) get_device(part_to_dev(part));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) piter->part = part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!part_nr_sects_read(part) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) !(piter->flags & DISK_PITER_INCL_EMPTY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) piter->idx == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) put_device(part_to_dev(part));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) piter->part = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) piter->idx += inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return piter->part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) EXPORT_SYMBOL_GPL(disk_part_iter_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * disk_part_iter_exit - finish up partition iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * @piter: iter of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * Called when iteration is over. Cleans up @piter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) void disk_part_iter_exit(struct disk_part_iter *piter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) disk_put_part(piter->part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) piter->part = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) EXPORT_SYMBOL_GPL(disk_part_iter_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static inline int sector_in_part(struct hd_struct *part, sector_t sector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return part->start_sect <= sector &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sector < part->start_sect + part_nr_sects_read(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * disk_map_sector_rcu - map sector to partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * @disk: gendisk of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * @sector: sector to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * Find out which partition @sector maps to on @disk. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * primarily used for stats accounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * RCU read locked. The returned partition pointer is always valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * because its refcount is grabbed except for part0, which lifetime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * is same with the disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * Found partition on success, part0 is returned if no partition matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * or the matched partition is being deleted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct disk_part_tbl *ptbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ptbl = rcu_dereference(disk->part_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) part = rcu_dereference(ptbl->last_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (part && sector_in_part(part, sector) && hd_struct_try_get(part))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) for (i = 1; i < ptbl->len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) part = rcu_dereference(ptbl->part[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (part && sector_in_part(part, sector)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * only live partition can be cached for lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * so use-after-free on cached & deleting partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * can be avoided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!hd_struct_try_get(part))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) rcu_assign_pointer(ptbl->last_lookup, part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) part = &disk->part0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * disk_has_partitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @disk: gendisk of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * Walk through the partition table and check if valid partition exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * True if the gendisk has at least one valid non-zero size partition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * Otherwise false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) bool disk_has_partitions(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct disk_part_tbl *ptbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ptbl = rcu_dereference(disk->part_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Iterate partitions skipping the whole device at index 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) for (i = 1; i < ptbl->len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (rcu_dereference(ptbl->part[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) EXPORT_SYMBOL_GPL(disk_has_partitions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * Can be deleted altogether. Later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #define BLKDEV_MAJOR_HASH_SIZE 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static struct blk_major_name {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct blk_major_name *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) } *major_names[BLKDEV_MAJOR_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* index in the above - for now: assume no multimajor ranges */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static inline int major_to_index(unsigned major)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return major % BLKDEV_MAJOR_HASH_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) void blkdev_show(struct seq_file *seqf, off_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct blk_major_name *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) mutex_lock(&block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) for (dp = major_names[major_to_index(offset)]; dp; dp = dp->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (dp->major == offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) seq_printf(seqf, "%3d %s\n", dp->major, dp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) mutex_unlock(&block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #endif /* CONFIG_PROC_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * register_blkdev - register a new block device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * @major: the requested major device number [1..BLKDEV_MAJOR_MAX-1]. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * @major = 0, try to allocate any unused major number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * @name: the name of the new block device as a zero terminated string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * The @name must be unique within the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * The return value depends on the @major input parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * - if a major device number was requested in range [1..BLKDEV_MAJOR_MAX-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * then the function returns zero on success, or a negative error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * - if any unused major number was requested with @major = 0 parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * then the return value is the allocated major number in range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * [1..BLKDEV_MAJOR_MAX-1] or a negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * See Documentation/admin-guide/devices.txt for the list of allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * major numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int register_blkdev(unsigned int major, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct blk_major_name **n, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int index, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) mutex_lock(&block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* temporary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (major == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (major_names[index] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (index == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) printk("%s: failed to get major for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) __func__, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) major = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ret = major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (major >= BLKDEV_MAJOR_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) pr_err("%s: major requested (%u) is greater than the maximum (%u) for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) __func__, major, BLKDEV_MAJOR_MAX-1, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (p == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) p->major = major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) strlcpy(p->name, name, sizeof(p->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) p->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) index = major_to_index(major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) for (n = &major_names[index]; *n; n = &(*n)->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if ((*n)->major == major)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (!*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) *n = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) printk("register_blkdev: cannot get major %u for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) major, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) mutex_unlock(&block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) EXPORT_SYMBOL(register_blkdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) void unregister_blkdev(unsigned int major, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct blk_major_name **n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct blk_major_name *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int index = major_to_index(major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) mutex_lock(&block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) for (n = &major_names[index]; *n; n = &(*n)->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if ((*n)->major == major)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!*n || strcmp((*n)->name, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) p = *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *n = p->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) mutex_unlock(&block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) EXPORT_SYMBOL(unregister_blkdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static struct kobj_map *bdev_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * blk_mangle_minor - scatter minor numbers apart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * @minor: minor number to mangle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * Scatter consecutively allocated @minor number apart if MANGLE_DEVT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * is enabled. Mangling twice gives the original value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * Mangled value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * Don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int blk_mangle_minor(int minor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) #ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) for (i = 0; i < MINORBITS / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int low = minor & (1 << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int high = minor & (1 << (MINORBITS - 1 - i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int distance = MINORBITS - 1 - 2 * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) minor ^= low | high; /* clear both bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) low <<= distance; /* swap the positions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) high >>= distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) minor |= low | high; /* and set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * blk_alloc_devt - allocate a dev_t for a partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * @part: partition to allocate dev_t for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * @devt: out parameter for resulting dev_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * Allocate a dev_t for block device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * 0 on success, allocated dev_t is returned in *@devt. -errno on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * Might sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct gendisk *disk = part_to_disk(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* in consecutive minor range? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (part->partno < disk->minors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) *devt = MKDEV(disk->major, disk->first_minor + part->partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* allocate ext devt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) idr_preload(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) spin_lock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) spin_unlock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) idr_preload_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return idx == -ENOSPC ? -EBUSY : idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) *devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * blk_free_devt - free a dev_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * @devt: dev_t to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * Free @devt which was allocated using blk_alloc_devt().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * Might sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) void blk_free_devt(dev_t devt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (devt == MKDEV(0, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) spin_lock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) spin_unlock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * We invalidate devt by assigning NULL pointer for devt in idr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) void blk_invalidate_devt(dev_t devt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) spin_lock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) idr_replace(&ext_devt_idr, NULL, blk_mangle_minor(MINOR(devt)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) spin_unlock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static char *bdevt_str(dev_t devt, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (MAJOR(devt) <= 0xff && MINOR(devt) <= 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) char tbuf[BDEVT_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) snprintf(tbuf, BDEVT_SIZE, "%02x%02x", MAJOR(devt), MINOR(devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) snprintf(buf, BDEVT_SIZE, "%-9s", tbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) snprintf(buf, BDEVT_SIZE, "%03x:%05x", MAJOR(devt), MINOR(devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * Register device numbers dev..(dev+range-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * range must be nonzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * The hash chain is sorted on range, so that subranges can override.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) void blk_register_region(dev_t devt, unsigned long range, struct module *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct kobject *(*probe)(dev_t, int *, void *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) int (*lock)(dev_t, void *), void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) kobj_map(bdev_map, devt, range, module, probe, lock, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) EXPORT_SYMBOL(blk_register_region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) void blk_unregister_region(dev_t devt, unsigned long range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) kobj_unmap(bdev_map, devt, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) EXPORT_SYMBOL(blk_unregister_region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static struct kobject *exact_match(dev_t devt, int *partno, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct gendisk *p = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return &disk_to_dev(p)->kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static int exact_lock(dev_t devt, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct gendisk *p = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!get_disk_and_module(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static void disk_scan_partitions(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct block_device *bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (!get_capacity(disk) || !disk_part_scan_enabled(disk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) set_bit(GD_NEED_PART_SCAN, &disk->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) bdev = blkdev_get_by_dev(disk_devt(disk), FMODE_READ, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (!IS_ERR(bdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) blkdev_put(bdev, FMODE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static void register_disk(struct device *parent, struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) const struct attribute_group **groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct device *ddev = disk_to_dev(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct disk_part_iter piter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ddev->parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dev_set_name(ddev, "%s", disk->disk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /* delay uevents, until we scanned partition table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dev_set_uevent_suppress(ddev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) WARN_ON(ddev->groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ddev->groups = groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (device_add(ddev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!sysfs_deprecated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) err = sysfs_create_link(block_depr, &ddev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) kobject_name(&ddev->kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) device_del(ddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * avoid probable deadlock caused by allocating memory with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * GFP_KERNEL in runtime_resume callback of its all ancestor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) pm_runtime_set_memalloc_noio(ddev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (disk->flags & GENHD_FL_HIDDEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) disk_scan_partitions(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* announce disk after possible partitions are created */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) dev_set_uevent_suppress(ddev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) kobject_uevent(&ddev->kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /* announce possible partitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) disk_part_iter_init(&piter, disk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) while ((part = disk_part_iter_next(&piter)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) disk_part_iter_exit(&piter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (disk->queue->backing_dev_info->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) err = sysfs_create_link(&ddev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) &disk->queue->backing_dev_info->dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) "bdi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) WARN_ON(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * __device_add_disk - add disk information to kernel list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * @parent: parent device for the disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * @disk: per-device partitioning information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * @groups: Additional per-device sysfs groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * @register_queue: register the queue if set to true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * This function registers the partitioning information in @disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * with the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * FIXME: error handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static void __device_add_disk(struct device *parent, struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) const struct attribute_group **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) bool register_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) dev_t devt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * The disk queue should now be all set with enough information about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * the device for the elevator code to pick an adequate default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * elevator if one is needed, that is, for devices requesting queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * registration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (register_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) elevator_init_mq(disk->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* minors == 0 indicates to use ext devt from part0 and should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * be accompanied with EXT_DEVT flag. Make sure all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * parameters make sense.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) WARN_ON(disk->minors && !(disk->major || disk->first_minor));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) WARN_ON(!disk->minors &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) !(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) disk->flags |= GENHD_FL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) retval = blk_alloc_devt(&disk->part0, &devt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) disk->major = MAJOR(devt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) disk->first_minor = MINOR(devt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) disk_alloc_events(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (disk->flags & GENHD_FL_HIDDEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * Don't let hidden disks show up in /proc/partitions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * and don't bother scanning for partitions either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) disk->flags |= GENHD_FL_NO_PART_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct backing_dev_info *bdi = disk->queue->backing_dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct device *dev = disk_to_dev(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* Register BDI before referencing it from bdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) dev->devt = devt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret = bdi_register(bdi, "%u:%u", MAJOR(devt), MINOR(devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) WARN_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) bdi_set_owner(bdi, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) blk_register_region(disk_devt(disk), disk->minors, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) exact_match, exact_lock, disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) register_disk(parent, disk, groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (register_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) blk_register_queue(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * Take an extra ref on queue which will be put on disk_release()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * so that it sticks around as long as @disk is there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) WARN_ON_ONCE(!blk_get_queue(disk->queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) disk_add_events(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) blk_integrity_add(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) void device_add_disk(struct device *parent, struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) const struct attribute_group **groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) __device_add_disk(parent, disk, groups, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) EXPORT_SYMBOL(device_add_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) void device_add_disk_no_queue_reg(struct device *parent, struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) __device_add_disk(parent, disk, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) EXPORT_SYMBOL(device_add_disk_no_queue_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) static void invalidate_partition(struct gendisk *disk, int partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct block_device *bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) bdev = bdget_disk(disk, partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (!bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) fsync_bdev(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) __invalidate_device(bdev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * Unhash the bdev inode for this device so that it gets evicted as soon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * as last inode reference is dropped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) remove_inode_hash(bdev->bd_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) bdput(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * del_gendisk - remove the gendisk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * @disk: the struct gendisk to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * Removes the gendisk and all its associated resources. This deletes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * partitions associated with the gendisk, and unregisters the associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * request_queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * This is the counter to the respective __device_add_disk() call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * The final removal of the struct gendisk happens when its refcount reaches 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * with put_disk(), which should be called after del_gendisk(), if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) * __device_add_disk() was used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * Drivers exist which depend on the release of the gendisk to be synchronous,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * it should not be deferred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * Context: can sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) void del_gendisk(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct disk_part_iter piter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) blk_integrity_del(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) disk_del_events(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * Block lookups of the disk until all bdevs are unhashed and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * disk is marked as dead (GENHD_FL_UP cleared).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) down_write(&disk->lookup_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* invalidate stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) disk_part_iter_init(&piter, disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) while ((part = disk_part_iter_next(&piter))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) invalidate_partition(disk, part->partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) delete_partition(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) disk_part_iter_exit(&piter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) invalidate_partition(disk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) set_capacity(disk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) disk->flags &= ~GENHD_FL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) up_write(&disk->lookup_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!(disk->flags & GENHD_FL_HIDDEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (disk->queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Unregister bdi before releasing device numbers (as they can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * get reused and we'd get clashes in sysfs).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (!(disk->flags & GENHD_FL_HIDDEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) bdi_unregister(disk->queue->backing_dev_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) blk_unregister_queue(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (!(disk->flags & GENHD_FL_HIDDEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) blk_unregister_region(disk_devt(disk), disk->minors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) * Remove gendisk pointer from idr so that it cannot be looked up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * while RCU period before freeing gendisk is running to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * use-after-free issues. Note that the device number stays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * "in-use" until we really free the gendisk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) blk_invalidate_devt(disk_devt(disk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) kobject_put(disk->part0.holder_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) kobject_put(disk->slave_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) part_stat_set_all(&disk->part0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) disk->part0.stamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (!sysfs_deprecated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) device_del(disk_to_dev(disk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) EXPORT_SYMBOL(del_gendisk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /* sysfs access to bad-blocks list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static ssize_t disk_badblocks_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!disk->bb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return sprintf(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return badblocks_show(disk->bb, page, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static ssize_t disk_badblocks_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) const char *page, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!disk->bb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return badblocks_store(disk->bb, page, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * get_gendisk - get partitioning information for a given device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * @devt: device to get partitioning information for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * @partno: returned partition index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * This function gets the structure containing partitioning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * information for the given device @devt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * Context: can sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct gendisk *get_gendisk(dev_t devt, int *partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct gendisk *disk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (MAJOR(devt) != BLOCK_EXT_MAJOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct kobject *kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) kobj = kobj_lookup(bdev_map, devt, partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) disk = dev_to_disk(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) spin_lock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (part && get_disk_and_module(part_to_disk(part))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) *partno = part->partno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) disk = part_to_disk(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) spin_unlock_bh(&ext_devt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (!disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * Synchronize with del_gendisk() to not return disk that is being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * destroyed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) down_read(&disk->lookup_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (unlikely((disk->flags & GENHD_FL_HIDDEN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) !(disk->flags & GENHD_FL_UP))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) up_read(&disk->lookup_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) put_disk_and_module(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) disk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) up_read(&disk->lookup_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * bdget_disk - do bdget() by gendisk and partition number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * @disk: gendisk of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * @partno: partition number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * Find partition @partno from @disk, do bdget() on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * Don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * Resulting block_device on success, NULL on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct block_device *bdget_disk(struct gendisk *disk, int partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct block_device *bdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) part = disk_get_part(disk, partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (part)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) bdev = bdget_part(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) disk_put_part(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) EXPORT_SYMBOL(bdget_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * print a full list of all partitions - intended for places where the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * filesystem can't be mounted and thus to give the victim some idea of what
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * went wrong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) void __init printk_all_partitions(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct class_dev_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) while ((dev = class_dev_iter_next(&iter))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct disk_part_iter piter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) char name_buf[BDEVNAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) char devt_buf[BDEVT_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * Don't show empty devices or things that have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * suppressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (get_capacity(disk) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) (disk->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * Note, unlike /proc/partitions, I am showing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * numbers in hex - the same format as the root=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * option takes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) while ((part = disk_part_iter_next(&piter))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) bool is_part0 = part == &disk->part0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) printk("%s%s %10llu %s %s", is_part0 ? "" : " ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) bdevt_str(part_devt(part), devt_buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) (unsigned long long)part_nr_sects_read(part) >> 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) , disk_name(disk, part->partno, name_buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) part->info ? part->info->uuid : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (is_part0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (dev->parent && dev->parent->driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) printk(" driver: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dev->parent->driver->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) printk(" (driver?)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) disk_part_iter_exit(&piter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) class_dev_iter_exit(&iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /* iterator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static void *disk_seqf_start(struct seq_file *seqf, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) loff_t skip = *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) struct class_dev_iter *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) iter = kmalloc(sizeof(*iter), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (!iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) seqf->private = iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) class_dev_iter_init(iter, &block_class, NULL, &disk_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) dev = class_dev_iter_next(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) } while (skip--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) static void *disk_seqf_next(struct seq_file *seqf, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) (*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) dev = class_dev_iter_next(seqf->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static void disk_seqf_stop(struct seq_file *seqf, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct class_dev_iter *iter = seqf->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /* stop is called even after start failed :-( */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (iter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) class_dev_iter_exit(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) kfree(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) seqf->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static void *show_partition_start(struct seq_file *seqf, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) p = disk_seqf_start(seqf, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (!IS_ERR_OR_NULL(p) && !*pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) seq_puts(seqf, "major minor #blocks name\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) static int show_partition(struct seq_file *seqf, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct gendisk *sgp = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct disk_part_iter piter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) char buf[BDEVNAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /* Don't show non-partitionable removeable devices or empty devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!get_capacity(sgp) || (!disk_max_parts(sgp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) (sgp->flags & GENHD_FL_REMOVABLE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /* show the full disk and all non-0 size partitions of it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) disk_part_iter_init(&piter, sgp, DISK_PITER_INCL_PART0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) while ((part = disk_part_iter_next(&piter)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) seq_printf(seqf, "%4d %7d %10llu %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) MAJOR(part_devt(part)), MINOR(part_devt(part)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) (unsigned long long)part_nr_sects_read(part) >> 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) disk_name(sgp, part->partno, buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) disk_part_iter_exit(&piter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static const struct seq_operations partitions_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .start = show_partition_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) .next = disk_seqf_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) .stop = disk_seqf_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) .show = show_partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static struct kobject *base_probe(dev_t devt, int *partno, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /* Make old-style 2.4 aliases work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) request_module("block-major-%d", MAJOR(devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static int __init genhd_device_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) block_class.dev_kobj = sysfs_dev_block_kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) error = class_register(&block_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (unlikely(error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) bdev_map = kobj_map_init(base_probe, &block_class_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) blk_dev_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) register_blkdev(BLOCK_EXT_MAJOR, "blkext");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /* create top-level block dir */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (!sysfs_deprecated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) block_depr = kobject_create_and_add("block", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) subsys_initcall(genhd_device_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static ssize_t disk_range_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) return sprintf(buf, "%d\n", disk->minors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) static ssize_t disk_ext_range_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return sprintf(buf, "%d\n", disk_max_parts(disk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) static ssize_t disk_removable_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) static ssize_t disk_hidden_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) (disk->flags & GENHD_FL_HIDDEN ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static ssize_t disk_ro_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return sprintf(buf, "%d\n", get_disk_ro(disk) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) ssize_t part_size_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct hd_struct *p = dev_to_part(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return sprintf(buf, "%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) (unsigned long long)part_nr_sects_read(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ssize_t part_stat_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct hd_struct *p = dev_to_part(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct request_queue *q = part_to_disk(p)->queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct disk_stats stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) unsigned int inflight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) part_stat_read_all(p, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (queue_is_mq(q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) inflight = blk_mq_in_flight(q, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) inflight = part_in_flight(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return sprintf(buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) "%8lu %8lu %8llu %8u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) "%8lu %8lu %8llu %8u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) "%8u %8u %8u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) "%8lu %8lu %8llu %8u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) "%8lu %8u"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) stat.ios[STAT_READ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) stat.merges[STAT_READ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) (unsigned long long)stat.sectors[STAT_READ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) (unsigned int)div_u64(stat.nsecs[STAT_READ], NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) stat.ios[STAT_WRITE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) stat.merges[STAT_WRITE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) (unsigned long long)stat.sectors[STAT_WRITE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) (unsigned int)div_u64(stat.nsecs[STAT_WRITE], NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) inflight,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) jiffies_to_msecs(stat.io_ticks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) (unsigned int)div_u64(stat.nsecs[STAT_READ] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) stat.nsecs[STAT_WRITE] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) stat.nsecs[STAT_DISCARD] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) stat.nsecs[STAT_FLUSH],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) stat.ios[STAT_DISCARD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) stat.merges[STAT_DISCARD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) (unsigned long long)stat.sectors[STAT_DISCARD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) (unsigned int)div_u64(stat.nsecs[STAT_DISCARD], NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) stat.ios[STAT_FLUSH],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) (unsigned int)div_u64(stat.nsecs[STAT_FLUSH], NSEC_PER_MSEC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) struct hd_struct *p = dev_to_part(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) struct request_queue *q = part_to_disk(p)->queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) unsigned int inflight[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (queue_is_mq(q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) blk_mq_in_flight_rw(q, p, inflight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) part_in_flight_rw(p, inflight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return sprintf(buf, "%8u %8u\n", inflight[0], inflight[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static ssize_t disk_capability_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return sprintf(buf, "%x\n", disk->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) static ssize_t disk_alignment_offset_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return sprintf(buf, "%d\n", queue_alignment_offset(disk->queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) static ssize_t disk_discard_alignment_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) static DEVICE_ATTR(range, 0444, disk_range_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static DEVICE_ATTR(ext_range, 0444, disk_ext_range_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static DEVICE_ATTR(removable, 0444, disk_removable_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) static DEVICE_ATTR(hidden, 0444, disk_hidden_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) static DEVICE_ATTR(ro, 0444, disk_ro_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) static DEVICE_ATTR(size, 0444, part_size_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static DEVICE_ATTR(alignment_offset, 0444, disk_alignment_offset_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) static DEVICE_ATTR(discard_alignment, 0444, disk_discard_alignment_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static DEVICE_ATTR(capability, 0444, disk_capability_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) static DEVICE_ATTR(stat, 0444, part_stat_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) static DEVICE_ATTR(badblocks, 0644, disk_badblocks_show, disk_badblocks_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) #ifdef CONFIG_FAIL_MAKE_REQUEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) ssize_t part_fail_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct hd_struct *p = dev_to_part(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) return sprintf(buf, "%d\n", p->make_it_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) ssize_t part_fail_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) struct hd_struct *p = dev_to_part(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (count > 0 && sscanf(buf, "%d", &i) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) p->make_it_fail = (i == 0) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) static struct device_attribute dev_attr_fail =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) __ATTR(make-it-fail, 0644, part_fail_show, part_fail_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) #endif /* CONFIG_FAIL_MAKE_REQUEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) #ifdef CONFIG_FAIL_IO_TIMEOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) static struct device_attribute dev_attr_fail_timeout =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) __ATTR(io-timeout-fail, 0644, part_timeout_show, part_timeout_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) static struct attribute *disk_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) &dev_attr_range.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) &dev_attr_ext_range.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) &dev_attr_removable.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) &dev_attr_hidden.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) &dev_attr_ro.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) &dev_attr_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) &dev_attr_alignment_offset.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) &dev_attr_discard_alignment.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) &dev_attr_capability.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) &dev_attr_stat.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) &dev_attr_inflight.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) &dev_attr_badblocks.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) #ifdef CONFIG_FAIL_MAKE_REQUEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) &dev_attr_fail.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) #ifdef CONFIG_FAIL_IO_TIMEOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) &dev_attr_fail_timeout.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static umode_t disk_visible(struct kobject *kobj, struct attribute *a, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) struct device *dev = container_of(kobj, typeof(*dev), kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (a == &dev_attr_badblocks.attr && !disk->bb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return a->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static struct attribute_group disk_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) .attrs = disk_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) .is_visible = disk_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static const struct attribute_group *disk_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) &disk_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) * disk_replace_part_tbl - replace disk->part_tbl in RCU-safe way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * @disk: disk to replace part_tbl for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * @new_ptbl: new part_tbl to install
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) * Replace disk->part_tbl with @new_ptbl in RCU-safe way. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) * original ptbl is freed using RCU callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * LOCKING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * Matching bd_mutex locked or the caller is the only user of @disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) static void disk_replace_part_tbl(struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) struct disk_part_tbl *new_ptbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) struct disk_part_tbl *old_ptbl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) rcu_dereference_protected(disk->part_tbl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) rcu_assign_pointer(disk->part_tbl, new_ptbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (old_ptbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) rcu_assign_pointer(old_ptbl->last_lookup, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) kfree_rcu(old_ptbl, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) * disk_expand_part_tbl - expand disk->part_tbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) * @disk: disk to expand part_tbl for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * @partno: expand such that this partno can fit in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * Expand disk->part_tbl such that @partno can fit in. disk->part_tbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * uses RCU to allow unlocked dereferencing for stats and other stuff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * LOCKING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) * Matching bd_mutex locked or the caller is the only user of @disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * Might sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) * 0 on success, -errno on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) int disk_expand_part_tbl(struct gendisk *disk, int partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) struct disk_part_tbl *old_ptbl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) rcu_dereference_protected(disk->part_tbl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) struct disk_part_tbl *new_ptbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) int len = old_ptbl ? old_ptbl->len : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) int i, target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * check for int overflow, since we can get here from blkpg_ioctl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * with a user passed 'partno'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) target = partno + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (target < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /* disk_max_parts() is zero during initialization, ignore if so */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (disk_max_parts(disk) && target > disk_max_parts(disk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (target <= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) new_ptbl = kzalloc_node(struct_size(new_ptbl, part, target), GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) disk->node_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (!new_ptbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) new_ptbl->len = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) rcu_assign_pointer(new_ptbl->part[i], old_ptbl->part[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) disk_replace_part_tbl(disk, new_ptbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) * disk_release - releases all allocated resources of the gendisk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * @dev: the device representing this disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) * This function releases all allocated resources of the gendisk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) * The struct gendisk refcount is incremented with get_gendisk() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) * get_disk_and_module(), and its refcount is decremented with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * put_disk_and_module() or put_disk(). Once the refcount reaches 0 this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) * function is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) * Drivers which used __device_add_disk() have a gendisk with a request_queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) * assigned. Since the request_queue sits on top of the gendisk for these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) * drivers we also call blk_put_queue() for them, and we expect the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * request_queue refcount to reach 0 at this point, and so the request_queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) * will also be freed prior to the disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) * Context: can sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static void disk_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) blk_free_devt(dev->devt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) disk_release_events(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) kfree(disk->random);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) disk_replace_part_tbl(disk, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) hd_free_part(&disk->part0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (disk->queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) blk_put_queue(disk->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) kfree(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) struct class block_class = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) .name = "block",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) static char *block_devnode(struct device *dev, umode_t *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) kuid_t *uid, kgid_t *gid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (disk->fops->devnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) return disk->fops->devnode(disk, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) const struct device_type disk_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) .name = "disk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .groups = disk_attr_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .release = disk_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .devnode = block_devnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * aggregate disk stat collector. Uses the same stats that the sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * entries do, above, but makes them available through one seq_file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * The output looks suspiciously like /proc/partitions with a bunch of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) * extra fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) static int diskstats_show(struct seq_file *seqf, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) struct gendisk *gp = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) struct disk_part_iter piter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) struct hd_struct *hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) char buf[BDEVNAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) unsigned int inflight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) struct disk_stats stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (&disk_to_dev(gp)->kobj.entry == block_class.devices.next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) seq_puts(seqf, "major minor name"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) " rio rmerge rsect ruse wio wmerge "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) "wsect wuse running use aveq"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) "\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) while ((hd = disk_part_iter_next(&piter))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) part_stat_read_all(hd, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (queue_is_mq(gp->queue))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) inflight = blk_mq_in_flight(gp->queue, hd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) inflight = part_in_flight(hd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) seq_printf(seqf, "%4d %7d %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) "%lu %lu %lu %u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) "%lu %lu %lu %u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) "%u %u %u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) "%lu %lu %lu %u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) "%lu %u"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) disk_name(gp, hd->partno, buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) stat.ios[STAT_READ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) stat.merges[STAT_READ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) stat.sectors[STAT_READ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) (unsigned int)div_u64(stat.nsecs[STAT_READ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) stat.ios[STAT_WRITE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) stat.merges[STAT_WRITE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) stat.sectors[STAT_WRITE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) (unsigned int)div_u64(stat.nsecs[STAT_WRITE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) inflight,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) jiffies_to_msecs(stat.io_ticks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) (unsigned int)div_u64(stat.nsecs[STAT_READ] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) stat.nsecs[STAT_WRITE] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) stat.nsecs[STAT_DISCARD] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) stat.nsecs[STAT_FLUSH],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) stat.ios[STAT_DISCARD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) stat.merges[STAT_DISCARD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) stat.sectors[STAT_DISCARD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) (unsigned int)div_u64(stat.nsecs[STAT_DISCARD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) NSEC_PER_MSEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) stat.ios[STAT_FLUSH],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) (unsigned int)div_u64(stat.nsecs[STAT_FLUSH],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) NSEC_PER_MSEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) disk_part_iter_exit(&piter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) static const struct seq_operations diskstats_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) .start = disk_seqf_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) .next = disk_seqf_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) .stop = disk_seqf_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) .show = diskstats_show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) static int __init proc_genhd_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) proc_create_seq("diskstats", 0, NULL, &diskstats_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) proc_create_seq("partitions", 0, NULL, &partitions_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) module_init(proc_genhd_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) #endif /* CONFIG_PROC_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) dev_t blk_lookup_devt(const char *name, int partno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) dev_t devt = MKDEV(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) struct class_dev_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) while ((dev = class_dev_iter_next(&iter))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (strcmp(dev_name(dev), name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (partno < disk->minors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) /* We need to return the right devno, even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * if the partition doesn't exist yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) devt = MKDEV(MAJOR(dev->devt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) MINOR(dev->devt) + partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) part = disk_get_part(disk, partno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) if (part) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) devt = part_devt(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) disk_put_part(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) disk_put_part(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) class_dev_iter_exit(&iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) return devt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) struct gendisk *__alloc_disk_node(int minors, int node_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) struct gendisk *disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) struct disk_part_tbl *ptbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (minors > DISK_MAX_PARTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) "block: can't allocate more than %d partitions\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) DISK_MAX_PARTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) minors = DISK_MAX_PARTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (!disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) disk->part0.dkstats = alloc_percpu(struct disk_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) if (!disk->part0.dkstats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) goto out_free_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) init_rwsem(&disk->lookup_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) disk->node_id = node_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (disk_expand_part_tbl(disk, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) free_percpu(disk->part0.dkstats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) goto out_free_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) ptbl = rcu_dereference_protected(disk->part_tbl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) rcu_assign_pointer(ptbl->part[0], &disk->part0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) * set_capacity() and get_capacity() currently don't use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) * seqcounter to read/update the part0->nr_sects. Still init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) * the counter as we can read the sectors in IO submission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) * patch using seqence counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) * TODO: Ideally set_capacity() and get_capacity() should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) * converted to make use of bd_mutex and sequence counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) hd_sects_seq_init(&disk->part0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (hd_ref_init(&disk->part0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) goto out_free_part0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) disk->minors = minors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) rand_initialize_disk(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) disk_to_dev(disk)->class = &block_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) disk_to_dev(disk)->type = &disk_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) device_initialize(disk_to_dev(disk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) return disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) out_free_part0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) hd_free_part(&disk->part0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) out_free_disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) kfree(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) EXPORT_SYMBOL(__alloc_disk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) * get_disk_and_module - increments the gendisk and gendisk fops module refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) * @disk: the struct gendisk to increment the refcount for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * This increments the refcount for the struct gendisk, and the gendisk's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) * fops module owner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) * Context: Any context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) struct kobject *get_disk_and_module(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) struct module *owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct kobject *kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (!disk->fops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) owner = disk->fops->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (owner && !try_module_get(owner))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) kobj = kobject_get_unless_zero(&disk_to_dev(disk)->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (kobj == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) module_put(owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) return kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) EXPORT_SYMBOL(get_disk_and_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * put_disk - decrements the gendisk refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) * @disk: the struct gendisk to decrement the refcount for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) * This decrements the refcount for the struct gendisk. When this reaches 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) * we'll have disk_release() called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) * Context: Any context, but the last reference must not be dropped from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) * atomic context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) void put_disk(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) kobject_put(&disk_to_dev(disk)->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) EXPORT_SYMBOL(put_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) * put_disk_and_module - decrements the module and gendisk refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * @disk: the struct gendisk to decrement the refcount for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) * This is a counterpart of get_disk_and_module() and thus also of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) * get_gendisk().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) * Context: Any context, but the last reference must not be dropped from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) * atomic context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) void put_disk_and_module(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (disk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) struct module *owner = disk->fops->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) put_disk(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) module_put(owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) EXPORT_SYMBOL(put_disk_and_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) static void set_disk_ro_uevent(struct gendisk *gd, int ro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) char event[] = "DISK_RO=1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) char *envp[] = { event, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (!ro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) event[8] = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) void set_device_ro(struct block_device *bdev, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) bdev->bd_part->policy = flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) EXPORT_SYMBOL(set_device_ro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) void set_disk_ro(struct gendisk *disk, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) struct disk_part_iter piter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) struct hd_struct *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (disk->part0.policy != flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) set_disk_ro_uevent(disk, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) disk->part0.policy = flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) while ((part = disk_part_iter_next(&piter)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) part->policy = flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) disk_part_iter_exit(&piter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) EXPORT_SYMBOL(set_disk_ro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) int bdev_read_only(struct block_device *bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if (!bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return bdev->bd_part->policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) EXPORT_SYMBOL(bdev_read_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) * Disk events - monitor disk events like media change and eject request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) struct disk_events {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) struct list_head node; /* all disk_event's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) struct gendisk *disk; /* the associated disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) struct mutex block_mutex; /* protects blocking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) int block; /* event blocking depth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) unsigned int pending; /* events already sent out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) unsigned int clearing; /* events being cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) long poll_msecs; /* interval, -1 for default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) struct delayed_work dwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) static const char *disk_events_strs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) [ilog2(DISK_EVENT_MEDIA_CHANGE)] = "media_change",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) [ilog2(DISK_EVENT_EJECT_REQUEST)] = "eject_request",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) static char *disk_uevents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) [ilog2(DISK_EVENT_MEDIA_CHANGE)] = "DISK_MEDIA_CHANGE=1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) [ilog2(DISK_EVENT_EJECT_REQUEST)] = "DISK_EJECT_REQUEST=1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) /* list of all disk_events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) static DEFINE_MUTEX(disk_events_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) static LIST_HEAD(disk_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) /* disable in-kernel polling by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) static unsigned long disk_events_dfl_poll_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) static unsigned long disk_events_poll_jiffies(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) struct disk_events *ev = disk->ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) long intv_msecs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) * If device-specific poll interval is set, always use it. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) * the default is being used, poll if the POLL flag is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) if (ev->poll_msecs >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) intv_msecs = ev->poll_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) else if (disk->event_flags & DISK_EVENT_FLAG_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) intv_msecs = disk_events_dfl_poll_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) return msecs_to_jiffies(intv_msecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) * disk_block_events - block and flush disk event checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) * @disk: disk to block events for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) * On return from this function, it is guaranteed that event checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) * isn't in progress and won't happen until unblocked by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) * disk_unblock_events(). Events blocking is counted and the actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) * unblocking happens after the matching number of unblocks are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) * Note that this intentionally does not block event checking from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) * disk_clear_events().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * Might sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) void disk_block_events(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) struct disk_events *ev = disk->ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) bool cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (!ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) * Outer mutex ensures that the first blocker completes canceling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) * the event work before further blockers are allowed to finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) mutex_lock(&ev->block_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) spin_lock_irqsave(&ev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) cancel = !ev->block++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) spin_unlock_irqrestore(&ev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (cancel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) cancel_delayed_work_sync(&disk->ev->dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) mutex_unlock(&ev->block_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) static void __disk_unblock_events(struct gendisk *disk, bool check_now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) struct disk_events *ev = disk->ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) unsigned long intv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) spin_lock_irqsave(&ev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) if (WARN_ON_ONCE(ev->block <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (--ev->block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) intv = disk_events_poll_jiffies(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) if (check_now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) queue_delayed_work(system_freezable_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) &ev->dwork, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) else if (intv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) queue_delayed_work(system_freezable_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) &ev->dwork, intv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) spin_unlock_irqrestore(&ev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * disk_unblock_events - unblock disk event checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) * @disk: disk to unblock events for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) * Undo disk_block_events(). When the block count reaches zero, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) * starts events polling if configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) * Don't care. Safe to call from irq context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) void disk_unblock_events(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) if (disk->ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) __disk_unblock_events(disk, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) * disk_flush_events - schedule immediate event checking and flushing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) * @disk: disk to check and flush events for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) * @mask: events to flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) * Schedule immediate event checking on @disk if not blocked. Events in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) * @mask are scheduled to be cleared from the driver. Note that this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) * doesn't clear the events from @disk->ev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) * If @mask is non-zero must be called with bdev->bd_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) void disk_flush_events(struct gendisk *disk, unsigned int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) struct disk_events *ev = disk->ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (!ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) spin_lock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) ev->clearing |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (!ev->block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) mod_delayed_work(system_freezable_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) &ev->dwork, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) spin_unlock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) * disk_clear_events - synchronously check, clear and return pending events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) * @disk: disk to fetch and clear events from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) * @mask: mask of events to be fetched and cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) * Disk events are synchronously checked and pending events in @mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) * are cleared and returned. This ignores the block count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) * CONTEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) * Might sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) static unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) struct disk_events *ev = disk->ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) unsigned int pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) unsigned int clearing = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (!ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) disk_block_events(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) * store the union of mask and ev->clearing on the stack so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) * race with disk_flush_events does not cause ambiguity (ev->clearing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) * can still be modified even if events are blocked).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) spin_lock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) clearing |= ev->clearing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) ev->clearing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) spin_unlock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) disk_check_events(ev, &clearing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) * if ev->clearing is not 0, the disk_flush_events got called in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) * middle of this function, so we want to run the workfn without delay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) __disk_unblock_events(disk, ev->clearing ? true : false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) /* then, fetch and clear pending events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) spin_lock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) pending = ev->pending & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) ev->pending &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) spin_unlock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) WARN_ON_ONCE(clearing & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) return pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) * bdev_check_media_change - check if a removable media has been changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) * @bdev: block device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) * Check whether a removable media has been changed, and attempt to free all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) * dentries and inodes and invalidates all block device page cache entries in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) * that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) * Returns %true if the block device changed, or %false if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) bool bdev_check_media_change(struct block_device *bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) unsigned int events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) events = disk_clear_events(bdev->bd_disk, DISK_EVENT_MEDIA_CHANGE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) DISK_EVENT_EJECT_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) if (!(events & DISK_EVENT_MEDIA_CHANGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) if (__invalidate_device(bdev, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) pr_warn("VFS: busy inodes on changed media %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) bdev->bd_disk->disk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) set_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) EXPORT_SYMBOL(bdev_check_media_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) * Separate this part out so that a different pointer for clearing_ptr can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) * passed in for disk_clear_events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) static void disk_events_workfn(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) struct delayed_work *dwork = to_delayed_work(work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) struct disk_events *ev = container_of(dwork, struct disk_events, dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) disk_check_events(ev, &ev->clearing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) static void disk_check_events(struct disk_events *ev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) unsigned int *clearing_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) struct gendisk *disk = ev->disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) char *envp[ARRAY_SIZE(disk_uevents) + 1] = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) unsigned int clearing = *clearing_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) unsigned int events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) unsigned long intv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) int nr_events = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) /* check events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) events = disk->fops->check_events(disk, clearing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) /* accumulate pending events and schedule next poll if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) spin_lock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) events &= ~ev->pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) ev->pending |= events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) *clearing_ptr &= ~clearing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) intv = disk_events_poll_jiffies(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) if (!ev->block && intv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) queue_delayed_work(system_freezable_power_efficient_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) &ev->dwork, intv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) spin_unlock_irq(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) * Tell userland about new events. Only the events listed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) * @disk->events are reported, and only if DISK_EVENT_FLAG_UEVENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) * is set. Otherwise, events are processed internally but never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) * get reported to userland.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) for (i = 0; i < ARRAY_SIZE(disk_uevents); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if ((events & disk->events & (1 << i)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) (disk->event_flags & DISK_EVENT_FLAG_UEVENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) envp[nr_events++] = disk_uevents[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) if (nr_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) kobject_uevent_env(&disk_to_dev(disk)->kobj, KOBJ_CHANGE, envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) * A disk events enabled device has the following sysfs nodes under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) * its /sys/block/X/ directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) * events : list of all supported events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) * events_async : list of events which can be detected w/o polling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) * (always empty, only for backwards compatibility)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) * events_poll_msecs : polling interval, 0: disable, -1: system default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) static ssize_t __disk_events_show(unsigned int events, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) const char *delim = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) ssize_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) for (i = 0; i < ARRAY_SIZE(disk_events_strs); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) if (events & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) pos += sprintf(buf + pos, "%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) delim, disk_events_strs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) delim = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if (pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) pos += sprintf(buf + pos, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) static ssize_t disk_events_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) if (!(disk->event_flags & DISK_EVENT_FLAG_UEVENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) return __disk_events_show(disk->events, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) static ssize_t disk_events_async_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) static ssize_t disk_events_poll_msecs_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) if (!disk->ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) return sprintf(buf, "-1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) return sprintf(buf, "%ld\n", disk->ev->poll_msecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) static ssize_t disk_events_poll_msecs_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) long intv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) if (!count || !sscanf(buf, "%ld", &intv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) if (intv < 0 && intv != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (!disk->ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) disk_block_events(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) disk->ev->poll_msecs = intv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) __disk_unblock_events(disk, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) static const DEVICE_ATTR(events, 0444, disk_events_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) static const DEVICE_ATTR(events_async, 0444, disk_events_async_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static const DEVICE_ATTR(events_poll_msecs, 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) disk_events_poll_msecs_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) disk_events_poll_msecs_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) static const struct attribute *disk_events_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) &dev_attr_events.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) &dev_attr_events_async.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) &dev_attr_events_poll_msecs.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) * The default polling interval can be specified by the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) * parameter block.events_dfl_poll_msecs which defaults to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) * (disable). This can also be modified runtime by writing to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) * /sys/module/block/parameters/events_dfl_poll_msecs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) static int disk_events_set_dfl_poll_msecs(const char *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) struct disk_events *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) ret = param_set_ulong(val, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) mutex_lock(&disk_events_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) list_for_each_entry(ev, &disk_events, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) disk_flush_events(ev->disk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) mutex_unlock(&disk_events_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) static const struct kernel_param_ops disk_events_dfl_poll_msecs_param_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) .set = disk_events_set_dfl_poll_msecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) .get = param_get_ulong,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) #undef MODULE_PARAM_PREFIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) #define MODULE_PARAM_PREFIX "block."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) &disk_events_dfl_poll_msecs, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) * disk_{alloc|add|del|release}_events - initialize and destroy disk_events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) static void disk_alloc_events(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) struct disk_events *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) if (!disk->fops->check_events || !disk->events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) ev = kzalloc(sizeof(*ev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) if (!ev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) pr_warn("%s: failed to initialize events\n", disk->disk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) INIT_LIST_HEAD(&ev->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) ev->disk = disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) spin_lock_init(&ev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) mutex_init(&ev->block_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) ev->block = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) ev->poll_msecs = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) disk->ev = ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) static void disk_add_events(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) /* FIXME: error handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) pr_warn("%s: failed to create sysfs files for events\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) disk->disk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) if (!disk->ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) mutex_lock(&disk_events_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) list_add_tail(&disk->ev->node, &disk_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) mutex_unlock(&disk_events_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) * Block count is initialized to 1 and the following initial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) * unblock kicks it into action.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) __disk_unblock_events(disk, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) static void disk_del_events(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (disk->ev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) disk_block_events(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) mutex_lock(&disk_events_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) list_del_init(&disk->ev->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) mutex_unlock(&disk_events_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) sysfs_remove_files(&disk_to_dev(disk)->kobj, disk_events_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) static void disk_release_events(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) /* the block count should be 1 from disk_del_events() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) WARN_ON_ONCE(disk->ev && disk->ev->block != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) kfree(disk->ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) }