]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - block/partitions/check.c
block: support embedded device command line partition
[mirror_ubuntu-artful-kernel.git] / block / partitions / check.c
CommitLineData
1da177e4
LT
1/*
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
5a0e3ad6 16#include <linux/slab.h>
ac2e5327 17#include <linux/vmalloc.h>
1da177e4 18#include <linux/ctype.h>
6f2576af 19#include <linux/genhd.h>
1da177e4
LT
20
21#include "check.h"
1da177e4
LT
22
23#include "acorn.h"
24#include "amiga.h"
25#include "atari.h"
26#include "ldm.h"
27#include "mac.h"
28#include "msdos.h"
29#include "osf.h"
30#include "sgi.h"
31#include "sun.h"
32#include "ibm.h"
33#include "ultrix.h"
34#include "efi.h"
0e6e1db4 35#include "karma.h"
19d0e8ce 36#include "sysv68.h"
bab55417 37#include "cmdline.h"
1da177e4 38
1da177e4
LT
39int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
40
1493bf21 41static int (*check_part[])(struct parsed_partitions *) = {
1da177e4
LT
42 /*
43 * Probe partition formats with tables at disk address 0
44 * that also have an ADFS boot block at 0xdc0.
45 */
46#ifdef CONFIG_ACORN_PARTITION_ICS
47 adfspart_check_ICS,
48#endif
49#ifdef CONFIG_ACORN_PARTITION_POWERTEC
50 adfspart_check_POWERTEC,
51#endif
52#ifdef CONFIG_ACORN_PARTITION_EESOX
53 adfspart_check_EESOX,
54#endif
55
56 /*
57 * Now move on to formats that only have partition info at
58 * disk address 0xdc0. Since these may also have stale
59 * PC/BIOS partition tables, they need to come before
60 * the msdos entry.
61 */
62#ifdef CONFIG_ACORN_PARTITION_CUMANA
63 adfspart_check_CUMANA,
64#endif
65#ifdef CONFIG_ACORN_PARTITION_ADFS
66 adfspart_check_ADFS,
67#endif
68
bab55417
CZ
69#ifdef CONFIG_CMDLINE_PARTITION
70 cmdline_partition,
71#endif
1da177e4
LT
72#ifdef CONFIG_EFI_PARTITION
73 efi_partition, /* this must come before msdos */
74#endif
75#ifdef CONFIG_SGI_PARTITION
76 sgi_partition,
77#endif
78#ifdef CONFIG_LDM_PARTITION
79 ldm_partition, /* this must come before msdos */
80#endif
1da177e4
LT
81#ifdef CONFIG_MSDOS_PARTITION
82 msdos_partition,
83#endif
84#ifdef CONFIG_OSF_PARTITION
85 osf_partition,
86#endif
87#ifdef CONFIG_SUN_PARTITION
88 sun_partition,
89#endif
90#ifdef CONFIG_AMIGA_PARTITION
91 amiga_partition,
92#endif
93#ifdef CONFIG_ATARI_PARTITION
94 atari_partition,
95#endif
96#ifdef CONFIG_MAC_PARTITION
97 mac_partition,
98#endif
99#ifdef CONFIG_ULTRIX_PARTITION
100 ultrix_partition,
101#endif
102#ifdef CONFIG_IBM_PARTITION
103 ibm_partition,
0e6e1db4
BC
104#endif
105#ifdef CONFIG_KARMA_PARTITION
106 karma_partition,
19d0e8ce
PDM
107#endif
108#ifdef CONFIG_SYSV68_PARTITION
109 sysv68_partition,
1da177e4
LT
110#endif
111 NULL
112};
1da177e4 113
ac2e5327
ML
114static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
115{
116 struct parsed_partitions *state;
117 int nr;
118
119 state = kzalloc(sizeof(*state), GFP_KERNEL);
120 if (!state)
121 return NULL;
122
123 nr = disk_max_parts(hd);
124 state->parts = vzalloc(nr * sizeof(state->parts[0]));
125 if (!state->parts) {
126 kfree(state);
127 return NULL;
128 }
129
130 state->limit = nr;
131
132 return state;
133}
134
135void free_partitions(struct parsed_partitions *state)
136{
137 vfree(state->parts);
138 kfree(state);
139}
140
94ea4158 141struct parsed_partitions *
1da177e4
LT
142check_partition(struct gendisk *hd, struct block_device *bdev)
143{
144 struct parsed_partitions *state;
57881dd9 145 int i, res, err;
1da177e4 146
ac2e5327 147 state = allocate_partitions(hd);
1da177e4
LT
148 if (!state)
149 return NULL;
9c867fbe
AD
150 state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
151 if (!state->pp_buf) {
ac2e5327 152 free_partitions(state);
9c867fbe
AD
153 return NULL;
154 }
155 state->pp_buf[0] = '\0';
1da177e4 156
1493bf21 157 state->bdev = bdev;
a2964188 158 disk_name(hd, 0, state->name);
9c867fbe 159 snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
a2964188 160 if (isdigit(state->name[strlen(state->name)-1]))
1da177e4 161 sprintf(state->name, "p");
a2964188 162
57881dd9 163 i = res = err = 0;
1da177e4 164 while (!res && check_part[i]) {
ac2e5327 165 memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
1493bf21 166 res = check_part[i++](state);
57881dd9
S
167 if (res < 0) {
168 /* We have hit an I/O error which we don't report now.
169 * But record it, and let the others do their job.
170 */
171 err = res;
172 res = 0;
173 }
174
1da177e4 175 }
9c867fbe
AD
176 if (res > 0) {
177 printk(KERN_INFO "%s", state->pp_buf);
178
179 free_page((unsigned long)state->pp_buf);
1da177e4 180 return state;
9c867fbe 181 }
b403a98e
TH
182 if (state->access_beyond_eod)
183 err = -ENOSPC;
9bebff6c 184 if (err)
57881dd9
S
185 /* The partition is unrecognized. So report I/O errors if there were any */
186 res = err;
1da177e4 187 if (!res)
9c867fbe 188 strlcat(state->pp_buf, " unknown partition table\n", PAGE_SIZE);
1da177e4 189 else if (warn_no_part)
9c867fbe
AD
190 strlcat(state->pp_buf, " unable to read partition table\n", PAGE_SIZE);
191
192 printk(KERN_INFO "%s", state->pp_buf);
193
194 free_page((unsigned long)state->pp_buf);
ac2e5327 195 free_partitions(state);
5127d002 196 return ERR_PTR(res);
1da177e4 197}