Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.10 193 lines 4.3 kB view raw
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 38int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ 39 40static int (*check_part[])(struct parsed_partitions *) = { 41 /* 42 * Probe partition formats with tables at disk address 0 43 * that also have an ADFS boot block at 0xdc0. 44 */ 45#ifdef CONFIG_ACORN_PARTITION_ICS 46 adfspart_check_ICS, 47#endif 48#ifdef CONFIG_ACORN_PARTITION_POWERTEC 49 adfspart_check_POWERTEC, 50#endif 51#ifdef CONFIG_ACORN_PARTITION_EESOX 52 adfspart_check_EESOX, 53#endif 54 55 /* 56 * Now move on to formats that only have partition info at 57 * disk address 0xdc0. Since these may also have stale 58 * PC/BIOS partition tables, they need to come before 59 * the msdos entry. 60 */ 61#ifdef CONFIG_ACORN_PARTITION_CUMANA 62 adfspart_check_CUMANA, 63#endif 64#ifdef CONFIG_ACORN_PARTITION_ADFS 65 adfspart_check_ADFS, 66#endif 67 68#ifdef CONFIG_EFI_PARTITION 69 efi_partition, /* this must come before msdos */ 70#endif 71#ifdef CONFIG_SGI_PARTITION 72 sgi_partition, 73#endif 74#ifdef CONFIG_LDM_PARTITION 75 ldm_partition, /* this must come before msdos */ 76#endif 77#ifdef CONFIG_MSDOS_PARTITION 78 msdos_partition, 79#endif 80#ifdef CONFIG_OSF_PARTITION 81 osf_partition, 82#endif 83#ifdef CONFIG_SUN_PARTITION 84 sun_partition, 85#endif 86#ifdef CONFIG_AMIGA_PARTITION 87 amiga_partition, 88#endif 89#ifdef CONFIG_ATARI_PARTITION 90 atari_partition, 91#endif 92#ifdef CONFIG_MAC_PARTITION 93 mac_partition, 94#endif 95#ifdef CONFIG_ULTRIX_PARTITION 96 ultrix_partition, 97#endif 98#ifdef CONFIG_IBM_PARTITION 99 ibm_partition, 100#endif 101#ifdef CONFIG_KARMA_PARTITION 102 karma_partition, 103#endif 104#ifdef CONFIG_SYSV68_PARTITION 105 sysv68_partition, 106#endif 107 NULL 108}; 109 110static struct parsed_partitions *allocate_partitions(struct gendisk *hd) 111{ 112 struct parsed_partitions *state; 113 int nr; 114 115 state = kzalloc(sizeof(*state), GFP_KERNEL); 116 if (!state) 117 return NULL; 118 119 nr = disk_max_parts(hd); 120 state->parts = vzalloc(nr * sizeof(state->parts[0])); 121 if (!state->parts) { 122 kfree(state); 123 return NULL; 124 } 125 126 state->limit = nr; 127 128 return state; 129} 130 131void free_partitions(struct parsed_partitions *state) 132{ 133 vfree(state->parts); 134 kfree(state); 135} 136 137struct parsed_partitions * 138check_partition(struct gendisk *hd, struct block_device *bdev) 139{ 140 struct parsed_partitions *state; 141 int i, res, err; 142 143 state = allocate_partitions(hd); 144 if (!state) 145 return NULL; 146 state->pp_buf = (char *)__get_free_page(GFP_KERNEL); 147 if (!state->pp_buf) { 148 free_partitions(state); 149 return NULL; 150 } 151 state->pp_buf[0] = '\0'; 152 153 state->bdev = bdev; 154 disk_name(hd, 0, state->name); 155 snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name); 156 if (isdigit(state->name[strlen(state->name)-1])) 157 sprintf(state->name, "p"); 158 159 i = res = err = 0; 160 while (!res && check_part[i]) { 161 memset(state->parts, 0, state->limit * sizeof(state->parts[0])); 162 res = check_part[i++](state); 163 if (res < 0) { 164 /* We have hit an I/O error which we don't report now. 165 * But record it, and let the others do their job. 166 */ 167 err = res; 168 res = 0; 169 } 170 171 } 172 if (res > 0) { 173 printk(KERN_INFO "%s", state->pp_buf); 174 175 free_page((unsigned long)state->pp_buf); 176 return state; 177 } 178 if (state->access_beyond_eod) 179 err = -ENOSPC; 180 if (err) 181 /* The partition is unrecognized. So report I/O errors if there were any */ 182 res = err; 183 if (!res) 184 strlcat(state->pp_buf, " unknown partition table\n", PAGE_SIZE); 185 else if (warn_no_part) 186 strlcat(state->pp_buf, " unable to read partition table\n", PAGE_SIZE); 187 188 printk(KERN_INFO "%s", state->pp_buf); 189 190 free_page((unsigned long)state->pp_buf); 191 free_partitions(state); 192 return ERR_PTR(res); 193}