blob: bc908672c9764ca782f1e575825c1495e11a6ab4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * fs/partitions/check.c
3 *
4 * Code extracted from drivers/block/genhd.c
5 * Copyright (C) 1991-1998 Linus Torvalds
6 * Re-organised Feb 1998 Russell King
7 *
8 * We now have independent partition support from the
9 * block drivers, which allows all the partition code to
10 * be grouped in one location, and it to be mostly self
11 * contained.
12 *
13 * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl}
14 */
15
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090016#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <linux/ctype.h>
Jerome Marchand6f2576a2008-02-08 11:04:35 +010018#include <linux/genhd.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019
20#include "check.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22#include "acorn.h"
23#include "amiga.h"
24#include "atari.h"
25#include "ldm.h"
26#include "mac.h"
27#include "msdos.h"
28#include "osf.h"
29#include "sgi.h"
30#include "sun.h"
31#include "ibm.h"
32#include "ultrix.h"
33#include "efi.h"
Bob Copeland0e6e1db2006-01-16 22:14:20 -080034#include "karma.h"
Philippe De Muyter19d0e8c2007-05-08 00:29:15 -070035#include "sysv68.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Linus Torvalds1da177e2005-04-16 15:20:36 -070037int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
38
Tejun Heo1493bf22010-05-15 20:09:30 +020039static int (*check_part[])(struct parsed_partitions *) = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 /*
41 * Probe partition formats with tables at disk address 0
42 * that also have an ADFS boot block at 0xdc0.
43 */
44#ifdef CONFIG_ACORN_PARTITION_ICS
45 adfspart_check_ICS,
46#endif
47#ifdef CONFIG_ACORN_PARTITION_POWERTEC
48 adfspart_check_POWERTEC,
49#endif
50#ifdef CONFIG_ACORN_PARTITION_EESOX
51 adfspart_check_EESOX,
52#endif
53
54 /*
55 * Now move on to formats that only have partition info at
56 * disk address 0xdc0. Since these may also have stale
57 * PC/BIOS partition tables, they need to come before
58 * the msdos entry.
59 */
60#ifdef CONFIG_ACORN_PARTITION_CUMANA
61 adfspart_check_CUMANA,
62#endif
63#ifdef CONFIG_ACORN_PARTITION_ADFS
64 adfspart_check_ADFS,
65#endif
66
67#ifdef CONFIG_EFI_PARTITION
68 efi_partition, /* this must come before msdos */
69#endif
70#ifdef CONFIG_SGI_PARTITION
71 sgi_partition,
72#endif
73#ifdef CONFIG_LDM_PARTITION
74 ldm_partition, /* this must come before msdos */
75#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070076#ifdef CONFIG_MSDOS_PARTITION
77 msdos_partition,
78#endif
79#ifdef CONFIG_OSF_PARTITION
80 osf_partition,
81#endif
82#ifdef CONFIG_SUN_PARTITION
83 sun_partition,
84#endif
85#ifdef CONFIG_AMIGA_PARTITION
86 amiga_partition,
87#endif
88#ifdef CONFIG_ATARI_PARTITION
89 atari_partition,
90#endif
91#ifdef CONFIG_MAC_PARTITION
92 mac_partition,
93#endif
94#ifdef CONFIG_ULTRIX_PARTITION
95 ultrix_partition,
96#endif
97#ifdef CONFIG_IBM_PARTITION
98 ibm_partition,
99#endif
Bob Copeland0e6e1db2006-01-16 22:14:20 -0800100#ifdef CONFIG_KARMA_PARTITION
101 karma_partition,
102#endif
Philippe De Muyter19d0e8c2007-05-08 00:29:15 -0700103#ifdef CONFIG_SYSV68_PARTITION
104 sysv68_partition,
105#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 NULL
107};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
Al Viro94ea4152011-09-16 00:45:36 -0400109struct parsed_partitions *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110check_partition(struct gendisk *hd, struct block_device *bdev)
111{
112 struct parsed_partitions *state;
Suzuki K P57881dd2006-12-06 20:35:16 -0800113 int i, res, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Tejun Heob403a982010-05-15 20:09:31 +0200115 state = kzalloc(sizeof(struct parsed_partitions), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 if (!state)
117 return NULL;
Alexey Dobriyan9c867fb2010-08-10 18:03:14 -0700118 state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
119 if (!state->pp_buf) {
120 kfree(state);
121 return NULL;
122 }
123 state->pp_buf[0] = '\0';
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
Tejun Heo1493bf22010-05-15 20:09:30 +0200125 state->bdev = bdev;
Greg Kroah-Hartmana2964182005-06-20 21:15:16 -0700126 disk_name(hd, 0, state->name);
Alexey Dobriyan9c867fb2010-08-10 18:03:14 -0700127 snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
Greg Kroah-Hartmana2964182005-06-20 21:15:16 -0700128 if (isdigit(state->name[strlen(state->name)-1]))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 sprintf(state->name, "p");
Greg Kroah-Hartmana2964182005-06-20 21:15:16 -0700130
Tejun Heob5d0b9d2008-09-03 09:06:42 +0200131 state->limit = disk_max_parts(hd);
Suzuki K P57881dd2006-12-06 20:35:16 -0800132 i = res = err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 while (!res && check_part[i]) {
134 memset(&state->parts, 0, sizeof(state->parts));
Tejun Heo1493bf22010-05-15 20:09:30 +0200135 res = check_part[i++](state);
Suzuki K P57881dd2006-12-06 20:35:16 -0800136 if (res < 0) {
137 /* We have hit an I/O error which we don't report now.
138 * But record it, and let the others do their job.
139 */
140 err = res;
141 res = 0;
142 }
143
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 }
Alexey Dobriyan9c867fb2010-08-10 18:03:14 -0700145 if (res > 0) {
146 printk(KERN_INFO "%s", state->pp_buf);
147
148 free_page((unsigned long)state->pp_buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 return state;
Alexey Dobriyan9c867fb2010-08-10 18:03:14 -0700150 }
Tejun Heob403a982010-05-15 20:09:31 +0200151 if (state->access_beyond_eod)
152 err = -ENOSPC;
suzuki9bebff62007-03-07 20:41:24 -0800153 if (err)
Suzuki K P57881dd2006-12-06 20:35:16 -0800154 /* The partition is unrecognized. So report I/O errors if there were any */
155 res = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 if (!res)
Alexey Dobriyan9c867fb2010-08-10 18:03:14 -0700157 strlcat(state->pp_buf, " unknown partition table\n", PAGE_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 else if (warn_no_part)
Alexey Dobriyan9c867fb2010-08-10 18:03:14 -0700159 strlcat(state->pp_buf, " unable to read partition table\n", PAGE_SIZE);
160
161 printk(KERN_INFO "%s", state->pp_buf);
162
163 free_page((unsigned long)state->pp_buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 kfree(state);
Suzuki Kp5127d002006-12-06 20:35:14 -0800165 return ERR_PTR(res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166}