aboutsummaryrefslogtreecommitdiffstats
path: root/block/partitions/check.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/partitions/check.c')
-rw-r--r--block/partitions/check.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/block/partitions/check.c b/block/partitions/check.c
new file mode 100644
index 000000000000..bc908672c976
--- /dev/null
+++ b/block/partitions/check.c
@@ -0,0 +1,166 @@
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/ctype.h>
18#include <linux/genhd.h>
19
20#include "check.h"
21
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"
34#include "karma.h"
35#include "sysv68.h"
36
37int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
38
39static int (*check_part[])(struct parsed_partitions *) = {
40 /*
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
76#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
100#ifdef CONFIG_KARMA_PARTITION
101 karma_partition,
102#endif
103#ifdef CONFIG_SYSV68_PARTITION
104 sysv68_partition,
105#endif
106 NULL
107};
108
109struct parsed_partitions *
110check_partition(struct gendisk *hd, struct block_device *bdev)
111{
112 struct parsed_partitions *state;
113 int i, res, err;
114
115 state = kzalloc(sizeof(struct parsed_partitions), GFP_KERNEL);
116 if (!state)
117 return NULL;
118 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';
124
125 state->bdev = bdev;
126 disk_name(hd, 0, state->name);
127 snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
128 if (isdigit(state->name[strlen(state->name)-1]))
129 sprintf(state->name, "p");
130
131 state->limit = disk_max_parts(hd);
132 i = res = err = 0;
133 while (!res && check_part[i]) {
134 memset(&state->parts, 0, sizeof(state->parts));
135 res = check_part[i++](state);
136 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
144 }
145 if (res > 0) {
146 printk(KERN_INFO "%s", state->pp_buf);
147
148 free_page((unsigned long)state->pp_buf);
149 return state;
150 }
151 if (state->access_beyond_eod)
152 err = -ENOSPC;
153 if (err)
154 /* The partition is unrecognized. So report I/O errors if there were any */
155 res = err;
156 if (!res)
157 strlcat(state->pp_buf, " unknown partition table\n", PAGE_SIZE);
158 else if (warn_no_part)
159 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);
164 kfree(state);
165 return ERR_PTR(res);
166}