Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
check.c
Go to the documentation of this file.
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 
37 int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
38 
39 static 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
46 #endif
47 #ifdef CONFIG_ACORN_PARTITION_POWERTEC
49 #endif
50 #ifdef CONFIG_ACORN_PARTITION_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
62 #endif
63 #ifdef CONFIG_ACORN_PARTITION_ADFS
65 #endif
66 
67 #ifdef CONFIG_EFI_PARTITION
68  efi_partition, /* this must come before msdos */
69 #endif
70 #ifdef CONFIG_SGI_PARTITION
72 #endif
73 #ifdef CONFIG_LDM_PARTITION
74  ldm_partition, /* this must come before msdos */
75 #endif
76 #ifdef CONFIG_MSDOS_PARTITION
78 #endif
79 #ifdef CONFIG_OSF_PARTITION
81 #endif
82 #ifdef CONFIG_SUN_PARTITION
84 #endif
85 #ifdef CONFIG_AMIGA_PARTITION
87 #endif
88 #ifdef CONFIG_ATARI_PARTITION
90 #endif
91 #ifdef CONFIG_MAC_PARTITION
93 #endif
94 #ifdef CONFIG_ULTRIX_PARTITION
96 #endif
97 #ifdef CONFIG_IBM_PARTITION
99 #endif
100 #ifdef CONFIG_KARMA_PARTITION
102 #endif
103 #ifdef CONFIG_SYSV68_PARTITION
105 #endif
106  NULL
107 };
108 
109 struct parsed_partitions *
110 check_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 }