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 39int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ 40 41static 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 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 141struct parsed_partitions * 142check_partition(struct gendisk *hd, struct block_device *bdev) 143{ 144 struct parsed_partitions *state; 145 int i, res, err; 146 147 state = allocate_partitions(hd); 148 if (!state) 149 return NULL; 150 state->pp_buf = (char *)__get_free_page(GFP_KERNEL); 151 if (!state->pp_buf) { 152 free_partitions(state); 153 return NULL; 154 } 155 state->pp_buf[0] = '\0'; 156 157 state->bdev = bdev; 158 disk_name(hd, 0, state->name); 159 snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name); 160 if (isdigit(state->name[strlen(state->name)-1])) 161 sprintf(state->name, "p"); 162 163 i = res = err = 0; 164 while (!res && check_part[i]) { 165 memset(state->parts, 0, state->limit * sizeof(state->parts[0])); 166 res = check_part[i++](state); 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 175 } 176 if (res > 0) { 177 printk(KERN_INFO "%s", state->pp_buf); 178 179 free_page((unsigned long)state->pp_buf); 180 return state; 181 } 182 if (state->access_beyond_eod) 183 err = -ENOSPC; 184 if (err) 185 /* The partition is unrecognized. So report I/O errors if there were any */ 186 res = err; 187 if (res) { 188 if (warn_no_part) 189 strlcat(state->pp_buf, 190 " unable to read partition table\n", PAGE_SIZE); 191 printk(KERN_INFO "%s", state->pp_buf); 192 } 193 194 free_page((unsigned long)state->pp_buf); 195 free_partitions(state); 196 return ERR_PTR(res); 197} 198