aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/genhd.c1
-rw-r--r--block/ioctl.c2
-rw-r--r--fs/partitions/check.c23
-rw-r--r--fs/partitions/check.h3
-rw-r--r--include/linux/genhd.h53
5 files changed, 76 insertions, 6 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 59a2db6fece..c8da1205526 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1004,6 +1004,7 @@ static void disk_release(struct device *dev)
1004 kfree(disk->random); 1004 kfree(disk->random);
1005 disk_replace_part_tbl(disk, NULL); 1005 disk_replace_part_tbl(disk, NULL);
1006 free_part_stats(&disk->part0); 1006 free_part_stats(&disk->part0);
1007 free_part_info(&disk->part0);
1007 kfree(disk); 1008 kfree(disk);
1008} 1009}
1009struct class block_class = { 1010struct class block_class = {
diff --git a/block/ioctl.c b/block/ioctl.c
index d8052f0dabd..2c15fe0912c 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -62,7 +62,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
62 62
63 /* all seems OK */ 63 /* all seems OK */
64 part = add_partition(disk, partno, start, length, 64 part = add_partition(disk, partno, start, length,
65 ADDPART_FLAG_NONE); 65 ADDPART_FLAG_NONE, NULL);
66 mutex_unlock(&bdev->bd_mutex); 66 mutex_unlock(&bdev->bd_mutex);
67 return IS_ERR(part) ? PTR_ERR(part) : 0; 67 return IS_ERR(part) ? PTR_ERR(part) : 0;
68 case BLKPG_DEL_PARTITION: 68 case BLKPG_DEL_PARTITION:
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 79fbf3f390f..6dfbee03ccc 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -352,6 +352,7 @@ static void part_release(struct device *dev)
352{ 352{
353 struct hd_struct *p = dev_to_part(dev); 353 struct hd_struct *p = dev_to_part(dev);
354 free_part_stats(p); 354 free_part_stats(p);
355 free_part_info(p);
355 kfree(p); 356 kfree(p);
356} 357}
357 358
@@ -401,7 +402,8 @@ static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH,
401 whole_disk_show, NULL); 402 whole_disk_show, NULL);
402 403
403struct hd_struct *add_partition(struct gendisk *disk, int partno, 404struct hd_struct *add_partition(struct gendisk *disk, int partno,
404 sector_t start, sector_t len, int flags) 405 sector_t start, sector_t len, int flags,
406 struct partition_meta_info *info)
405{ 407{
406 struct hd_struct *p; 408 struct hd_struct *p;
407 dev_t devt = MKDEV(0, 0); 409 dev_t devt = MKDEV(0, 0);
@@ -438,6 +440,14 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
438 p->partno = partno; 440 p->partno = partno;
439 p->policy = get_disk_ro(disk); 441 p->policy = get_disk_ro(disk);
440 442
443 if (info) {
444 struct partition_meta_info *pinfo = alloc_part_info(disk);
445 if (!pinfo)
446 goto out_free_stats;
447 memcpy(pinfo, info, sizeof(*info));
448 p->info = pinfo;
449 }
450
441 dname = dev_name(ddev); 451 dname = dev_name(ddev);
442 if (isdigit(dname[strlen(dname) - 1])) 452 if (isdigit(dname[strlen(dname) - 1]))
443 dev_set_name(pdev, "%sp%d", dname, partno); 453 dev_set_name(pdev, "%sp%d", dname, partno);
@@ -451,7 +461,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
451 461
452 err = blk_alloc_devt(p, &devt); 462 err = blk_alloc_devt(p, &devt);
453 if (err) 463 if (err)
454 goto out_free_stats; 464 goto out_free_info;
455 pdev->devt = devt; 465 pdev->devt = devt;
456 466
457 /* delay uevent until 'holders' subdir is created */ 467 /* delay uevent until 'holders' subdir is created */
@@ -481,6 +491,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
481 491
482 return p; 492 return p;
483 493
494out_free_info:
495 free_part_info(p);
484out_free_stats: 496out_free_stats:
485 free_part_stats(p); 497 free_part_stats(p);
486out_free: 498out_free:
@@ -642,6 +654,7 @@ rescan:
642 /* add partitions */ 654 /* add partitions */
643 for (p = 1; p < state->limit; p++) { 655 for (p = 1; p < state->limit; p++) {
644 sector_t size, from; 656 sector_t size, from;
657 struct partition_meta_info *info = NULL;
645 658
646 size = state->parts[p].size; 659 size = state->parts[p].size;
647 if (!size) 660 if (!size)
@@ -675,8 +688,12 @@ rescan:
675 size = get_capacity(disk) - from; 688 size = get_capacity(disk) - from;
676 } 689 }
677 } 690 }
691
692 if (state->parts[p].has_info)
693 info = &state->parts[p].info;
678 part = add_partition(disk, p, from, size, 694 part = add_partition(disk, p, from, size,
679 state->parts[p].flags); 695 state->parts[p].flags,
696 &state->parts[p].info);
680 if (IS_ERR(part)) { 697 if (IS_ERR(part)) {
681 printk(KERN_ERR " %s: p%d could not be added: %ld\n", 698 printk(KERN_ERR " %s: p%d could not be added: %ld\n",
682 disk->disk_name, p, -PTR_ERR(part)); 699 disk->disk_name, p, -PTR_ERR(part));
diff --git a/fs/partitions/check.h b/fs/partitions/check.h
index 8e4e103ba21..d68bf4dc3bc 100644
--- a/fs/partitions/check.h
+++ b/fs/partitions/check.h
@@ -1,5 +1,6 @@
1#include <linux/pagemap.h> 1#include <linux/pagemap.h>
2#include <linux/blkdev.h> 2#include <linux/blkdev.h>
3#include <linux/genhd.h>
3 4
4/* 5/*
5 * add_gd_partition adds a partitions details to the devices partition 6 * add_gd_partition adds a partitions details to the devices partition
@@ -12,6 +13,8 @@ struct parsed_partitions {
12 sector_t from; 13 sector_t from;
13 sector_t size; 14 sector_t size;
14 int flags; 15 int flags;
16 bool has_info;
17 struct partition_meta_info info;
15 } parts[DISK_MAX_PARTS]; 18 } parts[DISK_MAX_PARTS];
16 int next; 19 int next;
17 int limit; 20 int limit;
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 5f2f4c4d8fb..66e26b5a153 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,6 +104,7 @@ 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
@@ -181,6 +191,30 @@ static inline struct gendisk *part_to_disk(struct hd_struct *part)
181 return NULL; 191 return NULL;
182} 192}
183 193
194static inline void part_pack_uuid(const u8 *uuid_str, u8 *to)
195{
196 int i;
197 for (i = 0; i < 16; ++i) {
198 *to++ = (hex_to_bin(*uuid_str) << 4) |
199 (hex_to_bin(*(uuid_str + 1)));
200 uuid_str += 2;
201 switch (i) {
202 case 3:
203 case 5:
204 case 7:
205 case 9:
206 uuid_str++;
207 continue;
208 }
209 }
210}
211
212static inline char *part_unpack_uuid(const u8 *uuid, char *out)
213{
214 sprintf(out, "%pU", uuid);
215 return out;
216}
217
184static inline int disk_max_parts(struct gendisk *disk) 218static inline int disk_max_parts(struct gendisk *disk)
185{ 219{
186 if (disk->flags & GENHD_FL_EXT_DEVT) 220 if (disk->flags & GENHD_FL_EXT_DEVT)
@@ -342,6 +376,19 @@ static inline int part_in_flight(struct hd_struct *part)
342 return part->in_flight[0] + part->in_flight[1]; 376 return part->in_flight[0] + part->in_flight[1];
343} 377}
344 378
379static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)
380{
381 if (disk)
382 return kzalloc_node(sizeof(struct partition_meta_info),
383 GFP_KERNEL, disk->node_id);
384 return kzalloc(sizeof(struct partition_meta_info), GFP_KERNEL);
385}
386
387static inline void free_part_info(struct hd_struct *part)
388{
389 kfree(part->info);
390}
391
345/* block/blk-core.c */ 392/* block/blk-core.c */
346extern void part_round_stats(int cpu, struct hd_struct *part); 393extern void part_round_stats(int cpu, struct hd_struct *part);
347 394
@@ -533,7 +580,9 @@ extern int disk_expand_part_tbl(struct gendisk *disk, int target);
533extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); 580extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
534extern struct hd_struct * __must_check add_partition(struct gendisk *disk, 581extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
535 int partno, sector_t start, 582 int partno, sector_t start,
536 sector_t len, int flags); 583 sector_t len, int flags,
584 struct partition_meta_info
585 *info);
537extern void delete_partition(struct gendisk *, int); 586extern void delete_partition(struct gendisk *, int);
538extern void printk_all_partitions(void); 587extern void printk_all_partitions(void);
539 588