Branch data Line data Source code
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 : :
16 : : #include <linux/slab.h>
17 : : #include <linux/vmalloc.h>
18 : : #include <linux/ctype.h>
19 : : #include <linux/genhd.h>
20 : :
21 : : #include "check.h"
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"
35 : : #include "karma.h"
36 : : #include "sysv68.h"
37 : : #include "cmdline.h"
38 : :
39 : : int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
40 : :
41 : : static int (*check_part[])(struct parsed_partitions *) = {
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 : :
69 : : #ifdef CONFIG_CMDLINE_PARTITION
70 : : cmdline_partition,
71 : : #endif
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
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,
104 : : #endif
105 : : #ifdef CONFIG_KARMA_PARTITION
106 : : karma_partition,
107 : : #endif
108 : : #ifdef CONFIG_SYSV68_PARTITION
109 : : sysv68_partition,
110 : : #endif
111 : : NULL
112 : : };
113 : :
114 : 0 : static 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 [ # # ]: 0 : if (!state)
121 : : return NULL;
122 : :
123 : : nr = disk_max_parts(hd);
124 : 0 : state->parts = vzalloc(nr * sizeof(state->parts[0]));
125 [ # # ]: 0 : if (!state->parts) {
126 : 0 : kfree(state);
127 : 0 : return NULL;
128 : : }
129 : :
130 : 0 : state->limit = nr;
131 : :
132 : 0 : return state;
133 : : }
134 : :
135 : 0 : void free_partitions(struct parsed_partitions *state)
136 : : {
137 : 0 : vfree(state->parts);
138 : 0 : kfree(state);
139 : 0 : }
140 : :
141 : : struct parsed_partitions *
142 : 0 : check_partition(struct gendisk *hd, struct block_device *bdev)
143 : : {
144 : : struct parsed_partitions *state;
145 : : int i, res, err;
146 : :
147 : 0 : state = allocate_partitions(hd);
148 [ # # ]: 0 : if (!state)
149 : : return NULL;
150 : 0 : state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
151 [ # # ]: 0 : if (!state->pp_buf) {
152 : : free_partitions(state);
153 : 0 : return NULL;
154 : : }
155 : 0 : state->pp_buf[0] = '\0';
156 : :
157 : 0 : state->bdev = bdev;
158 : 0 : disk_name(hd, 0, state->name);
159 : 0 : snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
160 [ # # ]: 0 : if (isdigit(state->name[strlen(state->name)-1]))
161 : 0 : sprintf(state->name, "p");
162 : :
163 : : i = res = err = 0;
164 [ # # ][ # # ]: 0 : while (!res && check_part[i]) {
165 [ # # ]: 0 : memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
166 : 0 : res = check_part[i++](state);
167 [ # # ]: 0 : 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 : :
175 : : }
176 [ # # ]: 0 : if (res > 0) {
177 : 0 : printk(KERN_INFO "%s", state->pp_buf);
178 : :
179 : 0 : free_page((unsigned long)state->pp_buf);
180 : 0 : return state;
181 : : }
182 [ # # ]: 0 : if (state->access_beyond_eod)
183 : : err = -ENOSPC;
184 [ # # ]: 0 : if (err)
185 : : /* The partition is unrecognized. So report I/O errors if there were any */
186 : : res = err;
187 [ # # ]: 0 : if (!res)
188 : 0 : strlcat(state->pp_buf, " unknown partition table\n", PAGE_SIZE);
189 [ # # ]: 0 : else if (warn_no_part)
190 : 0 : strlcat(state->pp_buf, " unable to read partition table\n", PAGE_SIZE);
191 : :
192 : 0 : printk(KERN_INFO "%s", state->pp_buf);
193 : :
194 : 0 : free_page((unsigned long)state->pp_buf);
195 : : free_partitions(state);
196 : 0 : return ERR_PTR(res);
197 : : }
|