diff options
Diffstat (limited to 'block/genhd.c')
| -rw-r--r-- | block/genhd.c | 106 |
1 files changed, 86 insertions, 20 deletions
diff --git a/block/genhd.c b/block/genhd.c index f1ed83f3f083..db57546a709d 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -38,34 +38,100 @@ static inline int major_to_index(int major) | |||
| 38 | return major % MAX_PROBE_HASH; | 38 | return major % MAX_PROBE_HASH; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | #ifdef CONFIG_PROC_FS | 41 | struct blkdev_info { |
| 42 | /* get block device names in somewhat random order */ | 42 | int index; |
| 43 | int get_blkdev_list(char *p, int used) | 43 | struct blk_major_name *bd; |
| 44 | }; | ||
| 45 | |||
| 46 | /* | ||
| 47 | * iterate over a list of blkdev_info structures. allows | ||
| 48 | * the major_names array to be iterated over from outside this file | ||
| 49 | * must be called with the block_subsys_sem held | ||
| 50 | */ | ||
| 51 | void *get_next_blkdev(void *dev) | ||
| 52 | { | ||
| 53 | struct blkdev_info *info; | ||
| 54 | |||
| 55 | if (dev == NULL) { | ||
| 56 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
| 57 | if (!info) | ||
| 58 | goto out; | ||
| 59 | info->index=0; | ||
| 60 | info->bd = major_names[info->index]; | ||
| 61 | if (info->bd) | ||
| 62 | goto out; | ||
| 63 | } else { | ||
| 64 | info = dev; | ||
| 65 | } | ||
| 66 | |||
| 67 | while (info->index < ARRAY_SIZE(major_names)) { | ||
| 68 | if (info->bd) | ||
| 69 | info->bd = info->bd->next; | ||
| 70 | if (info->bd) | ||
| 71 | goto out; | ||
| 72 | /* | ||
| 73 | * No devices on this chain, move to the next | ||
| 74 | */ | ||
| 75 | info->index++; | ||
| 76 | info->bd = (info->index < ARRAY_SIZE(major_names)) ? | ||
| 77 | major_names[info->index] : NULL; | ||
| 78 | if (info->bd) | ||
| 79 | goto out; | ||
| 80 | } | ||
| 81 | |||
| 82 | out: | ||
| 83 | return info; | ||
| 84 | } | ||
| 85 | |||
| 86 | void *acquire_blkdev_list(void) | ||
| 87 | { | ||
| 88 | down(&block_subsys_sem); | ||
| 89 | return get_next_blkdev(NULL); | ||
| 90 | } | ||
| 91 | |||
| 92 | void release_blkdev_list(void *dev) | ||
| 93 | { | ||
| 94 | up(&block_subsys_sem); | ||
| 95 | kfree(dev); | ||
| 96 | } | ||
| 97 | |||
| 98 | |||
| 99 | /* | ||
| 100 | * Count the number of records in the blkdev_list. | ||
| 101 | * must be called with the block_subsys_sem held | ||
| 102 | */ | ||
| 103 | int count_blkdev_list(void) | ||
| 44 | { | 104 | { |
| 45 | struct blk_major_name *n; | 105 | struct blk_major_name *n; |
| 46 | int i, len; | 106 | int i, count; |
| 47 | 107 | ||
| 48 | len = snprintf(p, (PAGE_SIZE-used), "\nBlock devices:\n"); | 108 | count = 0; |
| 49 | 109 | ||
| 50 | down(&block_subsys_sem); | ||
| 51 | for (i = 0; i < ARRAY_SIZE(major_names); i++) { | 110 | for (i = 0; i < ARRAY_SIZE(major_names); i++) { |
| 52 | for (n = major_names[i]; n; n = n->next) { | 111 | for (n = major_names[i]; n; n = n->next) |
| 53 | /* | 112 | count++; |
| 54 | * If the curent string plus the 5 extra characters | ||
| 55 | * in the line would run us off the page, then we're done | ||
| 56 | */ | ||
| 57 | if ((len + used + strlen(n->name) + 5) >= PAGE_SIZE) | ||
| 58 | goto page_full; | ||
| 59 | len += sprintf(p+len, "%3d %s\n", | ||
| 60 | n->major, n->name); | ||
| 61 | } | ||
| 62 | } | 113 | } |
| 63 | page_full: | ||
| 64 | up(&block_subsys_sem); | ||
| 65 | 114 | ||
| 66 | return len; | 115 | return count; |
| 67 | } | 116 | } |
| 68 | #endif | 117 | |
| 118 | /* | ||
| 119 | * extract the major and name values from a blkdev_info struct | ||
| 120 | * passed in as a void to *dev. Must be called with | ||
| 121 | * block_subsys_sem held | ||
| 122 | */ | ||
| 123 | int get_blkdev_info(void *dev, int *major, char **name) | ||
| 124 | { | ||
| 125 | struct blkdev_info *info = dev; | ||
| 126 | |||
| 127 | if (info->bd == NULL) | ||
| 128 | return 1; | ||
| 129 | |||
| 130 | *major = info->bd->major; | ||
| 131 | *name = info->bd->name; | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 69 | 135 | ||
| 70 | int register_blkdev(unsigned int major, const char *name) | 136 | int register_blkdev(unsigned int major, const char *name) |
| 71 | { | 137 | { |
