aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/genhd.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/genhd.h')
-rw-r--r--include/linux/genhd.h117
1 files changed, 103 insertions, 14 deletions
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 5f2f4c4d8fb0..300d7582006e 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -12,6 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/kdev_t.h> 13#include <linux/kdev_t.h>
14#include <linux/rcupdate.h> 14#include <linux/rcupdate.h>
15#include <linux/slab.h>
15 16
16#ifdef CONFIG_BLOCK 17#ifdef CONFIG_BLOCK
17 18
@@ -86,7 +87,15 @@ struct disk_stats {
86 unsigned long io_ticks; 87 unsigned long io_ticks;
87 unsigned long time_in_queue; 88 unsigned long time_in_queue;
88}; 89};
89 90
91#define PARTITION_META_INFO_VOLNAMELTH 64
92#define PARTITION_META_INFO_UUIDLTH 16
93
94struct partition_meta_info {
95 u8 uuid[PARTITION_META_INFO_UUIDLTH]; /* always big endian */
96 u8 volname[PARTITION_META_INFO_VOLNAMELTH];
97};
98
90struct hd_struct { 99struct hd_struct {
91 sector_t start_sect; 100 sector_t start_sect;
92 sector_t nr_sects; 101 sector_t nr_sects;
@@ -95,16 +104,18 @@ struct hd_struct {
95 struct device __dev; 104 struct device __dev;
96 struct kobject *holder_dir; 105 struct kobject *holder_dir;
97 int policy, partno; 106 int policy, partno;
107 struct partition_meta_info *info;
98#ifdef CONFIG_FAIL_MAKE_REQUEST 108#ifdef CONFIG_FAIL_MAKE_REQUEST
99 int make_it_fail; 109 int make_it_fail;
100#endif 110#endif
101 unsigned long stamp; 111 unsigned long stamp;
102 int in_flight[2]; 112 atomic_t in_flight[2];
103#ifdef CONFIG_SMP 113#ifdef CONFIG_SMP
104 struct disk_stats __percpu *dkstats; 114 struct disk_stats __percpu *dkstats;
105#else 115#else
106 struct disk_stats dkstats; 116 struct disk_stats dkstats;
107#endif 117#endif
118 atomic_t ref;
108 struct rcu_head rcu_head; 119 struct rcu_head rcu_head;
109}; 120};
110 121
@@ -116,6 +127,12 @@ struct hd_struct {
116#define GENHD_FL_SUPPRESS_PARTITION_INFO 32 127#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
117#define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ 128#define GENHD_FL_EXT_DEVT 64 /* allow extended devt */
118#define GENHD_FL_NATIVE_CAPACITY 128 129#define GENHD_FL_NATIVE_CAPACITY 128
130#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256
131
132enum {
133 DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */
134 DISK_EVENT_EJECT_REQUEST = 1 << 1, /* eject requested */
135};
119 136
120#define BLK_SCSI_MAX_CMDS (256) 137#define BLK_SCSI_MAX_CMDS (256)
121#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) 138#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
@@ -129,10 +146,12 @@ struct blk_scsi_cmd_filter {
129struct disk_part_tbl { 146struct disk_part_tbl {
130 struct rcu_head rcu_head; 147 struct rcu_head rcu_head;
131 int len; 148 int len;
132 struct hd_struct *last_lookup; 149 struct hd_struct __rcu *last_lookup;
133 struct hd_struct *part[]; 150 struct hd_struct __rcu *part[];
134}; 151};
135 152
153struct disk_events;
154
136struct gendisk { 155struct gendisk {
137 /* major, first_minor and minors are input parameters only, 156 /* major, first_minor and minors are input parameters only,
138 * don't use directly. Use disk_devt() and disk_max_parts(). 157 * don't use directly. Use disk_devt() and disk_max_parts().
@@ -144,12 +163,16 @@ struct gendisk {
144 163
145 char disk_name[DISK_NAME_LEN]; /* name of major driver */ 164 char disk_name[DISK_NAME_LEN]; /* name of major driver */
146 char *(*devnode)(struct gendisk *gd, mode_t *mode); 165 char *(*devnode)(struct gendisk *gd, mode_t *mode);
166
167 unsigned int events; /* supported events */
168 unsigned int async_events; /* async events, subset of all */
169
147 /* Array of pointers to partitions indexed by partno. 170 /* Array of pointers to partitions indexed by partno.
148 * Protected with matching bdev lock but stat and other 171 * Protected with matching bdev lock but stat and other
149 * non-critical accesses use RCU. Always access through 172 * non-critical accesses use RCU. Always access through
150 * helpers. 173 * helpers.
151 */ 174 */
152 struct disk_part_tbl *part_tbl; 175 struct disk_part_tbl __rcu *part_tbl;
153 struct hd_struct part0; 176 struct hd_struct part0;
154 177
155 const struct block_device_operations *fops; 178 const struct block_device_operations *fops;
@@ -161,9 +184,8 @@ struct gendisk {
161 struct kobject *slave_dir; 184 struct kobject *slave_dir;
162 185
163 struct timer_rand_state *random; 186 struct timer_rand_state *random;
164
165 atomic_t sync_io; /* RAID */ 187 atomic_t sync_io; /* RAID */
166 struct work_struct async_notify; 188 struct disk_events *ev;
167#ifdef CONFIG_BLK_DEV_INTEGRITY 189#ifdef CONFIG_BLK_DEV_INTEGRITY
168 struct blk_integrity *integrity; 190 struct blk_integrity *integrity;
169#endif 191#endif
@@ -181,6 +203,30 @@ static inline struct gendisk *part_to_disk(struct hd_struct *part)
181 return NULL; 203 return NULL;
182} 204}
183 205
206static inline void part_pack_uuid(const u8 *uuid_str, u8 *to)
207{
208 int i;
209 for (i = 0; i < 16; ++i) {
210 *to++ = (hex_to_bin(*uuid_str) << 4) |
211 (hex_to_bin(*(uuid_str + 1)));
212 uuid_str += 2;
213 switch (i) {
214 case 3:
215 case 5:
216 case 7:
217 case 9:
218 uuid_str++;
219 continue;
220 }
221 }
222}
223
224static inline char *part_unpack_uuid(const u8 *uuid, char *out)
225{
226 sprintf(out, "%pU", uuid);
227 return out;
228}
229
184static inline int disk_max_parts(struct gendisk *disk) 230static inline int disk_max_parts(struct gendisk *disk)
185{ 231{
186 if (disk->flags & GENHD_FL_EXT_DEVT) 232 if (disk->flags & GENHD_FL_EXT_DEVT)
@@ -325,21 +371,34 @@ static inline void free_part_stats(struct hd_struct *part)
325 371
326static inline void part_inc_in_flight(struct hd_struct *part, int rw) 372static inline void part_inc_in_flight(struct hd_struct *part, int rw)
327{ 373{
328 part->in_flight[rw]++; 374 atomic_inc(&part->in_flight[rw]);
329 if (part->partno) 375 if (part->partno)
330 part_to_disk(part)->part0.in_flight[rw]++; 376 atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
331} 377}
332 378
333static inline void part_dec_in_flight(struct hd_struct *part, int rw) 379static inline void part_dec_in_flight(struct hd_struct *part, int rw)
334{ 380{
335 part->in_flight[rw]--; 381 atomic_dec(&part->in_flight[rw]);
336 if (part->partno) 382 if (part->partno)
337 part_to_disk(part)->part0.in_flight[rw]--; 383 atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
338} 384}
339 385
340static inline int part_in_flight(struct hd_struct *part) 386static inline int part_in_flight(struct hd_struct *part)
341{ 387{
342 return part->in_flight[0] + part->in_flight[1]; 388 return atomic_read(&part->in_flight[0]) + atomic_read(&part->in_flight[1]);
389}
390
391static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)
392{
393 if (disk)
394 return kzalloc_node(sizeof(struct partition_meta_info),
395 GFP_KERNEL, disk->node_id);
396 return kzalloc(sizeof(struct partition_meta_info), GFP_KERNEL);
397}
398
399static inline void free_part_info(struct hd_struct *part)
400{
401 kfree(part->info);
343} 402}
344 403
345/* block/blk-core.c */ 404/* block/blk-core.c */
@@ -348,7 +407,6 @@ extern void part_round_stats(int cpu, struct hd_struct *part);
348/* block/genhd.c */ 407/* block/genhd.c */
349extern void add_disk(struct gendisk *disk); 408extern void add_disk(struct gendisk *disk);
350extern void del_gendisk(struct gendisk *gp); 409extern void del_gendisk(struct gendisk *gp);
351extern void unlink_gendisk(struct gendisk *gp);
352extern struct gendisk *get_gendisk(dev_t dev, int *partno); 410extern struct gendisk *get_gendisk(dev_t dev, int *partno);
353extern struct block_device *bdget_disk(struct gendisk *disk, int partno); 411extern struct block_device *bdget_disk(struct gendisk *disk, int partno);
354 412
@@ -360,6 +418,11 @@ static inline int get_disk_ro(struct gendisk *disk)
360 return disk->part0.policy; 418 return disk->part0.policy;
361} 419}
362 420
421extern void disk_block_events(struct gendisk *disk);
422extern void disk_unblock_events(struct gendisk *disk);
423extern void disk_check_events(struct gendisk *disk);
424extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
425
363/* drivers/char/random.c */ 426/* drivers/char/random.c */
364extern void add_disk_randomness(struct gendisk *disk); 427extern void add_disk_randomness(struct gendisk *disk);
365extern void rand_initialize_disk(struct gendisk *disk); 428extern void rand_initialize_disk(struct gendisk *disk);
@@ -533,7 +596,10 @@ extern int disk_expand_part_tbl(struct gendisk *disk, int target);
533extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); 596extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
534extern struct hd_struct * __must_check add_partition(struct gendisk *disk, 597extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
535 int partno, sector_t start, 598 int partno, sector_t start,
536 sector_t len, int flags); 599 sector_t len, int flags,
600 struct partition_meta_info
601 *info);
602extern void __delete_partition(struct hd_struct *);
537extern void delete_partition(struct gendisk *, int); 603extern void delete_partition(struct gendisk *, int);
538extern void printk_all_partitions(void); 604extern void printk_all_partitions(void);
539 605
@@ -562,6 +628,29 @@ extern ssize_t part_fail_store(struct device *dev,
562 const char *buf, size_t count); 628 const char *buf, size_t count);
563#endif /* CONFIG_FAIL_MAKE_REQUEST */ 629#endif /* CONFIG_FAIL_MAKE_REQUEST */
564 630
631static inline void hd_ref_init(struct hd_struct *part)
632{
633 atomic_set(&part->ref, 1);
634 smp_mb();
635}
636
637static inline void hd_struct_get(struct hd_struct *part)
638{
639 atomic_inc(&part->ref);
640 smp_mb__after_atomic_inc();
641}
642
643static inline int hd_struct_try_get(struct hd_struct *part)
644{
645 return atomic_inc_not_zero(&part->ref);
646}
647
648static inline void hd_struct_put(struct hd_struct *part)
649{
650 if (atomic_dec_and_test(&part->ref))
651 __delete_partition(part);
652}
653
565#else /* CONFIG_BLOCK */ 654#else /* CONFIG_BLOCK */
566 655
567static inline void printk_all_partitions(void) { } 656static inline void printk_all_partitions(void) { }