diff options
-rw-r--r-- | block/genhd.c | 53 | ||||
-rw-r--r-- | include/linux/genhd.h | 1 | ||||
-rw-r--r-- | init/do_mounts.c | 7 |
3 files changed, 60 insertions, 1 deletions
diff --git a/block/genhd.c b/block/genhd.c index b5664440896c..93a2cf654597 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -213,6 +213,59 @@ struct gendisk *get_gendisk(dev_t dev, int *part) | |||
213 | return kobj ? to_disk(kobj) : NULL; | 213 | return kobj ? to_disk(kobj) : NULL; |
214 | } | 214 | } |
215 | 215 | ||
216 | /* | ||
217 | * print a full list of all partitions - intended for places where the root | ||
218 | * filesystem can't be mounted and thus to give the victim some idea of what | ||
219 | * went wrong | ||
220 | */ | ||
221 | void __init printk_all_partitions(void) | ||
222 | { | ||
223 | int n; | ||
224 | struct gendisk *sgp; | ||
225 | |||
226 | mutex_lock(&block_subsys_lock); | ||
227 | /* For each block device... */ | ||
228 | list_for_each_entry(sgp, &block_subsys.list, kobj.entry) { | ||
229 | char buf[BDEVNAME_SIZE]; | ||
230 | /* | ||
231 | * Don't show empty devices or things that have been surpressed | ||
232 | */ | ||
233 | if (get_capacity(sgp) == 0 || | ||
234 | (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)) | ||
235 | continue; | ||
236 | |||
237 | /* | ||
238 | * Note, unlike /proc/partitions, I am showing the numbers in | ||
239 | * hex - the same format as the root= option takes. | ||
240 | */ | ||
241 | printk("%02x%02x %10llu %s", | ||
242 | sgp->major, sgp->first_minor, | ||
243 | (unsigned long long)get_capacity(sgp) >> 1, | ||
244 | disk_name(sgp, 0, buf)); | ||
245 | if (sgp->driverfs_dev != NULL && | ||
246 | sgp->driverfs_dev->driver != NULL) | ||
247 | printk(" driver: %s\n", | ||
248 | sgp->driverfs_dev->driver->name); | ||
249 | else | ||
250 | printk(" (driver?)\n"); | ||
251 | |||
252 | /* now show the partitions */ | ||
253 | for (n = 0; n < sgp->minors - 1; ++n) { | ||
254 | if (sgp->part[n] == NULL) | ||
255 | continue; | ||
256 | if (sgp->part[n]->nr_sects == 0) | ||
257 | continue; | ||
258 | printk(" %02x%02x %10llu %s\n", | ||
259 | sgp->major, n + 1 + sgp->first_minor, | ||
260 | (unsigned long long)sgp->part[n]->nr_sects >> 1, | ||
261 | disk_name(sgp, n + 1, buf)); | ||
262 | } /* partition subloop */ | ||
263 | } /* Block device loop */ | ||
264 | |||
265 | mutex_unlock(&block_subsys_lock); | ||
266 | return; | ||
267 | } | ||
268 | |||
216 | #ifdef CONFIG_PROC_FS | 269 | #ifdef CONFIG_PROC_FS |
217 | /* iterator */ | 270 | /* iterator */ |
218 | static void *part_start(struct seq_file *part, loff_t *pos) | 271 | static void *part_start(struct seq_file *part, loff_t *pos) |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 2c65da7cabb2..f589559cf070 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -413,6 +413,7 @@ char *disk_name (struct gendisk *hd, int part, char *buf); | |||
413 | extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); | 413 | extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); |
414 | extern void add_partition(struct gendisk *, int, sector_t, sector_t, int); | 414 | extern void add_partition(struct gendisk *, int, sector_t, sector_t, int); |
415 | extern void delete_partition(struct gendisk *, int); | 415 | extern void delete_partition(struct gendisk *, int); |
416 | extern void printk_all_partitions(void); | ||
416 | 417 | ||
417 | extern struct gendisk *alloc_disk_node(int minors, int node_id); | 418 | extern struct gendisk *alloc_disk_node(int minors, int node_id); |
418 | extern struct gendisk *alloc_disk(int minors); | 419 | extern struct gendisk *alloc_disk(int minors); |
diff --git a/init/do_mounts.c b/init/do_mounts.c index 3f57ed4599d6..46fe407fb03e 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/root_dev.h> | 7 | #include <linux/root_dev.h> |
8 | #include <linux/security.h> | 8 | #include <linux/security.h> |
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/genhd.h> | ||
10 | #include <linux/mount.h> | 11 | #include <linux/mount.h> |
11 | #include <linux/device.h> | 12 | #include <linux/device.h> |
12 | #include <linux/init.h> | 13 | #include <linux/init.h> |
@@ -308,17 +309,21 @@ retry: | |||
308 | /* | 309 | /* |
309 | * Allow the user to distinguish between failed sys_open | 310 | * Allow the user to distinguish between failed sys_open |
310 | * and bad superblock on root device. | 311 | * and bad superblock on root device. |
312 | * and give them a list of the available devices | ||
311 | */ | 313 | */ |
312 | #ifdef CONFIG_BLOCK | 314 | #ifdef CONFIG_BLOCK |
313 | __bdevname(ROOT_DEV, b); | 315 | __bdevname(ROOT_DEV, b); |
314 | #endif | 316 | #endif |
315 | printk("VFS: Cannot open root device \"%s\" or %s\n", | 317 | printk("VFS: Cannot open root device \"%s\" or %s\n", |
316 | root_device_name, b); | 318 | root_device_name, b); |
317 | printk("Please append a correct \"root=\" boot option\n"); | 319 | printk("Please append a correct \"root=\" boot option; here are the available partitions:\n"); |
318 | 320 | ||
321 | printk_all_partitions(); | ||
319 | panic("VFS: Unable to mount root fs on %s", b); | 322 | panic("VFS: Unable to mount root fs on %s", b); |
320 | } | 323 | } |
321 | 324 | ||
325 | printk("List of all partitions:\n"); | ||
326 | printk_all_partitions(); | ||
322 | printk("No filesystem could mount root, tried: "); | 327 | printk("No filesystem could mount root, tried: "); |
323 | for (p = fs_names; *p; p += strlen(p)+1) | 328 | for (p = fs_names; *p; p += strlen(p)+1) |
324 | printk(" %s", p); | 329 | printk(" %s", p); |