]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1da177e4 LT |
2 | #ifndef _LINUX_GENHD_H |
3 | #define _LINUX_GENHD_H | |
4 | ||
5 | /* | |
6 | * genhd.h Copyright (C) 1992 Drew Eckhardt | |
7 | * Generic hard disk header file by | |
8 | * Drew Eckhardt | |
9 | * | |
10 | * <drew@colorado.edu> | |
11 | */ | |
12 | ||
1da177e4 | 13 | #include <linux/types.h> |
edfaa7c3 | 14 | #include <linux/kdev_t.h> |
e71bf0d0 | 15 | #include <linux/rcupdate.h> |
6d1d8050 | 16 | #include <linux/slab.h> |
6c71013e | 17 | #include <linux/percpu-refcount.h> |
63579785 | 18 | #include <linux/uuid.h> |
dbae2c55 | 19 | #include <linux/blk_types.h> |
1226b8dd | 20 | #include <asm/local.h> |
1da177e4 | 21 | |
ef45fe47 | 22 | extern const struct device_type disk_type; |
edfaa7c3 | 23 | extern struct device_type part_type; |
edfaa7c3 KS |
24 | extern struct class block_class; |
25 | ||
689d6fac | 26 | #define DISK_MAX_PARTS 256 |
3e1a7ff8 | 27 | #define DISK_NAME_LEN 32 |
689d6fac | 28 | |
34186efc DW |
29 | #include <linux/major.h> |
30 | #include <linux/device.h> | |
31 | #include <linux/smp.h> | |
32 | #include <linux/string.h> | |
33 | #include <linux/fs.h> | |
8ce7ad7b | 34 | #include <linux/workqueue.h> |
34186efc | 35 | |
6d1d8050 | 36 | #define PARTITION_META_INFO_VOLNAMELTH 64 |
1ad7e899 SW |
37 | /* |
38 | * Enough for the string representation of any kind of UUID plus NULL. | |
39 | * EFI UUID is 36 characters. MSDOS UUID is 11 characters. | |
40 | */ | |
63579785 | 41 | #define PARTITION_META_INFO_UUIDLTH (UUID_STRING_LEN + 1) |
6d1d8050 WD |
42 | |
43 | struct partition_meta_info { | |
1ad7e899 | 44 | char uuid[PARTITION_META_INFO_UUIDLTH]; |
6d1d8050 WD |
45 | u8 volname[PARTITION_META_INFO_VOLNAMELTH]; |
46 | }; | |
47 | ||
9243c6f3 SK |
48 | /** |
49 | * DOC: genhd capability flags | |
50 | * | |
51 | * ``GENHD_FL_REMOVABLE`` (0x0001): indicates that the block device | |
52 | * gives access to removable media. | |
53 | * When set, the device remains present even when media is not | |
54 | * inserted. | |
55 | * Must not be set for devices which are removed entirely when the | |
56 | * media is removed. | |
57 | * | |
58 | * ``GENHD_FL_CD`` (0x0008): the block device is a CD-ROM-style | |
59 | * device. | |
60 | * Affects responses to the ``CDROM_GET_CAPABILITY`` ioctl. | |
61 | * | |
62 | * ``GENHD_FL_UP`` (0x0010): indicates that the block device is "up", | |
63 | * with a similar meaning to network interfaces. | |
64 | * | |
65 | * ``GENHD_FL_SUPPRESS_PARTITION_INFO`` (0x0020): don't include | |
66 | * partition information in ``/proc/partitions`` or in the output of | |
67 | * printk_all_partitions(). | |
68 | * Used for the null block device and some MMC devices. | |
69 | * | |
70 | * ``GENHD_FL_EXT_DEVT`` (0x0040): the driver supports extended | |
71 | * dynamic ``dev_t``, i.e. it wants extended device numbers | |
72 | * (``BLOCK_EXT_MAJOR``). | |
73 | * This affects the maximum number of partitions. | |
74 | * | |
75 | * ``GENHD_FL_NATIVE_CAPACITY`` (0x0080): based on information in the | |
76 | * partition table, the device's capacity has been extended to its | |
77 | * native capacity; i.e. the device has hidden capacity used by one | |
78 | * of the partitions (this is a flag used so that native capacity is | |
79 | * only ever unlocked once). | |
80 | * | |
81 | * ``GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE`` (0x0100): event polling is | |
82 | * blocked whenever a writer holds an exclusive lock. | |
83 | * | |
84 | * ``GENHD_FL_NO_PART_SCAN`` (0x0200): partition scanning is disabled. | |
85 | * Used for loop devices in their default settings and some MMC | |
86 | * devices. | |
87 | * | |
88 | * ``GENHD_FL_HIDDEN`` (0x0400): the block device is hidden; it | |
89 | * doesn't produce events, doesn't appear in sysfs, and doesn't have | |
90 | * an associated ``bdev``. | |
91 | * Implies ``GENHD_FL_SUPPRESS_PARTITION_INFO`` and | |
92 | * ``GENHD_FL_NO_PART_SCAN``. | |
93 | * Used for multipath devices. | |
94 | */ | |
95 | #define GENHD_FL_REMOVABLE 0x0001 | |
96 | /* 2 is unused (used to be GENHD_FL_DRIVERFS) */ | |
97 | /* 4 is unused (used to be GENHD_FL_MEDIA_CHANGE_NOTIFY) */ | |
98 | #define GENHD_FL_CD 0x0008 | |
99 | #define GENHD_FL_UP 0x0010 | |
100 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 0x0020 | |
101 | #define GENHD_FL_EXT_DEVT 0x0040 | |
102 | #define GENHD_FL_NATIVE_CAPACITY 0x0080 | |
103 | #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 0x0100 | |
104 | #define GENHD_FL_NO_PART_SCAN 0x0200 | |
105 | #define GENHD_FL_HIDDEN 0x0400 | |
1da177e4 | 106 | |
77ea887e TH |
107 | enum { |
108 | DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ | |
109 | DISK_EVENT_EJECT_REQUEST = 1 << 1, /* eject requested */ | |
110 | }; | |
111 | ||
c92e2f04 MW |
112 | enum { |
113 | /* Poll even if events_poll_msecs is unset */ | |
114 | DISK_EVENT_FLAG_POLL = 1 << 0, | |
115 | /* Forward events to udev */ | |
116 | DISK_EVENT_FLAG_UEVENT = 1 << 1, | |
117 | }; | |
118 | ||
540eed56 TH |
119 | struct disk_part_tbl { |
120 | struct rcu_head rcu_head; | |
121 | int len; | |
8446fe92 CH |
122 | struct block_device __rcu *last_lookup; |
123 | struct block_device __rcu *part[]; | |
540eed56 TH |
124 | }; |
125 | ||
77ea887e | 126 | struct disk_events; |
99e6608c | 127 | struct badblocks; |
77ea887e | 128 | |
25520d55 | 129 | struct blk_integrity { |
869ab90f EB |
130 | const struct blk_integrity_profile *profile; |
131 | unsigned char flags; | |
132 | unsigned char tuple_size; | |
133 | unsigned char interval_exp; | |
134 | unsigned char tag_size; | |
25520d55 MP |
135 | }; |
136 | ||
1da177e4 | 137 | struct gendisk { |
689d6fac TH |
138 | /* major, first_minor and minors are input parameters only, |
139 | * don't use directly. Use disk_devt() and disk_max_parts(). | |
f331c029 | 140 | */ |
1da177e4 LT |
141 | int major; /* major number of driver */ |
142 | int first_minor; | |
143 | int minors; /* maximum number of minors, =1 for | |
144 | * disks that can't be partitioned. */ | |
f331c029 | 145 | |
3e1a7ff8 | 146 | char disk_name[DISK_NAME_LEN]; /* name of major driver */ |
77ea887e | 147 | |
c92e2f04 MW |
148 | unsigned short events; /* supported events */ |
149 | unsigned short event_flags; /* flags related to event processing */ | |
77ea887e | 150 | |
b5d0b9df | 151 | /* Array of pointers to partitions indexed by partno. |
e71bf0d0 TH |
152 | * Protected with matching bdev lock but stat and other |
153 | * non-critical accesses use RCU. Always access through | |
154 | * helpers. | |
155 | */ | |
4d2deb40 | 156 | struct disk_part_tbl __rcu *part_tbl; |
cb8432d6 | 157 | struct block_device *part0; |
e71bf0d0 | 158 | |
83d5cde4 | 159 | const struct block_device_operations *fops; |
1da177e4 LT |
160 | struct request_queue *queue; |
161 | void *private_data; | |
1da177e4 LT |
162 | |
163 | int flags; | |
38430f08 CH |
164 | unsigned long state; |
165 | #define GD_NEED_PART_SCAN 0 | |
6a4d44c1 | 166 | struct kobject *slave_dir; |
1da177e4 LT |
167 | |
168 | struct timer_rand_state *random; | |
1da177e4 | 169 | atomic_t sync_io; /* RAID */ |
77ea887e | 170 | struct disk_events *ev; |
7ba1ba12 | 171 | #ifdef CONFIG_BLK_DEV_INTEGRITY |
aff34e19 | 172 | struct kobject integrity_kobj; |
25520d55 | 173 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ |
a711d91c CH |
174 | #if IS_ENABLED(CONFIG_CDROM) |
175 | struct cdrom_device_info *cdi; | |
176 | #endif | |
540eed56 | 177 | int node_id; |
99e6608c | 178 | struct badblocks *bb; |
e319e1fb | 179 | struct lockdep_map lockdep_map; |
1da177e4 LT |
180 | }; |
181 | ||
0d02129e CH |
182 | /* |
183 | * The gendisk is refcounted by the part0 block_device, and the bd_device | |
184 | * therein is also used for device model presentation in sysfs. | |
185 | */ | |
186 | #define dev_to_disk(device) \ | |
187 | (dev_to_bdev(device)->bd_disk) | |
188 | #define disk_to_dev(disk) \ | |
189 | (&((disk)->part0->bd_device)) | |
190 | ||
a711d91c CH |
191 | #if IS_REACHABLE(CONFIG_CDROM) |
192 | #define disk_to_cdi(disk) ((disk)->cdi) | |
193 | #else | |
194 | #define disk_to_cdi(disk) NULL | |
195 | #endif | |
196 | ||
f331c029 TH |
197 | static inline int disk_max_parts(struct gendisk *disk) |
198 | { | |
689d6fac TH |
199 | if (disk->flags & GENHD_FL_EXT_DEVT) |
200 | return DISK_MAX_PARTS; | |
201 | return disk->minors; | |
b5d0b9df TH |
202 | } |
203 | ||
d27769ec | 204 | static inline bool disk_part_scan_enabled(struct gendisk *disk) |
b5d0b9df | 205 | { |
d27769ec TH |
206 | return disk_max_parts(disk) > 1 && |
207 | !(disk->flags & GENHD_FL_NO_PART_SCAN); | |
f331c029 TH |
208 | } |
209 | ||
210 | static inline dev_t disk_devt(struct gendisk *disk) | |
211 | { | |
517bf3c3 | 212 | return MKDEV(disk->major, disk->first_minor); |
f331c029 TH |
213 | } |
214 | ||
e71bf0d0 TH |
215 | /* |
216 | * Smarter partition iterator without context limits. | |
217 | */ | |
218 | #define DISK_PITER_REVERSE (1 << 0) /* iterate in the reverse direction */ | |
219 | #define DISK_PITER_INCL_EMPTY (1 << 1) /* include 0-sized parts */ | |
b5d0b9df | 220 | #define DISK_PITER_INCL_PART0 (1 << 2) /* include partition 0 */ |
71982a40 | 221 | #define DISK_PITER_INCL_EMPTY_PART0 (1 << 3) /* include empty partition 0 */ |
e71bf0d0 TH |
222 | |
223 | struct disk_part_iter { | |
224 | struct gendisk *disk; | |
ad1eaa53 | 225 | struct block_device *part; |
e71bf0d0 TH |
226 | int idx; |
227 | unsigned int flags; | |
228 | }; | |
229 | ||
230 | extern void disk_part_iter_init(struct disk_part_iter *piter, | |
231 | struct gendisk *disk, unsigned int flags); | |
ad1eaa53 | 232 | struct block_device *disk_part_iter_next(struct disk_part_iter *piter); |
e71bf0d0 | 233 | extern void disk_part_iter_exit(struct disk_part_iter *piter); |
10f36b1e | 234 | extern bool disk_has_partitions(struct gendisk *disk); |
1da177e4 | 235 | |
32ca163c | 236 | /* block/genhd.c */ |
fef912bf HR |
237 | extern void device_add_disk(struct device *parent, struct gendisk *disk, |
238 | const struct attribute_group **groups); | |
e63a46be DW |
239 | static inline void add_disk(struct gendisk *disk) |
240 | { | |
fef912bf | 241 | device_add_disk(NULL, disk, NULL); |
e63a46be | 242 | } |
fa70d2e2 MS |
243 | extern void device_add_disk_no_queue_reg(struct device *parent, struct gendisk *disk); |
244 | static inline void add_disk_no_queue_reg(struct gendisk *disk) | |
245 | { | |
246 | device_add_disk_no_queue_reg(NULL, disk); | |
247 | } | |
e63a46be | 248 | |
1da177e4 | 249 | extern void del_gendisk(struct gendisk *gp); |
f331c029 | 250 | extern struct block_device *bdget_disk(struct gendisk *disk, int partno); |
1da177e4 | 251 | |
1da177e4 LT |
252 | extern void set_disk_ro(struct gendisk *disk, int flag); |
253 | ||
b7db9956 TH |
254 | static inline int get_disk_ro(struct gendisk *disk) |
255 | { | |
cb8432d6 | 256 | return disk->part0->bd_read_only; |
b7db9956 TH |
257 | } |
258 | ||
77ea887e TH |
259 | extern void disk_block_events(struct gendisk *disk); |
260 | extern void disk_unblock_events(struct gendisk *disk); | |
85ef06d1 | 261 | extern void disk_flush_events(struct gendisk *disk, unsigned int mask); |
449f4ec9 | 262 | bool set_capacity_and_notify(struct gendisk *disk, sector_t size); |
77ea887e | 263 | |
1da177e4 | 264 | /* drivers/char/random.c */ |
0766f788 | 265 | extern void add_disk_randomness(struct gendisk *disk) __latent_entropy; |
1da177e4 LT |
266 | extern void rand_initialize_disk(struct gendisk *disk); |
267 | ||
268 | static inline sector_t get_start_sect(struct block_device *bdev) | |
269 | { | |
29ff57c6 | 270 | return bdev->bd_start_sect; |
1da177e4 | 271 | } |
a782483c CH |
272 | |
273 | static inline sector_t bdev_nr_sectors(struct block_device *bdev) | |
1da177e4 | 274 | { |
a782483c | 275 | return i_size_read(bdev->bd_inode) >> 9; |
1da177e4 | 276 | } |
a782483c CH |
277 | |
278 | static inline sector_t get_capacity(struct gendisk *disk) | |
1da177e4 | 279 | { |
cb8432d6 | 280 | return bdev_nr_sectors(disk->part0); |
1da177e4 LT |
281 | } |
282 | ||
142fe8f4 | 283 | int bdev_disk_changed(struct block_device *bdev, bool invalidate); |
a1548b67 | 284 | int blk_add_partitions(struct gendisk *disk, struct block_device *bdev); |
d46430bf | 285 | int blk_drop_partitions(struct block_device *bdev); |
1da177e4 | 286 | |
e319e1fb | 287 | extern struct gendisk *__alloc_disk_node(int minors, int node_id); |
1da177e4 | 288 | extern void put_disk(struct gendisk *disk); |
1da177e4 | 289 | |
e319e1fb BP |
290 | #define alloc_disk_node(minors, node_id) \ |
291 | ({ \ | |
292 | static struct lock_class_key __key; \ | |
293 | const char *__name; \ | |
294 | struct gendisk *__disk; \ | |
295 | \ | |
296 | __name = "(gendisk_completion)"#minors"("#node_id")"; \ | |
297 | \ | |
298 | __disk = __alloc_disk_node(minors, node_id); \ | |
299 | \ | |
300 | if (__disk) \ | |
301 | lockdep_init_map(&__disk->lockdep_map, __name, &__key, 0); \ | |
302 | \ | |
303 | __disk; \ | |
304 | }) | |
305 | ||
306 | #define alloc_disk(minors) alloc_disk_node(minors, NUMA_NO_NODE) | |
307 | ||
a160c615 CH |
308 | int __register_blkdev(unsigned int major, const char *name, |
309 | void (*probe)(dev_t devt)); | |
310 | #define register_blkdev(major, name) \ | |
311 | __register_blkdev(major, name, NULL) | |
3f1266f1 CH |
312 | void unregister_blkdev(unsigned int major, const char *name); |
313 | ||
95f6f3a4 | 314 | bool bdev_check_media_change(struct block_device *bdev); |
3f1266f1 | 315 | int __invalidate_device(struct block_device *bdev, bool kill_dirty); |
a782483c | 316 | void set_capacity(struct gendisk *disk, sector_t size); |
3f1266f1 CH |
317 | |
318 | /* for drivers/char/raw.c: */ | |
319 | int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); | |
320 | long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); | |
321 | ||
322 | #ifdef CONFIG_SYSFS | |
323 | int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk); | |
324 | void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk); | |
325 | #else | |
326 | static inline int bd_link_disk_holder(struct block_device *bdev, | |
327 | struct gendisk *disk) | |
328 | { | |
329 | return 0; | |
330 | } | |
331 | static inline void bd_unlink_disk_holder(struct block_device *bdev, | |
332 | struct gendisk *disk) | |
333 | { | |
334 | } | |
335 | #endif /* CONFIG_SYSFS */ | |
336 | ||
22ae8ce8 CH |
337 | extern struct rw_semaphore bdev_lookup_sem; |
338 | ||
c2637e80 | 339 | dev_t blk_lookup_devt(const char *name, int partno); |
22ae8ce8 | 340 | void blk_request_module(dev_t devt); |
1a4dcfa8 CH |
341 | #ifdef CONFIG_BLOCK |
342 | void printk_all_partitions(void); | |
87c1efbf | 343 | #else /* CONFIG_BLOCK */ |
1a4dcfa8 CH |
344 | static inline void printk_all_partitions(void) |
345 | { | |
346 | } | |
87c1efbf | 347 | #endif /* CONFIG_BLOCK */ |
9361401e | 348 | |
a8ae50ba | 349 | #endif /* _LINUX_GENHD_H */ |