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 v5.3 198 lines 4.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fs/partitions/check.c 4 * 5 * Code extracted from drivers/block/genhd.c 6 * Copyright (C) 1991-1998 Linus Torvalds 7 * Re-organised Feb 1998 Russell King 8 * 9 * We now have independent partition support from the 10 * block drivers, which allows all the partition code to 11 * be grouped in one location, and it to be mostly self 12 * contained. 13 * 14 * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl} 15 */ 16 17#include <linux/slab.h> 18#include <linux/vmalloc.h> 19#include <linux/ctype.h> 20#include <linux/genhd.h> 21 22#include "check.h" 23 24#include "acorn.h" 25#include "amiga.h" 26#include "atari.h" 27#include "ldm.h" 28#include "mac.h" 29#include "msdos.h" 30#include "osf.h" 31#include "sgi.h" 32#include "sun.h" 33#include "ibm.h" 34#include "ultrix.h" 35#include "efi.h" 36#include "karma.h" 37#include "sysv68.h" 38#include "cmdline.h" 39 40int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ 41 42static int (*check_part[])(struct parsed_partitions *) = { 43 /* 44 * Probe partition formats with tables at disk address 0 45 * that also have an ADFS boot block at 0xdc0. 46 */ 47#ifdef CONFIG_ACORN_PARTITION_ICS 48 adfspart_check_ICS, 49#endif 50#ifdef CONFIG_ACORN_PARTITION_POWERTEC 51 adfspart_check_POWERTEC, 52#endif 53#ifdef CONFIG_ACORN_PARTITION_EESOX 54 adfspart_check_EESOX, 55#endif 56 57 /* 58 * Now move on to formats that only have partition info at 59 * disk address 0xdc0. Since these may also have stale 60 * PC/BIOS partition tables, they need to come before 61 * the msdos entry. 62 */ 63#ifdef CONFIG_ACORN_PARTITION_CUMANA 64 adfspart_check_CUMANA, 65#endif 66#ifdef CONFIG_ACORN_PARTITION_ADFS 67 adfspart_check_ADFS, 68#endif 69 70#ifdef CONFIG_CMDLINE_PARTITION 71 cmdline_partition, 72#endif 73#ifdef CONFIG_EFI_PARTITION 74 efi_partition, /* this must come before msdos */ 75#endif 76#ifdef CONFIG_SGI_PARTITION 77 sgi_partition, 78#endif 79#ifdef CONFIG_LDM_PARTITION 80 ldm_partition, /* this must come before msdos */ 81#endif 82#ifdef CONFIG_MSDOS_PARTITION 83 msdos_partition, 84#endif 85#ifdef CONFIG_OSF_PARTITION 86 osf_partition, 87#endif 88#ifdef CONFIG_SUN_PARTITION 89 sun_partition, 90#endif 91#ifdef CONFIG_AMIGA_PARTITION 92 amiga_partition, 93#endif 94#ifdef CONFIG_ATARI_PARTITION 95 atari_partition, 96#endif 97#ifdef CONFIG_MAC_PARTITION 98 mac_partition, 99#endif 100#ifdef CONFIG_ULTRIX_PARTITION 101 ultrix_partition, 102#endif 103#ifdef CONFIG_IBM_PARTITION 104 ibm_partition, 105#endif 106#ifdef CONFIG_KARMA_PARTITION 107 karma_partition, 108#endif 109#ifdef CONFIG_SYSV68_PARTITION 110 sysv68_partition, 111#endif 112 NULL 113}; 114 115static struct parsed_partitions *allocate_partitions(struct gendisk *hd) 116{ 117 struct parsed_partitions *state; 118 int nr; 119 120 state = kzalloc(sizeof(*state), GFP_KERNEL); 121 if (!state) 122 return NULL; 123 124 nr = disk_max_parts(hd); 125 state->parts = vzalloc(array_size(nr, sizeof(state->parts[0]))); 126 if (!state->parts) { 127 kfree(state); 128 return NULL; 129 } 130 131 state->limit = nr; 132 133 return state; 134} 135 136void free_partitions(struct parsed_partitions *state) 137{ 138 vfree(state->parts); 139 kfree(state); 140} 141 142struct parsed_partitions * 143check_partition(struct gendisk *hd, struct block_device *bdev) 144{ 145 struct parsed_partitions *state; 146 int i, res, err; 147 148 state = allocate_partitions(hd); 149 if (!state) 150 return NULL; 151 state->pp_buf = (char *)__get_free_page(GFP_KERNEL); 152 if (!state->pp_buf) { 153 free_partitions(state); 154 return NULL; 155 } 156 state->pp_buf[0] = '\0'; 157 158 state->bdev = bdev; 159 disk_name(hd, 0, state->name); 160 snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name); 161 if (isdigit(state->name[strlen(state->name)-1])) 162 sprintf(state->name, "p"); 163 164 i = res = err = 0; 165 while (!res && check_part[i]) { 166 memset(state->parts, 0, state->limit * sizeof(state->parts[0])); 167 res = check_part[i++](state); 168 if (res < 0) { 169 /* We have hit an I/O error which we don't report now. 170 * But record it, and let the others do their job. 171 */ 172 err = res; 173 res = 0; 174 } 175 176 } 177 if (res > 0) { 178 printk(KERN_INFO "%s", state->pp_buf); 179 180 free_page((unsigned long)state->pp_buf); 181 return state; 182 } 183 if (state->access_beyond_eod) 184 err = -ENOSPC; 185 if (err) 186 /* The partition is unrecognized. So report I/O errors if there were any */ 187 res = err; 188 if (res) { 189 if (warn_no_part) 190 strlcat(state->pp_buf, 191 " unable to read partition table\n", PAGE_SIZE); 192 printk(KERN_INFO "%s", state->pp_buf); 193 } 194 195 free_page((unsigned long)state->pp_buf); 196 free_partitions(state); 197 return ERR_PTR(res); 198}